JPA Query를 이용해 여러 객체를 한번에 받아오는 법에 대해 알아보겠습니다.
예시를 들어 설명하기 위해 사용자가 유튜브 채널을 구독하는 어플리케이션이 있다고 가정하겠습니다.
이 어플리케이션을 구현하기 위해 세가지 Entity가 필요합니다.
@Entity
public class Channel {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String code;
private Long subscriptionId;
// getters, setters, etc.
}
@Entity
public class Subscription {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String code;
// getters, setters, etc.
}
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String email;
private Long subscriptionId;
// getters, setters, etc.
}
SELECT c, s, u
FROM Channel c, Subscription s, User u
WHERE c.subscriptionId = s.id AND s.id = u.subscriptionId AND u.email=:email
public class ReportRepository {
private final EntityManagerFactory emf;
public ReportRepository() {
// create an instance of entity manager factory
}
public List<Object[]> find(String email) {
EntityManager entityManager = emf.createEntityManager();
Query query = entityManager
.createQuery("SELECT c, s, u FROM Channel c, Subscription s, User u"
+ " WHERE c.subscriptionId = s.id AND s.id = u.subscriptionId AND u.email=:email");
query.setParameter("email", eamil);
return query.getResultList();
}
}
여러 객체를 한번에 반환받기 위해 SQL에서 조인하듯, Primary Key와 Foreign Key를 연결시켜줍니다.
JPA Query는 여러가지 Entity를 한번에 반환할 때 Objects 배열로 반환합니다.
이 Objects배열속 Entity의 순서는 쿼리의 Select절에 코딩한 순서와 일치합니다.
다시 말해 List안에는 서로 조인된 Entity들이 Object 배열로 저장되어있습니다.
이 순서를 기억하고, Objects 배열에 담긴 Entity들을 각 타입에 맞는 클래스로 캐스팅하여 사용할 수 있습니다.
List<Object[]> reportDetails = reportRepository.find("user1@gmail.com");
for (Object[] reportDetail : reportDetails) {
Channel channel = (Channel) reportDetail[0];
Subscription subscription = (Subscription) reportDetail[1];
User user = (User) reportDetail[2];
// do something with entities
}
참고 문헌
How to Return Multiple Entities In JPA Query. by Maciej Główka