-->
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.  [ 9 posts ] 
Author Message
 Post subject: cascading insertion
PostPosted: Mon Dec 18, 2006 5:02 am 
Newbie

Joined: Wed Oct 11, 2006 11:32 am
Posts: 18
Hello,

i got a problem with a simple one to many association.
i have a first table 'VarReportSetup' and a second one, 'VarReportAggregationTerm', which links the first one with a foreign key.

All i want to do is to define a new VarReportSetup, associate some VarReportAggregationTerm, and then make a cascading insertion, but it doesn't work. I succeed in loading a VarReportSetup and then update it with new VarReportAggregationTerms.

Here is the mapping of the first table :
Code:
   <class name="VarReportSetup" table="VarReportSetup">
        <...>

       <set name="aggregationTermCollection" table="VarReportAggregationTerm" cascade="all" inverse="true" sort="natural">
           <key column="VarReportSetupId" not-null="true" />
           <one-to-many class="VarReportAggregationTerm"/>
       </set>
   </class>


Here is the mapping of the second table

Code:
   <class name="VarReportAggregationTerm" table="VarReportAggregationTerm">
        <...>

      <property
         name="VarReportSetupId"
         column="VarReportSetupId"
         type="binary"
         not-null="true"
         length="12"
      />
   </class>


And then the stack trace :
Code:
org.hibernate.PropertyValueException: not-null property references a null or transient value: com.reuters.hibernate.test.VarReportAggregationTerm.VarReportSetupId
   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.DefaultMergeEventListener.entityIsTransient(DefaultMergeEventListener.java:186)
   at org.hibernate.event.def.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:123)


I tried to put a many to one association in the VarReportAggregationTerm mapping file

Code:
<many-to-one name="VarReportSetupId" class="VarReportSetup" column="VarReportSetupId" not-null="true" />


but i get the same error.

Many thanks for your help :)


Top
 Profile  
 
 Post subject:
PostPosted: Mon Dec 18, 2006 6:19 am 
Newbie

Joined: Wed Oct 11, 2006 11:32 am
Posts: 18
i forgot to tell that the error occurs when calling the 'save' or 'saveOrUpdate' methods


Top
 Profile  
 
 Post subject:
PostPosted: Mon Dec 18, 2006 6:29 am 
Regular
Regular

Joined: Wed Mar 23, 2005 8:43 am
Posts: 105
Location: Moscow, Russia
Can you provide your classes and key mappings also? Why you didn't use many-to-one association initially (if you map one end of yuor association as inverse, you must have other side of association, that Hibernate will useto persist this association)? Why type of your VarReportSetupId column is binary?

_________________
Best Regards


Top
 Profile  
 
 Post subject:
PostPosted: Mon Dec 18, 2006 1:45 pm 
Newbie

Joined: Wed Oct 11, 2006 11:32 am
Posts: 18
The type is binary because my Sybase database id format are binary. All ids in the database are formatted this way.

Here is the VarReportSetup class :

Code:
public abstract class BaseVarReportSetup  implements Serializable {

   private byte[] id;
   private java.util.Set<com.reuters.hibernate.test.VarReportAggregationTerm> aggregationTermCollection;

   public void setAggregationTermCollection (java.util.Set<com.reuters.hibernate.test.VarReportAggregationTerm> aggregationTermCollection) {
      this.aggregationTermCollection = aggregationTermCollection;
   }

   public void addToaggregationTermCollection (com.reuters.hibernate.test.VarReportAggregationTerm varReportAggregationTerm) {
      if (null == getAggregationTermCollection()) setAggregationTermCollection(new java.util.TreeSet<com.reuters.hibernate.test.VarReportAggregationTerm>());
      getAggregationTermCollection().add(varReportAggregationTerm);
   }

   public byte[] getId () {
      return id;
   }

