필드 접근 : AccessType.FIELD
프로퍼티 접근 : AccessType.PROPERTY
@Access
어노테이션을 붙이지 않으면, @Id
의 위치로 접근 방식이 결정 된다.
필드 접근 방식과 프로퍼티 접근 방식을 함께 사용할 수 있다.
@Entity
public class Member {
@Id
private String id;
@Transient
private String firstName;
@Transient
private String lastName;
@Access(AccessType.PROPERTY)
public String getFullName() {
return firstName + lastName;
}
}
@GenerateValue
어노테이션을 붙힌 id에 setter를 설정했을 때 문제가 발생한다. @Entity
public class Book {
@ManyToOne
Publisher publisher;
public void setPublisher(Publisher p) {
this.publisher = p;
}
// optinal 사용(JPA에서는 optional을 제공하지 않음)
public Optional<Publisher> getPublisher() {
return Optional<Publisher>.ofNullable(this.publisher);
}
…
}
equals()
메서드와 hashCode()
의 구현이 필드에 직접적으로 접근한다. @Entity
public class Book {
@NaturalId
String isbn;
...
@Override
public int hashCode() {
return Objects.hashCode(isbn);
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Book other = (Book) obj;
return Objects.equals(isbn, other.isbn);
}
}
5번째 이유를 보고서, 프록시가 초기화되는 시점을 테스트를 해보려고했는데 필드 접근과 프로퍼티 접근의 차이점을 발견하지 못했다...
필드 접근방식, 프로퍼티 접근 방식 모두 equals가 실행될때 proxy 객체를 초기화했다.프록시에 대해서 조금 더 공부해봐야하고 버그가 발생할 상황을 고려해봐야겠다.
어찌되었든, 특별한 경우가 아니면 필드접근방식을 사용하는 것이 맞다!