简体   繁体   中英

“No Persistence provider for EntityManager” error

I am newbie to JPA and I tried to do a simple example from the book. But no matter what I do I receive following error:

Exception in thread "main" javax.persistence.PersistenceException: No Persistence provider for EntityManager named EmployeeService
        at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:89)
        at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:60)
        at com.mycompany.simpleentity.EmployeeTest.main(EmployeeTest.java:18)

I googled a lot and I did all that I read about JPA.
Here is a directory tree of my project:

    .
|-- pom.xml
`-- src
    |-- main
    |   |-- java
    |   |   `-- com
    |   |       `-- mycompany
    |   |           `-- simpleentity
    |   |               |-- Employee.java
    |   |               |-- EmployeeService.java
    |   |               `-- EmployeeTest.java
    |   `-- resources
    |       `-- META-INF
    |           `-- persistence.xml
    `-- test

Here 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/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.mycompany</groupId>
  <artifactId>SimpleEntity</artifactId>
  <packaging>jar</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>SimpleEntity</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>javax.persistence</groupId>
      <artifactId>persistence-api</artifactId>
      <version>1.0</version>      
    </dependency>
    <dependency>
        <groupId>postgresql</groupId>
        <artifactId>postgresql</artifactId>
        <version>9.0-801.jdbc4</version>
    </dependency>
  </dependencies>

  <build>

      <plugins>
        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-compiler-plugin</artifactId>
          <configuration>
             <source>1.5</source>
             <target>1.5</target>
          </configuration>
        </plugin>

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>

            <configuration>
                <archive>
                    <manifest>
                        <addClasspath>true</addClasspath>
                        <mainClass>com.mycompany.simpleentity.EmployeeTest</mainClass>
                        <!-- <classpathLayoutType>repository</classpathLayoutType> -->
                        <classpathMavenRepositoryLayout>true</classpathMavenRepositoryLayout>
                        <classpathPrefix>${env.HOME}/.m2/repository</classpathPrefix>

                    </manifest>
                </archive>
            </configuration>
        </plugin>
      </plugins>

  </build> 
</project>

Here is my source code: EmployeeTest.java:

package com.mycompany.simpleentity;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

public class EmployeeTest {
    public static void main(String[] args) {
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("EmployeeService");
        EntityManager em = emf.createEntityManager();

    }
}

And here is my persistance.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="EmployeeService" transaction-type="RESOURCE_LOCAL">
        <class>com.mycompany.simpleentity.Employee</class>
        <properties>
            <property name="toplink.jdbc.driver"
                      value="org.postgresql.Driver"/>
            <property name="toplink.jdbc.url"
                      value="jdbc:postgresql://localhost:5432/testdb;create=true"/>
            <property name="toplink.jdbc.user" value="postgres"/>
            <property name="toplink.jdbc.password" value="111"/>

        </properties>
    </persistence-unit>
</persistence>

What do I do wrong? Thank you in advance.

JPA is a specification implemented by multiple JPA providers (Hibernate, EclipseLink, OpenJPA, Toplink).

You need to choose a provider to use and add the appropriate dependency to your pom.xml . Also you need to specify your provider in persistence.xml .

For example, if you use OpenJPA (I choosed it for this example since its latest version is available in Maven Central Repo, so there is no need to configure vendor-specific repositories):

 <dependencies> 
    <dependency> 
      <groupId>junit</groupId> 
      <artifactId>junit</artifactId> 
      <version>3.8.1</version> 
      <scope>test</scope> 
    </dependency> 
    <!-- Note that you don't need persistence-api dependency - it's transitive -->
    <dependency>
      <groupId>org.apache.openjpa</groupId>
      <artifactId>openjpa-all</artifactId>
      <version>2.0.1</version>
    </dependency>
    <dependency> 
        <groupId>postgresql</groupId> 
        <artifactId>postgresql</artifactId> 
        <version>9.0-801.jdbc4</version> 
    </dependency> 
  </dependencies> 

.

<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="EmployeeService" transaction-type="RESOURCE_LOCAL">   
        <!-- Provider specification -->
        <provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>

        <class>com.mycompany.simpleentity.Employee</class>       
        <properties>       
            <property name="javax.persistence.jdbc.driver"       
                      value="org.postgresql.Driver"/>       
            <property name="javax.persistence.jdbc.url"       
                      value="jdbc:postgresql://localhost:5432/testdb;create=true"/>       
            <property name="javax.persistence.jdbc.user" value="postgres"/>       
            <property name="javax.persistence.jdbc.password" value="111"/>       

        </properties>       
    </persistence-unit>       
</persistence>  

if you use JPA + eclipselink Provider than use this code

<properties>
            <property name="javax.persistence.jdbc.url" value="jdbc:postgresql://localhost/Database name" />
            <property name="javax.persistence.jdbc.user" value="" />
            <property name="javax.persistence.jdbc.password" value="" />
            <property name="javax.persistence.jdbc.driver" value="org.postgresql.Driver" />
</properties>

1) make sure you have defined the persistence provider(for whatever provider): Ex For openjpa: <persistence-unit ...> <provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider> ... ... </persistence-unit>

2) if you are using custom build/compile process (maven, etc) make sure your Meta-INF/persistance.xml is copied to the compiled/classes folder.

Actually,

You don't seem to have a dependency for an actual Peristence Provider.

JPA in itself does not have a implementation, you will need to also use Hibernate/Toplink/OpenJPA as an actual solution.

JPA being a specification has multiple providers (implementors). You have to choose one that provides the actual bytecode for the JPA specification. Hibernate is common choice, but yours may be different. Once you have identified that, add that as a dependency into your POM. Otherwise, add the JAR file to your build path.

According to your persistence.xml you are using TopLink with PostgreSQL as the RDBMS. While you reference the PostgreSQL JDBC driver in your pom.xml, you haven't declared TopLink as a dependency.

My guess (I admit) is that the persistence API doesn't find TopLink (your persistence provider) in the classpath. Try adding TopLink as a dependency.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM