java JPA:从属性创建 EntityManagerFactory
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17988247/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
JPA: create EntityManagerFactory from properties
提问by Sebastian
i am using JPA in a JAR-Project and used the persistence.xml to setup my EntityManager.
我在 JAR 项目中使用 JPA 并使用 persistence.xml 来设置我的 EntityManager。
But since the persistence.xml is inside the JAR after the build it is very complicated for the user to change the settings afterwards. So i'm looking for a solution where i can configure my connection over a propertyfile which is loaded at runtime.
但是由于persistence.xml 在构建后位于JAR 中,因此用户之后更改设置非常复杂。所以我正在寻找一种解决方案,我可以通过在运行时加载的属性文件配置我的连接。
I came across this solution on the web:
我在网上遇到了这个解决方案:
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);
Which is the solution i was looking for but i'm missing one thing here: In my persistence.xml i also declare a schema name over a mapping file:
这是我正在寻找的解决方案,但我在这里遗漏了一件事:在我的 persistence.xml 中,我还在映射文件上声明了一个架构名称:
persistence.xml:
持久性.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:
orm.xml:
<entity-mappings ...>
<persistence-unit-metadata>
<persistence-unit-defaults>
<schema>SCHEMA_NAME</schema>
</persistence-unit-defaults>
</persistence-unit-metadata>
</entity-mappings>
So my question is basically: Is there a property i can use to set the schema at runtime, just like i do with the other properties?
所以我的问题基本上是:是否有一个属性可以用来在运行时设置模式,就像我对其他属性所做的一样?
Or is there even a better solution?
或者有更好的解决方案吗?
Thanks in advance!
提前致谢!
回答by Leon
Switch to java config. Then you can easily inject property values by autowiring Environment
切换到java配置。然后您可以通过自动装配环境轻松注入属性值
This example is extremely basic. But in general if you know how to do the xml config you can map it straight onto the Java config
这个例子非常基础。但总的来说,如果您知道如何进行 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;
}
}
回答by Jonathan Rosenne
META-INF/orm.xml
is the default name, and if the file exists it will be used whether it has been specified in the persistence unit or not. If the mapping file in the persistence.xml
has another name then the default name is not used.
META-INF/orm.xml
是默认名称,如果文件存在,无论是否在持久性单元中指定,都将使用它。如果 中的映射文件persistence.xml
有另一个名称,则不使用默认名称。
To use several incompatible database providers, such as SQL Server and Oracle, it is possible to have several persistence-units in the persistence.xml
, and to select the suitable unit at run time. If the mapping files are named with non-default names, each unit can have its own mapping file or none at all.
要使用多个不兼容的数据库提供程序,例如 SQL Server 和 Oracle,可以在 中具有多个持久性单元persistence.xml
,并在运行时选择合适的单元。如果映射文件以非默认名称命名,则每个单元可以有自己的映射文件或根本没有。
回答by Ronald
Use this class PersistenceUnitProperties for names.
将此类 PersistenceUnitProperties 用于名称。
The see link https://gerardnico.com/jpa/property
见链接 https://gerardnico.com/jpa/property
Propertie example
属性示例
javax.persistence.jdbc.driver=org.sqlite.JDBC
eclipselink.ddl-generation=create-tables
#eclipselink.ddl-generation=none
javax.persistence.jdbc.url=jdbc:sqlite:domo.db
Persistence example (persistence.xml)
持久性示例 (persistence.xml)
<persistence
version="2.0"
xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="PersistenceNameExample" transaction-type="RESOURCE_LOCAL">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<properties></properties>
</persistence-unit>
</persistence>
Instance
实例
Properties props = new Properties();
//props.setProperty("hibernate.hbm2ddl.auto", "none");
props.load(new FileInputStream("prop_example.properties"));
Persistence.createEntityManagerFactory("PersistenceNameExample",props);
Eclipse example dependence for provider
提供程序的 Eclipse 示例依赖项
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>org.eclipse.persistence.jpa</artifactId>
<version>2.7.4</version>
</dependency>
回答by Shmil The Cat
I don't know if its a better solution, but you can annotate your JPA entities w/ the desired schema
我不知道它是否是更好的解决方案,但您可以使用所需的架构注释 JPA 实体
@Entity
@Table(name = "Foo", schema = "Bar")