Search code examples
javajpaopenjpa

OpenJpa merge detached object


I'm wondering if the way I use to save my entities with OpenJpa 2 is correct.

I receive object from a rest service that I deserialize, then to save this instance :

  1. Begin the transaction
  2. Retrieve the instance from the DB (even though I've already got this instance)
  3. Copy the attributes from the detached instance to the instance retrieved from the DB
  4. Call the merge
  5. Commit the transaction

In case of a complex entity model with compsitions, it becomes painful!

public boolean save(Collection<Event> events) throws DataException {

    if (events == null) {
        throw new DataException("Cannot save null events");
    }

    EntityManager em = getEntityManager();
    try {
        em.getTransaction().begin();
        for (Event event : events) {

            boolean add = true;

            if(event.getKey() > 0){
                Event previousEvent = em.find(Event.class, event.getKey());
                if (previousEvent != null) {
                    //update
                    previousEvent.setTitle(event.getTitle());
                    previousEvent.setDate(event.getDate());
                    previousEvent.setDescription(event.getDescription());

                    List<Member> participants = new ArrayList<>();
                    for(Member m : event.getParticipants()){
                        Member participant = em.find(Member.class, m.getKey());
                        if(participant != null){
                            participants.add(participant);
                        }
                    }
                    previousEvent.setParticipants(participants);

                    List<Member> registrants = new ArrayList<>();
                    for(Member m : event.getRegistrants()){
                        Member registrant = em.find(Member.class, m.getKey());
                        if(registrant != null){
                            participants.add(registrant);
                        }
                    }
                    previousEvent.setRegistrants(registrants);

                    em.merge(previousEvent);
                    add = false;
                } 
            } 
            if(add) {
                //add
                em.persist(event);
            }
        }
        em.getTransaction().commit();

    } catch (PersistenceException pe) {
        pe.printStackTrace();
        throw new DataException("An error occured while saving the event", pe);
    } finally {
        em.close();
    }
    return true;
}

Any suggestion?

THanks


Solution

  • Per Chris' comment - you should be able to just call em.merge(event) and let JPA handle all of it. It should automatically handle creating a new Event row if needed, updating the Event attributes, and updating or creating the contained objects as well.