Play2 How to manage the transaction from the service layer instead of action layer?

前端 未结 2 906
北海茫月
北海茫月 2021-01-16 17:09

I am using Play2.1.1 Java with JPA2.0 with hibernate implementation.

to control the transaction by code instead of using @transactional like below is the normal JPA

相关标签:
2条回答
  • 2021-01-16 17:35

    something like this:

    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);
        }       
    }
    
    0 讨论(0)
  • 2021-01-16 17:36

    After some time research, I write a method JPAUtil referring to JPA provided by Play which can use normally to control the transaction manually from the service layer actually everywhere.

    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 讨论(0)
提交回复
热议问题