2013-08-26 15 views
5

Ich bin ziemlich neu in Hibernate und habe versucht zu bestimmen, was es für Sie tun wird und was Sie tun müssen.Hibernate, automatisch persistente abhängige Objekte

Ein großes befasst sich mit einem Objekt, das Abhängigkeiten hat, die noch nicht in der Datenbank vorhanden sind. Zum Beispiel habe ich ein Project-Objekt, das ein Manufacturer-Feld enthält, das ein Manufacturer-Objekt als Wert akzeptiert. In der Datenbank habe ich eine Produkttabelle mit einer mfr_id-Spalte, die eine Referenz auf die Hersteller-Tabelle ist (eine ziemlich typische unidirektionale Eins-zu-viele-Beziehung).

Wenn der Hersteller, der dem Produktobjekt zugeordnet ist, sich auf einen Artikel bezieht, der bereits in der Datenbank enthalten ist, gibt es kein Problem. Wenn ich jedoch versuche, ein Objekt zu speichern oder zu aktualisieren, das auf einen Hersteller verweist, der noch nicht persistent ist, schlägt der Vorgang mit einer Ausnahme fehl.

Exception in thread „Application“ org.hibernate.TransientObjectException: Objekt verweist auf eine nicht gespeicherte transiente Instanz - die transiente Instanz speichern, bevor

Spülung Ich kann durch natürlich manuell überprüft den Zustand des Herstellers, seines Produkts zu sehen, ob es ID-Feld ist Null und speichern, wenn es ist, aber das scheint wie eine umständliche Lösung. Unterstützt Hibernate automatisch persistierende Abhängige, wenn der betreffende Abhängige noch nicht persistiert ist? Wenn ja, wie kann ich dieses Verhalten aktivieren? Ich benutze die Version von Hibernate, die mit Netbeans (3.5, glaube ich) und Inline-Annotationen zum Spezifizieren des Mapping-Verhaltens gebündelt ist. Im Folgenden sind meine Produkt- und Herstellerklassen aufgeführt, die auf die Teile beschränkt sind, die mit der Abhängigkeit umgehen. (Produkt erstreckt Sellable, die zu einem verkaufbaren Tabelle abbildet, wie die Vererbungsstrategie JOINED Verwendung ist es, dass Tabelle, die den Primärschlüssel enthält, die das Produkt identifiziert)

@Entity 
@Table (
     name="products", 
     schema="sellable" 
) 
public abstract class Product extends Sellable { 
    private Manufacturer      manufacturer; 

    @ManyToOne (fetch = FetchType.EAGER) 
    @JoinColumn (name = "mfr_id") 
    public Manufacturer getManufacturer() { 
     return this.manufacturer; 
    } 

    /** 
    * 
    * @param manufacturer 
    */ 
    public Product setManufacturer (Manufacturer manufacturer) { 
     this.manufacturer = manufacturer; 
     return this; 
    } 
} 

Der abhängige Hersteller

@Entity 
@Table (
     name="manufacturers", 
     schema="sellable", 
     uniqueConstraints = @UniqueConstraint(columnNames="mfr_name") 
) 
public class Manufacturer implements Serializable { 
    private Integer   mfrId  = null; 
    private String   mfrName  = null; 

    @Id 
    @SequenceGenerator (name = "manufacturers_mfr_id_seq", sequenceName = "sellable.manufacturers_mfr_id_seq", allocationSize = 1) 
    @GeneratedValue (strategy = GenerationType.SEQUENCE, generator = "manufacturers_mfr_id_seq") 
    @Column (name="mfr_id", unique=true, nullable=false) 
    public Integer getMfrId() { 
     return mfrId; 
    } 

    private Manufacturer setMfrId (Integer mfrId) { 
     this.mfrId = mfrId; 
     return this; 
    } 

    @Column(name="mfr_name", unique=true, nullable=false, length=127) 
    public String getMfrName() { 
     return mfrName; 
    } 

    public Manufacturer setMfrName (String mfrName) { 
     this.mfrName = mfrName; 
     return this; 
    } 
} 

UPDATE: Ich versuchte folgendes von this question, aber ich bekomme immer noch die transiente Objekt Ausnahme.

@ManyToOne (fetch = FetchType.EAGER, cascade = {CascadeType.PERSIST, CascadeType.MERGE}) 

Ich habe auch geprüft, welche Version von Hibernate mit Netbeans gebündelt ist, dann ist es 3.2.5

UPDATE 2: Ich, dass die folgende erscheint wollte offenbar gefunden zu arbeiten, wie ich.

Allerdings vermute ich, dass dies nicht die Kaskade ist, die ich wirklich will. Wenn ich ein Produkt lösche, denke ich nicht, dass das Löschen des zugehörigen Herstellers die richtige Aktion ist, was meiner Meinung nach jetzt passieren wird.

Ich habe versucht, einen Kaskadentyp zu erstellen, der aus allen verfügbaren Typen bestand, aber auch nicht. Ich habe dieselbe Ausnahme, als ich versuchte, ein Produkt zu speichern, mit dem ein nicht gespeicherter Hersteller verknüpft war.

@ManyToOne (fetch = FetchType.EAGER, cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH}) 

Ich habe gesehen, CascadeType.SAVE_UPDATE an mehreren Stellen erwähnt, aber das Modus scheint nicht in der Version von Hibernate zur Verfügung zu stehen, die mit Netbeans kommt.

Antwort

7

Sie müssen Kaskadierungsoperationen betrachten; Diese Art von Operation ermöglicht es Ihnen, den Lebenszyklus des inneren Objekts in Bezug auf seine Eltern zu verwalten.

@ManyToOne(cascade), wenn Sie verwenden Session.persist() Betrieb oder [email protected] wenn Sie nicht JPA Funktion Session.saveOrUpdate() verwenden.

Dies ist nur ein Beispiel für die vollständige doc Punkt here

für Ihren Code, wenn Sie automatisch Manufacturer wollen sparen, wenn Project Verwendung zu speichern:

@ManyToOne (fetch = FetchType.EAGER, cascade = {javax.persistence.CascadeType.PERSIST}) 
@JoinColumn (name = "mfr_id") 
public Manufacturer getManufacturer() { 
    return this.manufacturer; 
} 

oder

@Cascade(CascadeType.PERSIST) 
+0

Ich habe Ihren Vorschlag ausprobiert, aber ich bekomme immer noch die gleiche Ausnahme von transienten Objekten, wenn ich versuche, das Objekt zu speichern. Ich habe auch versucht, die in http://stackoverflow.com/questions/9032998/hibernate-cascades-object-references-an-unsaved-transient-instance-save-the vom \t @ManyToOne vorgeschlagene Methode (fetch = FetchType.EAGER, cascade = {CascadeType.PERSIST, CascadeType.MERGE}) aber das hat nicht funktioniert – GordonM

+0

verwendest du saveOrUpdate()? In diesem Fall benötigen Sie 'org.hibernate.annotation. @ Cascade (CascadeType.SAVE_UPDATE)' –

+0

Im Moment verwende ich nur save(). Ich werde mir andere Optionen ansehen, wenn ich heute Abend nach Hause komme. – GordonM

Verwandte Themen