我瞭解一個EntityManagerFactory(EMF1)的實例有它自己的EntityManager和會話。如果我使用與EMF1相同的憑據創建EntityManagerFactory(EMF2)的另一個實例,那麼它應該有它自己的連接池和會話。但它不是因爲這個原因會話定製也被稱爲一次,如果一切是相同JPA Eclipselink - 多個EntityManagerFactory實例返回相同的會話
package test.jpa.factory;
import java.sql.Connection;
import java.util.HashMap;
import java.util.Map;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import org.eclipse.persistence.config.PersistenceUnitProperties;
import org.eclipse.persistence.config.SessionCustomizer;
import org.eclipse.persistence.sessions.Session;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class TestEntityManagerFactory {
private static Logger logger = LoggerFactory.getLogger(TestEntityManagerFactory.class);
public static final String JDBC_URL = "javax.persistence.jdbc.url";
public static final String JDBC_USER = "javax.persistence.jdbc.user";
public static final String JDBC_PASSWD = "javax.persistence.jdbc.password";
public static final String WAREHOUSE_PERSISTENCE_UNIT = "etl-dw";
public static void main(String[] args) throws Exception {
String host = "xxxxcccc";
String port = "1521";
String user = "skipvpd";
String pwd = "abcd";
String service = "test_svc1";
System.out.println("Same user multiple EMF");
printSession(host, port, user, pwd, service);
printSession(host, port, user, pwd, service);
System.out.println("Different user multiple EMF");
user = "1032";
pwd = "abcd";
printSession(host, port, user, pwd, service);
user = "1033";
printSession(host, port, user, pwd, service);
}
private static void printSession(String host, String port, String user, String pwd, String serviceName)
throws Exception {
EntityManagerFactory emf = getEntityManagerFactory(host, port, user, pwd, serviceName);
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
Session session = (Session) em.unwrap(org.eclipse.persistence.sessions.Session.class);
Connection connection = (Connection) em.unwrap(java.sql.Connection.class);
System.out.println("con_hashcode=" + connection.hashCode() + ",session_hashcode=" + session.hashCode()
+ ",em_hashcode=" + em.hashCode() + ",emf_hashcode=" + emf.hashCode());
em.getTransaction().commit();
em.close();
}
private static EntityManagerFactory getEntityManagerFactory(String host, String port, String user, String pwd,
String serviceName) {
Map<String, String> jpaConfig = new HashMap<String, String>();
try {
String jdbcURL = "jdbc:oracle:thin:@" + host + ":" + port + "/" + serviceName;
jpaConfig.put("javax.persistence.jdbc.url", jdbcURL);
jpaConfig.put(JDBC_USER, user);
jpaConfig.put(JDBC_PASSWD, pwd);
jpaConfig.put(PersistenceUnitProperties.SESSION_CUSTOMIZER,
TestEntityManagerFactory.ETLSessionCustomizer.class.getName());
} catch (Throwable t) {
logger.error("ERROR=\"Error occured in getJPAConfiguration\" EXCEPTION={}", t);
}
return Persistence.createEntityManagerFactory(WAREHOUSE_PERSISTENCE_UNIT, jpaConfig);
}
public static class ETLSessionCustomizer implements SessionCustomizer {
public void customize(Session session) {
System.out.println("customize is called for session_hash_code=" + session.hashCode());
}
}
}
同一用戶的多個EMF
定製的要求session_hash_code = 1193471756
con_hashcode = 675100200 ,session_hashcode = 1193471756,em_hashcode = 627727856,emf_hashcode = 179294202
con_hashcode = 675100200,session_hashcode = 1193471756,em_hashcode = 166919726,emf_hashcode = 1305777754
不同用戶的多個EMF
定製被調用session_hash_code = 1240796303 con_hashcode = 738369543,session_hashcode = 1240796303,em_hashcode = 1017841629,emf_hashcode = 1760715967
定製被調用session_hash_code = 1161255903
con_hashcode = 92699135,session_hashcode = 1161255903,em_hashcode = 1535875885,emf_hashcode = 2054926467
默認情況下,會議將在同一線程被重用。如果您不想重複使用同一個會話,則必須明確向工廠詢問。 –
感謝您的回覆@GuillaumeF。我認爲這不是真的,如果是這樣,那麼它是一個更大的問題。您能否指出我對這個假設的文檔或源代碼。 在我的測試代碼中,如果用戶不同,會話不會共享。問題在兩個不同的實體經理工廠之間。 –
結果是邏輯,它非常簡單。使用同一個用戶獲得2個會話,您必須關閉連接(會話),或者始終直到會話結束/結束時纔會獲得相同的會話。 2個用戶有2個會話。 – bilelovitch