Uno-a-molti padre-figlio unidirezionale ID Cascade Salva
-
18-09-2019 - |
Domanda
Quando si tenta di salvare un ID della mia classe genitore in una classe figlia, continuo a ricevere l'errore "ERRORE - Il campo 'parent_id' non ha un valore predefinito"
Ho provato tutti i tipi di mappature. Sto usando le annotazioni.
Qualsiasi aiuto su questo sarebbe apprezzato
Parent:
@Id
@Column(name="id")
@GeneratedValue(strategy=GenerationType.AUTO)
private long id;
@Column(name="description")
private String description;
@OneToMany
@Cascade(value= {org.hibernate.annotations.CascadeType.SAVE_UPDATE, org.hibernate.annotations.CascadeType.DELETE})
@JoinColumn(name="parent_id")
private List<Child> children;
Bambino:
@Id
@Column(name="id")
@GeneratedValue(strategy=GenerationType.AUTO)
private long id;
@Column(name="description")
private String description;
Grazie.
Soluzione
È necessario disporre di qualcosa che non va da qualche altra parte perché quelle mappature funzioneranno come sono. Potrebbero essere migliore, ma faranno lavorare. In particolare, tutte le annotazioni @Column
sono ridondanti e inutili, e come noto non sequitor, si dovrebbe utilizzare la proprietà cascata di @OneToMany
dell'APP, invece di @Cascade
di Hibernate. Ho creato un esempio eseguibile con la versione ripulita di ciò che hai postato. Se si dispone di git e Maven, è possibile eseguire con:
git clone git://github.com/zzantozz/testbed tmp
cd tmp
mvn -q compile exec:java \
-Dexec.mainClass=rds.hibernate.UnidirectionalManyToOneJoinColumn \
-pl hibernate-unidirectional-one-to-many-with-join-column
Si crea un genitore con due figli, li salva e poi li carica e stampa il grafico. L'output è:
Creating parent with two children
Loading saved parent
Parent{description='parent', children=[Child{description='child 2'}, Child{description='child 1'}]}
Altri suggerimenti
Un ritardo Inoltre nel caso in cui nessuno mai corre lo stesso problema.
Questa entità qui, quando persisteva usando Hibernate 4.1.8, a cascata le FieldChange
entities, ma sarà non riempire la colonna di join:
@Entity
public class Event {
//ID and other fields here
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
@JoinColumn(name = "event_id")
private List<FieldChange<?>> fields = new ArrayList<FieldChange<?>>();
}
Nemmeno l'istruzione di inserimento impostare la colonna event_id
, né aggiornare l'entità inserito dopo il fatto - il event_id
rimane nullo ed il rapporto è perso.
Se, tuttavia, la definizione @JoinColumn
viene modificato in questo modo:
@JoinColumn(name = "event_id", nullable = false)
, allora l'istruzione di inserimento include la colonna event_id
come dovrebbe, e tutto va bene.
Questo può essere solo una regressione in questa particolare versione di Hibernate, ma forse aiuta qualcuno.
Nel tuo caso fornitore di APP a persistere oggetto figlio con il suo genitore eseguire almeno tre interrogazioni sui db. In primo luogo due persistono gli oggetti dal proprio. L'ultimo aggiornare oggetto bambino con il genitore riferimento chiave esterna. La seconda query fallire perché si dispone di un vincolo NOT NULL sulla colonna di chiave esterna. Sono disponibili tre opzioni:
- Rimuovi vincolo NOT NULL sulla chiave esterna nell'entità figlio
- Usa relazione bidirezionale
- fornitore Change APP a quella che sostiene tali casi.
Cambia la @OneToMany
per @OneToMany(cascade=CascadeType.ALL)
utilizzare JPA, piuttosto che le estensioni di Hibernate
La mia ipotesi è che il @JoinColumn annotation
ha bisogno di un referencedColumnName
assegnato.
@JoinColumn(name = "parent_id", referencedColumnName = "id")