-->
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.  [ 5 posts ] 
Author Message
 Post subject: Can't delete Child from Parent when relationship is Map
PostPosted: Thu Aug 24, 2006 12:13 am 
Beginner
Beginner

Joined: Mon Sep 15, 2003 6:28 pm
Posts: 26
There are some odd things happening when you try to delete a child from a (ejb3-style) Map relationship in the parent.

The bidirectional 1:M relationship is simple:

Code:
@Entity
@Cache(usage=CacheConcurrencyStrategy.TRANSACTIONAL)
public class Parent
{
   @Id
   @GeneratedValue
   Long id;
   public Long getId() { return this.id; }

   @OneToMany(cascade=CascadeType.ALL)
   @JoinColumn(name="parentId")
   @MapKey(name="id")
   @Cache(usage=CacheConcurrencyStrategy.TRANSACTIONAL)
   Map<Long, Child> children;
   public Map<Long, Child> getChildren() { return this.children; }
}

Code:
@Entity
@Cache(usage=CacheConcurrencyStrategy.TRANSACTIONAL)
public class Child
{
   @Id
   @GeneratedValue
   Long id;
   public Long getId() { return this.id; }

   @ManyToOne
   @JoinColumn(name="parentId", nullable=true)
   Parent parent;
   public Parent getParent() { return this.parent; }
   public void setParent(Parent value) { this.parent = value; }
}


It's apparently impossible to delete a child in this configuration. This series of method calls produces a nasty exception:

Transaction one, creating the data:
Code:
Parent p = new Parent();
this.em.persist(p);

Child c = new Child(p);
this.em.persist(c);
p.getChildren().put(c.getId(), c);


Transaction two, attempting the delete:
Code:
Parent p = this.em.find(Parent.class, parentId);
   
Long cId = p.getChildren().keySet().iterator().next();
Child c = p.getChildren().get(cId);
      
this.em.remove(c);
p.getChildren().remove(cId);


The exception (and a little bit of log) looks like this:

Code:
2006-08-23 21:03:26,625 DEBUG [org.hibernate.SQL] update Child set parentId=null where parentId=?
2006-08-23 21:03:26,640 DEBUG [org.hibernate.persister.collection.AbstractCollectionPersister] done deleting collection
2006-08-23 21:03:26,640 DEBUG [org.hibernate.jdbc.AbstractBatcher] Executing batch size: 1
2006-08-23 21:03:26,687 DEBUG [org.hibernate.jdbc.AbstractBatcher] about to close PreparedStatement (open PreparedStatements: 1, globally: 1)
2006-08-23 21:03:26,687 DEBUG [org.hibernate.jdbc.ConnectionManager] skipping aggressive-release due to flush cycle
2006-08-23 21:03:26,687 DEBUG [org.hibernate.util.JDBCExceptionReporter] Could not execute JDBC batch update [update Child set parentId=null where parentId=?]
java.sql.BatchUpdateException: Data truncation: Column set to default value; NULL supplied to NOT NULL column 'parentId' at row 1
   at com.mysql.jdbc.ServerPreparedStatement.executeBatch(ServerPreparedStatement.java:648)
   at org.jboss.resource.adapter.jdbc.WrappedStatement.executeBatch(WrappedStatement.java:517)
   at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:58)
   at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:242)
   at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:235)
   at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:142)
   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.ejb.AbstractEntityManagerImpl$1.beforeCompletion(AbstractEntityManagerImpl.java:475)
   at org.jboss.tm.TransactionImpl.doBeforeCompletion(TransactionImpl.java:1491)
   at org.jboss.tm.TransactionImpl.beforePrepare(TransactionImpl.java:1110)
   at org.jboss.tm.TransactionImpl.commit(TransactionImpl.java:324)
   at org.jboss.tm.TxManager.commit(TxManager.java:240)
   at org.jboss.aspects.tx.TxPolicy.endTransaction(TxPolicy.java:175)
   at org.jboss.aspects.tx.TxPolicy.invokeInOurTx(TxPolicy.java:87)
   at org.jboss.aspects.tx.TxInterceptor$Required.invoke(TxInterceptor.java:197)
   at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
   at org.jboss.aspects.tx.TxPropagationInterceptor.invoke(TxPropagationInterceptor.java:76)
   at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
   at org.jboss.aspects.security.AuthenticationInterceptor.invoke(AuthenticationInterceptor.java:78)
...


I'm especially puzzled about the statement: update Child set parentId=null where parentId=?

This seems bizarre and unnecessary, and probably what's causing the trouble. If I make Child.parentId nullable=true, then everything works.

Should I file my test case in JIRA?

Thanks,
Jeff


Top
 Profile  
 
 Post subject:
PostPosted: Thu Aug 24, 2006 12:24 am 
Beginner
Beginner

Joined: Mon Sep 15, 2003 6:28 pm
Posts: 26
By the way, this is JBoss 4.0.4GA and MySQL 5.0.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Aug 24, 2006 1:04 am 
Hibernate Team
Hibernate Team

Joined: Sun Sep 14, 2003 3:54 am
Posts: 7256
Location: Paris, France
at least you're missing a mappedBy somewhere

_________________
Emmanuel


Top
 Profile  
 
 Post subject:
PostPosted: Thu Aug 24, 2006 3:22 pm 
Beginner
Beginner

Joined: Mon Sep 15, 2003 6:28 pm
Posts: 26
emmanuel wrote:
at least you're missing a mappedBy somewhere


I'm an idiot. Thanks.

I've gotta say though, the failure mode for this case was pretty bad... everything seemed to work as advertised until a delete. Are there any legitimate cases for having non-inverse on both ends of a bidir relationship? If not, can this be flagged as an error at deployment?

Thanks,
Jeff


Top
 Profile  
 
 Post subject:
PostPosted: Thu Aug 24, 2006 7:12 pm 
Hibernate Team
Hibernate Team

Joined: Sun Sep 14, 2003 3:54 am
Posts: 7256
Location: Paris, France
There are legitimate cases :-)

_________________
Emmanuel


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