본문 바로가기
공부/프로그래밍

[SpringBoot] JPA Join 설정 및 조회.

by demonic_ 2018. 8. 23.
반응형

POST 1개당 여러개의 이미지파일이 들어갈 수 있기 때문 엔터티구성을 1:N 관계로 설정했다.



Post 엔터티
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// 여기서는 Lombok을 사용했는데, ToString을 그대로쓰면 
// Post의 postImgs과 PostImg의 post 의 toString 호출을 무한반복하고
// StackOverflowError 오류가 발생한다.
// 그래서 각각 exclude 를 해야한다.
@Data
@ToString(exclude = "post")
@Entity
@Table(name = "tb_post")
public class Post extends TimeStampEntity {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;
 
    @NotNull
    private long accountId;
    private String content;
 
    // 이부분이 다른테이블과 조인관계를 지정
    // 1개의 포스트에 여러개의 이미지가 연결될 수 있으므로 1:N
    // mapperBy를 연결해두지 않으면, 둘을 매핑하는 새로운 테이블이 생성된다.
    // 여기서는 tb_post_post_imgs 이런 이름의 테이블이 생성되었었음.
    @OneToMany(mappedBy = "post")
    private Collection<PostImg> postImgs;
}
cs


PostImg 엔터티
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@Data
@ToString(exclude = "post")         // 사용이유 위에 
@Entity
@Table(name="tb_post_img")
public class PostImg extends TimeStampEntity {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;
    private long size;
    private String suffix;
    private String orgPath;
    private String orgName;
    private String onlinePath;
    private String onlineName;
 
        // 여기 입장에서 보면 Post는 1개이므로 N:1=> ManyToOne
    @ManyToOne
    @JoinColumn(name="post_id")
    private Post post;
}
cs



주석에도 달아두었지만 @OneToMany를 쓸때에는 mappedBy를 꼭 설정해두어야 한다. 그러지 않으면 둘 사이를 연결하는 테이블을 하나더 생성한다.

mapperdBy를 제거했을때, 'tb_post_post_imgs' 이름의 테이블이 생성됐었다.

여기서 mapperdBy의 post는 Post클래스의 변수명이다.



@OneToMany의 fetch 기본전략은 LAZY 이고,

@ManyToOne의 fetch 기본전략은 EAGER 이다.



findBy를 사용하면 아래와 같은 메세지를 볼 수 있다.


org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: 엔터티명, could not initialize proxy - no Session


기본적으로 LAZY 전략이기 때문에 문제가 발생하는 것이다. 이것을 해결하기 위해선 @Transactional 를 사용하면 된다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 테스트 작성
@Test
@Transactional
public void testPostList(){
    Optional<Post> post = postRepo.findById((long1);
    System.out.println("=================");
    System.out.println(post.get());
}
 
/* 결과 */
Post(
    id=1
    , accountId=1
    , content=fsfasdfdsf
    , postImgs=[
        PostImg(id=1, size=157514, suffix=jpg, orgPath=파일경로, orgName=111.jpg, onlinePath=파일경로, onlineName=0b23423c-be98-417d-ac2c-3ef0bc8eb822), 
        PostImg(id=2, size=395815, suffix=jpg, orgPath=파일경로, orgName=white-ling-3598577_1920.jpg, onlinePath=파일경로, onlineName=ed48f251-35fe-48c7-b511-14e800bdd660)]
)
cs


반응형

댓글