2013-08-01 165 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中有幾個持久性單元,並在運行時選擇合適的單元。如果映射文件以非默認名稱命名,則每個單元都可以擁有自己的映射文件,或者根本沒有映射文件。

相關問題