Jpa Play2如何从服务层而不是操作层管理事务?
我正在使用Play2.1.1Java和带有hibernate实现的JPA2.0 通过代码控制事务而不是像下面那样使用@transactional是正常的JPA代码风格,有没有办法像下面这样工作?或者如何使用JPA.withtranaction()来做?我试过了,不知道如何传入参数,我不熟悉函数代码。谢谢。请给我一些基于下面的示例代码Jpa Play2如何从服务层而不是操作层管理事务?,jpa,playframework-2.0,Jpa,Playframework 2.0,我正在使用Play2.1.1Java和带有hibernate实现的JPA2.0 通过代码控制事务而不是像下面那样使用@transactional是正常的JPA代码风格,有没有办法像下面这样工作?或者如何使用JPA.withtranaction()来做?我试过了,不知道如何传入参数,我不熟悉函数代码。谢谢。请给我一些基于下面的示例代码 public void createActorB(final String email, final String psw) throws Throwable {
public void createActorB(final String email, final String psw) throws Throwable {
EntityManager manager = JPA.em();
try {
EntityTransaction ex = manager.getTransaction();
this.dbActor.setEmail(email);
this.dbActor.setCredential(psw);
manager.persist(this.dbActor);
ex.commit();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
throw new ActorException(CODE.UNKNOWN, e);
} finally {
manager.close();
}
}
现在我修改了下面的代码,从服务层开始事务处理,看起来效率不高,还有其他的编写方法吗?谢谢
private void internalCreateActor(String email, String psw) throws ActorException {
if (StringUtils.isEmpty(email) || StringUtils.isEmpty(psw))
throw new ActorException(CODE.INVALIDE_PARAMETER);
try {
this.dbActor.setEmail(email);
this.dbActor.setCredential(psw);
this.dbActor.setCreateD(new Date());
JPA.em().persist(this.dbActor);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
throw new ActorException(CODE.UNKNOWN, e);
}
}
public void createActor(final String email, final String psw, final String cellPhone, final Actor.TYPE type)
throws Throwable {
JPA.withTransaction(new Callback0() {
@Override
public void invoke() throws Throwable {
internalCreateActor(email, psw, cellPhone, type);
}
});
}
经过一段时间的研究,我参考Play提供的JPA编写了一个方法JPAUtil,该方法通常可以用于从服务层手动控制事务,实际上无处不在
public class JPAUtil {
static ThreadLocal<EntityManager> currentEntityManager = new ThreadLocal<EntityManager>();
/**
* Get the EntityManager for specified persistence unit for this thread.
*/
public static EntityManager em(String key) {
Application app = Play.application();
if (app == null) {
throw new RuntimeException("No application running");
}
JPAPlugin jpaPlugin = app.plugin(JPAPlugin.class);
if (jpaPlugin == null) {
throw new RuntimeException("No JPA EntityManagerFactory configured for name [" + key + "]");
}
EntityManager em = jpaPlugin.em(key);
if (em == null) {
throw new RuntimeException("No JPA EntityManagerFactory configured for name [" + key + "]");
}
bindForCurrentThread(em);
return em;
}
/**
* Get the default EntityManager for this thread.
*/
public static EntityManager em() {
EntityManager em = currentEntityManager.get();
if (em == null) {
return em(Constants.DATASOURCEKEY);
}
return em;
}
/**
* Bind an EntityManager to the current thread.
*/
public static void bindForCurrentThread(EntityManager em) {
currentEntityManager.set(em);
}
public static void closeEM() {
EntityManager em = currentEntityManager.get();
if (em != null) {
em.close();
}
bindForCurrentThread(null);
}
public static void beginTransaction() {
em().getTransaction().begin();
}
public static void commitTransaction() {
em().getTransaction().commit();
}
}
公共类JPAUtil{
静态ThreadLocal currentEntityManager=new ThreadLocal();
/**
*获取此线程的指定持久化单元的EntityManager。
*/
公共静态实体管理器em(字符串键){
应用程序app=Play.Application();
如果(app==null){
抛出新的RuntimeException(“无应用程序运行”);
}
JPAPlugin=app.plugin(JPAPlugin.class);
if(jpaPlugin==null){
抛出新的RuntimeException(“没有为name[“+key+”]配置JPA EntityManagerFactory”);
}
EntityManager em=jpaPlugin.em(键);
if(em==null){
抛出新的RuntimeException(“没有为name[“+key+”]配置JPA EntityManagerFactory”);
}
bindForCurrentThread(em);
返回em;
}
/**
*获取此线程的默认EntityManager。
*/
公共静态实体管理器em(){
EntityManager em=currentEntityManager.get();
if(em==null){
返回em(Constants.DATASOURCEKEY);
}
返回em;
}
/**
*将EntityManager绑定到当前线程。
*/
公共静态无效bindForCurrentThread(EntityManager em){
currentEntityManager.set(em);
}
公共静态void closem(){
EntityManager em=currentEntityManager.get();
如果(em!=null){
em.close();
}
bindForCurrentThread(空);
}
公共静态void beginTransaction(){
em().getTransaction().begin();
}
公共静态无效提交事务(){
em().getTransaction().commit();
}
}
类似这样的内容:
public static User getUserByIdentity(final AuthUserIdentity identity) {
try {
return JPA.withTransaction(new play.libs.F.Function0<User>() {
public User apply() {
return User.findByAuthUserIdentity(identity);
}
});
} catch (Throwable t) {
throw new RuntimeException(t);
}
}
公共静态用户getUserByIdentity(最终AuthUserIdentity){
试一试{
返回JPA.withTransaction(new play.libs.F.Function0(){
公共用户apply(){
返回User.findByAuthUserIdentity(identity);
}
});
}捕获(可丢弃的t){
抛出新的运行时异常(t);
}
}
Thank@biesior我更新了版本并编写了当前的漫游,还有其他解决方案吗?谢谢。看起来很像,我是从JPA那里学来的。使用JPAUtil,您可以像正常的JPA2.0方式一样管理事务生命周期,而不是按播放框架进行管理。