DarkCrow
DarkCrow

Reputation: 850

How to save an entity within a new transaction?

I have a method which calls another method to save an entity object with new transaction.

public class FooProcessor {
    @Transactional
    public Foo process(final String id, final String name, final String description) {
        final Foo foo = this.fooCreator.createFoo(id, name, description);
        foo.setDescription("Change description");
        this.fooDAO.save(foo);
        return foo;
    }
}

The process() is calling a createFoo() method in a FooCreator class to create foo object with @Transactional(propagation = Propagation.REQUIRES_NEW).

public class FooCreator {
     @Transactional(propagation = Propagation.REQUIRES_NEW)
     public Foo createFoo(final String id, final String name, final String description) {
           return this.fooDAO.save(new Foo(id, name, description));
     }
    
}

When the returned foo object is modified in process method it saves as a new object. How do I modify the existing foo object which createFoo() has returned?

If I try findById its still throwing an exception.

public class FooProcessor {
 @Transactional
    public Foo process(final String id, final String name, final String description) {
        final Foo foo = this.fooCreator.createFoo(id, name, description);
        final Foo newFoo = fooDAO.findById(foo.getId())
                .orElseThrow(() -> new NotFoundException("Foo not found"));
        newFoo.setDescription("Change description");
        this.fooDAO.save(newFoo);
        return newFoo;
    }
}

How do I save an entity in a new transaction and use the same entity in the caller method?

Upvotes: 3

Views: 1849

Answers (1)

David SN
David SN

Reputation: 3519

Your method should be unable to read the changes in the new Transaction if it's not using an appropriate isolation level. If you set the isolation level to READ_COMMITED, your process method can read the changes of your creator method.

@Transaction(isolation = Isolation.READ_COMMITTED)
public Foo process(final String id, final String name, final String description) {
}

If you have a more restrictive isolation level, the transaction could be unable to read the changes made in the method with the REQUIRED_NEW transaction. To give an example, if you set the more restrictive Isolation.SERIALIZABLE, your code will give a NotFoundException as the changes made in the creator method cannot be read inside the transaction of the process method.

Upvotes: 1

Related Questions