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