2013-08-01 104 views
3

我在JAR项目中使用JPA并使用persistence.xml来设置我的EntityManager。JPA:从属性创建EntityManagerFactory

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

我在网络上对这个解决方案来:

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:

<persistence version="2.0" ...> 
    <persistence-unit name="jpa" transaction-type="RESOURCE_LOCAL"> 
    <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider> 
    <class>...</class> 
    <exclude-unlisted-classes>true</exclude-unlisted-classes> 
    <properties> 
     <property name="javax.persistence.jdbc.url" value="..."/> 
     <property name="javax.persistence.jdbc.password" value="..."/> 
     <property name="javax.persistence.jdbc.driver" value="oracle.jdbc.OracleDriver"/> 
     <property name="javax.persistence.jdbc.user" value="..."/> 
    </properties> 
    <mapping-file>META-INF/orm.xml</mapping-file> 
    </persistence-unit> 
</persistence> 

orm.xml中:

<entity-mappings ...> 
<persistence-unit-metadata> 
    <persistence-unit-defaults> 
    <schema>SCHEMA_NAME</schema> 
    </persistence-unit-defaults> 
</persistence-unit-metadata> 
</entity-mappings> 

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

或者还有更好的解决方案吗?

在此先感谢!

+0

所以你是在调暗黑暗面,是吗? ;) –

回答

0

我不知道,如果它是一个更好的解决方案,但你可以标注您的JPA实体瓦特/所需要的模式

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

难道它不会硬编码模式,因此用户根本无法更改它吗? – bigbasti

+0

它的确如此。避免这种硬编码。 – javadev

2

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

此示例非常基本。但总的来说,如果你知道如何做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; 
    } 

} 
+0

您能否提供一个示例或更多信息的链接? – bigbasti

+0

我在答案中增加了一个非常基本的例子。希望它有助于:) – Leon

+0

感谢这个例子,它现在更清楚你的想法。但是我们不在这个项目中使用Spring,并且我看不到您在哪里配置模式? (我想念什么?) – bigbasti

0

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

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

相关问题