-
[Spring JPA] How to retrieve Only SuperClass from a class hierarchy.Back End/Spring Data JPA 2022. 1. 28. 18:47
StackOverFlow 에서 아무도 해결 못했던데...!
제가 해냈습니다 여러분...!
✌️✌️✌️
I see many posts lead us to @Polymorphism(PolymorphismType.EXPLICIT) and using @Customizer from EclipseLink.
I could confidently tell you that those approach wouldn't work because I tested it already.
And I guess many people solved it with native query but if you want to know the way not using it, read my post.
There are 2 ways to select only superclass within @Inheritance.
1. Make Immutable Read-Only Entity.
2. Using Interface-Based DTO Projection.
I will skip immutable-approach and show you guys how to do it with DTO-Projection.
Without further ado, Let's crack this down.
These are my code snippets.
# Entity
// SuperClass - Item @Inheritance(strategy = InheritanceType.JOINED) @DiscriminatorColumn(name="dtype") @Getter @ToString @NoArgsConstructor @AllArgsConstructor @Entity public class Item{ @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; public Long itemId; //FolderId & BookmarkId public String name; public Long parentId; public BigDecimal visitCount; public Long userId; } // SubClass 1 - Folder @Getter @NoArgsConstructor @ToString(callSuper = true) @EqualsAndHashCode(callSuper = true) @Entity public class Folder extends Item{ private String test; } // SubClass 2 - Bookmark @Getter @NoArgsConstructor @ToString(callSuper = true) @Entity public class Bookmark extends Item { private String url; private String comment; }
# Interface-Based Projection
// Interface for Projection public interface ItemOnlyRes{ Long getId(); Long getItemId(); String getName(); Long getParentId(); Long getUserId(); default String toText(){ return getId()+" "+getName(); } } // Repository for SuperClass - Item public interface ItemRepository extends JpaRepository<Item,Long> { List<ItemOnlyRes> findByItemId(Long itemId); }
# Test
@Test void test(){ /* making Folder and Bookmark and Saving those .... .... .... folderRepository.saveAll(Arrays.asList(rootfolder, afolder,bfolder)); bookmarkRepository.saveAll(Arrays.asList(aMark, bMark,cMark)); */ // easy easy right? em.flush(); em.clear(); itemRepository.findByItemId(1L); }
Then, you can see clean SELECT Query without Outer Join like This !!!
Hope it'd be helpful :D ..!
[Notice]
I found Interface-Based Projection works well under version 2.6.1 but doesn't work in 2.6.3.
728x90'Back End > Spring Data JPA' 카테고리의 다른 글
save() 메서드 호출 시, select 쿼리가 하나 더 나가요 ㅠㅠ... (1) 2022.02.17 [Spring JPA] JPA, JPQL 의 조인 시 주의할 점 (Outer, Inner, Fetch) (0) 2022.01.29 [Spring JPA] Interface-Based Projection doesn't work. (0) 2022.01.28 [Spring JPA] 복합키(PK)의 성능을 알아보자! (0) 2022.01.26 [Spring JPA] @OneToOne 에서 @MapsId 를 이용해 컬럼갯수를 줄여보자! (0) 2022.01.26