新建springboot项目时,entityManagerFactory报错的解决
新建springboot项目entitymanagerfactory报错
解决办法
1.查看注解引入是否正确,实体类和jpa的。
2.检查包的引用是否有冲突
spring生成entitymanagerfactory三种方式
1.localentitymanagerfactorybean
只是简单环境中使用。它使用jpa persistenceprovider自动检测机制( according to jpa's java se bootstrapping ),并且大多数情况下,你只能定义一下persistence unit name
例如:
<beans> <bean id="myemf" class="org.springframework.orm.jpa.localentitymanagerfactorybean"> <property name="persistenceunitname" value="mypersistenceunit"/> </bean> </beans>
2.从jndi获取entitymanagerfactory
这个选项是当你应用发布在javaee5的服务器中。你可以参阅自己应用服务器文档,如何发布一个自定义的jpa provider到你的应用服务器中。
例:
<beans> <jee:jndi-lookup id="myemf" jndi-name="persistence/mypersistenceunit"/> </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节点下,如下:
<resource name="" auth="container" type="javax.sql.datasource" username="" password="" driveclassname="oracle.jdbc.driver.oracledriver" url="" maxactive="45" maxidle="25"/>
jndi也可以配置在server.xml,context.xml中
2)jta usertransaction配置
在server.xml文件globalnamingresources节点下配置如下:
<!-- resource configuration for usertransaction use jotm --> <resource name="usertransaction" auth="container" type="javax.transaction.usertransaction" factory="org.objectweb.jotm.usertransactionfactory" jotm.timeout="60"/>
然后在 项目名.xml 文件的context节点下加:
<resourcelink name="usertransaction" global="usertransaction" type="javax.transaction.usertransaction"/>
spring 仅仅做的是是把entitymanagerfactory通过依赖注入到应用的object中。如果要管理事务,则使用jtatransactionmanager。
3.localcontainerentitymanagerfactorybean
这个选项中,spring扮演了容器的角色。完全掌管jpa。
localcontainerentitymanagerfactorybean会根据persistence.xml创造一个persistenceunitinfo实现。
<beans> <bean id="myemf" class="org.springframework.orm.jpa.localcontainerentitymanagerfactorybean"> <property name="datasource" ref="somedatasource"/> <property name="loadtimeweaver"> <bean class="org.springframework.instrument.classloading.instrumentationloadtimeweaver"/> </property> </bean> </beans>
不是所有的jpa provider都需要load-time weaving。hibernate就不需要。呵呵。 <property name="loadtimeweaver">这个就不是必须的了。。
persistence.xml配置:
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="1.0"> <persistence-unit name="myunit" transaction-type="resource_local"> <mapping-file>meta-inf/orm.xml</mapping-file> <exclude-unlisted-classes/> </persistence-unit> </persistence>
如何处理多个persistence units。spring提供了persistenceunitmanager统一管理。
<bean id="pum" class="org.springframework.orm.jpa.persistenceunit.defaultpersistenceunitmanager"> <property name="persistencexmllocations"> <list> <value>org/springframework/orm/jpa/domain/persistence-multi.xml</value> <value>classpath:/my/package/**/custom-persistence.xml</value> <value>classpath*:meta-inf/persistence.xml</value> </list> </property> <property name="datasources"> <map> <entry key="localdatasource" value-ref="local-db"/> <entry key="remotedatasource" value-ref="remote-db"/> </map> </property> <!-- if no datasource is specified, use this one --> <property name="defaultdatasource" ref="remotedatasource"/> </bean> <bean id="emf" class="org.springframework.orm.jpa.localcontainerentitymanagerfactorybean"> <property name="persistenceunitmanager" ref="pum"/> <property name="persistenceunitname" value="mycustomunit"/> </bean>
datasources中的key是persistence.xml中配置的datasource名字,value-ref是spring管理的数据源。
另外:
entitymanagerfactory是线程安全的,但是entitymanager不是。
public class productdaoimpl implements productdao { private entitymanagerfactory emf; @persistenceunit public void setentitymanagerfactory(entitymanagerfactory emf) { this.emf = emf; } public collection loadproductsbycategory(string category) { entitymanager em = this.emf.createentitymanager(); try { query query = em.createquery("from product as p where p.category = ?1"); query.setparameter(1, category); return query.getresultlist(); } finally { if (em != null) { em.close(); } } } }
这样使用有个最大问题就是每次都要创建一个新的entitymanager。那么该怎么办?
你可以通过@persistencecontext获取一个transactional entitymanager("shared entitymanager")。为什么称它为transactional?因为它是一个共享的以及线程安全的当前的transactional entitymanager的一个代理。
public class productdaoimpl implements productdao { @persistencecontext private entitymanager em; public collection loadproductsbycategory(string category) { query query = em.createquery("from product as p where p.category = :category"); query.setparameter("category", category); return query.getresultlist(); } }
结束了。
以上为个人经验,希望能给大家一个参考,也希望大家多多支持。
推荐阅读
-
springboot使用CommandLineRunner解决项目启动时初始化资源的操作
-
Tomcat启动springboot项目war包报错:启动子级时出错的问题
-
在写vue项目时.vue后缀名的页面中写注释双斜杆报错的解决方法
-
springboot集成springCloud中gateway时启动报错的解决
-
解决mac下Android Studio新建项目时自动下载gradle过慢的问题
-
新建springboot项目时,entityManagerFactory报错的解决
-
解决Android studio新建项目时过慢,一直在sync的问题
-
springboot使用CommandLineRunner解决项目启动时初始化资源的操作
-
Tomcat启动springboot项目war包报错:启动子级时出错的问题
-
springboot启动feign项目报错:Service id not legal hostnam的解决