JPA: How to look for a collection of inline elements

Consider the following model

@Entity // JPA and JAXB annotations here public class Employee implements Serializable { // other fields, annotations, stuffs ... @ElementCollection(fetch = FetchType.LAZY, targetClass = Address.class) @CollectionTable(name = "employee_address", schema = "hris", joinColumns = @JoinColumn(name = "employee_id", nullable = false, referencedColumnName = "employee_id", foreignKey = @ForeignKey(ConstraintMode.CONSTRAINT))) protected Set<Address> addresses; // setters, getters ... } @Embeddable // JAXB annotations here public class Address implements Serializable { // fields, setters, getters } 

The Address class is annotated with the @Embeddable annotation, and the Employee class has a built-in set of addresses . A collection of fetch elements is installed on FetchType.LAZY . Now I would like to create @NamedQuery which will retrieve all employees with eagerly initialized addresses. Knowing that JOIN FETCH will only work with entity collections annotated with @OneToMany or @ManyToMany based on JPA 2.1, how can I create a valid JPQL that would allow me to look forward to collections of inline elements?

+6
source share
2 answers

In the JPA 2.1 specification (JSR 338), I can’t find any hint that fetch connections only work with entity relationships (but not embeddable ones). JSR 338, section 4.4.5.3 even states:

A FETCH JOIN allows you to retrieve an association or collection of elements as a side effect of query execution.

As another hint of the following minimal example (essentially resembling yours) performed with Hibernate 4.3.11, since the JPA provider leads to one request:

Embeddable address:

 @Embeddable public class Address { private String city; } 

The essence of the employee:

 @Entity public class Employee { @Id private Long id; @ElementCollection(fetch = FetchType.LAZY) @CollectionTable(name = "address", joinColumns = @JoinColumn(name="employee_id")) private Set<Address> addresses; } 

JPQL query:

 em.createQuery("select e from Employee e join fetch e.addresses").getResultList(); 

The resulting SQL query:

 select employee0_.id as id1_1_, addresses1_.employee_id as employee1_1_0__, addresses1_.city as city2_5_0__ from Employee employee0_ inner join address addresses1_ on employee0_.id=addresses1_.employee_id 

So the aforementioned JPQL query seems to solve your problem.

+2
source

By the way, a more efficient way might not be to use the connection, but a subquery

 @Fetch(FetchMode.SUBSELECT) @BatchSize(size=500) 

he makes two choices, not one, but does not cause so much ambiguity.

+2
source

All Articles