[2.4.2] Hibernate - No EntityManager found in a method that worked in 2.3

769 views
Skip to first unread message

Johan Dahlberg

unread,
Jul 7, 2015, 8:17:22 AM7/7/15
to play-fr...@googlegroups.com
In Play 2.3.x we had a getLoggedOnUser method to fetch the User object for the logged in user. The method was located in the Application controller and used by both views and other controllers but since the update JPA/Hibernate complains that:

"No EntityManager found in the context. Try to annotate your action method with @play.db.jpa.Transactional]]"

Since I guess it's not possible to use several transactions for a single request that it's not helping to add it to the getLoggedOnUser method so my question is how I could implement a similar method now in 2.4.x

Is it more that has changed that could cause problem with Hibernate because it seams like there are more errors that has to do with Hibernate. But I can't find any changes in the documentation.

/Johan

public static User getLoggedOnUser() {
        String sessionId = session("sessionId");

        if (sessionId == null || sessionId.equals(""))
            return null;

return User.authenticate(sessionId);
}


Johan Dahlberg

unread,
Jul 8, 2015, 2:23:14 AM7/8/15
to play-fr...@googlegroups.com
I got a similar problem in our API:

What I do here is that I receive the request in my action handleFeedback and then use the following code to use a different execution context for the parsing.

ExecutionContext feedbackExecutionCtx = Akka.system().dispatchers().lookup("akka.actor.simple-feedback-operations");
return F.Promise.promise(() -> handleFeedback(xmlString, dom), feedbackExecutionCtx).get(5, TimeUnit.MINUTES);

Do I need to use JPA.withTransaction when I change execution context?


java.lang.RuntimeException: No EntityManager bound to this thread. Try wrapping this call in JPA.withTransaction, or ensure that the HTTP context is setup on this thread.
at play.db.jpa.JPA.em(JPA.java:76)
at dao.AbstractDAO.<init>(AbstractDAO.java:47)
at dao.feedback.CompanyInfoFeedbackItemDAO.<init>(CompanyInfoFeedbackItemDAO.java:12)
at utils.parsers.XmlParser.parseFeedbackNode(XmlParser.java:186)
at utils.parsers.XmlParser.parseXml(XmlParser.java:140)
at controllers.Feedback.handleFeedback(Feedback.java:368)
at controllers.Feedback.lambda$handleFeedback$15(Feedback.java:360)
at controllers.Feedback$$Lambda$67/360448727.apply(Unknown Source)
at play.core.j.FPromiseHelper$$anonfun$promise$2.apply(FPromiseHelper.scala:36)
at scala.concurrent.impl.Future$PromiseCompletingRunnable.liftedTree1$1(Future.scala:24)
at scala.concurrent.impl.Future$PromiseCompletingRunnable.run(Future.scala:24)
at akka.dispatch.TaskInvocation.run(AbstractDispatcher.scala:40)
at akka.dispatch.ForkJoinExecutorConfigurator$AkkaForkJoinTask.exec(AbstractDispatcher.scala:397)
at scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260)
at scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339)
at scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979)
at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107)
2015-07-08 08:17:01,088 - [error] XmlParser - No EntityManager bound to this thread. Try wrapping this call in JPA.withTransaction, or ensure that the HTTP context is setup on this thread.
2015-07-08 08:17:01,088 - [error] XmlParser - [play.db.jpa.JPA.em(JPA.java:76), dao.AbstractDAO.<init>(AbstractDAO.java:47), dao.feedback.CompanyInfoFeedbackItemDAO.<init>(CompanyInfoFeedbackItemDAO.java:12), utils.parsers.XmlParser.parseFeedbackNode(XmlParser.java:186), utils.parsers.XmlParser.parseXml(XmlParser.java:140), controllers.Feedback.handleFeedback(Feedback.java:368), controllers.Feedback.lambda$handleFeedback$15(Feedback.java:360), controllers.Feedback$$Lambda$67/360448727.apply(Unknown Source), play.core.j.FPromiseHelper$$anonfun$promise$2.apply(FPromiseHelper.scala:36), scala.concurrent.impl.Future$PromiseCompletingRunnable.liftedTree1$1(Future.scala:24), scala.concurrent.impl.Future$PromiseCompletingRunnable.run(Future.scala:24), akka.dispatch.TaskInvocation.run(AbstractDispatcher.scala:40), akka.dispatch.ForkJoinExecutorConfigurator$AkkaForkJoinTask.exec(AbstractDispatcher.scala:397), scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260), scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339), scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979), scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107)]

2015-07-08 08:17:01,089 - [error] Feedback - There is no HTTP Context available from here.



/Johan

Johan Dahlberg

unread,
Jul 8, 2015, 4:56:18 AM7/8/15
to play-fr...@googlegroups.com
One more place where this is causing problem is in all my DAO. Because I use a static newInstance to create a new instance of my DAO, that could look like the following example.

public class UserDAO extends AbstractDAO<User, User_> {
    public UserDAO() {
        super(User.class, User_.class);
    }

    public static UserDAO newInstance() {
        return new UserDAO();
    }

    public Optional<User> findByEmail(String email) {
        Query q = em.createQuery("FROM User WHERE email=?1")
                .setParameter(1, email);
        try {
            return Optional.ofNullable((User) q.getSingleResult());
        } catch(NoResultException ex) {
            return Optional.empty();
        }
    }

    ...
}


public abstract class AbstractDAO<T extends AbstractModel, M extends AbstractModel_> {
    protected final Class<T> classType;
    protected final EntityManager em;
    protected final CriteriaBuilder cb;

    protected AbstractDAO(Class<T> classType, Class<M> metaType) {
        this.em = JPA.em();
        this.cb = em.getCriteriaBuilder();
        this.classType = classType;
    }

    ...
}

/Johan
Reply all
Reply to author
Forward
0 new messages