2015-11-18 17 views
6

Si consideri il seguente modelloJPA: come recuperare con entusiasmo una collezione elemento incorporato

@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 
} 

La classe Address è annotato con @Embeddable annotazioni, e la classe Employee ha una collezione elemento incorporato di addresses. La serie di elementi fetch è impostata su FetchType.LAZY. Ora, vorrei creare un @NamedQuery che recuperi tutti i dipendenti con indirizzi inizializzati con entusiasmo. Sapendo che JOIN FETCHwill only work with entity collections annotato con @OneToMany o @ManyToMany basato su JPA 2.1, come dovrei creare una query JPQL valida che mi consenta di recuperare con interesse le raccolte di elementi incorporate?

+0

Come hai concluso che 'join fetch' funziona solo con le entità? Hai fatto un tentativo? –

+0

@DraganBozanovic: in base alla documentazione, "L'associazione a cui fa riferimento il lato destro della clausola FETCH JOIN deve essere un'associazione che appartiene a un'entità restituita come risultato della query. Non è consentito specificare un variabile di identificazione per le entità a cui fa riferimento il lato destro della clausola FETCH JOIN, e quindi i riferimenti alle entità implicitamente recuperate non possono apparire altrove nella query. " –

+0

Il percorso con valori di raccolta deve essere risolto in un campo di associazione –

risposta

2

Nella specifica JPA 2.1 (JSR 338) non riesco a trovare alcun suggerimento che recuperi i join solo per le relazioni delle entità (ma non per quelle incorporabili). JSR 338, sezione 4.4.5.3 afferma anche:

A FETCH JOIN consente il prelievo di un'associazione o elemento di raccolta come effetto collaterale della esecuzione di una query.

Come altro suggerimento seguente esempio minimo (essenzialmente simile tuo) eseguito con Hibernate 4.3.11 come JPA risultati di provider in una singola query:

Indirizzo: incorporabile entità

@Embeddable public class Address { private String city; } 

dipendenti:

@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(); 

risultante query SQL:

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 

Quindi la query JPQL sopra sembra risolvere il problema.

2

proposito, più efficace potrebbe essere non utilizzare unirsi, ma Sottoseleziona

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

rende due seleziona, invece di uno, ma non produce tanto ambiguità.