-->
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.  [ 2 posts ] 
Author Message
 Post subject: Removing an Entity in ManyToMany reflexive relationships.
PostPosted: Thu Jun 21, 2007 9:42 am 
Newbie

Joined: Wed Jun 13, 2007 5:44 am
Posts: 16
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).


Last edited by Zerg-Spirit on Fri Jun 22, 2007 4:28 am, edited 2 times in total.

Top
 Profile  
 
 Post subject:
PostPosted: Fri Jun 22, 2007 4:18 am 
Newbie

Joined: Wed Jun 13, 2007 5:44 am
Posts: 16
I think I've solved my problem, although I have the feeling I may have missed the 'real problem' behind it.
Considering the fact the EntityManager clearly didn't see any difference when I was merging a topic with updated children or parents list, I just created new updated List object and set them to topics.
My guess is that since the reference to the children/parents list is new, the EntityManager now knows that he has some changes to perform in the database, whereas it didn't before.

It gives me something like that:

Code:
if(topic.getParents().size()>0){
                                 //Retrieving every parents of the topic to delete.
            for(Topic t:topic.getParents()){
                                       //Removing the reference to that topic from their children list.
               t.removeChild(topic);
                                       
               ArrayList<Topic> childrenList = new ArrayList<Topic>();
                                        //Creating and filling a new List of children for that parent.
               for(Topic tp:t.getChildren()){
                     childrenList.add(tp);   
               }
               t.setChildren(childrenList);
                                        //Finally merging the parent, performing the changes to the database.
               em.merge(t);
            }


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