Java Spring-boot:不能使用持久化
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/20848485/
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-boot: cannot use persistence
提问by Lurk21
I am days into this, and - although I am learning a lot - starting to despair.
我已经有几天了,而且——尽管我学到了很多东西——开始感到绝望。
I have tried all the suggestions on this excellent question:
我已经尝试了关于这个优秀问题的所有建议:
No Persistence provider for EntityManager named
I had this working at one point using the ubiquitous HibernateUtil class, but was told to move to a plain JPA style here:
我曾经使用无处不在的 HibernateUtil 类进行了这项工作,但被告知要在此处改用普通的 JPA 样式:
Spring RESTful controller method improvement suggestions
Unfortunately, I could not get the bean injection to work properly in spring-boot. Here is my attempt:
不幸的是,我无法让 bean 注入在 spring-boot 中正常工作。这是我的尝试:
Spring JPA (Hibernate) No qualifying bean of type: javax.persistence.EntityManagerFactory
Spring JPA (Hibernate) 没有符合条件的 bean 类型:javax.persistence.EntityManagerFactory
After much work down that path I ended up with a null entity manager. I found this and began to think it could not work:
在沿着这条路做了很多工作之后,我最终得到了一个空实体管理器。我发现了这个并开始认为它行不通:
Using JPA2 in Tomcat 6: @PersitenceContext doesn't work, EntityManager is null
在 Tomcat 6 中使用 JPA2:@PersitenceContext 不起作用,EntityManager 为 null
It seems to me like the EntityManagerFactory absolutely should be a bean in whatever context spring-boot creates, but ... whatever. I would think that at least this would work:
在我看来 EntityManagerFactory 绝对应该是 spring-boot 创建的任何上下文中的 bean,但是......无论如何。我认为至少这会起作用:
Application launch:
应用启动:
@Configuration
@ComponentScan
@EnableAutoConfiguration
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
Controller:
控制器:
@Controller
public class GetController {
private static final String PERSISTENCE_UNIT_NAME = "cpJpaPu";
@RequestMapping(value = "/user", method = RequestMethod.GET)
public @ResponseBody User getUser(@RequestParam(value="id", required=true) int id) {
User user = null;
EntityManagerFactory emf = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME);
EntityManager em = emf.createEntityManager();
UserDAO userDao = new UserDAO();
userDao.setEntityManager(em);
user = userDao.load(id);
return user;
}
}
DAO:
道:
public class UserDAO {
public EntityManager entityManager;
public void setEntityManager(EntityManager entityManager) {
this.entityManager = entityManager;
}
public EntityManager getEntityManager() {
return entityManager;
}
public void insert(User user) {
entityManager.persist(user);
}
public User load(int id) {
return entityManager.find(User.class, id);
}
}
/src/main/resources/persistence.xml:
/src/main/resources/persistence.xml:
<persistence 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_1_0.xsd" version="1.0">
<persistence-unit name="cpJpaPu" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>com.mydomain.User</class>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect"/>
<property name="hibernate.connection.driver_class" value="org.postgresql.Driver"/>
<property name="hibernate.show_sql" value="false"/>
<property name="hibernate.connection.username" value="user"/>
<property name="hibernate.connection.password" value=""/>
<property name="hibernate.connection.url" value="jdbc:postgresql://localhost:5432/mydb"/>
</properties>
</persistence-unit>
</persistence>
And it doesn't work:
它不起作用:
javax.persistence.PersistenceException: No Persistence provider for EntityManager named cpJpaPu
javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:61)
javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:39)
com.mydomain.GetController.getUser(GetController.java:25)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
java.lang.reflect.Method.invoke(Unknown Source)
org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:214)
org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132)
org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:748)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:689)
org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:83)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:947)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:878)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:946)
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:837)
javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:822)
javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:108)
--- Added Info ---
--- 添加信息 ---
POM:
聚甲醛:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.mygroup</groupId>
<artifactId>myartifact</artifactId>
<version>0.1.0</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>0.5.0.M6</version>
</parent>
<dependencies>
<!-- Spring framework -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Hibernate -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>4.3.0.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<!-- Must override version or face stack traces -->
<version>4.3.0.Final</version>
</dependency>
<!-- Spring ORM, works with Hibernate -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
</dependency>
<!-- Spring implementation of Hymanson for RESTful JSON -->
<dependency>
<groupId>com.fasterxml.Hymanson.core</groupId>
<artifactId>Hymanson-databind</artifactId>
</dependency>
<!-- JDBC -->
<dependency>
<groupId>postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>9.1-901.jdbc4</version>
</dependency>
<!-- Logging -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</dependency>
<!-- Prevent logging conflicts -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
<scope>compile</scope>
<exclusions>
<exclusion>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<properties>
<start-class>com.cloudfordev.controlpanel.Application</start-class>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>spring-snapshots</id>
<url>http://repo.spring.io/libs-snapshot</url>
<snapshots><enabled>true</enabled></snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>spring-snapshots</id>
<url>http://repo.spring.io/libs-snapshot</url>
<snapshots><enabled>true</enabled></snapshots>
</pluginRepository>
</pluginRepositories>
</project>
采纳答案by Lurk21
This question was answered with a much better architecture over here:
这个问题在这里得到了更好的架构的回答:
Spring JPA (Hibernate) No qualifying bean of type: javax.persistence.EntityManagerFactory
Spring JPA (Hibernate) 没有符合条件的 bean 类型:javax.persistence.EntityManagerFactory
回答by Dave Syer
There are some features of JPA that only work in XML configuration unfortunately, but I can't see anything like that in yours. I don't think persistence.xml
is loaded by default, so probably that's the issue. So why don't you go with the flow and use Java and application.properties to configure the entity manager? The JPA sample from Spring Boothas everything you need to get started. It uses Spring Data JPA, whereas your code is only using the JPA APIs, but you can easily strip back to that level by just removing the Spring Data dependencies in the sample.
不幸的是,JPA 的某些功能仅适用于 XML 配置,但我在您的功能中看不到类似的功能。我认为persistence.xml
默认情况下不会加载,所以可能这就是问题所在。那么为什么不顺其自然,使用 Java 和 application.properties 来配置实体管理器呢?Spring Boot 中的JPA 示例包含您开始使用所需的一切。它使用 Spring Data JPA,而您的代码仅使用 JPA API,但您只需删除示例中的 Spring Data 依赖项,即可轻松恢复到该级别。
Recent Spring Boot snapshots have a feature that lets you create your own LocalEntityManagerFactoryBean
so that you can add a custom XML configuration, but up to M7 you would have to do all the JPA configuration manually once you needed a custom EntityManager
.
最近的 Spring Boot 快照具有一项功能,可让您创建自己的LocalEntityManagerFactoryBean
配置,以便您可以添加自定义 XML 配置,但在 M7 之前,一旦您需要自定义EntityManager
.
N.B. you aren't really using dependency injection very effectively in your controller - why wouldn't you just inject the UserDao
?
注意,您并没有真正在控制器中非常有效地使用依赖注入 - 为什么不直接注入UserDao
?
回答by xi.lin
The persistence.xml should be in the META-INF directory
persistence.xml 应该在 META-INF 目录中
/src/main/resources/META-INF/persistence.xml
/src/main/resources/META-INF/persistence.xml
回答by vedat
spring boot does not read persistence.xml file by default, see the document here
spring boot默认不读取persistence.xml文件,看这里的文档
https://docs.spring.io/spring-boot/docs/current/reference/html/howto-data-access.html
https://docs.spring.io/spring-boot/docs/current/reference/html/howto-data-access.html
so if you want to keep using persistence.xml file just add below code into your AppConfig class
因此,如果您想继续使用 persistence.xml 文件,只需将以下代码添加到您的 AppConfig 类中
@Bean
public LocalEntityManagerFactoryBean entityManagerFactory(){
LocalEntityManagerFactoryBean factoryBean = new LocalEntityManagerFactoryBean();
factoryBean.setPersistenceUnitName("cpJpaPu");
return factoryBean;
}
回答by capcom923
I resolved this issue after deleted all hibernate-core folders under below directory: .m2\repository\org\hibernate\hibernate-core
删除以下目录下的所有 hibernate-core 文件夹后,我解决了这个问题:.m2\repository\org\hibernate\hibernate-core
and rebuilt my projects.
并重建了我的项目。
Now, it works fine under Spring Boot 2.0.4.RELEASE. And I'm sure that it loads the main/resources/META-INF/persistence.xml without injecting LocalEntityManagerFactoryBean Bean.
现在,它在 Spring Boot 2.0.4.RELEASE 下运行良好。而且我确定它加载 main/resources/META-INF/persistence.xml 而不注入 LocalEntityManagerFactoryBean Bean。
Before I delete them, there are 4 versions of hibernate-core in the above folder. They are "4.3.6"/"5.0.12"/"5.2.17"/"5.3.4".
在我删除它们之前,上面的文件夹中有 4 个版本的 hibernate-core。它们是“4.3.6”/“5.0.12”/“5.2.17”/“5.3.4”。
After I deleted them, there are "5.0.12"/"5.2.17"/"5.3.4" after rebuilt my projects.
我删除它们后,重建我的项目后有“5.0.12”/“5.2.17”/“5.3.4”。
And when I dig into this issue, I found that the "hibernate-core-5.2.17.Final.jar" in previous "5.2.17" folder is bigger than the normal and it has no "hibernate-core-5.2.17.Final.jar.sha1".
当我深入研究这个问题时,我发现之前“5.2.17”文件夹中的“hibernate-core-5.2.17.Final.jar”比正常的要大,而且没有“hibernate-core-5.2.17” .Final.jar.sha1”。
So, it may caused by poor network or poor mirror.
所以,可能是网络不好或者镜像不好造成的。