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:
Spring RESTful controller method improvement suggestions
Unfortunately, I could not get the bean injection to work properly in spring-boot. Here is my attempt:
Spring JPA (Hibernate) No qualifying bean of type: 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
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:
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:
<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 Jackson for RESTful JSON -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-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>
spring boot does not read persistence.xml file by default, see the document here
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
#Bean
public LocalEntityManagerFactoryBean entityManagerFactory(){
LocalEntityManagerFactoryBean factoryBean = new LocalEntityManagerFactoryBean();
factoryBean.setPersistenceUnitName("cpJpaPu");
return factoryBean;
}
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 Boot has 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.
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.
N.B. you aren't really using dependency injection very effectively in your controller - why wouldn't you just inject the UserDao?
The persistence.xml should be in the META-INF directory
/src/main/resources/META-INF/persistence.xml
This question was answered with a much better architecture over here:
Spring JPA (Hibernate) No qualifying bean of type: javax.persistence.EntityManagerFactory
I resolved this issue after deleted all hibernate-core folders under below directory: .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.
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".
After I deleted them, there are "5.0.12"/"5.2.17"/"5.3.4" after rebuilt my projects.
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".
So, it may caused by poor network or poor mirror.
Related
I am setting up a Springboot(version 2.0.4) project with maven build to use PostgreSQL database. I want to utilize data-source auto configuration feature of Springboot but it is giving me following errors:
Field dataSource in com.praveen.demo.MyController required a bean of type 'javax.sql.DataSource' that could not be found.
Bean method 'dataSource' not loaded because #ConditionalOnClass did not find required class 'org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType'
Bean method 'dataSource' not loaded because #ConditionalOnClass did not find required classes 'javax.transaction.TransactionManager', 'org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType'
In my pom.xml I've dependencies on postgresql and HikariCP as below:
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
</dependency>
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
</dependency>
Also I've in my application.properties file
spring.datasource.url=jdbc:postgresql://localhost:5432/mydb?user=myself&password=mypassword
In my Java file having #RestController annotation , I am injecting DataSource as below:
#Autowired
private DataSource dataSource;
I am following below artcile: https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-sql.html
I do not want to use JPA. I believe article is not suggesting to use the JPA for auto configuration to work.
I am expecting that Spring boot should auto-configure Data source for the application as I've declared the dependencies and provided the database URL. Still I get errors(as mentioned on top) on starting the application.
Edit-1: I am following below article:
https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-sql.html
Edit-2: Complete 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.praveen</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.5.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
</dependency>
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Although, I am still confused by the documentation provided at https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-sql.html and was expecting that I should not be required to use JPA for auto-configuration to work if I am explicitly declaring a dependency on HikariCP and Postgresql. Closing it for now.
Your pom is fine if you don't want to use JPA.
Define #Bean for Datasource to configure or add property in application.properties spring.datasource.type=com.zaxxer.hikari.HikariDataSource:
#Configuration
public class DbConfig {
#Bean
#ConfigurationProperties("spring.datasource")
public HikariDataSource dataSource() {
return DataSourceBuilder.create().type(HikariDataSource.class).build();
}
}
also change your properties to below:
spring.datasource.url=jdbc:postgresql://localhost:5432/mydb
spring.datasource.username-myself
spring.datasource.password= mypassword
Note: JPA configure for you everything so if not using JPA then you need to configure DataSource by telling about Hikari.
As per reference document 29.1.2 Connection to a Production Database
If you use the spring-boot-starter-jdbc or
spring-boot-starter-data-jpa “starters”, you automatically get a
dependency to HikariCP.
You can bypass that algorithm completely and specify the connection
pool to use by setting the spring.datasource.type property. This is
especially important if you run your application in a Tomcat
container, as tomcat-jdbc is provided by default.
[Tip] Additional connection pools can always be configured manually.
If you define your own DataSource bean, auto-configuration does not
occur.
I am trying to use oracle database in my java web app, but I keep getting the error when I run my code as a java application:
Exception in thread "main" javax.persistence.PersistenceException: No Persistence provider for EntityManager named databaseTest
here is my code just a simple code to create an entity manager:
package com.sabir.test;
import javax.persistence.Persistence;
public class DatabaseService {
public static void main(String[] args) {
System.out.println("test");
Persistence.createEntityManagerFactory("databaseTest");
}
}
and here is my persistence.xml file
<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 persistence_1_0.xsd" version="1.0">
<persistence-unit name= "databaseTest" transaction-type="RESOURCE_LOCAL">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<properties>
<property name="javax.persistence.jdbc.driver" value="oracle.jdbc.OracleDriver"/>
<property name="javax.persistence.jdbc.url" value="jdbc:oracle:thin:#localhost:1521:orcl"/>
<property name="javax.persistence.jdbc.user" value="HR"/>
<property name="javax.persistence.jdbc.password" value="password"/>
</properties>
</persistence-unit>
</persistence>
and if required here is my pom.xml file :
<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.sabir.test</groupId>
<artifactId>databaseTest</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>databaseTest Maven Webapp</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc6</artifactId>
<version>11.2.0.3</version>
</dependency>
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>eclipselink</artifactId>
<version>2.5.0-RC1</version>
<scope>compile</scope>
</dependency>
</dependencies>
<repositories>
<repository>
<id>codelds</id>
<url>https://code.lds.org/nexus/content/groups/main-repo</url>
</repository>
<repository>
<id>oss.sonatype.org</id>
<name>OSS Sonatype Staging</name>
<url>https://oss.sonatype.org/content/groups/staging</url>
</repository>
<repository>
<id>EclipseLink</id>
<url>http://download.eclipse.org/rt/eclipselink/maven.repo</url>
</repository>
</repositories>
<build>
<finalName>databaseTest</finalName>
</build>
</project>
I don't know why I am getting the error! here is also my files structure :
I am suspecting the file structure but after I checked many websites, I believe this is the correct one. I also imported the eclipslink in maven so I believe that is all I need, I also added the repository or oracle.
my database is also up and running and I can query from the oracle developer tool
First of all check if you have Maven Libraries on the build path.
In Eclipse you would go to
Project Properties -> Java Build Path -> Libraries.
If you do, check below:
You don't have provider you are referring to on your classpath.
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
I suggest to add the following to your dependencies(and remove eclipselink dependency):
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>7.0</version>
<scope>provided</scope>
</dependency>
or change eclipselink dependency to
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>org.eclipse.persistence.jpa</artifactId>
<version>2.6.4</version>
</dependency>
How and where do you obtain EntityManager from EntityManagerFactory?
I see only that you are creating instance of EntityManagerFactory only.
It should be
EntityManagerFactory emf = Persistence.createEntityManagerFactory("databaseTest");
EntityManager em = emf.createEntityManager();
In general this approach is useful only if you want to bootstrap in Java SE environment.
Instead you might use dependency injection:
#PersistenceContext
EntityManager em;
or
#PersistenceUnit(unitName="myUnit")
EntityMangerFactory emf;
then in your methods you can get EntityManager again as follows
EntityManager em = emf.createEntityManager();
Or you can use JNDI lookup.
I try to create a JPA Project with Maven in Intellij.
I use Eclipse Link and the Database is SQlite.
This is my current pom.xml File (only the Dependencies):
<dependency>
<groupId>org.xerial</groupId>
<artifactId>sqlite-jdbc</artifactId>
<version>3.8.11.2</version>
</dependency>
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>org.eclipse.persistence.jpa</artifactId>
<version>2.6.3</version>
</dependency>
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>javax.persistence</artifactId>
<version>2.1.1</version>
</dependency>
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>eclipselink</artifactId>
<version>2.6.3</version>
</dependency>
My persistence.xml file looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence" version="2.1">
<persistence-unit name="NewPersistenceUnit">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<class>com.raeste.db.BuchungEntity</class>
<class>com.raeste.db.KategorieEntity</class>
<properties>
<property name="eclipselink.jdbc.url" value="jdbc:sqlite:/home/raeste/programmierung/haushaltsbuch.db"/>
<property name="eclipselink.jdbc.driver" value="org.sqlite.JDBC"/>
</properties>
</persistence-unit>
</persistence>
If i now try to create an EntityMangerFactory I get the following exception:
Exception in thread "main" javax.persistence.PersistenceException: No Persistence provider for EntityManager named NewPersistenceUnit
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:85)
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:54)
The Code to create the EntityManagerFactory is:
EntityManagerFactory emf = Persistence.createEntityManagerFactory("NewPersistenceUnit");
I know there are several questions with that problem but non of them helped.
The persistence.xml file is under the following path:
src/main/java/META-INF/
The persistence.xml file should be at src/main/resources/META-INF.
src/main/java is for Java source code.
src/main/resources is for resource files.
Try it.
I'm working on a project made with :
Web Dynamic Project + JPA 2.1 / EclipseLink 2.5.2
Tomcat 8.0.28 / JRE 1.8.0_66
Eclipse Luna
JPA part of the project was running fine when executed in a simple JPA project as a Java Application.
I made no changes on that part of the code.
I wanted to print some request results in a JSP. I generated a servlet and tried to print the name of a user already created in the database. For hours I had errors about JDBC driver and persistence.xml not found.
In order to solve dependancies problems I added Maven.
Now, my user is printed in the JSP and that's fine, but my "Run.java" class I used previously doesn't work anymore.
I'm quiet lost with the error I get when running my app as a "Java Application" :
Exception in thread "main" java.lang.ExceptionInInitializerError
at org.eclipse.persistence.internal.jpa.EntityManagerFactoryProvider.<clinit>(EntityManagerFactoryProvider.java:55)
at org.eclipse.persistence.jpa.PersistenceProvider.createEntityManagerFactoryImpl(PersistenceProvider.java:92)
at org.eclipse.persistence.jpa.PersistenceProvider.createEntityManagerFactory(PersistenceProvider.java:188)
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:79)
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:54)
at dao.LayerDAO.<init>(LayerDAO.java:16)
at exec.Run.main(Run.java:18)
Caused by: java.lang.NullPointerException
at org.eclipse.persistence.platform.server.NoServerPlatformDetector.checkPlatform(NoServerPlatformDetector.java:28)
at org.eclipse.persistence.platform.server.ServerPlatformUtils.detectServerPlatform(ServerPlatformUtils.java:58)
at org.eclipse.persistence.internal.jpa.IsolatedHashMap.<clinit>(IsolatedHashMap.java:48)
... 7 more
Clearly the error occurs when I'm creating the EntityManagerFactory in the DAO class (the same one that is working with the JSP).
Here is my POM :
<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>CitizenWeb</groupId>
<artifactId>com.citizenweb</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<build>
<sourceDirectory>src</sourceDirectory>
<resources>
<resource>
<directory>src</directory>
<excludes>
<exclude>**/*.java</exclude>
</excludes>
</resource>
</resources>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.6</version>
<configuration>
<warSourceDirectory>WebContent</warSourceDirectory>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
</plugins>
</build>
<properties>
<!-- Generic properties -->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<!-- Web -->
<jsp.version>2.2</jsp.version>
<jstl.version>1.2</jstl.version>
<servlet.version>2.5</servlet.version>
<!-- Logging -->
<logback.version>1.0.13</logback.version>
<slf4j.version>1.7.5</slf4j.version>
<!-- Test -->
<junit.version>4.11</junit.version>
</properties>
<dependencies>
<!-- Other Web dependencies -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>${jstl.version}</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>${servlet.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>${jsp.version}</version>
<scope>provided</scope>
</dependency>
<!-- Logging with SLF4J & LogBack -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>${logback.version}</version>
<scope>runtime</scope>
</dependency>
<!-- EclipseLink -->
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>org.eclipse.persistence.core</artifactId>
<version>2.5.2</version>
</dependency>
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>org.eclipse.persistence.jpa</artifactId>
<version>2.5.2</version>
</dependency>
<!-- MySQL DB -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.37</version>
</dependency>
</dependencies>
</project>
If needed, here is my persistence.xml :
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
<persistence-unit name="CitizenWeb" transaction-type="RESOURCE_LOCAL">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<mapping-file>META-INF/orm.xml</mapping-file>
<properties>
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/citizen"/>
<property name="javax.persistence.jdbc.user" value="user"/>
<property name="javax.persistence.jdbc.password" value="user"/>
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
<property name="eclipselink.ddl-generation" value="drop-and-create-tables"/>
</properties>
</persistence-unit>
</persistence>
Entities mapping is managed with an orm.xml
Here's also the beginning of the DAO class :
package dao;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.Persistence;
import javax.persistence.Query;
import entities.Address;
import entities.GroupAssoc;
import entities.RightsGranted;
import entities.User;
public class LayerDAO implements IFLayerDAOLocal {
EntityManager em = Persistence.createEntityManagerFactory("CitizenWeb").createEntityManager();
public void createUser(User user) {
System.out.println("DAO > addUser > "+em.hashCode());
em.getTransaction().begin();
em.persist(user);
em.getTransaction().commit();
}
Nothing has been changed here, neither in the persistence.xml
The "only" changes are in the build.path because of the change in the nature of project (JPA -> Web Dynamic+JPA). Maven has solved the problem with the webserver and the mysql connector, but now the app side is broken.
Do you see something I don't ?
Thanx.
In the buildpath of the project, I added an alternate "JRE System Library".
I previously had : JDK 1.8.0_66
I added : JRE 1.8.0_66
Now JSP works and also java Run class.
I've been trying to get a simple skeleton app to run (and commit to the DB) using JPA, MySQL, Hibernate & Maven, however I'm having problems.
Listed below are my 2 trivial classes, my pom.xml, and my META-INF/persistence.xml
I can build the project without any problem (mvn clean install), however running it (mvn exec:java -Dexec.mainClass=com.foo.HelloWorld -X) causes an exception, with the following StackTrace.
Any help would be greatly appreciated!
Stacktrace:
org.apache.maven.lifecycle.LifecycleExecutionException: An exception occured while executing the Java class. null
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoals(DefaultLifecycleExecutor.java:719)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeStandaloneGoal(DefaultLifecycleExecutor.java:569)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoal(DefaultLifecycleExecutor.java:539)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoalAndHandleFailures(DefaultLifecycleExecutor.java:387)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeTaskSegments(DefaultLifecycleExecutor.java:348)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.execute(DefaultLifecycleExecutor.java:180)
at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:328)
at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:138)
at org.apache.maven.cli.MavenCli.main(MavenCli.java:362)
at org.apache.maven.cli.compat.CompatibleMain.main(CompatibleMain.java:60)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.codehaus.classworlds.Launcher.launchEnhanced(Launcher.java:315)
at org.codehaus.classworlds.Launcher.launch(Launcher.java:255)
at org.codehaus.classworlds.Launcher.mainWithExitCode(Launcher.java:430)
at org.codehaus.classworlds.Launcher.main(Launcher.java:375)
Caused by: org.apache.maven.plugin.MojoExecutionException: An exception occured while executing the Java class. null
at org.codehaus.mojo.exec.ExecJavaMojo.execute(ExecJavaMojo.java:346)
at org.apache.maven.plugin.DefaultPluginManager.executeMojo(DefaultPluginManager.java:490)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoals(DefaultLifecycleExecutor.java:694)
... 17 more
Caused by: java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.codehaus.mojo.exec.ExecJavaMojo$1.run(ExecJavaMojo.java:291)
at java.lang.Thread.run(Thread.java:619)
Caused by: java.lang.NoSuchMethodError: org.hibernate.event.PreInsertEvent.getSource()Lorg/hibernate/engine/SessionImplementor;
at org.hibernate.validator.event.ValidateEventListener.onPreInsert(ValidateEventListener.java:167)
at org.hibernate.action.EntityIdentityInsertAction.preInsert(EntityIdentityInsertAction.java:142)
at org.hibernate.action.EntityIdentityInsertAction.execute(EntityIdentityInsertAction.java:65)
at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:279)
at org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:321)
at org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:204)
at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:130)
at org.hibernate.event.def.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:154)
at org.hibernate.event.def.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:110)
at org.hibernate.event.def.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:61)
at org.hibernate.impl.SessionImpl.firePersist(SessionImpl.java:646)
at org.hibernate.impl.SessionImpl.persist(SessionImpl.java:620)
at org.hibernate.impl.SessionImpl.persist(SessionImpl.java:624)
at org.hibernate.ejb.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:212)
at com.foo.HelloWorld.create(HelloWorld.java:32)
at com.foo.HelloWorld.main(HelloWorld.java:11)
... 6 more
I have the following two classes:
The Entity to store.
package com.foo;
import java.io.Serializable;
import javax.persistence.Basic;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
#Entity
public class Message {
#Id
#GeneratedValue
private int id;
#Basic
private String message;
public Message() {}
public Message(String message) {
this.message = message;
}
public String toString() {
return "Greeting id=" + id + ", message=" + message;
}
}
The Application:
package com.foo;
public class HelloWorld {
private javax.persistence.EntityManagerFactory emf;
private javax.persistence.EntityManager em;
private String PERSISTENCE_UNIT_NAME = "hello-world";
public static void main(String[] args) {
HelloWorld hello = new HelloWorld();
hello.initEntityManager();
hello.create();
// hello.read();
hello.closeEntityManager();
}
private void initEntityManager() {
emf = javax.persistence.Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME);
em = emf.createEntityManager();
}
private void closeEntityManager() {
em.close();
emf.close();
}
private void create() {
em.getTransaction().begin();
Message hello = new Message("hello world");
Message bye = new Message("goodbye, world");
Message[] messages = new Message[] {hello, bye};
for (Message m : messages) {
em.persist(m);
}
em.getTransaction().commit();
}
// private void read() {
// Message m = (Message)em.createQuery("select m from Message m").getSingleResult();
// System.out.println("Query returned: " + m);
// }
}
The following is my pom.xml
<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.treocht.hibernate.tutorial</groupId>
<artifactId>hibernate-tutorial</artifactId>
<version>1.0.0-SNAPSHOT</version>
<name>First Hibernate Tutorial</name>
<dependencies>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>3.3.2.GA</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>javax.persistence</groupId>
<artifactId>persistence-api</artifactId>
<version>1.0</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.0.4</version>
</dependency>
<dependency>
<groupId>hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<version>1.8.0.7</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate</artifactId>
<version>3.2.2.ga</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-annotations</artifactId>
<version>3.2.1.ga</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>3.2.1.ga</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-tools</artifactId>
<version>3.2.0.beta9a</version>
</dependency>
<dependency>
<groupId>c3p0</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.1</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.6.1</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.13</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
</dependencies>
<build>
<!--
we dont want the version to be part of the generated war file name
-->
<finalName>${artifactId}</finalName>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
And I have this META-INF/persistence.xml file:
<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 persistence_1_0.xsd"
version="1.0">
<persistence-unit name="hello-world" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>com.foo.Message</class>
<properties>
<property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/my_db" />
<property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver" />
<property name="hibernate.connection.password" value="password" />
<property name="hibernate.connection.username" value="username" />
<property name="hibernate.hbm2ddl.auto" value="update" />
</properties>
</persistence-unit>
</persistence>
You're indeed using incompatible versions of Hibernate artifacts as this can be verified using the official Hibernate Compatibility Matrix. Don't rely on some random tutorial found around the net for that.
But since you're using Maven, you actually don't need to declare all Hibernate artifacts, just leverage the transitive dependencies. So just declare a dependency in the hibernate-entitymanager (especially if you're not sure of what you're doing):
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>3.4.0.GA</version><!-- for JPA 1.0 -->
</dependency>
And remove these hibernate, hibernate-core, hibernate-annotations, persistence-api, slf4j dependencies.
And if you want to change the version of the sfl4j-api artifact that you get transitively, you should do that in the dependency management section:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.6.1</version>
</dependency>
</dependencies>
</dependencyManagement>
Actually (and I'm sorry to say so) your whole pom is a big mess, try to spend some time cleaning it. Use mvn dependency:tree (or some visual fronted offered by your IDE) to do so.
And let me insist, don't rely on some random (and wrong) tutorial found around the net, leverage Maven transitive dependency mechanism.
PS: As of Hibernate 3.5, the various projects (Hibernate Annotation, Hibernate EntityManager) have been merged back to Hibernate Core and their versions are synchronized which simplifies a lot version management, even for Maven users.
There might be the conflicts in version.
compare it with this
This is now working, and my pom.xml looks like this:
<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.company.hibernate.tutorial</groupId>
<artifactId>hibernate-tutorial</artifactId>
<version>1.0.0-SNAPSHOT</version>
<name>Hibernate Tutorial</name>
<repositories>
<repository>
<id>JBoss repository</id>
<url>http://repository.jboss.com/maven2/</url>
</repository>
</repositories>
<dependencies>
<!-- Hibernate framework -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>3.4.0.GA</version><!-- for JPA 1.0 -->
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.13</version>
<type>jar</type>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.16</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-jdk14</artifactId>
<version>1.6.1</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
</dependencies>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.6.1</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
</dependencies>
</dependencyManagement>
</project>