Frage

Gibt es eine Möglichkeit, ohne die Bearbeitung der Entitätsobjekt die PPV holen Art auf einem einzigen Verfahren zu ändern?

Ich habe eine gemeinsame ORM Schicht aus PPV Entitätsklassen. Diese ORM-Schicht wird durch zwei Schichten DAO abgerufen. Ein DAO muss faul fetching, wie es für meine Web-Anwendung ist, die andere Bedürfnisse eifrig fetching, wie ich es brauche THREAD zu sein.

Hier ist ein Beispiel Methode von meinem Thread-DAO,

@PersistenceContext(unitName = "PersistenceUnit", type = PersistenceContextType.TRANSACTION)
private EntityManager em;

public ErrorCode findErrorCodeById(short id) {
    return (ErrorCode) em.createNamedQuery("ErrorCode.findById").
            setParameter("id", id).getSingleResult();
}

Wie würde ich diese Methode (oder ganz Klasse) eifrig fetching verwenden?

War es hilfreich?

Lösung

Ich gehe davon aus, dass Ihr Unternehmen Verbände (@OneToOne, @OneToMany, @ManyToOne) sind fechted faul (FetchType.LAZY)

Dann kann ich denke an zwei Möglichkeiten:

A. schreibt zwei JPA Abfrage einer, die die Assoziation des lazy (das ist die Standardmethode für den Ruhezustand), und eine zweite Abfrage, die explizite Kraft gespannt Beladung von Verbindung (siehe „fetch“ Schlüsselwort in query) holen.

        Query q = HibernateUtil.getSessionFactory().getCurrentSession()
                .createQuery("select c from Category as c" +
                        " left join fetch c.categorizedItems as ci" +
                        " join fetch ci.item as i");


B. verwenden Hibernate.initialize (entity) eifrig Laden von faulen Beziehungen eines Unternehmens zu erzwingen, nachdem Sie sie abgerufen haben (zum Beispiel durch finder ...)

ErrorCode lazyCode = findErrorCodeById(1);
// eager load associations
Hibernate.initialize(lazyCode);

Andere Tipps

In JPA der Fetch-Modus wird auf jede Persistenz Attribute spezifiziert ist, entweder durch eine Anmerkung oder in einer XML-Zuordnungs-Datei.

So ein JPA anbieterunabhängig Weg, um Ihr Ziel zu erreichen, ist für jede DAO-Schicht-separate Zuordnungsdatei zu haben. Leider wird dies eine separate PersistenceUnit für jede Mapping-Datei benötigen, aber Sie können die gleichen Entitätsklassen und die gleiche JPQL Abfrage zumindest teilen.

Code-Skelette folgen.

persistence.xml:

<persistence>
    <persistence-unit name="dao-eager">
        <mapping-file>orm-eager.xml</mapping-file>
    </persistence-unit>

    <persistence-unit name="dao-lazy">
        <mapping-file>orm-lazy.xml</mapping-file>
    </persistence-unit>
</persistence>

ORM-eager.xml:

<entity-mappings>
    <entity class="ErrorCode">
        <attributes>
            <basic name="name" fetch="EAGER"/>
        </attributes>
    </entity> 
</entity-mappings>

ORM-lazy.xml:

<entity-mappings>
    <entity class="ErrorCode">
        <attributes>
            <basic name="name" fetch="LAZY"/>
        </attributes>
    </entity> 
</entity-mappings>

Dann ist es nur eine Frage der eine EntityManagerFactory für die entsprechende Ausdauer-Einheit in Ihre DAO Schichten zu schaffen.

Eigentlich brauchen Sie nicht zwei Mapping-Dateien, können Sie entweder faul oder EAGER als Anmerkung in der Entity angeben konnten und dann das Gegenteil in einer XML-Mapping-Datei angeben (Sie wollen noch zwei Ausdauer-Einheiten obwohl).

Könnte ein wenig mehr Code als die Hibernate Lösung oben sein, aber Ihre Anwendung sollte auf anderen PPV-Anbieter tragbar sein.

Als beiseite stellt OpenJPA ähnliche Funktionalität wie die Hibernate Lösung oben mit FetchGroups (ein Konzept von JDO entlehnt).

Eine letzte Einschränkung, FetchType.LAZY ist ein Hinweis in JPA kann der Anbieter die Zeilen mit Spannung geladen werden, wenn nötig.

Aktualisiert pro Anfrage.

eine Entität wie folgt vor:

@Entity 
public class ErrorCode { 
    //  . . . 
    @OneToMany(fetch=FetchType.EAGER)  // default fetch is LAZY for Collections
    private Collection myCollection; 
    // . . .
}

In diesem Fall würden Sie müssen noch zwei Persistenzeinheiten, aber Sie werden nur ORM-lazy.xml benötigen. Ich änderte den Feldnamen ein realistischeres Szenario widerspiegeln (nur Sammlungen und Blobs verwenden FetchType.LAZY Standard). So ist die resultierende ORM-lazy.xml könnte wie folgt aussehen:

<entity-mappings>
    <entity class="ErrorCode">
        <attributes>
            <one-to-many name="myCollection" fetch="LAZY"/>
        </attributes>
    </entity> 
</entity-mappings>

Und persistence.xml wird wie folgt aussehen:

<persistence>
    <persistence-unit name="dao-eager">
       <!--
          . . .
         -->
    </persistence-unit>

    <persistence-unit name="dao-lazy">
        <!--
           . . . 
          -->
        <mapping-file>orm-lazy.xml</mapping-file>
    </persistence-unit>
</persistence>

Da niemand OpenJPA erwähnt, werde ich hier eine Antwort setzen.

In OpenJPA die zuvor faul konfigurierten Sammlungen und Felder können mit Spannung, wie unten

geladen werden
    OpenJPAEntityManager kem = OpenJPAPersistence.cast(em);
    kem.getFetchPlan().addField(Order.class, "products");
    TypedQuery<Order> query = kem.createQuery(yourQuery, Order.class);

Referenz: http: //openjpa.apache.org/builds/1.0.3/apache-openjpa-1.0.3/docs/manual/ref_guide_fetch.html

In JPA2 Ich benutze EntityGraphs , die Sie, was im Zusammenhang Objekte, die Sie abrufen möchten definieren können:

https://docs.oracle.com/javaee/7 /tutorial/persistence-entitygraphs002.htm https://docs.oracle.com/javaee/7/tutorial/ Persistenz-entitygraphs003.htm

Sie erstellen eine NamedQuery wie du, und du einen Tipp mit Schlüsseln javax.persistence.loadgraph oder javax.persistence.fetchgraph befestigen. Es werden die zugehörigen Entitäten abzurufen, die Sie in der Grafik definiert.

Sie können die Details der Unterschied zwischen „loadgraph“ und „fetchgraph“ finden Sie hier: Was die diffenece zwischen FETCH und LOAD für Entity ist Diagramm der JPA?

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top