2015-11-18 8 views
6

das folgende ModellJPA: Wie eifrig ein eingebettetes Element Sammlung holen

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

Die Address Klasse kommentierte mit @Embeddable Annotation und die Employee Klasse hat ein eingebettetes Element Sammlung von addresses Betrachten. Die Elementsammlung fetch ist auf FetchType.LAZY festgelegt. Jetzt möchte ich ein @NamedQuery erstellen, das alle Mitarbeiter mit Adressen abrufen würde, die eifrig initialisiert wurden. Wenn ich wüsste, dass JOIN FETCHwill only work with entity collections mit @OneToMany oder @ManyToMany basierend auf JPA 2.1 kommentiert wird, wie würde ich eine gültige JPQL Abfrage erstellen, die es mir erlauben würde, eingebettete Element-Sammlungen abzurufen?

+0

Wie sind Sie zu dem Schluss gekommen, dass "Join Fetch" nur mit Entitäten funktioniert? Hast du es versucht? –

+0

@DraganBozanovic: Basierend auf der Dokumentation "Die von der rechten Seite der FETCH JOIN-Klausel referenzierte Zuordnung muss eine Verknüpfung sein, die zu einer Entität gehört, die als Ergebnis der Abfrage zurückgegeben wird. Es ist nicht zulässig, eine anzugeben Identifizierungsvariable für die Entitäten, auf die auf der rechten Seite der FETCH JOIN-Klausel verwiesen wird, und daher können Verweise auf die implizit abgerufenen Entitäten nicht an anderer Stelle in der Abfrage erscheinen. " –

+0

Der für die Sammlung bewertete Pfad muss in ein Verknüpfungsfeld aufgelöst werden –

Antwort

2

In der JPA 2.1-Spezifikation (JSR 338) kann ich keinen Hinweis finden, dass Fetch-Joins nur für Entity-Beziehungen funktionieren (aber nicht für Embeddables). JSR 338, Abschnitt 4.4.5.3 sogar heißt:

A FETCH JOIN ermöglicht das Abrufen einer Zuordnung oder Element Sammlung als Nebenwirkung der Ausführung einer Abfrage.

Als weiterer Hinweis des folgende minimale Beispiel (im Wesentlichen bei Ihnen ähnlich) ausgeführt mit Hibernate 4.3.11 als JPA-Provider Ergebnisse in einer einzigen Abfrage:

Adresse embeddable:

@Embeddable public class Address { private String city; } 

Employee-Entität:

@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 Abfrage:

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

resultierende SQL-Abfrage:

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 die oben JPQL Abfrage scheint Ihr Problem zu lösen.

2

By the way, könnte effektiver nicht sein, zu verwenden, kommen aber

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

es macht zwei wählt, statt einer, aber nicht produzieren so viel Unklarheit Unterauswahl.

Verwandte Themen