Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@mkurz
Copy link
Member

@mkurz mkurz commented Dec 5, 2016

Replaces #6013

As we know to run code within a JPA transaction the preferred way is to call

// inject jpaApi
jpaApi.withTransaction(em -> ...)

With this PR an entity manager now always gets passed to all the various withTransaction methods. The em doesn't get stored in a ThreadLocal anymore.

Only when using @Transactional the entity manager still will be stored in the Http.Context so we can access and (re-)use it later from within the controller's action methods. But I did change how this happens. Instead of just accessing Http.Context.current() you now have to explicitly pass the context in which the em should get stored to withTransaction (happens in TransactionalAction.java).
Eventually, to retrieve the em we now have to pass a context to JPA.em(ctx).

With this changes JPAEntityManagerContext is becoming "just" a simple helper class which just makes it easier to store and read entity managers from a http context.

In future we can remove JPA.em() (it's deprecated now) in favor of JPA.em(ctx) - actually it's just a shortcut for JPAEntityManagerContext.em(ctx).

This should make play-jpa ready for the removal of the http context threadlocal which I think is targeted for a future play version. (It should work nicely with the changes in #6473 done by @gmethvin)

One more thing:
In @TransactionalAction we tell withTransaction to keep the em and transaction open so it doesn't get closed immediately but only after the future has completed. I am not entirely sure if this should be managed here or if I should add a withTransaction that returns a CompletionStage<T> and manage it there. Related to #6489

@mkurz mkurz mentioned this pull request Dec 5, 2016
Copy link
Member

@marcospereira marcospereira left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Matthias,

I was thinking about this API also and was planning to do something different of what you did. My idea is to separate the responsibility of get the EntityManager and the execution of transactions completely so that the JPAApi won't be responsible to expose/create/retrieve EntityManagers.

The complete surface of JPAApi would be:

public interface JPAApi {

    public <T> T withTransaction(Function<EntityManager, T> block);

    public <T> T withTransaction(String name, Function<EntityManager, T> block);

    public <T> T withTransaction(String name, boolean readOnly, Function<EntityManager, T> block);

    public <T> T withTransaction(Supplier<T> block);

    public void withTransaction(Runnable block);

    public <T> T withTransaction(String name, boolean readOnly, Supplier<T> block);
}

And then, we can inject a EntityManager resolver into the DefaultJPAApi. This resolver could use the Http.Context right now, but it will eventually migrate to use #6798. The way I see #6798 evolving, we can even have controllers like this:

public MyController extends Controller {

    private EntityManager em;

    @Inject
    public MyController(EntityManager em) {
        this.em = em;
    }
}

Anyway, we are not there yet. See my other comments.

*
* @return EntityManager for the specified persistence unit name
*/
public EntityManager em() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we should deprecate this instead of remove it.

* @return code execution result
*/
@Override
public <T> T withTransaction(String name, boolean readOnly, Http.Context ctx, boolean keepTransactionOpen, Function<EntityManager, T> block) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we are mixing layers here. We now have the (lower) Persistence layer depending on the (higher) HTTP layer. One implication here is now that to test a model/service object, I will need a Http.Context.

@mkurz
Copy link
Member Author

mkurz commented Sep 19, 2018

Outdated. Replaced by #8616

@mkurz mkurz closed this Sep 19, 2018
@mkurz mkurz removed their assignment Sep 19, 2018
@mkurz mkurz deleted the jpaRefactor branch September 20, 2018 18:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants