Sono abbastanza nuovo di Hibernate e ho cercato di determinare cosa farà per te e cosa ti richiede di fare.Hibernate, automaticamente persistono oggetti dipendenti
Uno grande ha a che fare con un oggetto che ha dipendenti che non esistono ancora nel database. Ad esempio, ho un oggetto Project che include un campo Manufacturer che accetta un oggetto Manufacturer come valore. Nel database ho una tabella prodotti con una colonna mfr_id che è un riferimento alla tabella produttori (una relazione unidirezionale unidirezionale piuttosto comune).
Se il produttore assegnato all'oggetto prodotto si riferisce a uno già presente nel database, non si verificano problemi. Tuttavia, quando provo a salvare o aggiornare un oggetto che fa riferimento a un produttore che non è ancora stato persistuto, l'operazione non riesce con un'eccezione.
Exception in thread "Applicazione" org.hibernate.TransientObjectException: oggetto fa riferimento a un'istanza transiente non salvato - salva l'istanza transitorio prima di vampate di calore
posso controllare naturalmente manualmente lo stato del produttore del prodotto vedere se il campo ID è nullo e salvarlo se lo è, ma questa sembra una soluzione ingombrante. Hibernate supporta automaticamente dipendenti persistenti se il dipendente in questione non è ancora persistente? In tal caso, come abilito questo comportamento? Sto usando la versione di Hibernate in bundle con Netbeans (3.5, credo) e le annotazioni in linea per specificare il comportamento della mappatura. Di seguito sono elencate le classi di prodotto e produttore, ridotte alle parti che gestiscono la dipendenza. (Si estende prodotto Sellable che associa a una tabella vendibile, utilizzando unito come la strategia di ereditarietà E 'quella tabella che contiene la chiave primaria che identifica il prodotto)
@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;
}
}
Il Costruttore dipendente
@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: I ha provato quanto segue da this question, ma ottengo ancora l'eccezione di oggetto transitorio.
@ManyToOne (fetch = FetchType.EAGER, cascade = {CascadeType.PERSIST, CascadeType.MERGE})
Ho anche controllato quale versione di Hibernate è fornito in bundle con Netbeans, è 3.2.5
UPDATE 2: Ho trovato che la seguente sembra funzionare a quanto pare come avrei voluto.
@ManyToOne (fetch = FetchType.EAGER, cascade = CascadeType.ALL)
Tuttavia, ho il sospetto che questo non sia il tipo a cascata che voglio veramente. Se cancello un prodotto, non penso che eliminare il suo produttore associato sia l'azione corretta, che è ciò che ritengo succederà ora.
Ho provato a creare un tipo di cascata che consisteva di tutti i tipi che erano disponibili, ma che non funzionava neanche. Ho avuto la stessa eccezione quando ho provato a salvare un prodotto a cui era associato un produttore non salvato.
@ManyToOne (fetch = FetchType.EAGER, cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH})
ho visto CascadeType.SAVE_UPDATE citato in diversi luoghi, ma che la modalità non sembra essere disponibile nella versione di Hibernate che viene fornito con Netbeans.
Ho provato il tuo suggerimento, ma ottengo ancora la stessa eccezione sugli oggetti transitori quando provo a salvare l'oggetto. Ho anche provato l'approccio suggerito in http://stackoverflow.com/questions/9032998/hibernate-cascades-object-references-an-unsaved-transient-instance-save-the di \t @ManyToOne (fetch = FetchType.EAGER, a cascata = {CascadeType.PERSIST, CascadeType.MERGE}) ma non ha funzionato né – GordonM
stai usando saveOrUpdate()? in questo caso hai bisogno di 'org.hibernate.annotation. @ Cascade (CascadeType.SAVE_UPDATE)' –
Al momento sto usando solo save(). Vedrò altre opzioni quando torno a casa stasera. – GordonM