经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » Java相关 » Spring » 查看文章
新建springboot项目时,entityManagerFactory报错的解决
来源:jb51  时间:2022/1/17 16:40:49  对本文有异议

新建springboot项目entityManagerFactory报错

在这里插入图片描述

解决办法

1.查看注解引入是否正确,实体类和jpa的。

2.检查包的引用是否有冲突

spring生成EntityManagerFactory三种方式

1.LocalEntityManagerFactoryBean

只是简单环境中使用。它使用JPA PersistenceProvider自动检测机制( according to JPA's Java SE  bootstrapping ),并且大多数情况下,你只能定义一下persistence unit name

例如:

  1. <beans>
  2. <bean id="myEmf" class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
  3. <property name="persistenceUnitName" value="myPersistenceUnit"/>
  4. </bean>
  5. </beans>

2.从JNDI获取EntityManagerFactory

这个选项是当你应用发布在javaee5的服务器中。你可以参阅自己应用服务器文档,如何发布一个自定义的JPA provider到你的应用服务器中。

例:

  1. <beans>
  2. <jee:jndi-lookup id="myEmf" jndi-name="persistence/myPersistenceUnit"/>
  3. </beans>

当javaee服务器启动时,会自动检测persistence units。实际上,是检测应用包中的META-INF/persistence.xml 文件和web.xml中的persistence-unit-ref,以及定义的environment naming。我理解就是JNDI的name。

一般应用情景是:

在META-INF/persistence.xml中 使用<jta-data-source>java:/ MySqlDS</jta-data-source> 获取容器发布的Datesource。

transactions是使用的javaee容器支持的JTA系统,例如tomcat中,可以这样

如果你的项目准备部署在tomcat上,要支持jta,则需把相关的包放在tomcat/lib包下

1)jndi配置,可以把jndi的配置放置在  tomcat/conf/Catalina/域名(如localhost)/项目名.xml

文件的Context节点下,如下:

  1. ? ?<Resource name="" auth="Container" type="javax.sql.DataSource"?
  2. ? ? ? ?username=""?
  3. ? ? ? ?password=""
  4. ? ? ? ?driveClassName="oracle.jdbc.driver.OracleDriver"?
  5. ? ? ? ?url="" maxActive="45" maxIdle="25"/>

 jndi也可以配置在server.xml,context.xml中 

2)jta UserTransaction配置 

在server.xml文件GlobalNamingResources节点下配置如下: 

  1. ? ? <!-- Resource configuration for UserTransaction
  2. ? ? ? ? ?use JOTM -->
  3. ? ? <Resource name="UserTransaction" auth="Container"
  4. ? ? ? ? type="javax.transaction.UserTransaction"
  5. ? ? ? ? factory="org.objectweb.jotm.UserTransactionFactory"
  6. ? ? ? ? jotm.timeout="60"/>

然后在 项目名.xml 文件的context节点下加:

  1. ? ?<ResourceLink name="UserTransaction"
  2. ? ? ? ? ? ? global="UserTransaction"
  3. ? ? ? ? ? ? type="javax.transaction.UserTransaction"/>?
  4. ?

 SPRING 仅仅做的是是把EntityManagerFactory通过依赖注入到应用的object中。如果要管理事务,则使用JtaTransactionManager。

3.LocalContainerEntityManagerFactoryBean

这个选项中,spring扮演了容器的角色。完全掌管JPA。

LocalContainerEntityManagerFactoryBean会根据persistence.xml创造一个PersistenceUnitInfo实现。

  1. <beans>
  2. <bean id="myEmf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
  3. <property name="dataSource" ref="someDataSource"/>
  4. <property name="loadTimeWeaver">
  5. <bean class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver"/>
  6. </property>
  7. </bean>
  8. </beans>

不是所有的JPA provider都需要load-time weaving。hibernate就不需要。呵呵。 <property name="loadTimeWeaver">这个就不是必须的了。。

Persistence.xml配置:

  1. <persistence xmlns="http://java.sun.com/xml/ns/persistence" version="1.0">
  2. <persistence-unit name="myUnit" transaction-type="RESOURCE_LOCAL">
  3. <mapping-file>META-INF/orm.xml</mapping-file>
  4. <exclude-unlisted-classes/>
  5. </persistence-unit>
  6. </persistence>

如何处理多个persistence units。spring提供了PersistenceUnitManager统一管理。

  1. <bean id="pum" class="org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager">
  2. <property name="persistenceXmlLocations">
  3. <list>
  4. <value>org/springframework/orm/jpa/domain/persistence-multi.xml</value>
  5. <value>classpath:/my/package/**/custom-persistence.xml</value>
  6. <value>classpath*:META-INF/persistence.xml</value>
  7. </list>
  8. </property>
  9. <property name="dataSources">
  10. <map>
  11. <entry key="localDataSource" value-ref="local-db"/>
  12. <entry key="remoteDataSource" value-ref="remote-db"/>
  13. </map>
  14. </property>
  15. <!-- if no datasource is specified, use this one -->
  16. <property name="defaultDataSource" ref="remoteDataSource"/>
  17. </bean>
  18. <bean id="emf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
  19. <property name="persistenceUnitManager" ref="pum"/>
  20. <property name="persistenceUnitName" value="myCustomUnit"/>
  21. </bean>

dataSources中的key是persistence.xml中配置的datasource名字,value-ref是spring管理的数据源。

另外:

EntityManagerFactory是线程安全的,但是EntityManager不是。

  1. public class ProductDaoImpl implements ProductDao {
  2. private EntityManagerFactory emf;
  3. @PersistenceUnit
  4. public void setEntityManagerFactory(EntityManagerFactory emf) {
  5. this.emf = emf;
  6. }
  7. public Collection loadProductsByCategory(String category) {
  8. EntityManager em = this.emf.createEntityManager();
  9. try {
  10. Query query = em.createQuery("from Product as p where p.category = ?1");
  11. query.setParameter(1, category);
  12. return query.getResultList();
  13. }
  14. finally {
  15. if (em != null) {
  16. em.close();
  17. }
  18. }
  19. }
  20. }

这样使用有个最大问题就是每次都要创建一个新的entityManager。那么该怎么办?

你可以通过@PersistenceContext获取一个transactional EntityManager("shared EntityManager")。为什么称它为transactional?因为它是一个共享的以及线程安全的当前的transactional EntityManager的一个代理。

  1. public class ProductDaoImpl implements ProductDao {
  2. @PersistenceContext
  3. private EntityManager em;
  4. public Collection loadProductsByCategory(String category) {
  5. Query query = em.createQuery("from Product as p where p.category = :category");
  6. query.setParameter("category", category);
  7. return query.getResultList();
  8. }
  9. }

结束了。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持w3xue。

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号