@Entity
public class Person {
@Id
private Long id;
private String email;
@ElementCollection
@CollectionTable( name = "address", joinColumns = @JoinColumn(name = "person_id") )
List<AddressInfo> addressInfoList = new ArrayList<>();
}
Entity 와 라이프 싸이클을 같이 하며 독립적으로 사용 불가능 하다.
부모 Entity가 삭제될 경우 같이 삭제된다. (실제 클래스에 cascade 를 설정하는 옵션이 없다.)
ElementCollection의 Fetch 전략은 기본이 Lazy 이다.
실제 테이블은 FK 를 이용해서 생성된다.
Hibernate: create table address (person_id bigint not null, address1 varchar(255), address2 varchar(255), zip_code varchar(255))
Hibernate: create table person (id bigint not null, email varchar(255), primary key (id))
Hibernate: alter table address add constraint FK81ihijcn1kdfwffke0c0sjqeb foreign key (person_id) references person
CollectionTable Annocation 을 사용하지 않을 경우에는 다음과 같이 테이블이 생성된다.
@Access(AccessType.PROPERTY)
public String getAddress2() {
return address1 + address2;
}
3. AccessType 이 지정되지 않은 경우는 @Id 위치에 따라 지정된다.
@Entity
public class OrderInfo {
@Id
private Long id;
private String address1;
@Transient
private String address2;
@Access(AccessType.PROPERTY)
public String getAddress2() {
return address1 + address2;
}
public void setAddress2(String address2) {
this.address2 = address2;
}
}
- @Id 위치가 필드에 있기때문에 기본적으로 AccessType.FIELD 가 적용된다. AccessType.PROPERTY를 같이 적용하기 위해서는 메소드 위에 AccessType.PROPERTY 를 넣어주면 된다.
4. 기타 설명들
@Access is used to specify how JPA must access (get and set) mapped properties of the entity. If access type is set to FIELD, the values will directly be read/set on the field, bypassing getters and setters. If set to PROPERTY, the getters and setters are used to access the field value.
FIELD 로 정의하면 다이렉트로 field를 read/set 하고 PROPERTY로 설정하면 getter, setter 메소드를 통해서 접근한다. https://stackoverflow.com/questions/19264871/what-is-the-use-of-the-access-annoation-in-jpa-means-at-the-entity-level
If you use field-based access, your JPA implementation uses reflection to read or write your entity attributes directly. It also expects that you place your mapping annotations on your entity attributes. If you use property-based access, you need to annotate the getter methods of your entity attributes with the required mapping annotations. Your JPA implementation then calls the getter and setter methods to access your entity attributes.
5 reasons why you should use field-based access Better readability of your code Omit getter or setter methods that shouldn’t be called by your application Flexible implementation of getter and setter methods No need to mark utility methods as *@Transient* Avoid bugs when working with proxies
UserDetailsService에 있는 loadUserByUsername 메소드를 제정의 해서 UserDetails 객체를 정의해준다. UserDetails는 사용자의 인증정보를 담고있다. 위에서 Account Service에서 loginId로 정보를 조회해서 가져온 id, password, 권한(아직 미구현으로 객체만 생성했다) 정보를 user로 생성해주고 있다.
아직 사용이 익숙하지 않은 IntelliJ 에서 작업을 하다가 JPA의 Entity로 되어 있는 도메인들을 못찾는 현상이 발생했다.
src/main/generated 라는 폴더 안에 Qdomain 들이 실제 존재하고 있는 상황인데 build 를 돌리면 찾지 못했다.
에러 내용은 위와 같이 cannot find symbol, class QCode. 저 캡쳐는 한 부분만 캡쳐를 했지만 실제로는 모든 Qdomain을 찾지 못한다고 에러가 났다.
그래서 구글링을 해보니 generated 폴더를 패스에 추가를 해줘야 한다는 것을 알았다.
IntelliJ 에서 File>Project Structure>Modules 에 들어가면 아래와 같이 화면이 구성되어있다.
위에 화면에서는 이미 Source Folder 에 src\main\genereated 폴더가 추가한 후의 캡쳐이다. 실제로는 우측에 Source Folders 에 src\main\java 만 있었다. 실제로 추가하는 방법은 위 화면에서 보이는 좌측 트리에 src 부분을 펼쳐 보면 genreated 폴더가 보인다. 거기에서 마우스 우클릭을 하면 아래와 같이 메뉴가 나온다. 거기에서 Sources를 선택을 하면 우측 Source Folders 에 추가가 된다.
이렇게 하고 난 후 build를 실행하게 되면 에러 없이 정상적으로 success 가 된다.