I recently switched development machines and now writing objects to/retrieving objects from the persistence database is not working any longer. This happens when I try to debug the webapp project on my new machine.
It works on my old laptop but somehow won't on the new one. I also deployed the webapp to an server and there everything works as expected.
I get the following two error message while interacting with the database:
Writing objects to the database:
SEVERE: Exception sending context initialized event to listener instance of class org.example.webapp.startup.ServletContextClass
java.lang.IllegalArgumentException: Object: org.example.utility.trs.objects.ChangeLog#789a464b is not a known entity type.
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.registerNewObjectForPersist(UnitOfWorkImpl.java:4222)
at org.eclipse.persistence.internal.jpa.EntityManagerImpl.persist(EntityManagerImpl.java:496)
at org.example.webapp.changelog.dao.ChangeLogDao.addChangeLog(ChangeLogDao.java:42)
at org.example.webapp.startup.ServletContextClass.initializeChangeLog(ServletContextClass.java:104)
at org.example.webapp.startup.ServletContextClass.contextInitialized(ServletContextClass.java:59)
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4797)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5221)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1408)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1398)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Code to write to the database:
public void addChangeLog(ChangeLog changeLog, EntityManagerFactory emf) {
String changeLogId = changeLog.getModelResource();
if(!contentProvider.containsKey(changeLogId)) {
//create new user
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
em.persist(changeLog);
em.getTransaction().commit();
em.close();
contentProvider.put(changeLogId, changeLog);
}
Retrieving objects from the database:
SEVERE: Exception sending context initialized event to listener instance of class org.example.webapp.startup.ServletContextClass
java.lang.IllegalArgumentException: An exception occurred while creating a query in EntityManager:
Exception Description: Problem compiling [SELECT c FROM ChangeLog c].
[14, 23] The abstract schema type 'ChangeLog' is unknown.
at org.eclipse.persistence.internal.jpa.EntityManagerImpl.createQuery(EntityManagerImpl.java:1585)
at org.eclipse.persistence.internal.jpa.EntityManagerImpl.createQuery(EntityManagerImpl.java:1605)
at org.example.webapp.startup.ServletContextClass.contextInitialized(ServletContextClass.java:59)
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4797)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5221)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1408)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1398)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Code to read from the database:
List<ChangeLog> changeLogList = em.createQuery("SELECT c FROM ChangeLog c",
ChangeLog.class).getResultList();
Here is how the ChangeLog class looks like:
package org.example.utility.trs.objects;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.NamedQuery;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
#Entity
#NamedQuery(name="ChangeLog.findAll", query="SELECT c FROM ChangeLog c")
#XmlRootElement
#XmlAccessorType(XmlAccessType.FIELD)
public class ChangeLog implements Serializable {
private static final long serialVersionUID = 123L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long changeLogId;
...
}
This is the persistence.xml file:
<?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="webapp-name" transaction-type="RESOURCE_LOCAL">
<class>org.example.utility.trs.objects.ChangeLog</class>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<properties>
<!-- mysql persistence driver -->
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/persistence"/>
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
<property name="javax.persistence.jdbc.username" value="admin"/>
<property name="javax.persistence.jdbc.password" value="password"/>
<!-- EclipseLink should create the database schema automatically -->
<property name="eclipselink.ddl-generation.output-mode" value="database" />
<property name="javax.persistence.jdbc.user" value="admin"/>
</properties>
</persistence-unit>
</persistence>
Here is the part of the pom.xml file that includes the persistence libraries. I can post the whole file if this of any assistence:
<!-- persistence api -->
<dependency>
<groupId>org.hibernate.javax.persistence</groupId>
<artifactId>hibernate-jpa-2.0-api</artifactId>
<version>1.0.1.Final</version>
</dependency>
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>eclipselink</artifactId>
<version>2.5.0</version>
</dependency>
I can connect to the database and there is a table with content that I was able to create and read on my old development machine.
Thus I assume that the issue is rather with the configuration of eclipselink than an actual problem in the code. Maybe it is an issue with the configuration of the JPA facet in the eclipse project.
However I have no idea how to debug this issue.
On the other hand the ChangeLog class is in a from a different project that is stored in my local Maven repository and is not defined in the webapp project. So this might be an issue. This was never a problem on my old machine though.
Any help is appreciated
So after some testing I finally figured out what went wrong. I leave this here if anyone else comes across this problem.
It turned out that while deploying the code to the new development machine I changed some of the dependency versions in my pom.xml file. So I created the database table with version 2.6.4 of the eclipselink API.
On the new development machine I changed it to version 2.5 and recompiled the project which broke the extraction of the objects from the database.
Once I changed the version back it worked again.
Related
I tried to write some code with EntityManager but hibernate was updated to hibernate-core(6.0.0.Final) and with new hibernate 6.0 my old codes doesn't work
There my code:
my pom.xml
enter image description here
my persistence.xml file
<persistence 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"
version="2.1">
<persistence-unit name="CRM">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<properties>
<property name="hibernate.connection.driver_class" value="org.postgresql.Driver"/>
<property name="hibernate.connection.url" value="jdbc:postgresql://localhost:5678/postgres"/>
<property name="hibernate.connection.username" value="postgres"/>
<property name="hibernate.connection.password" value="postgres"/>
<property name="hibernate.hbm2ddl.auto" value="create"/>
<property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect"/>
<property name="hibernate.show_sql" value="true"/>
</properties>
</persistence-unit>
and my main method
EntityManagerFactory entityManagerFactory =
Persistence.createEntityManagerFactory("CRM");
EntityManager entityManager = entityManagerFactory.createEntityManager();
entityManager.getTransaction().begin();
entityManager.persist(new SuperHero());
entityManager.getTransaction().commit();
entityManager.close();
entityManagerFactory.close();
here result
enter image description here
thanks in advance for your help
It looks as if you are mixing 2 incompatible versions of Hibernate resources:
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>6.0.0.Final</version>
</dependency>
and:
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>5.6.7.Final</version>
</dependency>
From v6 onwards, the Hibernate libraries have moved from using Java Persistence to Jakarta Persistence. You can read about this larger Java ecosystem change elsewhere Transition from Java EE to Jakarta EE - and also in other SO questions and answers.
By including a Hibernate Entity Manager v5 dependency, your project will still be referring to a Java Persistence library (e.g. via javax.persistence-api-2.2.jar or similar). This means your code may still compile - but, as you see, it will not execute. You will see error messages referring to javax classes, which are no longer supported by the v6 Hibernate Core library.
Furthermore, Hibernate's JPA support has been merged into the hibernate-core module, making the hibernate-entitymanager module obsolete. You can see a note about this by looking at the readme.txt file in your Entity Manager 5.6.7 JAR file:
Hibernate's JPA support has been merged into the hibernate-core module, making this hibernate-entitymanager module obsolete. This module will be removed in Hibernate ORM 6.0.
Recommended steps:
Remove the hibernate-entitymanager dependency from your POM. That will probably trigger a series of compilation errors, because you will no longer have any library support for classes such as javax.persistence.EntityManager.
Update all your javax imports to jakarta imports. So, for example, taking the class from (1) above, that becomes:
import jakarta.persistence.EntityManager;
In your persistence.xml file you will also need to fix any similar references to javax - for example:
<property name="jakarta.persistence.jdbc.driver"
value="com.mysql.jdbc.Driver" />
Final Notes
If you still face issues following the above steps, then you can refer to the official Hibernate ORM 6.0 Migration Guide.
I have an issue here and I must assume someone else must have run into this before. It has been 3 weeks now and I have ran out of options nou.
Environment:
Jboss eap 7
Java 8
Java EE 7
Postgres
Hibernate 5x
Linux
The idea is to be able to write to two data sources in a single transaction using the xa-resource for my transaction management. I have two databases both with different tables represented by different entities as such.
My service bean is called by a managed bean from the war layer through an injected service interface at post construct.
My service implementation has an injected entity manager(em) annotated with the persistence context specifying the target database as a “unitName”. The service bean calls the entity interface implementation passing the chosen em as a param, eventually the em is received by the base entity that in turn does the db operations.
My application is divided into 3 modules/layers web=war, services=jar, and domain=jar with an EAR as the main archive. My problem is actually in the back-end.
I had first added in my persistence xml the following:
Created 2 persistence units (PU1 has 15 entities, PU2 has 17 listed in class element)
transaction-type = JTA
exclude-unlisted-classes = false and
hibernate.hbm2ddl.auto is = update
I have a base entity, entities and also have a repository package that holds my interfaces and their implementations to interact with my databases.
Now when i run my setup like this, both my databases have exactly 32 tables each and my tables have some of the columns merged, i.e. I have table1 with fields a, b, and c in db1 then I also have table1 (same name) in db2 with fields d, e, and f and both the tables in their database end up with columns a, b, c, d, e, and f.
If I manipulate my persistence.xml as below:
<persistence-unit name="PU1" transaction-type="JTA">
<jta-data-source>java:jboss/datasources/db1</jta-data-source>
<properties>
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.format_sql" value="true"/>
<property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect"/>
<property name="hibernate.ejb.naming_strategy" value="org.hibernate.cfg.ImprovedNamingStrategy"/>
</properties>
<class>domain.org.PemsBusinessArea</class>
...
</persistence-unit>
<persistence-unit name="PU2" transaction-type="JTA">
<jta-data-source>java:jboss/datasources/db2</jta-data-source>
<properties>
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.format_sql" value="true"/>
<property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect"/>
<property name="hibernate.ejb.naming_strategy" value="org.hibernate.cfg.ImprovedNamingStrategy"/>
</properties>
<class>domain.org .KeyFields</class>
...
</persistence-unit>
and I deploy and run my application I end up with the exception:
Caused by: org.hibernate.exception.SQLGrammarException: could not extract ResultSet
at org.hibernate.exception.internal.SQLStateConversionDelegate.convert(SQLStateConversionDelegate.java:106)
at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:42)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:109)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:95)
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.extract(ResultSetReturnImpl.java:79)
at org.hibernate.loader.Loader.getResultSet(Loader.java:2117)
at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1900)
at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1876)
at org.hibernate.loader.Loader.doQuery(Loader.java:919)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:336)
at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:501)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:371)
at Caused by: org.postgresql.util.PSQLException: ERROR: column plexusbusi0_.name does not exist
and the column “name” exists in the target database table.
Is there anyone who can help me with the above situation? Thanks in advance.
So it turns out I had missed specifying the target PU in one of my service bean methods. After that change, all is now working fine.
I'm trying to implement EHCache into my working prototype, where I have a javax.persistence.Entity representing a table on my database (MySQL, mysql-connector-java-5.1.20.jar), which be provided as XML to the consumers.
The issue I'm facing is that seems Hibernate still retrieving the data from the database, even when EHCache stores the query result on memory.
I'm using the EHCache monitor to see the count of items in memory, and changing the data directly on database before the cache expires to know if the cached data is actually used.
I been looking for a replication for this issue without succeed, so maybe I'm missing something (I just geting into the java world).
My files
pom.xml
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>4.3.0.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>4.1.4.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-ehcache</artifactId>
<version>4.1.4.Final</version>
</dependency>
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache-core</artifactId>
<version>2.5.2</version>
</dependency>
<dependency>
<groupId>org.terracotta</groupId>
<artifactId>ehcache-probe</artifactId>
<version>1.0.2</version>
</dependency>
Entity class
package myPrototype.entities
import javax.persistence.Cacheable;
import javax.persistence.Entity;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;
import javax.xml.bind.annotation.XmlRootElement;
import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
#Entity #Cacheable
#Cache(usage=CacheConcurrencyStrategy.READ_ONLY)
#Table(name = "Cars")
#XmlRootElement
#NamedQueries({
#NamedQuery(name = "Cars.findAll", query = "SELECT d FROM Cars d"),
[...]
public class Cars implements Serializable {
private static final long serialVersionUID = 1L;
#Basic(optional = false)
#NotNull
#Column(name = "id")
#ReferenceField
private int id;
[...]
ehcache.xml
<?xml version="1.0" encoding="UTF-8"?>
<ehcache>
<cache name="myPrototype.entities.Cars"
maxElementsInMemory="500"
eternal="false"
overflowToDisk="false"
timeToIdleSeconds="60"
timeToLiveSeconds="120" />
</ehcache>
* I tried setting eternal="true", but the result still the same
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">
<persistence-unit name="MyPrototype" transaction-type="JTA">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<jta-data-source>java:app/jdbc/mysqlserver/prototype</jta-data-source>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<shared-cache-mode>ENABLE_SELECTIVE</shared-cache-mode>
<properties>
<!-- property name="hibernate.cache.region.factory_class" value="org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory"/ -->
<property name="hibernate.cache.region.factory_class" value="org.hibernate.cache.ehcache.EhCacheRegionFactory" />
<property name="hibernate.cache.use_second_level_cache" value="true"/>
<property name="hibernate.cache.use_query_cache" value="true"/>
<property name="hibernate.cache.region_prefix" value=""/>
</properties>
</persistence-unit>
</persistence>
* I tried switching between SingletonEhCacheRegionFactory and EhCacheRegionFactory
EJB
import myPrototype.entities.Cars
import java.util.Date;
import java.util.List;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
#Stateless
public class CarsEJB {
#PersistenceContext(unitName="MyPrototype")
private EntityManager em;
#Override
public List<Cars> getCars() {
return (List<Cars>)em.createNamedQuery("Cars.findAll").setMaxResults(200).getResultList();
}
}
* Added to clarify how I run the query
Like I said, I can see a count of items in memory through EHCache monitor, so I noted the following:
- The ehcache configuration is property loaded elements are expiring
- The elements expiration not being reseted when the query runs while they still alive (they expired N seconds after the first query).
Again; I'm quite a newbie with java, so asume I could be missing basic concepts.
Thanks for reading!
Hibernate will never execute queries on your cache. What it can do is execute a query on the database, cache the results, and return these cached results the next time you execute the same query, with the same parameters. But to do that, the query, each time it's executed, must be cacheable.
WIth the JPA API, this is done using query hints, directly on the named query definition, or each time you create a query:
#NamedQuery(name = "Cars.findAll",
query = "SELECT d FROM Cars d",
hints = {#QueryHint(name = "org.hibernate.cacheable", value = "true")})
Now that the query is cacheable, Hibernate will load the IDs of the cars from the database the first time this query is executed, and from the query cache afterwards. Then the corresponding cars themselves will be loaded from the entity cache.
I am new to JPA & Hibernate. After reading some online materials I now understand what Hibernate is and how it can be used with JPA.
Now, I am trying to run this JPA & Hibernate tutorial. I've done everything they mention in this tutorial.
I don't have Oracle DB, only MySQL. So I made some changes to persistence.xml using my understanding of JPA & Hibernate (I don't know if it's correct or not... Seems to me it is.)
Here is my 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="customerManager" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>Customer</class>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLInnoDBDialect"/>
<property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver"/>
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.connection.username" value="root"/>
<property name="hibernate.connection.password" value="1234"/>
<property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/general"/>
<property name="hibernate.max_fetch_depth" value="3"/>
</properties>
</persistence-unit>
</persistence>
But I don't seem to get the output they describe. It's giving me:
Customer id before creation:null
log4j:WARN No appenders could be found for logger (org.hibernate.cfg.annotations.Version).
log4j:WARN Please initialize the log4j system properly.
Exception in thread "main" javax.persistence.PersistenceException: No Persistence provider for EntityManager named customerManager
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:55)
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:33)
at CustomerDAO.create(CustomerDAO.java:8)
at CustomerDAO.main(CustomerDAO.java:22)
Any suggestions will be appreciated.
Update:
I have made the changes that are asked to done. But, still getting the asme error lines!!!
They didnt mentioned anything about orm.xml in that tutorial. may it be a problem causer!!!
Just for completeness. There is another situation causing this error:
missing META-INF/services/javax.persistence.spi.PersistenceProvider
file.
For Hibernate, it's located in hibernate-entitymanager-XXX.jar, so, if hibernate-entitymanager-XXX.jar is not in your classpath, you will got this error too.
This error message is so misleading, and it costs me hours to get it correct.
See JPA 2.0 using Hibernate as provider - Exception: No Persistence provider for EntityManager.
Your persistence.xml is not valid and the EntityManagerFactory can't get created. It should be:
<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="customerManager" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>Customer</class>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLInnoDBDialect"/>
<property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver"/>
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.connection.username" value="root"/>
<property name="hibernate.connection.password" value="1234"/>
<property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/general"/>
<property name="hibernate.max_fetch_depth" value="3"/>
</properties>
</persistence-unit>
</persistence>
(Note how the <property> elements are closed, they shouldn't be nested)
Update: I went through the tutorial and you will also have to change the Id generation strategy when using MySQL (as MySQL doesn't support sequences). I suggest using the AUTO strategy (defaults to IDENTITY with MySQL). To do so, remove the SequenceGenerator annotation and change the code like this:
#Entity
#Table(name="TAB_CUSTOMER")
public class Customer implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
#Column(name="CUSTOMER_ID", precision=0)
private Long customerId = null;
...
}
This should help.
PS: you should also provide a log4j.properties as suggested.
I had the same problem today. My persistence.xml was in the wrong location. I had to put it in the following path:
project/src/main/resources/META-INF/persistence.xml
I was facing the same issue. I realised that I was using the Wrong provider class in persistence.xml
For Hibernate it should be
<provider>org.hibernate.ejb.HibernatePersistence</provider>
And for EclipseLink it should be
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
If you use Hibernate 5.2.10.Final, you should change
<provider>org.hibernate.ejb.HibernatePersistence</provider>
to
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
in your persistence.xml
According to Hibernate 5.2.2: No Persistence provider for EntityManager
If you are using Maven you may have both src/{main,test}/resources/META-INF/persistence.xml. This is a common setup: test your JPA code with h2 or Derby and deploy it with PostgreSQL or some other full DBMS. If you're using this pattern, do make sure the two files have different unit names, else some versions of the Persistence class will try to load BOTH (because of course your test-time CLASSPATH includes both classes and test-classes); this will cause conflicting definitions of the persistence unit, resulting in the dreaded annoying message that we all hate so much!
Worse: this may "work" with some older versions of e.g., Hibernate, but fail with current versions. Worth getting it right anyway...
A bit too late but I got the same issue and fixed it switching schemalocation into schemaLocation in the persistence.xml file (line 1).
I have seen this error , for me the issue was there was a space in the absolute path of the persistance.xml , removal of the same helped me.
I was also facing the same issue when I was trying to get JPA entity manager configured in Tomcat 8. First I has an issue with the SystemException class not being found and hence the entityManagerFactory was not being created. I removed the hibernate entity manager dependency and then my entityManagerFactory was not able to lookup for the persistence provider. After going thru a lot of research and time got to know that hibernate entity manager is must to lookup for some configuration. Then put back the entity manager jar and then added JTA Api as a dependency and it worked fine.
my experience tells me that missing persistence.xml,will generate the same exception too.
i caught the same error msg today when i tried to run a jar package packed by ant.
when i used jar tvf to check the content of the jar file, i realized that "ant" forgot to pack the persistnece.xml for me.
after I manually repacked the jar file ,the error msg disappered.
so i believe maybe you should try simplely putting META-INF under src directory and placing your persistence.xml there.
I'm new to JPA and I'm having problems with the autogeneration of primary key values.
I have the following entity:
package jpatest.entities;
import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
#Entity
public class MyEntity implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
private String someProperty;
public String getSomeProperty() {
return someProperty;
}
public void setSomeProperty(String someProperty) {
this.someProperty = someProperty;
}
public MyEntity() {
}
public MyEntity(String someProperty) {
this.someProperty = someProperty;
}
#Override
public String toString() {
return "jpatest.entities.MyEntity[id=" + id + "]";
}
}
and the following main method in other class:
public static void main(String[] args) {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("JPATestPU");
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
MyEntity e = new MyEntity("some value");
em.persist(e); /* (exception thrown here) */
em.getTransaction().commit();
em.close();
emf.close();
}
This is my persistence unit:
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.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_1_0.xsd">
<persistence-unit name="JPATestPU" transaction-type="RESOURCE_LOCAL">
<provider>oracle.toplink.essentials.PersistenceProvider</provider>
<class>jpatest.entities.MyEntity</class>
<properties>
<property name="toplink.jdbc.user" value="..."/>
<property name="toplink.jdbc.password" value="..."/>
<property name="toplink.jdbc.url" value="jdbc:mysql://localhost:3306/jpatest"/>
<property name="toplink.jdbc.driver" value="com.mysql.jdbc.Driver"/>
<property name="toplink.ddl-generation" value="create-tables"/>
</properties>
</persistence-unit>
</persistence>
When I execute the program I get the following exception in the line marked with the proper comment:
Exception in thread "main" java.lang.IllegalArgumentException: Object: jpatest.entities.MyEntity[id=null] is not a known entity type.
at oracle.toplink.essentials.internal.sessions.UnitOfWorkImpl.registerNewObjectForPersist(UnitOfWorkImpl.java:3212)
at oracle.toplink.essentials.internal.ejb.cmp3.base.EntityManagerImpl.persist(EntityManagerImpl.java:205)
at jpatest.Main.main(Main.java:...)
What am I missing?
I ran into this same problem using NetBeans IDE 6.9.
Apparently, this is a known issue.
See
http://wiki.eclipse.org/EclipseLink/Development/JPA_2.0/metamodel_api#DI_101:_20100218:_Descriptor.javaClass_is_null_on_a_container_EM_for_a_specific_case.
Also see http://netbeans.org/bugzilla/show_bug.cgi?id=181068.
I added the last line below to persistence.xml and it fixed it for me.
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<!-- Add the following to work around exception issue -->
<exclude-unlisted-classes>false</exclude-unlisted-classes>
As Charles pointed out in his answer, the problem is not the id generation, but the persistence layer not finding the entity.
As you, I am also new to JPA. I have tried to write a "Hello World" JPA application using org.eclipse.persistence.jpa.PersistenceProvider when I got this error. The mentioned workaround also worked for me. Moreover, through trial-error I also found that to declare your entities, you must always anotate #entity in each entity and:
if you set exclude-unlisted-classes to true, you also have to list the entities within class elements in your persistence.xml
if you set exclude-unlisted-classes to false the persistence layer can find the entities regardles of the class element in your persistence.xml.
TopLink used to require you to explicitly set GenerationType.IDENTITY for MySQL, so change this and drop the database. Then try running your sample again. Further you might also want to explcitly set the database platform:
<property name="toplink.platform.class.name"
value="oracle.toplink.platform.database.MySQL4Platform"/>
Also I vaguely remember that you have to run Toplink using its Java agent in order to make it function properly with a resource local entitymanager.
I did however successfully run your example using EclipseLink (which you should use since Toplink is outdated). Only cavat was that I did not have MySQL server handy, so I ran it using H2. I used the following Maven pom.xml to resolve the dependencies:
<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>org.randompage</groupId>
<artifactId>sandbox</artifactId>
<packaging>jar</packaging>
<version>1.0</version>
<name>sandbox</name>
<repositories>
<repository>
<id>EclipseLink Repo</id>
<url>http://www.eclipse.org/downloads/download.php?r=1&nf=1&file=/rt/eclipselink/maven.repo</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>javax.persistence</groupId>
<artifactId>javax.persistence</artifactId>
<version>2.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>eclipselink</artifactId>
<version>2.0.0</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.2.130</version>
</dependency>
</dependencies>
</project>
and this 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">
<persistence-unit name="JPATestPU" transaction-type="RESOURCE_LOCAL">
<provider>
org.eclipse.persistence.jpa.PersistenceProvider
</provider>
<class>org.randompage.MyEntity</class>
<properties>
<property name="javax.persistence.jdbc.user" value="johndoe"/>
<property name="javax.persistence.jdbc.password" value="secret"/>
<property name="javax.persistence.jdbc.driver" value="org.h2.Driver"/>
<property name="javax.persistence.jdbc.url" value="jdbc:h2:~/.h2/testdb;FILE_LOCK=NO"/>
<property name="eclipselink.ddl-generation" value="create-tables"/>
<property name="eclipselink.logging.level" value="INFO"/>
</properties>
</persistence-unit>
</persistence>
With these settings your code ran as expected.
I use this syntax rather than type AUTO
#javax.persistence.Id
#javax.persistence.GeneratedValue(strategy = GenerationType.IDENTITY)
Then, I use the simple type "long" for ID's with a lowercase l :
private long taskID;
This may be unrelated, but I also specify a different table name for my entities:
#javax.persistence.Entity(name = "Tasks")
public class Task implements Serializable
I ran into the same exception, when deploying web applications to GlassFish v3 (which uses EclipseLink as its JPA provider). I am not sure it's the same scenario as above - but the explanation for this bug in my case might help others :-) - turns out there's a bug in EclipseLink, when running under OSGi (which is the case in GlassFish), which leads EclipseLink to hold on to an "old" version of the entity class when re-deploying, resulting in this exception. The bug report is here.
As far as I know, whenever I get this error, I just re-start glassfish. Works everytime.
if you are only getting this error in junit
try adding this in persistence.xml
<jar-file>file:../classes</jar-file>
You could try and leave the definition out of the persistnce.xml The Persistence provider should than scan all classes in the classpath for #Entity annotations.
I also have to add one other item to my persistence.xml when changing class/table defs so that the EM knows to build/update tables:
<property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema(SchemaAction='refresh')"/>
If I want a fresh start, I instead use:
<!--<property name="openjpa.jdbc.SynchronizeMappings"
value="buildSchema(SchemaAction='dropDB,add')"/>
-->
I noticed that in your persistence.xml schema management is only set to "create tables" as opposed to drop/create, or update
Check the class output folder of eclipse, sometimes you change the xml and it was not updated.
The combination of deployment from within NetBeans 8.2 on Glassfish 4.1 on a Maven project with the "Debug" function of a project can cause an outdated version to be re-deployed (unclear where the fault lies).
Stop GlassFish, delete [glassfish base]/glassfish/domains/[domain name]/generated/, restart and redeploy.