-->
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.  [ 4 posts ] 
Author Message
 Post subject: error persisting parent/child outside of transaction
PostPosted: Tue May 23, 2006 11:48 am 
Newbie

Joined: Mon May 22, 2006 6:59 pm
Posts: 1
I am using Hibernate 3.2.CR2 and EntityManager/Annotations 3.2.CR1 though this also occurs with the latest svn version as of today.

I have a parent/child relationship defined as follows.
Code:
@Entity
public class Library {
    protected Integer id;
    protected Set<Book> books = new HashSet<Book>();
   
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    public Integer getId() {
        return id;
    }
    void setId(Integer id) {
        this.id = id;
    }
    @OneToMany(cascade = CascadeType.ALL)
    @JoinColumn(name = "libraryId", nullable = false)
    public Set<Book> getBooks() {
        return books;
    }
    public void setBooks(Set<Book> items) {
        this.books = items;
    }
}

@Entity
public class Book {
    protected Integer id;
    protected String title;
    protected Library library;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    public Integer getId() {
        return id;
    }
    void setId(Integer id) {
        this.id = id;
    }
    public String getTitle() {
        return title;
    }
    public void setTitle(String title) {
        this.title = title;
    }
    @ManyToOne
    @JoinColumn(name = "libraryId", insertable = false, updatable = false, nullable = false)
    public Library getLibrary() {
        return library;
    }
    void setLibrary(Library library) {
        this.library = library;
    }
}


When I do the following inside of a transaction everything works fine, however this code generates a ClassCastException.
Code:
EntityManager em = Persistence.createEntityManagerFactory("manager").createEntityManager();
Library library = new Library();
Book book = new Book();
book.setTitle("New Book");
book.setLibrary(library);
library.getBooks().add(book);
em.persist();
em.getTransaction().begin();
em.getTransaction().commit();


Exception:

Caused by: java.lang.ClassCastException: org.hibernate.action.DelayedPostInsertIdentifier
at org.hibernate.type.IntegerType.set(IntegerType.java:41)
at org.hibernate.type.NullableType.nullSafeSet(NullableType.java:83)
at org.hibernate.type.NullableType.nullSafeSet(NullableType.java:60)
at org.hibernate.persister.entity.AbstractEntityPersister.dehydrate(AbstractEntityPersister.java:1910)
at org.hibernate.persister.entity.AbstractEntityPersister.dehydrate(AbstractEntityPersister.java:1887)
at org.hibernate.persister.entity.AbstractEntityPersister$1.bindValues(AbstractEntityPersister.java:2038)
at org.hibernate.id.insert.AbstractReturningDelegate.performInsert(AbstractReturningDelegate.java:32)
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2044)
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2481)
at org.hibernate.action.EntityIdentityInsertAction.execute(EntityIdentityInsertAction.java:47)
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:139)
at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:297)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:993)
at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:340)
at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106)
at org.hibernate.ejb.TransactionImpl.commit(TransactionImpl.java:53)


In looking at the source the DelayedPostInsertIdentifier is used as a placeholder for the entity identifier when a transaction isn't present.

When I do a persist up above three EntityIdentityInsertActions are queued up to be executed when a transaction comes online. The status of the object is also recorded in the state array. The Library id is not available at this point and a DelayedPostInsertIdentifier object is used for the key in the Book state arrays.

When the library object is persisted it replaces it's delayed EntityKey in the persistence context with the real one, however the state arrays of the Book objects are never updated with the real key. This causes a ClassCastException when the IntegerType class tries to cast the DelayedPostInsertIdentifier to an Integer to put it into the prepared statement.

Somehow the state array in the insert actions need to be updated when the parent actually gets a real key. My first thought was to change DelayedPostInsertIdentifier to keep a reference to the entity it is being used for and then when the value is needed it can be looked up from the persisence context. Right now I am doing this lookup in NullableType.nullSafeSet which works for us but probably doesn't cover all cases.

Should I enter this issues into JIRA and is there a better place to do the lookup?


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jun 29, 2006 12:13 am 
Expert
Expert

Joined: Thu Jan 08, 2004 6:17 pm
Posts: 278
I just got the exact same exception in a Seam application. This app was working previously with a 1.0beta2 version of Seam. I upgraded to 1.0.1 and now I am getting this exception on some pretty innocuous code:

Code:
@Entity
@Name("changeset")
public class Changeset {
...
   private Long id;
...
   @Id @GeneratedValue
   public Long getId()
   {
      return id;
   }
...
   public List queryChangedObjects (Session database) {
      Query query = database.createQuery("from BlogPostImpl bp where bp.replicatedChangeset = :changeset")
              .setParameter("changeset", this);
      List ret = query.list();
      log.debug("Got list of changed objects in " + this + ", it's " + ret);
      return ret;
   }

I get the exception as follows:
Code:
   [testng] java.lang.ClassCastException: org.hibernate.action.DelayedPostInsertIdentifier
   [testng]     at org.hibernate.type.LongType.set(LongType.java:42)
   [testng]     at org.hibernate.type.NullableType.nullSafeSet(NullableType.java:83)
   [testng]     at org.hibernate.type.NullableType.nullSafeSet(NullableType.java:65)
   [testng]     at org.hibernate.type.ManyToOneType.nullSafeSet(ManyToOneType.java:77)
   [testng]     at org.hibernate.loader.hql.QueryLoader.bindNamedParameters(QueryLoader.java:515)
   [testng]     at org.hibernate.loader.Loader.prepareQueryStatement(Loader.java:1577)
   [testng]     at org.hibernate.loader.Loader.doQuery(Loader.java:661)
   [testng]     at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:224)
   [testng]     at org.hibernate.loader.Loader.doList(Loader.java:2145)
   [testng]     at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2029)
   [testng]     at org.hibernate.loader.Loader.list(Loader.java:2024)
   [testng]     at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:392)
   [testng]     at org.hibernate.hql.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:333)
   [testng]     at org.hibernate.engine.query.HQLQueryPlan.performList(HQLQueryPlan.java:172)
   [testng]     at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1114)
   [testng]     at org.hibernate.impl.QueryImpl.list(QueryImpl.java:79)
   [testng]     at com.robjsoftware.replog.replicated.Changeset.queryChangedObjects(Changeset.java:77)
   [testng]     at com.robjsoftware.replog.test.ChangesetTest$2.invokeApplication(ChangesetTest.java:77)
   [testng]     at org.jboss.seam.mock.SeamTest$Script.run(SeamTest.java:242)
   [testng]     at com.robjsoftware.replog.test.ChangesetTest.testChangeset(ChangesetTest.java:57)

Very confusing since I'm not clear on how this could have worked before but not now!

I will post this to the Seam forum also....
Cheers,
Rob


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jun 29, 2006 12:32 am 
Expert
Expert

Joined: Thu Jan 08, 2004 6:17 pm
Posts: 278
Never mind me, I fixed it in my case. See here: http://jboss.com/index.html?module=bb&op=viewtopic&p=3954232#3954232 -- not relevant to the original poster, though!

(I'm not clear on whether Hibernate even wants to try to support the original poster's use case, but that's for him to worry about... ;-)
Cheers,
Rob


Top
 Profile  
 
 Post subject:
PostPosted: Wed Dec 20, 2006 8:10 am 
Newbie

Joined: Wed Oct 26, 2005 3:37 am
Posts: 15
I have a similar problem. Has anyone found the reason/solution?


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