3
\$\begingroup\$

This is an attempt to create interfaces holding the boilerplate code of basic JPA interactions.

Code in question/review

Hierarchy Diagram

JPAInteraction.java

package personal.learn.jpa.jpa_all.config;

import javax.persistence.EntityManager;

public interface JPAInteraction {

    default void close(EntityManager entityManager) {
        if (entityManager != null && entityManager.isOpen()) entityManager.close();
    }

}

JPAAction.java

package personal.learn.jpa.jpa_all.config;

import javax.persistence.EntityManager;

import static personal.learn.jpa.jpa_all.config.JPAConfig.getNewEntityManager;

public interface JPAAction extends JPAInteraction {

    void internalAction(EntityManager entityManager) throws Exception;

    default void performEnclosedAction() throws Exception {
        final EntityManager entityManager = getNewEntityManager();
        try {
            internalAction(entityManager);
        } finally {
            close(entityManager);
        }
    }
}

JPACommit.java

package personal.learn.jpa.jpa_all.config;

import javax.persistence.EntityManager;

import static personal.learn.jpa.jpa_all.config.JPAConfig.getNewEntityManager;

public interface JPACommit extends JPAInteraction {

    void internalCommit(EntityManager entityManager) throws Exception;

    default void performEnclosedCommit() throws Exception {
        final EntityManager entityManager = getNewEntityManager();
        try {
            entityManager.getTransaction().begin();
            internalCommit(entityManager);
            entityManager.getTransaction().commit();
        } catch (Exception e) {
            if (entityManager != null && entityManager.getTransaction() != null && entityManager.getTransaction().isActive()) entityManager.getTransaction().rollback();
            throw e;
        } finally {
            close(entityManager);
        }
    }

}

Intended Use Example

package personal.learn.jpa.jpa_all.exc;

import org.junit.Test;
import personal.learn.jpa.jpa_all.config.JPAAction;
import personal.learn.jpa.jpa_all.config.JPACommit;
import personal.learn.jpa.jpa_all.entities.EntitiesFactory;
import personal.learn.jpa.jpa_all.entities.Entity44_;

import javax.persistence.EntityManager;

public class Test_JPAInteractions {

    @Test
    public void test_JPACommit() throws Exception {
        new JPACommit() {
            @Override
            public void internalCommit(EntityManager entityManager) throws Exception {
                entityManager.persist(EntitiesFactory.getEntity44_instance(1));
            }
        }.performEnclosedCommit();
    }

    @Test
    public void test_JPAAction() throws Exception {
        new JPAAction() {
            @Override
            public void internalAction(EntityManager entityManager) throws Exception {
                final Entity44_ entity44_ = entityManager.find(Entity44_.class, (long) 1);
            }
        }.performEnclosedAction();
    }
}

When I created those classes I had no idea of the different types of EntityManagers and that they have different life cycles. What those classes did was essentially enclose EntityManager creation and closure and committing/rolling-back any committable action. After I've found out that EntityManagers can have their lifecycle managed in different ways, I updated my code to the following.

JPAConfig.java

import javax.persistence.EntityManager;

public class JPAConfig {

    public static void close(EntityManager entityManager) {
        if (entityManager != null && entityManager.isOpen()) entityManager.close();
    }

}

JPACommit

import javax.persistence.EntityManager;

public interface JPACommit {

    void commitAction(EntityManager entityManager) throws Exception;

    default void performCommit(EntityManager entityManager) throws Exception {
        try {
            entityManager.getTransaction().begin();
            commitAction(entityManager);
            entityManager.getTransaction().commit();
        } catch (Exception e) {
            if (entityManager != null && entityManager.getTransaction() != null && entityManager.getTransaction().isActive()) entityManager.getTransaction().rollback();
            throw e;
        }
    }

}

Use example

    @Test
    public void test_() throws Exception {
        final EntityManager entityManager = getNewEntityManager();

        new JPACommit() {
            @Override
            public void commitAction(EntityManager entityManager) throws Exception {
                /*commitable code here*/
            }
        }.performCommit(entityManager);

        /*non-commitable code here*/

        JPAConfig.close(entityManager);
    }
\$\endgroup\$
  • \$\begingroup\$ Are there any specific aspects of the code you would like to have reviewed, or do you have any specific questions? \$\endgroup\$ – Daniel Jun 3 '18 at 8:44
  • \$\begingroup\$ Nothing specific, i just want to know if i should generalize using this code in all of my JPA code. \$\endgroup\$ – zessi Jun 3 '18 at 9:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.