这是一个与最佳做法相关的问题。我将Play Framework 2.2.1和JPA用于ORM持久性。 Play提供了很多帮助"方法和类,特别是我发现的是JPA.em()方法。但是,当我尝试在公共静态方法中使用此方法获取EntityManager对象时,我收到以下错误:
RuntimeException: No EntityManager bound to this thread. Try to annotate your action method with @play.db.jpa.Transactional
由于我是从静态方法调用JPA.em(),我猜上面的错误是有道理的。我的问题是,创建EntityManager对象的最佳做法是什么?通过在静态方法中执行类似的操作来创建em对象是一项昂贵的操作,该方法将在应用程序的整个生命周期中多次调用:
EntityManager em = Persistence.createEntityManagerFactory("DefaultDS").createEntityManager();
或者我应该创建一个EntityManagerFactory的公共静态引用,并在静态方法中执行类似的操作:
EntityManager em = staticEntityFactory.createEntityManager();
或者我应该在实体中创建一个em对象,并让每个实体像这样维护对em对象的引用?
@Entity
public class myEntity {
private static EntityManager em = Persistence.createEntityManagerFactory("DefaultDS").createEntityManager();
}
非常感谢有关处理此问题的最佳方法的一些指导,谢谢!
答案 0 :(得分:2)
我还在尝试了解Play的各个方面,因此我无法真正指导您完成最佳做法 但我认为,正如您提到的错误,您必须在控制器方法中添加@Transactionnal,您可以从实体中调用静态JPA方法,并在实体的这些静态方法中使用JPA.em()方法。
类似的东西:
@Entity
public class Account {
....
public static Account getAccount(Long id) {
return JPA.em().find(Account.class, id);
}
}
在你的控制器中:
public class AccountService extends Controller{
@Transactional(readOnly = true)
public static Result getAccount(Long id){
Account account = Account.getAccount(id);
return ok(Json.toJson(account));
}
}