Frage

Ermöglicht die Frage Setup zuerst.

Was ich habe, ist> 4 Tabellen: Kunde, Adresse, Ordnung, Orderitem. Jeder gemappt mit Hibernate Annotations und der Zugriff über eine Feder DAO / Services-Ebene.

Was ich versuche zu tun, zusammen doppelte Kunden fusionieren. Also alles, was wirklich geschehen muss, ist alle Aufträge und Adressen mit dem Kunden B zugeordnet sind, müssen ihre customer_id Fremdschlüssel zu aktualisieren, um Kunden A. Dann Kunde nach Punkt B muss seine deaktiviert Bit gesetzt haben.

Anstatt diese einfachen Abfragen zu unserer Datenbank zu senden, geht Hibernate verrückt und Ausgaben eine Tonne wählen dann Abfragen aktualisieren. Insbesondere wählt sie alle Elemente, um zu einem Auftrag angebracht (weil diese EAGER definiert ist, und dieser Punkt ist nicht veränderbar.). Um die wählt, bevor Update zu erhalten zu stoppen passiert Ich habe versucht, die Hibernate-Einheit Anmerkung oben auf der regulären javax.persistence.Entity Zugabe wie:

@org.hibernate.annotations.Entity(dynamicUpdate = true, selectBeforeUpdate = false, dynamicInsert = true)

dies schien nicht zu haben, beeinflussen, außer mit einfachen Abfragen, wo es nur einzelne Elemente in einer Tabelle aktualisiert.

Ich erhalte die Objekte der folgenden Hibernate Kriterien:

            Criteria c1 = null;
            Criteria c2 = null;
            Criteria c = session.createCriteria(Customer.class);
            c.setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY);

            if(resultLimit>0) c.setMaxResults(resultLimit);
            if(timeout>0) c.setTimeout(timeout);
            for(String filter: sqlFilters) {
                if(filter.indexOf("{alias}.customer_")!=-1) c.add(Restrictions.sqlRestriction(filter));
                else if(filter.indexOf("{alias}.address_")!=-1 && addrsAttached) {
                    if(c1==null)
                        c1 = c.createCriteria("addresses").setFetchMode("type", FetchMode.JOIN);
                    c1.add(Restrictions.sqlRestriction(filter));
                } else if(filter.indexOf("{alias}.order_")!=-1 && ordersAttached) {
                    if(c2==null)
                        c2 = c.createCriteria("orders").setFetchMode("orderItems", FetchMode.SELECT);
                    c2.add(Restrictions.sqlRestriction(filter));
                }
            }
            return (List<Customer>) c.list();

Dann bewege ich mich all die Adresse und um Objekte von Kunden B zu Kunde A und führen Sie ein

return (Customer) this.getHibernateTemplate().merge(customer);

auf beiden Kundenobjekten. Dies endet mit einer Tonne select-Anweisungen erstellen, die alle zugehörigen Objekte erhalten (das heißt Orderitem Produkte, Product, ProductPricingTmpl, etc ..)

Ich brauche diese wählt entfernt werden! Wenn sie nicht da die Abfrage wäre, würde normal aussehen und effizient sein! Die Aktualisierung ausgegebenen Abfragen sind perfekt und dynamisch.

Irgendwelche Ideen?

War es hilfreich?

Lösung

Der Schlüssel könnte in der Wahl des merge () Betriebes sein. Aus dem Ruhezustand javadoc:

  

Kopieren Sie den Zustand des angegebenen Objekts   auf das persistente Objekt mit der   gleiche Kennung. Wenn es keine   persistente Instanz zur Zeit   mit der Sitzung verknüpft ist, wird es   geladen werden.

Sie sind also Hibernate zwingen in alle Daten zu laden, bevor es zu ändern.

Versuchen

eine andere Operation, wie update ():

  

Aktualisieren Sie die persistente Instanz mit   die Kennung des gegebenen losgelöst   Beispiel.

Keine Versprechungen, obwohl, Hibernate können entscheiden, ob sie es in irgendeiner Weise laden muss. Das dynamicUpdates = true Config könnte tatsächlich noch schlimmer machen, da sie muss wissen, was es zu starten, bevor es dynamisches Updates ausgeben kann.

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