History | Log In     View a printable version of the current page.  
Issue Details (XML | Word | Printable)

Key: HHH-2382
Type: Bug Bug
Status: Open Open
Priority: Major Major
Assignee: Unassigned
Reporter: Eelco Hillenius
Votes: 4
Watchers: 5
Operations

If you were logged in you would be able to see more operations.
Hibernate Core

DefaultLoadEventListener#onLoad throws exception when DelayedPostInsertIdentifier is set as an entity id

Created: 24/Jan/07 07:06 PM   Updated: 08/May/08 05:04 PM
Component/s: core
Affects Version/s: 3.2.1, 3.2.2, 3.2.0.ga
Fix Version/s: None

Time Tracking:
Not Specified


 Description  « Hide
DefaultLoadEventListener#onLoad has this code:

  if ( idClass != null && ! idClass.isInstance( event.getEntityId() ) ) {
    throw new TypeMismatchException(
      "Provided id of the wrong type. Expected: " + idClass + ", got " + event.getEntityId().getClass());
  }

However, EntityIdentityInsertAction has this in it's constructor:

  delayedEntityKey = isDelayed ? generateDelayedEntityKey() : null;

and method:

  private synchronized EntityKey generateDelayedEntityKey() {
    if ( !isDelayed ) {
      throw new AssertionFailure( "cannot request delayed entity-key for non-delayed post-insert-id generation" );
    }
    return new EntityKey( new DelayedPostInsertIdentifier(), getPersister(), getSession().getEntityMode() );
  }

In case an insert is tried outside of an existing transaction users may run into this problem (like I did).

I don't know what the best fix is. The easiest fix would be:

Index: /Users/eelcohillenius/Documents/workspace/hibernate3/src/org/hibernate/event/def/DefaultLoadEventListener.java
===================================================================
--- /Users/eelcohillenius/Documents/workspace/hibernate3/src/org/hibernate/event/def/DefaultLoadEventListener.java (revision 11098)
+++ /Users/eelcohillenius/Documents/workspace/hibernate3/src/org/hibernate/event/def/DefaultLoadEventListener.java (working copy)
@@ -5,6 +5,7 @@
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+import org.hibernate.EntityMode;
 import org.hibernate.HibernateException;
 import org.hibernate.LockMode;
 import org.hibernate.NonUniqueObjectException;
@@ -10,7 +11,7 @@
 import org.hibernate.NonUniqueObjectException;
 import org.hibernate.PersistentObjectException;
 import org.hibernate.TypeMismatchException;
-import org.hibernate.EntityMode;
+import org.hibernate.action.DelayedPostInsertIdentifier;
 import org.hibernate.cache.CacheConcurrencyStrategy;
 import org.hibernate.cache.CacheKey;
 import org.hibernate.cache.entry.CacheEntry;
@@ -82,7 +83,7 @@
  }
  else {
  Class idClass = persister.getIdentifierType().getReturnedClass();
- if ( idClass != null && ! idClass.isInstance( event.getEntityId() ) ) {
+ if ( idClass != null && ! (idClass.isInstance( event.getEntityId() ) || event.getEntityId() instanceof DelayedPostInsertIdentifier )) {
  throw new TypeMismatchException(
  "Provided id of the wrong type. Expected: " + idClass + ", got " + event.getEntityId().getClass()
  );

but that would look like a quick hack to me.


 All   Comments   Work Log   Change History   FishEye      Sort Order: Ascending order - Click to sort in descending order
Eelco Hillenius - 24/Jan/07 07:12 PM
As a side note, EntityIdentityInsertAction can be improved. There is no reason why generateDelayedEntityKey should be synchronized and the isDelayed delayed test can be removed as that method is private is only called from the constructor (and isDelayed is final).

Dave Copeland - 08/May/08 04:42 PM
I have experienced this problem running outside of an EJB container (running in Tomcat). The solution was to run inside a transaction, vi EntityManager.getTransaction(). Well, more of a workaround. Keep in mind that there's another bug where child entities are inserted with null foreign keys so your database has to allow null on all foreign keys.

Dave Copeland - 08/May/08 05:04 PM
My comment re: bug with foreign keys is not true (solvable by nullable=false in annotations), however the entitymanager workaround is still required to avoid this bug.