-->
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.  [ 1 post ] 
Author Message
 Post subject: DefaultMergeEventListener produces copies with empty IDs?
PostPosted: Mon Oct 11, 2010 6:34 pm 
Newbie

Joined: Mon Oct 11, 2010 5:24 pm
Posts: 6
Using Hibernate 3.3.2.GA.

Hello:

When attempting to perform a cascading merge using the mapping below I encountered a NonUniqueObjectException on one of my child collections (DeterminantTypeMember) that has a key-many-to-one mapping to the parent. The relevant mappings and code are below, but the distinguishing features of this entity are that it consists only of key fields, and that both the local and foreign key mappings use a custom UserType.

As best I can tell the cause of the error is that DefaultMergeEventListener is not populating the id fields for the copy it is storing in the copyCache map (line 291) and passing on to AbstractSaveEventListener. This in turn seems to be caused by the method EntityMetamodel.getIdentifierProperty().isVirtual() returning true when called from AbstractEntityPersister (line 3260).

This behavior seems intentional and I don't claim to understand it, but the problem is when the empty id copy gets attached to the session, then a second instance with a different key comes along it also gets an empty id copy and now the session thinks there are 2 copies of the same (empty) identity when in fact both of my passed instances had distinct, populated id values.

What is it that causes EntityMetamodel.getIdentifierProperty().isVirtual() to return true, and why is an object copy with an empty ID being attached to the session? I'm assuming that the population of the ID is simply being deferred for some reason, but shouldn't Hibernate have to finish populating the ID before it can start trying to process other instances of the same class?

Can somebody please help me figure out what I am missing?

Here is what I believe is the relevant portion of my mapping (let me know if you need to see more):

Code:

   <class name="com.etse.model.configuration.Determinant" table="DETERMINANT">
        <id name="name">
           <column name="DETERMINANTNAME"  length="100"/>
        </id>
      <property name="primary" type="yes_no">
             <column name="PRIMARY"/>
          </property>
        <set name="determinantDefinitions">
           <key column="DETERMINANTNAME"/>
           <one-to-many class="com.etse.model.configuration.DeterminantDefinition"/>
        </set>
    </class>

    <class name="com.etse.model.configuration.DeterminantDefinition" table="DETERMINANTDEFINITION">
        <composite-id>
           <key-many-to-one name="determinant">
              <column name="DETERMINANTNAME"/>
           </key-many-to-one>
           <key-property name="effectiveDate" type="com.etse.persistence.hibernate.UTCJodaDateTimeType">
              <column name="EFFECTIVEDATE" sql-type="timestamp"/>
           </key-property>
           <key-property name="executionEffectiveDate" type="com.etse.persistence.hibernate.UTCJodaDateTimeType">
              <column name="EXECUTIONEFFECTIVEDATE" sql-type="timestamp"/>
           </key-property>
        </composite-id>
        <set name="determinantTypeMembers">
           <key>
              <column name="DETERMINANTNAME"/>
              <column name="EFFECTIVEDATE"/>
              <column name="EXECUTIONEFFECTIVEDATE"/>
            </key>
           <one-to-many class="com.etse.model.configuration.DeterminantTypeMember"/>
        </set>
    </class>

    <class name="com.etse.model.configuration.DeterminantTypeMember" table="DETERMINANTTYPEMEMBER">
        <composite-id>
           <key-many-to-one name="determinantDefinition">
              <column name="DETERMINANTNAME"/>
              <column name="EFFECTIVEDATE"/>
              <column name="EXECUTIONEFFECTIVEDATE"/>
           </key-many-to-one>
           <key-property name="determinantType" type="com.etse.persistence.hibernate.StringEnumType">
              <column name="DETERMINANTTYPE"  length="50"/>
           </key-property>
        </composite-id>
    </class>



And the code:
Code:
public class DeterminantTypeMember implements Serializable {
   
   private DeterminantDefinition determinantDefinition;
   private DeterminantType determinantType;
   
   public DeterminantTypeMember(){}
   
   public DeterminantTypeMember(DeterminantDefinition determinantDefinition,
         DeterminantType determinantType) {
      this.determinantDefinition = determinantDefinition;
      this.determinantType = determinantType;
   }

   public String toString(){
      if (this.determinantType != null){
         return this.determinantType.toString();
      }else{
         return "null";
      }
   }
   
   public DeterminantDefinition getDeterminantDefinition() {
      return determinantDefinition;
   }

   public void setDeterminantDefinition(DeterminantDefinition determinantDefinition) {
      this.determinantDefinition = determinantDefinition;
   }

   public DeterminantType getDeterminantType() {
      return determinantType;
   }

   public void setDeterminantType(DeterminantType determinantType) {
      this.determinantType = determinantType;
   }

   @Override
   public int hashCode() {
      final int prime = 31;
      int result = 1;
      result = prime
            * result
            + ((determinantDefinition == null) ? 0 : determinantDefinition
                  .hashCode());
      result = prime * result
            + ((determinantType == null) ? 0 : determinantType.hashCode());
      return result;
   }

   @Override
   public boolean equals(Object obj) {
      if (this == obj)
         return true;
      if (obj == null)
         return false;
      if (getClass() != obj.getClass())
         return false;
      DeterminantTypeMember other = (DeterminantTypeMember) obj;
      if (determinantDefinition == null) {
         if (other.determinantDefinition != null)
            return false;
      } else if (!determinantDefinition.equals(other.determinantDefinition))
         return false;
      if (determinantType == null) {
         if (other.determinantType != null)
            return false;
      } else if (!determinantType.equals(other.determinantType))
         return false;
      return true;
   }   
}




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

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.