ossys
ossys

Reputation: 4217

Play Framework JPA EntityManager Best Practice

This is a question related more to best practices. I'm using the Play Framework 2.2.1 with JPA for ORM persistence. Play offers a lot of "helper" methods and classes, and on in particular I found is the JPA.em() method. However, when I try to get the EntityManager object using this method in a public static method, I get the following error:

RuntimeException: No EntityManager bound to this thread. Try to annotate your action method with @play.db.jpa.Transactional

Being that I'm calling JPA.em() from a static method, I guess the above error makes sense. My question is, what's best practices for creating an EntityManager object? Is it an expensive operation to create the em object by doing something like this inside of the static method that will be called multiple times throughout the life of the app:

EntityManager em = Persistence.createEntityManagerFactory("DefaultDS").createEntityManager();

Or should I create a public static reference to the EntityManagerFactory and do something like this within the static method:

EntityManager em = staticEntityFactory.createEntityManager();

Or should I create an em object in the Entity and have each entity maintain a reference to the em object like this?

@Entity
public class myEntity {
   private static EntityManager em = Persistence.createEntityManagerFactory("DefaultDS").createEntityManager();
}

Some guidance on the best way to handle this would be greatly appreciated, thanks!

Upvotes: 1

Views: 1693

Answers (1)

GSP59
GSP59

Reputation: 413

I'm also still trying to understand every aspect of Play so I can't really guide you through the best practices But I think as your error mentioned, you have to add a @Transactionnal to your controller method from where you call your static JPA methods from your entities and use the JPA.em() method in these static methods from your entities.

Something like :

@Entity
public class Account {
    ....
    public static Account getAccount(Long id) {
        return JPA.em().find(Account.class, id);
    }
}

And in your controller :

public class AccountService extends Controller{

@Transactional(readOnly = true)
public static Result getAccount(Long id){
    Account account = Account.getAccount(id);

    return ok(Json.toJson(account));
}
}

Upvotes: 2

Related Questions