How to properly fix "No EntityManager bound to this thread..." caused by nested JPA.withTransaction calls?

1,198 views
Skip to first unread message

Sergiy Sokolenko

unread,
Sep 9, 2014, 9:34:18 AM9/9/14
to play-fr...@googlegroups.com
Hi,

we're facing issues with nested JPA.withTransaction calls which result in well known RuntimeException("No EntityManager bound to this thread...").
Here is simplified use-case:

    @Transactional
    public static Result index() {

        JPA.em().isOpen(); // true

        // 2nd call to JPA.withTransaction binds new EntityManager to current thread (erasing previously bound EntityManager)
        JPA.withTransaction(() -> {
            JPA.em().isOpen(); // true
        });
        // after JPA.withTransaction call there is no EntityManager bound anymore

        JPA.em().isOpen(); // RuntimeException: No EntityManager bound to this thread.

        return ok();
    }

The obvious solution is to keep current EntityManager while new EntityManager is being bound and then rebind it when new EM is no longer used (i.e. at the end of JPA.withTransaction); see pull request.

Are there any potential or known issues with this solution? Otherwise, what is proper way to make nested JPA.withTransaction calls work?

We really think tha the inability to nest JPA.withTransaction calls is a bug because: a) it's not documented that we need not nest withTransaction calls; b) in real-life projects it's sometimes not possible to control third-party code that might call withTransaction while being executed within controller action which also requires @Transactional annotation or JPA.withTransaction call. It's possible to workaround such nasty cases, but it makes code very dirty & harder to maintain.

Any reply is deeply appreciated!
--

insign - simply e-business

Gambo

unread,
Aug 8, 2015, 6:23:00 AM8/8/15
to play-framework
Hi, can somebody provide an update for this issue? I am having the same problem trying to use the JPA helper.

I have a rest backend where I want to check the authtoken of a user for each request against a database/cache. Therefore I am extending Security.Authenticator(getUsername). When I am annotating an action with @Transactional the Security.Authenticator gets executed first and checks the authtoken with its entitymanager(Using JPA.withTransaction) but when the Action is being executed the entity manager is gone and it fails.

I could workaround in my Security.Authenticator checking if the entitymanager is there but that leads to very dirty code.

I am using Play 2.4.2 with Java, JPA/Hibernate.

Matthias Kurz

unread,
Nov 18, 2015, 3:43:01 AM11/18/15
to play-framework
Starting with Play 2.5 nested JPA transactions will be supported.
Reply all
Reply to author
Forward
0 new messages