   /**
    * Set the unique identifier of this class
    * @param id the new ID
    */
   public void setId (byte[] id) {
      this.id = id;
      this.hashCode = Integer.MIN_VALUE;
   }
   public boolean equals (Object obj) {
      if (null == obj) return false;
      if (!(obj instanceof com.reuters.hibernate.test.VarReportSetup)) return false;
      else {
         com.reuters.hibernate.test.VarReportSetup varReportSetup = (com.reuters.hibernate.test.VarReportSetup) obj;
         if (null == this.getId() || null == varReportSetup.getId()) return false;
         else return (this.getId().equals(varReportSetup.getId()));
      }
   }

   public int hashCode () {
      if (Integer.MIN_VALUE == this.hashCode) {
         if (null == this.getId()) return super.hashCode();
         else {
            String hashStr = this.getClass().getName() + ":" + this.getId().hashCode();
            this.hashCode = hashStr.hashCode();
         }
      }
      return this.hashCode;
   }
}


and its mapping :

Code:
   <class
      name="VarReportSetup"
      table="VarReportSetup"
   >
      <meta attribute="sync-DAO">false</meta>

      <id name="Id" type="binary">
           <generator class="com.speed.hibernate.test.util.UUIDGenerator"/>
        </id>

       <set name="aggregationTermCollection" table="VarReportAggregationTerm" cascade="all-delete-orphan" inverse="true">
           <key column="VarReportSetupId" />
           <one-to-many class="VarReportAggregationTerm"/>
       </set>
   </class>




then the VarReportAggregationTerm class :

Code:
public abstract class BaseVarReportAggregationTerm  implements Serializable, Comparable {

   // primary key
   private byte[] id;

   // fields
   private byte[] attributeTypeId;
   private java.lang.Integer aggregationLevel;

   // many to one
   private com.reuters.hibernate.test.VarReportSetup varReportSetupId;

  //getters, setters...

   public int compareTo(Object arg0) {
      
      if (arg0 instanceof VarReportAggregationTerm) {
         VarReportAggregationTerm comp = (VarReportAggregationTerm) arg0;
         if (comp != null && Arrays.equals(comp.getId(), this.getId())) {
            return 0;
         }
         return 1;
      }
      return -1;
   }
}


with the following mapping :

Code:
   <class
      name="VarReportAggregationTerm"
      table="VarReportAggregationTerm"
   >

      <id name="Id" type="binary">
           <generator class="com.speed.hibernate.test.util.UUIDGenerator"/>
        </id>
      

      <property
         name="AttributeTypeId"
         column="AttributeTypeId"
         type="binary"
         not-null="true"
         length="12"
      />
      <property
         name="AggregationLevel"
         column="AggregationLevel"
         type="integer"
         not-null="true"
         length="10"
      />

      <many-to-one name="VarReportSetupId" class="VarReportSetup" column="VarReportSetupId" not-null="true" />
      
   </class>   


Thanks for your help lester


Top
 Profile  
 
 Post subject:
PostPosted: Mon Dec 18, 2006 2:54 pm 
Senior
Senior

Joined: Sun Jun 04, 2006 1:58 am
Posts: 136
since you have inverse relationship set up you have to
set VarReportSetup VarReportAggregationTerm before saving it

since you didnt post your code , i guess you need something like

VarReportSetup varSetup = new VarReportSetup()

//add VarReportAggregationTerm to the set on varSetup

varSetupItem.setVarReportSetupId(varSetup) // u must have missed this

_________________
Don't forget to rate


Top
 Profile  
 
 Post subject:
PostPosted: Tue Dec 19, 2006 5:36 am 
Newbie

Joined: Wed Oct 11, 2006 11:32 am
Posts: 18
yes you're right, but what i want to do is to insert a new VarReportSetup with one or more VarReportAggregationTerm attached.
Isn't it possible with the cascade attributes set ?

Code:
VarReportSetup vrs = new VarReportSetup();
       VarReportAggregationTerm term = generateVarReportAggregationTerm(0);
       VarReportAggregationTerm term2 = generateVarReportAggregationTerm(1);


      Transaction tx = null;
      try {
          tx = session.beginTransaction();
          session.saveOrUpdate(vrs);

          vrs.getAggregationTermCollection().add(term);
          vrs.getAggregationTermCollection().add(term2);
          session.save(vrs);
         
         
          tx.commit();
      } catch (Exception e) {
         e.printStackTrace();
          if (tx != null) tx.rollback();
      }


Top
 Profile  
 
 Post subject:
PostPosted: Tue Dec 19, 2006 6:11 am 
Regular
Regular

Joined: Wed Mar 23, 2005 8:43 am
Posts: 105
Location: Moscow, Russia
Yes it's possible. But what scarface sad, is that you must set non-inverse side of association, if you want that Hibernate save this association (with cascading attribute set). Association in Hibernate and Java have two-side representation in memory (one from VarReportSetup to collection of VarReportAggregationTerm's and other from each instance of VarReportAggregationTerm to VarReportSetup in your case). Side of association that marked as inverse="true" in your mapping will not be used to persist this association. So you must use something like following:

private void addTerm(VarReportSetup vrs, VarReportAggregationTerm term) {
vrs.getAggregationTermCollection().add(term);
term.setVarReportSetup(vrs);
}

_________________
Best Regards


Top
 Profile  
 
 Post subject:
PostPosted: Tue Dec 19, 2006 9:34 am 
Newbie

Joined: Wed Oct 11, 2006 11:32 am
Posts: 18
ok thank you very much guys, i did it !


Top
 Profile  
 
 Post subject:
PostPosted: Thu Dec 21, 2006 12:11 pm 
Newbie

Joined: Wed Oct 11, 2006 11:32 am
Posts: 18
now i got a problem that occurs when deleting the VarReportSetup :(

I open a new transaction and perform a delete :

Code:
          tx = session.beginTransaction();
         
          session.delete(vrs);
         
          tx.commit();

and then when i execute the code i got theses traces. It looks like hibernate sets the foreign key of a VarReportAggregationTerm to null ??

Code:
Hibernate: update VarReportAggregationTerm set VarReportSetupId=null where VarReportSetupId=?
17:08:32,753  WARN JDBCExceptionReporter:71 - SQL Error: 233, SQLState: 23000
17:08:32,753 ERROR JDBCExceptionReporter:72 - The column VarReportSetupId in table VarReportAggregationTerm does not allow null values.

17:08:32,753 ERROR AbstractFlushingEventListener:301 - Could not synchronize database state with session
org.hibernate.exception.ConstraintViolationException: could not delete collection: [com.reuters.hibernate.test.VarReportSetup.aggregationTermCollection#9b968b0961664b34800bb2af]
   at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:71)
   at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
   at org.hibernate.persister.collection.AbstractCollectionPersister.remove(AbstractCollectionPersister.java:1071)
   at org.hibernate.action.CollectionRemoveAction.execute(CollectionRemoveAction.java:28)
   at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:248)
   at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:232)
   at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:141)
   at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:298)
   at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
   at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000)
   at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:338)
   at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106)
   at com.reuters.hibernate.test.api.ProfilingLocaleUserApi.main(ProfilingLocaleUserApi.java:101)
Caused by: java.sql.SQLException: The column VarReportSetupId in table VarReportAggregationTerm does not allow null values.

   at net.sourceforge.jtds.jdbc.SQLDiagnostic.addDiagnostic(SQLDiagnostic.java:365)
   at net.sourceforge.jtds.jdbc.TdsCore.tdsErrorToken(TdsCore.java:2781)
   at net.sourceforge.jtds.jdbc.TdsCore.nextToken(TdsCore.java:2224)
   at net.sourceforge.jtds.jdbc.TdsCore.getMoreResults(TdsCore.java:633)
   at net.sourceforge.jtds.jdbc.JtdsStatement.processResults(JtdsStatement.java:525)
   at net.sourceforge.jtds.jdbc.JtdsStatement.executeSQL(JtdsStatement.java:487)
   at net.sourceforge.jtds.jdbc.JtdsPreparedStatement.executeUpdate(JtdsPreparedStatement.java:421)
   at org.hibernate.jdbc.NonBatchingBatcher.addToBatch(NonBatchingBatcher.java:23)
   at org.hibernate.persister.collection.AbstractCollectionPersister.remove(AbstractCollectionPersister.java:1048)
   ... 10 more



Thanks again guys :)


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 9 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.