2013-08-31 1 views
0

Я использую Play2.1.1 Java с JPA2.0 с реализацией спящего режима.Play2 Как управлять транзакцией из уровня сервиса вместо слоя действия?

для управления транзакцией по коду вместо использования @transactional, как показано ниже, является нормальным стилем JPA-кода, есть ли способ работать, как показано ниже в Play? или как использовать 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); 
    }  
} 
Смежные вопросы