Back End/Spring Data JPA
[Spring JPA] How to retrieve Only SuperClass from a class hierarchy.
DevPing9_
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