-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 3 posts ] 
Author Message
 Post subject: PropertyValueException when persisting new entities
PostPosted: Sat May 20, 2006 6:02 pm 
Beginner
Beginner

Joined: Mon May 16, 2005 6:06 am
Posts: 20
When trying to persist an entity that references another new entity via a one2many AND a many2one relation a not-null property references a null or transient value is thrown. This happens even if cascading options are specified.

Hibernate version:
Hibernate 3.2CR2, Hibernate Annotations 3.1CR1, Hibernate Entity Manager 3.1 CR1

Full stack trace of any exception that occurs:
Code:
javax.persistence.PersistenceException: org.hibernate.PropertyValueException: not-null property references a null or transient value: test.ManyToOneAndOneToManyTest$Address.contact
   at org.hibernate.ejb.AbstractEntityManagerImpl.throwPersistenceException(AbstractEntityManagerImpl.java:567)
   at org.hibernate.ejb.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:192)
   at test.ManyToOneAndOneToManyTest.persist(ManyToOneAndOneToManyTest.java:62)
   at test.ManyToOneAndOneToManyTest.testManyToOneAndOneToMany2(ManyToOneAndOneToManyTest.java:116)
   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
   at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
   at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
   at java.lang.reflect.Method.invoke(Unknown Source)
   at junit.framework.TestCase.runTest(TestCase.java:154)
   at junit.framework.TestCase.runBare(TestCase.java:127)
   at junit.framework.TestResult$1.protect(TestResult.java:106)
   at junit.framework.TestResult.runProtected(TestResult.java:124)
   at junit.framework.TestResult.run(TestResult.java:109)
   at junit.framework.TestCase.run(TestCase.java:118)
   at junit.framework.TestSuite.runTest(TestSuite.java:208)
   at junit.framework.TestSuite.run(TestSuite.java:203)
   at org.eclipse.jdt.internal.junit.runner.junit3.JUnit3TestReference.run(JUnit3TestReference.java:128)
   at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
   at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:457)
   at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:670)
   at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386)
   at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)
Caused by: org.hibernate.PropertyValueException: not-null property references a null or transient value: test.ManyToOneAndOneToManyTest$Address.contact
   at org.hibernate.engine.Nullability.checkNullability(Nullability.java:72)
   at org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:284)
   at org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:180)
   at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:121)
   at org.hibernate.event.def.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:131)
   at org.hibernate.event.def.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:87)
   at org.hibernate.impl.SessionImpl.firePersist(SessionImpl.java:611)
   at org.hibernate.impl.SessionImpl.persist(SessionImpl.java:603)
   at org.hibernate.engine.CascadingAction$8.cascade(CascadingAction.java:202)
   at org.hibernate.engine.Cascade.cascadeToOne(Cascade.java:213)
   at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:157)
   at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:108)
   at org.hibernate.engine.Cascade.cascade(Cascade.java:248)
   at org.hibernate.event.def.AbstractSaveEventListener.cascadeBeforeSave(AbstractSaveEventListener.java:412)
   at org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:261)
   at org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:180)
   at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:121)
   at org.hibernate.event.def.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:131)
   at org.hibernate.event.def.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:87)
   at org.hibernate.event.def.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:38)
   at org.hibernate.impl.SessionImpl.firePersist(SessionImpl.java:620)
   at org.hibernate.impl.SessionImpl.persist(SessionImpl.java:594)
   at org.hibernate.impl.SessionImpl.persist(SessionImpl.java:598)
   at org.hibernate.ejb.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:186)
   ... 20 more


TestCase
Code:
package test;

import java.util.ArrayList;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Persistence;

import junit.framework.TestCase;

import org.hibernate.annotations.GenericGenerator;

public class ManyToOneAndOneToManyTest extends TestCase
{
   @javax.persistence.Entity
   public static class Address
   {
      @ManyToOne(optional = false, fetch = FetchType.EAGER)
      Contact contact;

      @Id
      @GeneratedValue(generator = "system-uuid")
      @GenericGenerator(name = "system-uuid", strategy = "uuid")
      String id;
   }

   @javax.persistence.Entity
   public static class Contact
   {
      @OneToMany(mappedBy = "contact", cascade = {CascadeType.ALL}, fetch = FetchType.EAGER)
      @org.hibernate.annotations.Cascade(org.hibernate.annotations.CascadeType.DELETE_ORPHAN)
      @org.hibernate.annotations.OnDelete(action = org.hibernate.annotations.OnDeleteAction.CASCADE)
      List<Address> addresses = new ArrayList<Address>();

      @ManyToOne(cascade = {CascadeType.ALL}, fetch = FetchType.EAGER, optional = true)
      Address defaultDeliveryAddress;

      @Id
      @GeneratedValue(generator = "system-uuid")
      @GenericGenerator(name = "system-uuid", strategy = "uuid")
      String id;
   }

   private EntityManagerFactory emf;

   private void persist(Object e) throws RuntimeException
   {
      EntityManager em = emf.createEntityManager();
      EntityTransaction tx = null;
      try
      {
         tx = em.getTransaction();
         tx.begin();
         em.persist(e);
         tx.commit();
      }
      catch (RuntimeException ex)
      {
         if (tx != null && tx.isActive()) tx.rollback();
         throw ex;
      }
      finally
      {
         em.close();
      }
   }

   protected void setUp() throws Exception
   {
      emf = Persistence.createEntityManagerFactory("manager1");
   }

   protected void tearDown() throws Exception
   {
      emf.close();
   }

   /**
    * WORKS
    * persisting contact first and address separately
    */
   public void testManyToOneAndOneToMany1()
   {
      Contact contact = new Contact();
      persist(contact);

      Address address = new Address();

      address.contact = contact;
      contact.addresses.add(address);
      contact.defaultDeliveryAddress = address;

      persist(address);
   }

   /**
    * DOES NOT WORK
    * persisting contact and cascade to address
    */
   public void testManyToOneAndOneToMany2()
   {
      Contact contact = new Contact();

      Address address = new Address();

      address.contact = contact;
      contact.addresses.add(address);
      contact.defaultDeliveryAddress = address;

      // exception is thrown here
      persist(contact);
   }
}


Any help, comments and suggestions are appreciated.

Johan


Top
 Profile  
 
 Post subject:
PostPosted: Mon May 22, 2006 4:25 am 
Expert
Expert

Joined: Sat Oct 25, 2003 8:49 am
Posts: 490
Location: Vrhnika, Slovenia
It cascades persist to addresses, then on each address there is a contact that is still transient.

Try cascading on address.contact also.


Top
 Profile  
 
 Post subject:
PostPosted: Mon May 22, 2006 7:34 am 
Beginner
Beginner

Joined: Mon May 16, 2005 6:06 am
Posts: 20
Well, thats basically not what I want. This way persisting/merging events would also be cascaded to the contact (parent) when I'm directly persisting/merging an address (child).


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 3 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.