2013-08-31 81 views
0

我使用Play2.1.1 Java和JPA2.0與hibernate實現。Play2如何從服務層而不是操作層管理事務?

來控制代碼的交易,而不是使用@Transactional像下面是正常的JPA代碼風格的,有什麼辦法像下面的工作在玩嗎?或者如何使用JPA.withtranaction()來做?我試過了,不知道如何傳遞參數,我不熟悉功能代碼。非常感謝。請根據以下內容給我一些示例代碼。

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); 
      } 
     }); 
    } 
+0

感謝@biesior我更新的版本和周圍寫電流的步行路程,還有沒有其他的解決辦法?謝謝。 – LWang

回答

0

一些時間研究之後,我寫了一個方法JPAUtil指由JPA提供遊戲能正常使用,從服務層手動控制交易實際上無處不在。

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(); 
    } 

} 
+0

這看起來很像https://github.com/playframework/playframework/blob/master/framework/src/play-java-jpa/src/main/java/play/db/jpa/JPA.java –

+0

這是,我從JPA複製了這個想法。使用JPAUtil,您可以像普通的JPA2.0一樣管理事務生命週期,而不是通過Play框架進行管理。 – LWang

1

是這樣的:

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); 
    }  
}