JPA:从属性创建EntityManagerFactory

我在JAR-Project中使用JPA并使用persistence.xml来设置我的EntityManager。

但是由于persistence.xml在构建之后位于JAR内部,因此用户之后更改设置非常复杂。 所以我正在寻找一个解决方案,我可以通过在运行时加载的属性文件配置我的连接。

我在网上遇到了这个解决方案:

Map properties = new HashMap(); // Configure the internal EclipseLink connection pool properties.put(JDBC_DRIVER, "oracle.jdbc.OracleDriver"); properties.put(JDBC_URL, "jdbc:oracle:thin:@localhost:1521:ORCL"); properties.put(JDBC_USER, "user-name"); properties.put(JDBC_PASSWORD, "password"); Persistence.createEntityManagerFactory("unit-name", properties); 

这是我正在寻找的解决方案,但我在这里缺少一件事:在我的persistence.xml中,我还在映射文件上声明了一个模式名称:

persistence.xml中:

   org.eclipse.persistence.jpa.PersistenceProvider ... true       META-INF/orm.xml   

orm.xml中:

    SCHEMA_NAME    

所以我的问题基本上是:我是否可以使用在运行时设置架构的属性,就像我对其他属性一样?

或者甚至有更好的解决方案?

提前致谢!

切换到java配置。 然后,您可以通过自动assembly环境轻松注入属性值

这个例子非常基本。 但一般来说,如果您知道如何执行xml配置,则可以将其直接映射到Java配置

contextConfig.java

 /** * Spring Context configuration. */ @ComponentScan(basePackages = { "com.example" }) @PropertySource({ "classpath:common.properties" }) @Configuration @Import(JpaConfig.class) public class ContextConfig extends WebMvcConfigurerAdapter { /** * This bean is needed because Spring when you use xml config to load property files the bean is automatically * created... when you use @PropertySource then not so much * @return new bean */ @Bean public PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() { return new PropertySourcesPlaceholderConfigurer(); } } 

jpaConfig.java

 @Configuration @EnableJpaRepositories("com.example.repository") public class JpaConfig { @Autowired private Environment env; /** * Create the fooDataSource Bean. * @return fooDataSource Bean */ @Bean public BasicDataSource fooDataSource() { BasicDataSource basicDataSource = new BasicDataSource(); basicDataSource.setDriverClassName(env.getProperty("cfg_foo.driver.name")); basicDataSource.setUrl(env.getProperty("cfg_foo.jdbc.url")); basicDataSource.setUsername(env.getProperty("cfg_foo.username")); basicDataSource.setPassword(env.getProperty("cfg_foo.password")); basicDataSource.setPoolPreparedStatements(Boolean.valueOf(env.getProperty("cfg_foo.poolPreparedStatements"))); basicDataSource.setInitialSize(Integer.valueOf(env.getProperty("cfg_foo.poolInitialSize"))); basicDataSource.setMaxActive(Integer.valueOf(env.getProperty("cfg_foo.poolMaxActive"))); basicDataSource.setMaxIdle(Integer.valueOf(env.getProperty("cfg_foo.poolMaxIdle"))); basicDataSource.setValidationQuery("SELECT '1'"); return basicDataSource; } /** * Create the hibernateJpaVendorAdapter Bean. * @return hibernateJpaVendorAdapter Bean */ @Bean public HibernateJpaVendorAdapter hibernateJpaVendorAdapter() { HibernateJpaVendorAdapter adapter = new HibernateJpaVendorAdapter(); adapter.setDatabasePlatform("org.hibernate.dialect.MySQLDialect"); adapter.setShowSql(Boolean.valueOf(env.getProperty("show.sql"))); adapter.setGenerateDdl(Boolean.valueOf(env.getProperty("format.sql"))); return adapter; } /** * Create the entityManagerFactory Bean. * @return entityManagerFactory Bean */ @Bean public LocalContainerEntityManagerFactoryBean entityManagerFactory() { LocalContainerEntityManagerFactoryBean entityManagerFactory = new LocalContainerEntityManagerFactoryBean(); entityManagerFactory.setPersistenceUnitName("foo"); entityManagerFactory.setDataSource(fooDataSource()); entityManagerFactory.setJpaVendorAdapter(hibernateJpaVendorAdapter()); entityManagerFactory.setPackagesToScan("com.example.repository"); return entityManagerFactory; } } 

我不知道它是否是更好的解决方案,但您可以使用所需的架构来注释JPA实体

 @Entity @Table(name = "Foo", schema = "Bar") 

META-INF/orm.xml是默认名称,如果文件存在,则无论是否在持久性单元中指定,都将使用它。 如果persistence.xml的映射文件具有其他名称,则不使用默认名称。

要使用多个不兼容的数据库提供程序(如SQL Server和Oracle),可以在persistence.xml中包含多个持久性单元,并在运行时选择合适的单元。 如果映射文件以非默认名称命名,则每个单元可以拥有自己的映射文件,或者根本没有。