欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

新建springboot项目时,entityManagerFactory报错的解决

程序员文章站 2022-03-09 22:11:56
目录新建springboot项目entitymanagerfactory报错解决办法spring生成entitymanagerfactory三种方式1.localentitymanagerfactor...

新建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();
}
}

结束了。

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