Try to separate transaction control and logic in J2SE environment Does not use any J2EE application server container or Spring features
The execution environment is as follows
I made a logic to "register xml file in postgresql" in Jouhousyori.java. I think the textbook example is as follows
Jouhousyori.java
public void execute() throws Exception{
EntityManagerFactory factory = Persistence.createEntityManagerFactory("myUnitInPersistenceXML");
EntityManager em = factory.createEntityManager();
EntityTransaction entityTransaction = em.getTransaction();
JouhousyoriEntity entity = new JouhousyoriEntity();
String xml = new String(Files.readAllBytes(Paths.get(getPath())));
entity .setText(xml);
em.persist(entity);
entityTransaction.commit();
}
First, the process of getting an EM is too annoying. Even if it is a write-down program, it is troublesome to write the EM acquisition process every time the number of classes and methods that process the DB increases.
Next, if you put control of transaction start, end, and rollback in the logic class, the readability of the logic class seems to be significantly reduced. I think people have different tastes here, but I want to separate logic and transaction control.
If you want to process common logic in Java, you can use a function called Interceptor. About Interceptor https://blogs.yahoo.co.jp/dk521123/33226901.html There is a concrete Java implementation example in Also, for the class diagram and brief explanation of the above site https://afternoon-garden-70542.herokuapp.com/diarydetails/show/details/?id=76 I put it on, so please also
The following processing is performed by TransactionInterceptor
--Starting and ending a transaction by EM --Set an instance of EM in the Jouhousyori class
By writing the transaction and EM operation processing on the TransactionInterceptor side, the Jouhousyori class can concentrate on the processing that it originally wants to do, "read the xml file and perform persistence processing on the em". By the way, it seems that something like DI has been realized.
Jouhousyori.java
package logic;
import java.nio.file.Files;
import java.nio.file.Paths;
import javax.persistence.EntityManager;
import entity.JouhousyoriEntity;
public class Jouhousyori implements Logic{
private EntityManager em;
private String path;
@Override
public void execute() throws Exception{
JouhousyoriEntity entity = new JouhousyoriEntity();
String xml = new String(Files.readAllBytes(Paths.get(getPath())));
entity .setText(xml);
em.persist(entity);
}
public EntityManager getEm() {
return em;
}
public void setEm(EntityManager em) {
this.em = em;
}
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
}
TransactionIntercepter.java
package proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;
public class TransactionIntercepter implements InvocationHandler {
Object target;
private TransactionIntercepter(Object target) {
this.target = target;
}
@SuppressWarnings({ "rawtypes", "unchecked" })
public static <T> T getProxyInstance(T instance) {
Class<? extends Object> clazz = instance.getClass();
//List of interfaces implemented by the target class
Class[] classes = clazz.getInterfaces();
TransactionIntercepter intercepter = new TransactionIntercepter(instance);
T proxyInstance = (T) Proxy.newProxyInstance(clazz.getClassLoader(), classes, intercepter);
return proxyInstance;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
EntityManagerFactory factory = Persistence.createEntityManagerFactory("myUnitInPersistenceXML");
EntityManager em = factory.createEntityManager();
EntityTransaction entityTransaction = em.getTransaction();
entityTransaction.begin();
Object result=null;
try {
//Set an instance of EntityManater
target.getClass().getDeclaredMethod("setEm",EntityManager.class).invoke(target,em);
//Call the actual code
result = method.invoke(this.target, args);
}catch(Exception e) {
e.printStackTrace();
entityTransaction.rollback();;
throw e;
}
entityTransaction.commit();
return result;
}
}
LogicTest.java
import org.junit.jupiter.api.Test;
import logic.Jouhousyori;
import logic.Logic;
import proxy.TransactionIntercepter;
class LogicTest {
@Test
void testParsePDF() throws Exception{
Jouhousyori target = new Jouhousyori();
target.setPath("C:\\java\\workspace\\jyouhousyori2\\pdf\\xml\\2018h30h_sc_am2_qs.pdf.xml");
Logic targetClass = TransactionIntercepter.getProxyInstance(target);
targetClass.execute();
}
}
Recommended Posts