Reputation: 21435
I am creating a simple example by following the hibernate documentation for one-to-many unidirectional mapping
I have created Person
entity and Address
entity as follows:
Person.java
public class Person {
private int id;
private Set<Address> addresses = new HashSet<Address>();
// Setters & Getters
public void addAddress(Address address) {
this.addresses.add(address);
}
}
Address.java
public class Address {
private int id;
// Setters & Getters
}
Mapping file:
<hibernate-mapping>
<class name="Person">
<id name="id" column="personId">
<generator class="native" />
</id>
<set name="addresses">
<key column="personId" not-null="true" />
<one-to-many class="Address" />
</set>
</class>
<class name="Address">
<id name="id" column="addressId">
<generator class="native" />
</id>
</class>
</hibernate-mapping>
My program to save person and address:
Session session = getSession();
session.getTransaction().begin();
Person p = new Person();
Address a = new Address();
p.addAddress(a);
session.save(a);
session.save(p);
Executing this program is giving an exception as: not-null property references a null or transient value : Address._Person.addressesBackref
Complete stacktrace:
org.hibernate.PropertyValueException: not-null property references a null or transient value : Address._Person.addressesBackref
at org.hibernate.engine.internal.Nullability.checkNullability(Nullability.java:106)
at org.hibernate.action.internal.AbstractEntityInsertAction.nullifyTransientReferencesIfNotAlready(AbstractEntityInsertAction.java:132)
at org.hibernate.action.internal.AbstractEntityInsertAction.makeEntityManaged(AbstractEntityInsertAction.java:141)
at org.hibernate.engine.spi.ActionQueue.addResolvedEntityInsertAction(ActionQueue.java:201)
at org.hibernate.engine.spi.ActionQueue.addInsertAction(ActionQueue.java:179)
at org.hibernate.engine.spi.ActionQueue.addAction(ActionQueue.java:166)
at org.hibernate.event.internal.AbstractSaveEventListener.addInsertAction(AbstractSaveEventListener.java:332)
at org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:288)
at org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:194)
at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:137)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:209)
at org.hibernate.event.internal.DefaultSaveEventListener.saveWithGeneratedOrRequestedId(DefaultSaveEventListener.java:55)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:194)
at org.hibernate.event.internal.DefaultSaveEventListener.performSaveOrUpdate(DefaultSaveEventListener.java:49)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:90)
at org.hibernate.internal.SessionImpl.fireSave(SessionImpl.java:715)
at org.hibernate.internal.SessionImpl.save(SessionImpl.java:707)
at org.hibernate.internal.SessionImpl.save(SessionImpl.java:702)
Can you please help me in fixing the issue.
Upvotes: 0
Views: 184
Reputation: 40338
Here it is clearly saying you are putting a null value for a property which is declared as a not null property.
You are directly setting the objects with out any values.So person id is setting null.But you configured it as a not null.Check it once.
Upvotes: 1
Reputation: 21435
At DB level, your Address
table has a foreign key called personId
with Person
table. Also as per the hibernate mapping file the foreign key has not-null
constraint.
As per your code you are trying to save Address
entity first (which goes to Address
table) then you are saving the Person
entity. So when hiberate tries to save the Address
entity it has to insert the column personId
because it has not-null
constraint, as there is no record in Person
table so hibernate throws an exception as Address._Person.addressesBackref
.
So to fix this issue:
Solution 1:
Save the Person
first then try to save the Address
entity like this:
Person p = new Person();
Address a = new Address();
p.addAddress(a);
session.save(p);
session.save(a);
Solution 2
Just remove the not-null
constraint on the foreign key - personId
Upvotes: 0
Reputation: 21913
The Exception clearly explains that Address
you are adding to Person.addresses
is either null or transient (Not saved). You can try saving Address
before adding it to the Person.addresses.
And you need to commit the transaction. Please try the following code.
Session session = getSession();
Transaction tx;
try {
tx = session.beginTransaction();
//do some work
Person p = new Person();
Address a = new Address();
session.save(a);
p.addAddress(a);
session.save(p);
tx.commit();
}
catch (Exception e) {
if (tx!=null) tx.rollback();
throw e;
}
finally {
session.close();
}
Upvotes: 0