Java Spring JPA 和persistence.xml
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1132565/
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
Spring JPA and persistence.xml
提问by bmw0128
I'm trying to set up a Spring JPA Hibernate simple example WAR for deployment to Glassfish. I see some examples use a persistence.xml file, and other examples do not. Some examples use a dataSource, and some do not. So far my understanding is that a dataSource is not needed if I have:
我正在尝试设置一个 Spring JPA Hibernate 简单示例 WAR 以部署到 Glassfish。我看到一些示例使用了 persistence.xml 文件,而其他示例则没有。有些示例使用数据源,有些则不使用。到目前为止,我的理解是,如果我有以下情况,则不需要 dataSource:
<persistence-unit name="educationPU"
transaction-type="JTA">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>com.coe.jpa.StudentProfile</class>
<properties>
<property name="hibernate.connection.driver_class"
value="com.mysql.jdbc.Driver" />
<property name="hibernate.connection.url"
value="jdbc:mysql://localhost:3306/COE" />
<property name="hibernate.connection.username" value="root" />
<property name="show_sql" value="true" />
<property name="dialect" value="org.hibernate.dialect.MySQLDialect" />
</properties>
</persistence-unit>
I can deploy fine, but my EntityManager is not getting injected by Spring.
我可以很好地部署,但我的 EntityManager 没有被 Spring 注入。
My applicationContext.xml:
我的 applicationContext.xml:
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
<property name="persistenceUnitName" value="educationPU" />
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
<tx:annotation-driven transaction-manager="transactionManager" />
<bean id="StudentProfileDAO" class="com.coe.jpa.StudentProfileDAO">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<bean id="studentService" class="com.coe.services.StudentService">
</bean>
My class with the EntityManager:
我的 EntityManager 课程:
public class StudentService {
private String saveMessage;
private String showModal;
private String modalHeader;
private StudentProfile studentProfile;
private String lastName;
private String firstName;
@PersistenceContext(unitName="educationPU")
private EntityManager em;
@Transactional
public String save()
{
System.out.println("*** em: " + this.em); //em is null
this.studentProfile= new StudentProfile();
this.saveMessage = "saved";
this.showModal = "true";
this.modalHeader= "Information Saved";
return "successs";
}
My web.xml:
我的 web.xml:
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
Are there any pieces I am missing to have Spring inject "em" in to StudentService?
Spring 将“em”注入到 StudentService 中是否有任何我遗漏的部分?
采纳答案by Michael Wiles
Just to confirm though you probably did...
只是为了确认,尽管您可能已经这样做了...
Did you include the
你包括
<!-- tell spring to use annotation based congfigurations -->
<context:annotation-config />
<!-- tell spring where to find the beans -->
<context:component-scan base-package="zz.yy.abcd" />
bits in your application context.xml?
您的应用程序 context.xml 中的位?
Also I'm not so sure you'd be able to use a jta transaction type with this kind of setup? Wouldn't that require a data source managed connection pool? So try RESOURCE_LOCAL instead.
另外,我不太确定您是否能够在这种设置中使用 jta 事务类型?那不需要数据源托管连接池吗?因此,请尝试使用 RESOURCE_LOCAL。
回答by Rich Kroll
I have a test application set up using JPA/Hibernate & Spring, and my configuration mirrors yours with the exception that I create a datasource and inject it into the EntityManagerFactory, and moved the datasource specific properties out of the persistenceUnit and into the datasource. With these two small changes, my EM gets injected properly.
我有一个使用 JPA/Hibernate & Spring 设置的测试应用程序,除了我创建一个数据源并将其注入到 EntityManagerFactory 中,并将数据源特定属性移出持久性单元并移入数据源之外,我的配置反映了您的配置。通过这两个小变化,我的 EM 被正确注入。
回答by Michael Wiles
I'm confused. You're injecting a PU into the service layer and not the persistence layer? I don't get that.
我糊涂了。您将 PU 注入服务层而不是持久层?我不明白。
I inject the persistence layer into the service layer. The service layer contains business logic and demarcates transaction boundaries. It can include more than one DAO in a transaction.
我将持久层注入到服务层。服务层包含业务逻辑并划分事务边界。它可以在一笔交易中包含多个 DAO。
I don't get the magic in your save() method either. How is the data saved?
我也没有在您的 save() 方法中获得魔力。数据是如何保存的?
In production I configure spring like this:
在生产中,我像这样配置 spring:
<jee:jndi-lookup id="entityManagerFactory" jndi-name="persistence/ThePUname" />
along with the reference in web.xml
以及 web.xml 中的引用
For unit testing I do this:
对于单元测试,我这样做:
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
p:dataSource-ref="dataSource" p:persistence-xml-location="classpath*:META-INF/test-persistence.xml"
p:persistence-unit-name="RealPUName" p:jpaDialect-ref="jpaDialect"
p:jpaVendorAdapter-ref="jpaVendorAdapter" p:loadTimeWeaver-ref="weaver">
</bean>
回答by billy vandory
This may be old, but if anyone has the same problem try changing unitname to just name in the PersistenceContext annotation:
这可能是旧的,但如果有人遇到同样的问题,请尝试在 PersistenceContext 注释中将 unitname 更改为仅 name:
From
从
@PersistenceContext(unitName="educationPU")
to
到
@PersistenceContext(name="educationPU")
回答by Faraz
If anyone wants to use purelyJava configuration instead of xml
configuration of hibernate, use this:
如果有人想使用纯Java 配置而不是xml
hibernate 配置,请使用以下命令:
You can configure Hibernate without using persistence.xml at all in Spring like like this:
您可以像这样在 Spring 中完全不使用 persistence.xml 来配置 Hibernate:
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactoryBean()
{
Map<String, Object> properties = new Hashtable<>();
properties.put("javax.persistence.schema-generation.database.action",
"none");
HibernateJpaVendorAdapter adapter = new HibernateJpaVendorAdapter();
adapter.setDatabasePlatform("org.hibernate.dialect.MySQL5InnoDBDialect"); //you can change this if you have a different DB
LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
factory.setJpaVendorAdapter(adapter);
factory.setDataSource(this.springJpaDataSource());
factory.setPackagesToScan("package name");
factory.setSharedCacheMode(SharedCacheMode.ENABLE_SELECTIVE);
factory.setValidationMode(ValidationMode.NONE);
factory.setJpaPropertyMap(properties);
return factory;
}
Since you are not using persistence.xml, you should create a bean that returns DataSource which you specify in the above method that sets the data source:
由于您没有使用persistence.xml,您应该创建一个bean,它返回您在上述设置数据源的方法中指定的DataSource:
@Bean
public DataSource springJpaDataSource()
{
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setUrl("jdbc:mysql://localhost/SpringJpa");
dataSource.setUsername("tomcatUser");
dataSource.setPassword("password1234");
return dataSource;
}
Then you use @EnableTransactionManagement
annotation over this configuration file. Now when you put that annotation, you have to create one last bean:
然后@EnableTransactionManagement
在这个配置文件上使用注解。现在,当您放置该注释时,您必须创建最后一个 bean:
@Bean
public PlatformTransactionManager jpaTransactionManager()
{
return new JpaTransactionManager(
this.entityManagerFactoryBean().getObject());
}
Now, don't forget to use @Transactional
Annotation over those method that deal with DB.
现在,不要忘记@Transactional
在那些处理 DB 的方法上使用Annotation。
Lastly, don't forget to inject EntityManager
in your repository (This repository class should have @Repository
annotation over it).
最后,不要忘记注入EntityManager
你的存储库(这个存储库类应该有@Repository
注释)。