Eclipselink Maven No Persistence provider for EntityManager named - java

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.

Related

Unable to create requested service [org.hibernate.engine.jdbc.env.spi.JdbcEnvironment] in Hibernate JPA

I'm new to JPA, Hibernate and Maven and I'm using this video tutorial to create a project. I'm running into some problems with Hibernate, I believe, but the other answers I've seen on this website don't seem to address my problem. I'm using Hibernate 5.4.1.Final and mysql 8.0.20. Below is the partial stack trace (full is pretty long).
WARN: HHH000342: Could not obtain connection to query metadata : null
Exception in thread "main" java.lang.ExceptionInInitializerError
Caused by: org.hibernate.service.spi.ServiceException: Unable to create requested service [org.hibernate.engine.jdbc.env.spi.JdbcEnvironment]
at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:275)
...
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:79)
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:54)
at com.sommaven.JEETut3.TestSystem.<clinit>(TestSystem.java:15)
Caused by: org.hibernate.HibernateException: Access to DialectResolutionInfo cannot be null when 'hibernate.dialect' not set
at org.hibernate.engine.jdbc.dialect.internal.DialectFactoryImpl.determineDialect(DialectFactoryImpl.java:100)
at org.hibernate.engine.jdbc.dialect.internal.DialectFactoryImpl.buildDialect(DialectFactoryImpl.java:54)
at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:137)
at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:35)
at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.initiateService(StandardServiceRegistryImpl.java:101)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:263)
...
This is my persistence.xml
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0"
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_2_0.xsd">
<!-- Define a name used to get an entity manager. Define that you will
complete transactions with the DB -->
<persistence-unit name="JEETut3" transaction-type="RESOURCE_LOCAL">
<!-- Define the class for Hibernate which implements JPA -->
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<!-- Define the object that should be persisted in the database -->
<class>com.newthinktank.JEETut3.Customer</class>
<properties>
<!-- Driver for DB database -->
<property name="javax.persistence.jdbc.driver" value="com.mysql.cj.jdbc.Driver" />
<!-- URL for DB -->
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost/test4" />
<!-- Username -->
<property name="javax.persistence.jdbc.user" value="dbadmin" />
<!-- Password -->
<property name="javax.persistence.jdbc.password" value="turtledove" />
</properties>
</persistence-unit>
</persistence>
And this 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>
<!-- 1. New -> Maven Project (Quick Start)
Group Id : com.newthinktank
Artifact ID : JEETut3
Update the dependencies here
Maven is project management software that handles builds, dependencies, documentation and more
-->
<groupId>com.newthinktank</groupId>
<artifactId>JEETut3</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>JEETut3</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.4.1.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>5.4.1.Final</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.15</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
I see that the hibernate.dialect isn't set, do I need to manually set it to mysql?
You are seeing this exception as you haven't provided any dialect in the persistence.xml and left it to Hibernate to resolve automatically at startup. Hibernate can determine the correct dialect to use automatically, but in order to do this, it needs a live connection to the database. I think the dialect is not getting resolved for you at startup due to connectivity issues maybe, so try adding the following to your persistence.xml:
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLInnoDBDialect" />
You could also check to verify that the database server that you are trying to connect to is up and running or the driver versions are compatible or not. Also double check the url , password etc to verify if you left out any particular port that you need to specify etc.

Why does my Java app work in local but when delivering to IBM Cloud it gives this error

I have created an app that uses JPA as well as servlets with JAX-RS.
When I run the app locally, I am able to query my server with curl and get the proper response for all the GET and POST requests. However, when I host the server on IBM Cloud and I query it with curl I get the error: "No Persistence provider for EntityManager".
What's causing the discrepancy between the local and remote (IBM Cloud) environments and what can I do to fix it?
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="ibmcloud">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<non-jta-data-source>java:comp/DefaultDataSource</non-jta-data-source>
<class>entities.Comment</class>
<properties>
<property name="javax.persistence.schema-generation.database.action" value="drop-and-create"/>
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.format_sql" value="true"/>
<property name="hibernate.use_sql_comments" value="true"/>
</properties>
</persistence-unit>
</persistence>
.travis.yml
language: java
jdk: oraclejdk8
sudo: false
before_install:
mvn install -DskipTests=true -Dmaven.javadoc.skip=true -B -V
before_deply:
cf login -u $BLUEMIX_USER -o $BLUEMIX_ORG
script:
mvn test -B
language: java
git:
depth: 1
dist: trusty
cache:
directories:
- "$HOME/.m2"
deploy:
edge: true
provider: bluemixcloudfoundry
username: $BLUEMIX_USER
password: $BLUEMIX_PASSWORD
organization: $BLUEMIX_ORG
space: $BLUEMIX_SPACE
manifest: manifest.yml
app_name: ibmcloudapp
region: eu-gb
api: https://api.eu-gb.bluemix.net
skip_cleanup: true
manifest.yml
applications:
- name: ibmcloud
path: target/ibmcloud.war
instances: 1
random-route: true
pom.xml
<?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.dotheminimum</groupId>
<artifactId>ibmcloud</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<failOnMissingWebXml>false</failOnMissingWebXml>
</properties>
<dependencies>
<!-- https://mvnrepository.com/artifact/javax.ws.rs/javax.ws.rs-api -->
<dependency>
<groupId>javax.ws.rs</groupId>
<artifactId>javax.ws.rs-api</artifactId>
<version>2.1.1</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.4.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.4.0</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.hibernate.javax.persistence/hibernate-jpa-2.1-api -->
<!-- <dependency>
<groupId>org.hibernate.javax.persistence</groupId>
<artifactId>hibernate-jpa-2.1-api</artifactId>
<version>1.0.2.Final</version>
</dependency> -->
<!-- https://mvnrepository.com/artifact/javax.persistence/javax.persistence-api -->
<dependency>
<groupId>javax.persistence</groupId>
<artifactId>javax.persistence-api</artifactId>
<version>2.2</version>
</dependency>
</dependencies>
<build>
<finalName>${project.artifactId}</finalName>
<plugins>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.1</version>
</plugin>
</plugins>
</build>
</project>
The source code for the app is hosted here
The problem was that my "persistence.xml" file was under "src/main/java/META-INF" instead of "src/main/resources/META-INF".
My local environment was able to find the file, but IBM Cloud didn't. After changing the path of "persistence.xml", the file was detected by IBM Cloud.
If I had been exhaustive, I would have been able to find my solution in the comments of the first result of the search linked to by Billy Frost (No Persistence provider for EntityManager named)

Exception in thread "main" javax.persistence.PersistenceException: No Persistence provider for EntityManager named databaseTest

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.

Error while initializing persistence.xml

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.

Spring-boot: cannot use persistence

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.

Categories

Resources