users@glassfish.java.net

Re: JPA Recursive Updates for One-to-Many and Many-To-One Relationships

From: <glassfish_at_javadesktop.org>
Date: Sun, 24 Feb 2008 08:23:58 PST

Okay I spent most of yesterday changing the relationships' for Cascade type to:

[code]
@ManyToOne(cascade={CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH}, fetch=FetchType.LAZY)
@JoinColumn(name="<FK of current entity> ", referencedColumnName="<PK of target> ", unique=false, nullable=true, insertable=true, updatable=true)

or

@OneToMany(cascade={CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH}, fetch=FetchType.LAZY, mappedBy= <owning class>)

or

@OneToOne(cascade={CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH}, optional=true, fetch=FetchType.LAZY)
[/code]

The database I created has no data inside it; merge operations are not called with Entities that do not exist within the database. Therefore, I use the persist method on individual entities. The entity becomes "detached" once it returned from the persist operation. Flush operations are accomplished at the end of the transaction from the root entity.

My process starts with the root entity. I create an EntityManager and add the process to the transaction. Next I pull out any relationship entities (collection) from the root entity and call the EAO for the specific entity (passing the collection). The individual subordinate entities take the collection and breaks the collection up into an elment and persist each element. The results are added to a new collection. The new collection is returned to the parent entity. The parent entity takes the "detached" entity collection and overrights the relationship in the "detached" parent entity.

Here is the start of the process. Note the VO object is the "detached" entity:

[code]
public JtdiSite addJtdiSite(JtdiSite jtdiSiteVO) {

        EntityManager em = getEntityManager();

                        em.joinTransaction();

                     // Multiple Operations similar to the below are carried out

                        JtdiLocationEAO JtdiLocationEAO = EAOFactory.JPA.getJtdiLocationEAO();

                        Set<JtdiLocation> locations =null;

                        int setSize = 0;

                        if(((locations = jtdiSiteVO.getJtdiLocations()) != null) &&

                           ((setSize = locations.size()) > EMPTY)){

                                    locations = JtdiLocationEAO.addJtdiLocations(locations);
                                    jtdiSiteVO.setJtdiLocations(locations);

                        }else{

                                    jtdiSiteVO.setJtdiLocations(null);

                        }

                      em.persist(jtdiSiteVO);
                     // I have tried the following too
                    // em.refresh(em.merge(jtdiSiteVO));

           return jtdiSiteVO;

  }//end method
[/code]

The process is repeated in each of the children entities, so I'll give one example.

[code]
      public JtdiLocation addJtdiLocation(JtdiLocation jtdiLocationVO) {

              EntityManager em = getEntityManager();

              em.joinTransaction();

              em.persist(jtdiLocationVO);

            return jtdiLocationVO;

      }

 

      

      public Set<JtdiLocation> addJtdiLocations(Set<JtdiLocation> jtdiLocationSetVO) {

        EntityManager em = getEntityManager();

        em.joinTransaction();

        Set<JtdiLocation> jtdiLocationSet = new HashSet<JtdiLocation>();

        for(Iterator it = jtdiLocationSetVO.iterator(); it.hasNext();){

              JtdiLocation jtdiLocation = (JtdiLocation)it.next();

              if(((jtdiLocation.getLocationId()) != null) &&

                 ((jtdiLocation.getLocationId().intValue() )>=DB_RECORD)){

                  //this record exist in database.

                    em.refresh(em.merge(jtdiLocation));

                    jtdiLocationSet.add(jtdiLocation);

              }else if ( jtdiLocation.getLocationId() == null){

                  //this a new jtdi Location

                  jtdiLocationSet.add(addJtdiLocation(jtdiLocation));

              }

        }//end for loop

         return jtdiLocationSet;

      }//end method

[/code]

I am still getting a stackoverflow error with this approach. Any suggestions would greatly appreciated.

Thank you for taking the time to read my post.

Russ
[Message sent by forum member 'russ205' (russ205)]

http://forums.java.net/jive/thread.jspa?messageID=260619