Hi,
I'm using Jboss 4.0.5 and Seam 1.2.1 and I'm getting some problem with the EntityManager, trying to remove some Entities.
Here's the point.
I have an Entity, called Topic, which have a ManyToMany relationship to itself.
I decided, regarding my application, to store both children and parents in an entity, whereas I have only one table in the Database to make that.
Here's how I mapped it:
Code:
@Entity
@Scope(SESSION)
public class Topic implements Serializable {
@Id
@GeneratedValue
private Long id;
@ManyToMany(targetEntity=Topic.class,cascade={CascadeType.PERSIST,CascadeType.MERGE}, fetch=FetchType.LAZY)
@LazyCollection(LazyCollectionOption.TRUE)
@JoinTable(
name="Topic_Topic",
joinColumns={@JoinColumn(name="Topic_id")},
inverseJoinColumns={@JoinColumn(name="Child_id")})
private List<Topic> children;
@LazyCollection(LazyCollectionOption.TRUE)
@ManyToMany(
cascade={CascadeType.PERSIST, CascadeType.MERGE},
mappedBy="children",
targetEntity=Topic.class
)
private List<Topic> parents;
...
Anyway, the mapping seems to work well, since I got the right results and even the Lazy Loading is working without any problem.
But when it comes to delete a Topic entity, it's another story.
See, I can't use the Cascade to handle it, since deleting a parent doesn't mean its children have to be deleted, since they can have other parent.
So I'm trying to 'break' the links between parents and children before removing the entity.
Here's my code, inside a SFSB.
Not that my EntityManager has en Extended type.
Code:
@PersistenceContext(type=PersistenceContextType.EXTENDED)
EntityManager em;
...
public String deleteTopic(Topic topic){
if(topic!=null){
if(topic.getParents().size()>0){
for(Topic t:topic.getParents()){
//I remove the child reference of the topic to delete in its parents entities.
t.removeChild(topic);
}
Topic temp;
for(int i=0;i<=topic.getParents().size()-1;i++){
//Then I remove the parents reference from the topic to delete.
temp = topic.getParents().get(i);
topic.removeParent(temp);;
//Once it's done, I'm sure the topic to delete is isolated, so I merge the parent with the EntityManager in order to remove these links from the DB (this part doesn't seem to work).
em.merge(temp);
}
}
//This line throws the exception.
em.remove(em.merge(topic));
I then have this exception:
Code:
15:26:18,495 ERROR [SeamPhaseListener] uncaught exception
org.jboss.seam.TransactionException: Could not commit transaction
at org.jboss.seam.jsf.AbstractSeamPhaseListener.commitOrRollback(AbstractSeamPhaseListener.java:334)
at org.jboss.seam.jsf.TransactionalSeamPhaseListener.handleTransactionsAfterPhase(TransactionalSeamPhaseListener.java:45)
at org.jboss.seam.jsf.SeamPhaseListener.afterPhase(SeamPhaseListener.java:111)
at org.apache.myfaces.lifecycle.PhaseListenerManager.informPhaseListenersAfter(PhaseListenerManager.java:89)
at org.apache.myfaces.lifecycle.LifecycleImpl.invokeApplication(LifecycleImpl.java:345)
at org.apache.myfaces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:86)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:137)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:252)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
at org.jboss.seam.web.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:63)
at org.jboss.seam.web.ExceptionFilter.doFilter(ExceptionFilter.java:57)
at org.jboss.seam.web.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:49)
at org.jboss.seam.debug.hot.HotDeployFilter.doFilter(HotDeployFilter.java:60)
at org.jboss.seam.web.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:49)
at org.jboss.seam.web.RedirectFilter.doFilter(RedirectFilter.java:45)
at org.jboss.seam.web.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:49)
at org.jboss.seam.web.MultipartFilter.doFilter(MultipartFilter.java:79)
at org.jboss.seam.web.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:49)
at org.jboss.seam.web.SeamFilter.doFilter(SeamFilter.java:84)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
at org.ajax4jsf.framework.ajax.xmlfilter.BaseXMLFilter.doXmlFilter(BaseXMLFilter.java:96)
at org.ajax4jsf.framework.ajax.xmlfilter.BaseFilter.doFilter(BaseFilter.java:220)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
at org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:178)
at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:175)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:432)
at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:74)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:126)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:105)
at org.jboss.web.tomcat.tc5.jca.CachedConnectionValve.invoke(CachedConnectionValve.java:156)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:107)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:148)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:869)
at org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java:664)
at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:527)
at org.apache.tomcat.util.net.MasterSlaveWorkerThread.run(MasterSlaveWorkerThread.java:112)
at java.lang.Thread.run(Thread.java:619)
Caused by: org.jboss.tm.JBossRollbackException: Unable to commit, tx=TransactionImpl:XidImpl[FormatId=257, GlobalId=lrboss/140, BranchQual=, localId=140] status=STATUS_NO_TRANSACTION; - nested throwable: (javax.persistence.EntityNotFoundException: deleted entity passed to persist: [com.lrb.Thesaurus.Topic#<null>])
at org.jboss.tm.TransactionImpl.commit(TransactionImpl.java:372)
at org.jboss.tm.TxManager.commit(TxManager.java:240)
at org.jboss.tm.usertx.client.ServerVMClientUserTransaction.commit(ServerVMClientUserTransaction.java:140)
at org.jboss.seam.jsf.AbstractSeamPhaseListener.commitOrRollback(AbstractSeamPhaseListener.java:324)
... 42 more
Caused by: javax.persistence.EntityNotFoundException: deleted entity passed to persist: [com.lrb.Thesaurus.Topic#<null>]
at org.hibernate.ejb.AbstractEntityManagerImpl.throwPersistenceException(AbstractEntityManagerImpl.java:631)
at org.hibernate.ejb.AbstractEntityManagerImpl$1.beforeCompletion(AbstractEntityManagerImpl.java:524)
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)
... 45 more
Note that if I do a 'em.clear()' before removing the entity, it works, BUT the references to the parents aren't broken, so my db then contains error (relations between entities that no longer exist).