Neriyan
Neriyan

Reputation: 155

Updating two objects in the same transaction

I have a two classes defined as follows:

public class CallDetail {

@OneToMany(mappedBy = "callDetail", cascade = CascadeType.ALL, orphanRemoval = true)
    private Set<Task> tasks = new HashSet<Task>();

}

public class Task {

    @ManyToOne
    private CallDetail callDetail;

    @OneToMany
    private Set<Task> preRequisiteTask = new HashSet<Task>();
}

I have two objects of class CallDetail which are already in database. I then attempt the following update in the service layer:

Task countStock = new Task();
Task takeOrder = new Task();
takeOrder.getPreRequisites().add(countStock);

callOne.getTaskInstances.add(countStock);
callTwo.getTaskInstances.add(taskOrder);

try {
        callDetailService.updateCallDetail(callOne);
        isValid = true;
    }catch(Exception e) {
        e.printStackTrace();
    }
if (isValid) {
            callDetailService.updateCallDetail(callDetail);
        }

When the update runs, the error I get is:

org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: za.co.itdynamics.ccs.domain.Task

How do I prevent this error from happening when both CallDetail objects are related to each other (where takeOrder in callOne has a prerequisite of countStock in callTwo)? Is it possible to update both CallDetail objects (callOne and callTwo) in one transaction?

Upvotes: 0

Views: 212

Answers (2)

Ralph
Ralph

Reputation: 120871

Of course you have to start a transaction at the beginning (@Transactional)

Then you need to persist both Tasks. There are at least two ways:

  • add CascadeType.PERSIST (or .ALL) to the @OneToMany relationship, or
  • invoke EntityManager.persist(countStock) and EntityManager.persist(takeOrder) BEFORE you add them to an already persisited entity.

(I prefer the second way.)

Upvotes: 1

outdev
outdev

Reputation: 5502

Add cascade for the preRequisiteTask:

@OneToMany(cascade = CascadeType.ALL)
private Set<Task> preRequisiteTask = new HashSet<Task>();

Upvotes: 2

Related Questions