Learner
Learner

Reputation: 21435

Getting error with basic one-to-many mapping

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

Answers (3)

PSR
PSR

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

Learner
Learner

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 Personfirst 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

shazin
shazin

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

Related Questions