3

有没有办法在运行时重新创建已经在 Web 应用程序中使用的 EntityManagerFactory?我想要的是告诉 entityManagerFactory 忘记最后一个数据库连接并在网络用户选择其他数据库(mysql 模式)时在运行时连接到新模式。或者不要忘记已经使用过的,但也要使用一个新的连接到另一个尚未使用的 mysql 模式。这些模式具有完全相同的结构(表等),但出于安全和其他原因,针对不同的用户。这可能吗?

我正在使用 Vaadin 框架、Eclipselink 2.4.1、Mysql 5.5 和 Tomcat 7。我发现与我的情况相关的内容以及我已经尝试过的内容如下。我正在使用 Eclipselink 复合持久性单元,第二个成员始终相同,当用户在网页上选择第 42 个候选者后,我想将第一个模式更改为例如“42_candidate”,而其他模式已经连接,如“41_candidate” ”。

private static EntityManager createEntityManagerForCandidateSchema(String candidateSchemaName) throws javax.persistence.PersistenceException {        

    System.out.println("createEntityManagerForCandidateSchema called");
    // set persistence unit properties
    HashMap<String,String> candidatePuProps = new HashMap<String,String>();
    candidatePuProps.put("javax.persistence.jdbc.url", "jdbc:mysql://localhost:3306/"+candidateSchemaName+"?useUnicode=true&amp;characterEncoding=UTF-8");

    HashMap<String,Map> compositePuProps = new HashMap<String,Map>();
    compositePuProps.put("election_model_candidate", candidatePuProps);

    Map puProps = new HashMap();
    puProps.put("eclipselink.logging.level", "FINEST");
    puProps.put("eclipselink.composite-unit.properties", compositePuProps);
    // puProps.put(PersistenceUnitProperties.SESSION_CUSTOMIZER, "com.beharbe.ui.ElectionSessionCustomizer");       

    boolean candidateDatabaseSchemaNotFound = false;
    try {
        EntityManagerFactory emf = javax.persistence.Persistence.createEntityManagerFactory("election_composite_pu",puProps);
        emf.close(); // to forget latest things
        emf = javax.persistence.Persistence.createEntityManagerFactory("election_composite_pu",puProps);            
        EntityManager em = emf.createEntityManager(compositePuProps);

...
public void selectionChanged(int newCandidatePersonId) {
    entityManager = Util.createEntityManagerForCandidateSchema(newCandidatePersonId);
    ...

(Eclipselink 复合 PU)wiki.eclipse.org/EclipseLink/UserGuide/sandbox/gelernter/Composite_Persistence_Units#Persistence_Unit_Properties

(动态持久性)dev.eclipse.org/svnroot/rt/org.eclipse.persistence/branches/2.1/trunk/examples/jpa.employee/eclipselink.example.jpa.employee.dynamic/src/example/Main.java

(EclipseLink - 如何在运行时配置数据库模式名称)www.rqna.net/qna/kxvmwy-jpa-eclipselink-how-to-configure-database-schema-name-at-runtime.html

(Eclipselink 与 Tomcat 教程)wiki.eclipse.org/EclipseLink/Examples/JPA/Tomcat_Web_Tutorial#Session_Customizer

(将 JPAContainer 与 Hibernate(Vaadin)一起使用)vaadin.com/book/-/page/jpacontainer.hibernate.html

(如何让 JPA 应用程序访问不同的数据库?)stackoverflow.com/questions/9315593/how-can-i-make-a-jpa-application-access-different-databases

(动态连接两个或多个数据库)stackoverflow.com/questions/9732750/connect-two-or-more-databases-dynamically?lq=1

(JPA - 使用多个数据源来定义访问控制) www.rqna.net/qna/kqqihk-jpa-using-multiple-data-sources-to-define-access-control.html

JPA2 运行时数据库连接

JPA - EclipseLink - 如何在运行时配置数据库模式名称 (Eclipselink SessionCustomizer)

也许我应该用 EclipseLink SessionCustomizer 以某种方式做到这一点?(见最新链接)

提前感谢您的帮助


同时我发现了一些东西,这可能是我必须使用的:

http://wiki.eclipse.org/EclipseLink/Examples/JPA/Auditing

我正在尝试这种方式,但它仍然连接到第一次调用 EMF 时首先连接的模式:

....
candidatePuProps.put(PersistenceUnitProperties.JDBC_URL, "jdbc:mysql://localhost:3306/"+candidateSchemaName+"?useUnicode=true&amp;characterEncoding=UTF-8");
    candidatePuProps.put(PersistenceUnitProperties.EXCLUSIVE_CONNECTION_MODE, "Always");
    candidatePuProps.put(PersistenceUnitProperties.EXCLUSIVE_CONNECTION_IS_LAZY, "false");
...
4

1 回答 1

2

如果你想访问两个不同的数据库/模式,你可以调用 createEntityManagerFactory() 传递一个新连接的属性映射。

要在代码中使用 EclipseLink 设置模式,您可以在定制器中设置 tableQualifier。要获得新的 EntityManagerFactory,您可以传递“eclipselink.session-name”属性。

您的代码看起来正确。您使用的是什么版本的 EclipseLink?

删除复合持久性单元,我认为您似乎只想连接到不同的数据库。复合持久性单元适用于跨数据库的关系。

于 2013-07-15T14:18:37.897 回答