Hi
I have two very simple objects "Main" and "Sub" mapped using two unidirectional mappings (Main -> Sub @OneToOne and Sub->Main @ManyToOne) as can be seen from the classes below.
Creating a Main object and attaching a Sub-object to it and trying to store it results in a org.hibernate.PropertyValueException (not-null property references a null or transient value: Sub.main) when the Sub->Main relation has been marked with nullable=false. If I change nullable to true for this relation it works and everything is stored as expected (no null value is stored).
Is this a problem with my mapping or a bug in Hibernate? Feels like my mapping should be correct.
Testcase:
Main main = new Main();
Sub sub = new Sub();
main.setSub(sub);
sub.setMain(main);
main = (Main) session.merge(main);
Classes:
@Entity
public class Main {
private Long id;
private Sub sub;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
public Long getId() {
return this.id;
}
@OneToOne(cascade = { CascadeType.ALL })
@JoinColumn(name = "fk_sub_id")
public Sub getSub() {
return this.sub;
}
// Irrelevant setters removed
}
@Entity
public class Sub {
private Long id;
private Main main;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
public Long getId() {
return this.id;
}
@ManyToOne
@JoinColumn(name = "fk_main_id", nullable = false)
public Main getMain() {
return this.main;
}
// Irrelevant setters removed
}
Hibernate version: 3.2.6.ga
Full stack trace of any exception that occurs:
Caused by: org.hibernate.PropertyValueException: not-null property references a null or transient value:
Sub.main
at org.hibernate.engine.Nullability.checkNullability(Nullability.java:72)
at org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:290)
at org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:181)
at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:121)
at org.hibernate.event.def.DefaultMergeEventListener.entityIsTransient(DefaultMergeEventListener.java:186)
at org.hibernate.event.def.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:123)
at org.hibernate.impl.SessionImpl.fireMerge(SessionImpl.java:687)
at org.hibernate.impl.SessionImpl.merge(SessionImpl.java:669)
at org.hibernate.engine.CascadingAction$6.cascade(CascadingAction.java:245)
at org.hibernate.engine.Cascade.cascadeToOne(Cascade.java:268)
at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:216)
at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:169)
at org.hibernate.engine.Cascade.cascade(Cascade.java:130)
at org.hibernate.event.def.AbstractSaveEventListener.cascadeBeforeSave(AbstractSaveEventListener.java:431)
at org.hibernate.event.def.DefaultMergeEventListener.entityIsTransient(DefaultMergeEventListener.java:178)
at org.hibernate.event.def.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:123)
at org.hibernate.event.def.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:53)
at org.hibernate.impl.SessionImpl.fireMerge(SessionImpl.java:677)
at org.hibernate.impl.SessionImpl.merge(SessionImpl.java:661)
at org.hibernate.impl.SessionImpl.merge(SessionImpl.java:665)
Name and version of the database you are using: PostgreSQL 8.2
Debug level Hibernate log excerpt:
2008-04-03 14:31:02,149 DEBUG [org.hibernate.jdbc.AbstractBatcher] about to open PreparedStatement (open PreparedStatements: 0, globally: 0)
2008-04-03 14:31:02,149 DEBUG [org.hibernate.jdbc.ConnectionManager] opening JDBC connection
2008-04-03 14:31:02,149 DEBUG [org.hibernate.SQL] nextval ('hibernate_sequence')
2008-04-03 14:31:02,149 DEBUG [org.hibernate.id.SequenceGenerator] Sequence identifier generated: 11061
2008-04-03 14:31:02,149 DEBUG [org.hibernate.jdbc.AbstractBatcher] about to close PreparedStatement (open PreparedStatements: 1, globally: 1)
2008-04-03 14:31:02,165 DEBUG [org.hibernate.jdbc.ConnectionManager] aggressively releasing JDBC connection
2008-04-03 14:31:02,165 DEBUG [org.hibernate.jdbc.ConnectionManager] releasing JDBC connection [ (open PreparedStatements: 0, globally: 0) (open ResultSets: 0, globally: 0)]
2008-04-03 14:31:02,165 DEBUG [org.hibernate.event.def.AbstractSaveEventListener] generated identifier: 11061, using strategy: org.hibernate.id.SequenceGenerator
2008-04-03 14:31:02,165 DEBUG [org.hibernate.event.def.AbstractSaveEventListener] generated identifier: 11061, using strategy: org.hibernate.id.SequenceGenerator
at XXX
Caused by: org.hibernate.PropertyValueException: not-null property references a null or transient value: Sub.main
at org.hibernate.engine.Nullability.checkNullability(Nullability.java:72)
at org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:290)
at org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:181)
at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:121)
at org.hibernate.event.def.DefaultMergeEventListener.entityIsTransient(DefaultMergeEventListener.java:186)
at org.hibernate.event.def.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:123)
at org.hibernate.impl.SessionImpl.fireMerge(SessionImpl.java:687)
at org.hibernate.impl.SessionImpl.merge(SessionImpl.java:669)
at org.hibernate.engine.CascadingAction$6.cascade(CascadingAction.java:245)
at org.hibernate.engine.Cascade.cascadeToOne(Cascade.java:268)
at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:216)
at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:169)
at org.hibernate.engine.Cascade.cascade(Cascade.java:130)
at org.hibernate.event.def.AbstractSaveEventListener.cascadeBeforeSave(AbstractSaveEventListener.java:431)
at org.hibernate.event.def.DefaultMergeEventListener.entityIsTransient(DefaultMergeEventListener.java:178)
at org.hibernate.event.def.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:123)
at org.hibernate.event.def.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:53)
at org.hibernate.impl.SessionImpl.fireMerge(SessionImpl.java:677)
at org.hibernate.impl.SessionImpl.merge(SessionImpl.java:661)
at org.hibernate.impl.SessionImpl.merge(SessionImpl.java:665)
|