How can I make a JPA application access different databases?

后端 未结 2 1872
既然无缘
既然无缘 2020-12-04 00:42

I\'m writing a Java SE (desktop) application that has to access different databases all of which will have the same data model (same schema, tables, etc.). I want to reuse

相关标签:
2条回答
  • 2020-12-04 01:17

    You can create EntityManagerFactory at runtime by providing properties.

    Map<String, Object> properties = new HashMap<String, Object>();
    
    properties.put(TRANSACTION_TYPE, PersistenceUnitTransactionType.RESOURCE_LOCAL.name());
    properties.put(JDBC_DRIVER, driver);
    properties.put(JDBC_URL, db_url);
    properties.put(JDBC_USER, "userName");
    properties.put(JDBC_PASSWORD, "password");
    
    EntityManagerFactory factory = Persistence.createEntityManagerFactory("PERSISTENT_UNIT_NAME", properties);
    

    Also you can try having a property file from which properties will be loaded at runtime into map. Therefore it will decouple the database configuration from code.

    Edit : The property keys(JDBC_URL etc) are vendor specific, they should be replaced accordingly.

    0 讨论(0)
  • 2020-12-04 01:20

    Nayan,

    I need to expand on your answer because it's not complete.

    The confusing thing about using properties to dynamically create EntityManagers is that there are three createEntityManagerFactory() methods in JPA and all 3 take a persistenceunit name. I didn't realize that the properties override the persistenceunit name until I checked the JPA 2.0 spec. Section 9.4.3 says that the properties override the values given in the persistence.xml. It also shows what the standard property names are.

    (The JavaDocs don't tell you what can go into the properties and they don't say that the properties override what is in persistence.xml. Another example where JavaDocs suck.)

    Your example uses property names like "JDBC_URL" that aren't in the Java EE 6 API Javadocs. The JPA spec explains that vendor specific property names can be used in addition to the standard properties. The EclipseLink docs show what property names that implementation supports via the non-standard PersistenceUnitProperties class:

    http://www.eclipse.org/eclipselink/api/2.3/index.html

    So in order to have dynamic EntityManagers it is necessary to use vendor specific properties, so dynamic entity managers aren't portable. I guess you can't have everything.

    One case where dynamic EntityManagers would be portable is through the use of the standard javax.persistence.jtaDataSource property. You would have to add the data source to your Java EE container, but that is as dynamic as you can be when running in a container. In Java SE it doesn't look like there are any portable, dynamic options.

    The JavaDocs need to do a much better job of explaining how properties work with the createEntityManagerFactory() methods.

    0 讨论(0)
提交回复
热议问题