인프런 커뮤니티 질문&답변

그냥곰님의 프로필 이미지
그냥곰

작성한 질문수

자바 ORM 표준 JPA 프로그래밍 - 기본편

다형성 쿼리

treat 관련 질문이 있습니다.

작성

·

392

0

JOINED 전략을 명시한 Item 클래스와

그런 Item 클래스를 상속한 Album, Book, Movie 클래스를 생성 후 코드를 다음과 같이 작성했습니다.


EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello"); //애플리케이션 전체 공유 (persistence.xml 참조)
		EntityManager em = emf.createEntityManager(); //한번 쓰고 버려야함, 쓰레드간 공유하지 않음
		EntityTransaction tx = em.getTransaction(); //조회를 제외한 DML 작업시 필수로 사용
		tx.begin();
		
		try {
			Album album = new Album();
			album.setName("album");
			album.setPrice(10000);
			album.setArtist("artist");
			em.persist(album);
			
			Book book = new Book();
			book.setName("book");
			book.setPrice(20000);
			book.setAuthor("author");
			book.setIsbn("isbn");
			em.persist(book);
			
			Movie movie = new Movie();
			movie.setName("movie");
			movie.setPrice(30000);
			movie.setDirector("director");
			movie.setActor("actor");
			em.persist(movie);
			
			em.flush();
			em.clear();
			
			//1번
			String jpql = "select i from Item i where type(i) in (Book, Movie)";
			List<Item> items = em.createQuery(jpql, Item.class).getResultList();
			for (Item data : items) {
				System.out.println("data : " + data);
			}
			
			em.clear();
			
			//2번
			jpql = "select i from Item i where treat(i as Book).author = 'author'"; //SINGLE_TABLE에서는 되는데 JOINED에서는 안 먹힘
			items = em.createQuery(jpql, Item.class).getResultList();
			for (Item data : items) {
				System.out.println("data : " + data);
			}
			
			tx.commit();
		} catch (Exception e) {
			e.printStackTrace();
			tx.rollback();
		} finally {
			em.close();
		}
		
		emf.close();

1번의 경우에는 다음과 같이 정상적으로 동작합니다.

Hibernate: 
    /* select
        i 
    from
        Item i 
    where
        type(i) in (Book, Movie) */ select
            i1_0.Id,
            i1_0.DTYPE,
            i1_0.name,
            i1_0.price,
            i1_1.artist,
            i1_2.author,
            i1_2.isbn,
            i1_3.actor,
            i1_3.director 
        from
            Item i1_0 
        left join
            Album i1_1 
                on i1_0.Id=i1_1.Id 
        left join
            Book i1_2 
                on i1_0.Id=i1_2.Id 
        left join
            Movie i1_3 
                on i1_0.Id=i1_3.Id 
        where
            i1_0.DTYPE in('B','M')
data : Book(author=author, isbn=isbn)
data : Movie(director=director, actor=actor)

그런데 2번의 경우에는 다음과 같은 현상이 발생하고 있습니다.

Hibernate: 
    /* select
        i 
    from
        Item i 
    where
        treat(i as Book).author = 'author' */ select
            i1_0.Id,
            i1_0.DTYPE,
            i1_0.name,
            i1_0.price,
            i1_1.artist,
            i1_2.author,
            i1_2.isbn,
            i1_3.actor,
            i1_3.director 
        from
            Item i1_0 
        join
            Book i1_2 
                on i1_0.Id=i1_2.Id 
        where
            i1_2.author='author'

존재하지 않는 i1_1과 i1_3을 참조있어서 오류가 나는데

왜 이런 현상이 발생하는지 궁금합니다.

 

그와 별개로 SINGLE_TABLE 전략을 사용했을 때

2번을 실행하면 저같은 경우에는 다음과 같은 쿼리가 실행됩니다.

Hibernate: 
    /* select
        i 
    from
        Item i 
    where
        treat(i as Book).author = 'author' */ select
            i1_0.Id,
            i1_0.DTYPE,
            i1_0.name,
            i1_0.price,
            i1_0.artist,
            i1_0.author,
            i1_0.isbn,
            i1_0.actor,
            i1_0.director 
        from
            (select
                * 
            from
                Item t 
            where
                t.DTYPE='B') i1_0 
        where
            i1_0.author='author'

 

그런데 강사님께서 제공해주신 pdf 파일에 보면

원래는 쿼리가 다음과 같이 실행된다고 말씀해주셨는데

select i.* from Item i where i.DTYPE = ‘B’ and i.author = ‘kim’

제가 sql 실행했을 때와 강사님이 적어주신 sql이

다른 이유가 제 생각에는 하이버네이트 버전차이때문일것 같긴한데 혹시 제 생각이 맞는지 질문드리고 싶습니다.

※ 저는 하이버네이트 6버전을 쓰고 있습니다.

답변 1

0

김영한님의 프로필 이미지
김영한
지식공유자

안녕하세요. 그냥곰님

전체 프로젝트를 압축해서 구글 드라이브로 공유해서 링크를 남겨주세요.

구글 드라이브 업로드 방법은 다음을 참고해주세요.

https://bit.ly/3fX6ygx

주의: 업로드시 링크에 있는 권한 문제 꼭 확인해주세요

추가로 다음 내용도 코멘트 부탁드립니다.

1. 실행 방법을 알려주세요.

2. 어떻게 문제를 확인할 수 있는지 자세한 설명을 남겨주세요.

감사합니다.

그냥곰님의 프로필 이미지
그냥곰

작성한 질문수

질문하기