JPA: java.lang.IllegalArgumentException: Not an entity - java

I wrote a simple Java that uses POJOs, servlets, JSPs. I am using:
Tomcat 7.0.16
Oracle 11g
Oracle Java build 1.6.0_26-b03
I use ivy to resolve my dependencies:
<dependency org="oracle" name="ojdbc6" rev="11g" conf="default -> default" />
<dependency org="org.hibernate" name="hibernate-commons-annotations" rev="3.2.0.Final" conf="compile -> runtime" />
<dependency org="org.hibernate" name="hibernate-annotations" rev="3.5.6-Final" conf="default -> runtime" />
<dependency org="org.hibernate" name="hibernate-core" rev="3.6.5.Final" conf="default -> runtime" />
<dependency org="org.hibernate" name="hibernate-validator" rev="4.0.2.GA" conf="runtime -> runtime" />
<dependency org="org.hibernate.javax.persistence" name="hibernate-jpa-2.0-api" rev="1.0.1.Final" conf="compile -> default" />
<dependency org="org.hibernate" name="hibernate-entitymanager" rev="3.6.5.Final" conf="compile -> default" />
My POJO Vehicle contains the following annotations:
import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Version;
#Entity
public class Vehicle implements Serializable{
/**
*
*/
private static final long serialVersionUID = 8560417193012227968L;
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private Long identifier;
private String serialNumber;
private String model;
private String manufacturer;
private int year;
private String condition;
#Version
private long version;
public Vehicle(){
}
When I run my code, I get the following:
2013-10-28 11:40:50 ERROR SqlVehicleService:42 - java.lang.IllegalArgumentException: Not an entity: class com.foo.demos.car.model.Vehicle
java.lang.IllegalArgumentException: Not an entity: class com.foo.demos.car.model.Vehicle
at org.hibernate.ejb.metamodel.MetamodelImpl.entity(MetamodelImpl.java:160)
at org.hibernate.ejb.criteria.QueryStructure.from(QueryStructure.java:138)
at org.hibernate.ejb.criteria.CriteriaQueryImpl.from(CriteriaQueryImpl.java:179)
at com.foo.demos.car.impl.SqlVehicleService.getVehicles(SqlVehicleService.java:37)
at org.apache.jsp.secured.vehicles_jsp._jspService(vehicles_jsp.java:194)
at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:419)
at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:389)
at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:333)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:304)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:240)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:164)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:572)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:164)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:563)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:403)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:301)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:162)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:309)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:662)
My persistence.xml does not contain any information about Vehicle. My understanding is that annotations are enough. Is that correct?
<?xml version="1.0" encoding="UTF-8"?>
<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="cardemo">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<!-- the JNDI data source -->
<non-jta-data-source>java:comp/env/jdbc/cardemo</non-jta-data-source>
<properties>
<property name="javax.persistence.validation.mode" value="NONE" />
<!-- if this is true, hibernate will print (to stdout) the SQL it executes,
so you can check it to ensure it"s not doing anything crazy -->
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.format_sql" value="true" />
<!-- since most database servers have slightly different versions of the
SQL, Hibernate needs you to choose a dialect so it knows the subtleties of
talking to that server -->
<property name="hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect" />
<!-- this tell Hibernate to update the DDL when it starts, very useful
for development, dangerous in production -->
<property name="hibernate.hbm2ddl.auto" value="update" />
</properties>
</persistence-unit>
</persistence>
I obviously overlooked something. What's that? What am I missing?

My persistence.xml does not contain any information about Vehicle. My understanding is that annotations are enough. Is that correct?
No, it's not. The entities must be listed in the persistence.xml file, under the persistence-unit element:
<class>com.foo.demos.car.model.Vehicle</class>

You need to give a hint to where the persistent entities can be found. I normally configure via Spring so don't have the exact info required however look here for some further discussion.
Do I need <class> elements in persistence.xml?

you can specify your entity locations via <property name="packagesToScan" value="" /> in the persistence.xml

My problem was that I created a SessionFactory like this:
Configuration configuration = new Configuration();
configuration.configure();
serviceRegistry = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties()).build();
sessionFactory = configuration.buildSessionFactory(serviceRegistry);
instead of like this:
Configuration configuration = new Configuration();
configuration.configure();
sessionFactory = configuration.buildSessionFactory();
When I replaced the former with the later, it worked! So be careful when using SessionFactory's initialization from tutorials.

If you dynamically build your persistence and add properties, you can declare entity classes using 'org.reflections:reflections:0.9.11':
new HibernatePersistenceProvider()
.createContainerEntityManagerFactory(
new javax.persistence.spi.PersistenceUnitInfoImpl(persistenceUnitName),
ImmutableMap.<String, Object>builder()
.put(AvailableSettings.LOADED_CLASSES, getEntities())
.build());
...
private List<Class<?>> getEntities() {
Set<Class<?>> entitiesInPackage = new Reflections("rf.dom.model")
.getTypesAnnotatedWith(Entity.class); // Annotated #Entity
List entities = new ArrayList<>(entitiesInPackage);
return entities;
}

Add packages-to-scan entry in your yml file.
jpa:
default:
packages-to-scan:
- 'com.foo.demos.car.model'
- 'your.entity.package.name'

Related

Ejb wont initialize entity manager

my english is not my native language so i am sorry in advanced for my poor english.
My project is working well when i manage the transaction with entity manager, entity factory and get transactions.
I want to use the ejb to handle the transactions for me.
I did every thing needed in order for it to work but the ejb wont initalized the entity manager and he will stay null.
i cant understand what i am doing wrong.
i have configured my persistance.xml with jta data source and did all the annotations needed but still cant get it to work.
what i try to create a query i get a null pointer exception and the entity manager is null.
I have been searching and looking for a solution but did not succeed.
I hope some one here can find the answer.
Thank you for you time!
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="swap" transaction-type="JTA">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<jta-data-source>java:jboss/datasources/swap</jta-data-source>
<class>org.Roper.WebService.Model.User</class>
<class>org.Roper.WebService.Model.BaseEntity</class>
<class>org.Roper.WebService.Model.Person</class>
<class>org.Roper.WebService.Model.Admin</class>
<class>org.Roper.WebService.Model.BusinessOwner</class>
<class>org.Roper.WebService.Model.Business</class>
<class>org.Roper.WebService.Model.Product</class>
<class>org.Roper.WebService.Model.Category</class>
<class>org.Roper.WebService.Model.Tourist</class>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<properties>
<!-- Hibernate properties -->
<property name="javax.persistence.jdbc.driver"
value="org.postgresql.Driver" /> <!-- DB Driver -->
<property name="hibernate.hbm2ddl.auto" value="update" />
<property name="hibernate.connection.zeroDateTimeBehavior"
value="convertToNull" />
<property name="hibernate.show_sql" value="false" />
<property name="hibernate.format_sql" value="true" />
<property name="hibernate.dialect"
value="org.hibernate.dialect.PostgreSQLDialect" />
<property name="hibernate.transaction.jta.platform"
value="org.hibernate.service.jta.platform.internal.JBossStandAloneJtaPlatform" />
<!-- Database properties -->
<property name="javax.persistence.jdbc.url"
value="jdbc:postgresql://hidden/swap?useUnicode=yes&characterEncoding=UTF-8" /> <!-- BD Mane -->
<property name="javax.persistence.jdbc.user" value="hidden" /> <!-- DB User -->
<property name="javax.persistence.jdbc.password"
value="hidden" /> <!-- DB Password -->
</properties>
</persistence-unit>
</persistence>
This is the main class that call the ejb:
#Path("PersonService")
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON)
public class PersonResource {
private static final Logger logger = Logger.getLogger(PersonResource.class);
#EJB
PersonService personService = new PersonService();
#GET
#Path("/users")
public List<Person> getUsers(#BeanParam FilterBean fb)
{
logger.info("Getting all users.");
return personService.GetAllUsers();
}
}
this is the service class that call the entity managet:
#Stateless
#LocalBean
public class PersonService {
private static final Logger logger = Logger.getLogger(PersonService.class);
#PersistenceContext(unitName="swap")
public EntityManager em;
/**
*This function is querying the database selecting all the person entities.
*#return List of all the users from the database.
*/
public List<Person> GetAllUsers()
{
logger.debug("Starting to get all users.");
try {
try {
List<Person> users = em.createQuery("SELECT u FROM Person u").getResultList();
logger.info("Success, got all users.");
return new ArrayList<Person>(users);
}
catch(PersistenceException e)
{
if(e.getCause().getCause().getMessage().contains("ERROR: relation \"users\" does not exist"))
{
logger.info("No users in the database.");
}
else
{
logger.error("Error while getting users from the database, error: ", e);
}
}
}catch(Exception e)
{
logger.error("Cant get the users, error: ",e);
}
return null;
}
The datasource from the standalone-full.xml:
<subsystem xmlns="urn:jboss:domain:datasources:5.0">
<datasources>
<datasource jndi-name="java:jboss/datasources/swap" pool-name="swap" enabled="true" use-java-context="true">
<connection-url>jdbc:postgresql://127.0.0.1:5432/swap?useUnicode=yes&characterEncoding=UTF-8</connection-url>
<driver>org.postgresql</driver>
<security>
<user-name>postgres</user-name>
<password>postgres</password>
</security>
</datasource>
<drivers>
<driver name="org.postgresql" module="org.postgresql">
<driver-class>org.postgresql.Driver</driver-class>
<xa-datasource-class>org.postgresql.Driver</xa-datasource-class>
</driver>
</drivers>
</datasources>
</subsystem>
Following lines look suspicious:
#EJB
PersonService personService = new PersonService();
It should be either injected (so no = new PersonService();is needed) or created via constructor but that instance is not managed by any container and, as a consequence, no injection happens there and EntityManager em stays null.
Please update your code as follows:
#EJB
PersonService personService;
Beside that, Integrating JAX-RS with EJB Technology and CDI section of JavaEE 6 tutorial suggests that JAX-RS resources should be either EJBs themselves (so annotated with #Stateless or #Stateful) OR CDI beans (so annotated with #ApplicationScoped or #RequestScoped). I would suggest to add a #Stateless annotation on the PersonResource class itself.

Eclipselink: error writing objects to/retrieving objects from persistence database

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.

Getting "java.lang.UnsupportedOperationException:"

I created the small JPA project to persist a Student record. I use Oracle database. I use the OpenJPA as the JPa provider.
I have created the Table student and relevant sequences correctly.
Student Entity class
#Entity
#Table(name = "Student")
public class Student implements Serializable {
private int id;
private String name;
private static final long serialVersionUID = 1L;
public Student() {
super();
}
#Id
#Column(name = "ID")
#SequenceGenerator(name = "TRAIN_SEQ", sequenceName = "STUDENT_SEQ")
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "TRAIN_SEQ")
public int getId() {
return this.id;
}
public void setId(int id) {
this.id = id;
}
#Column(name = "NAME")
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
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="JPAOracleDemo">
<provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
<class>com.jpa.demo.model.Student</class>
<properties>
<property name="openjpa.ConnectionURL" value="jdbc:oracle:thin:#TEST:50111:TESTPEGAD1" />
<property name="openjpa.ConnectionDriverName" value="oracle.jdbc.driver.OracleDriver" />
<property name="openjpa.ConnectionUserName" value="admin" />
<property name="openjpa.ConnectionPassword" value="admin" />
<property name="openjpa.RuntimeUnenhancedClasses" value="supported" />
<property name="openjpa.jdbc.Schema" value="MYSCHEMA" />
</properties>
</persistence-unit>
</persistence>
Client Class
OpenJPAEntityManager em = JPAUtil.getEntityManager();
OpenJPAEntityTransaction tx = em.getTransaction();
tx.begin();
// Create the instance of Employee Entity class
Student student = new Student();
student.setName("A.Ramesh");
// JPA API to store the Student instance on the database.
em.persist(student);
tx.commit();
em.close();
System.out.println("Done...");
Util class
private static OpenJPAEntityManagerFactory emf = OpenJPAPersistence
.createEntityManagerFactory("JPAOracleDemo", "META-INF/persistence.xml");
private static OpenJPAEntityManager entManager;
/**
* No need to create any instance for this Util.
*/
private JPAUtil() {
}
/**
* Get {#link EntityManager}.
*
* #return the {#link EntityManager}
*/
public static OpenJPAEntityManager getEntityManager() {
if (entManager == null || !entManager.isOpen()) {
entManager = emf.createEntityManager();
}
return entManager;
}
The data persist in the student table successfully, but I have the bellow error
Exception in thread "Attachment 60230" java.lang.UnsupportedOperationException: cannot get the capability, performing dispose of the retransforming environment
at com.ibm.tools.attach.javaSE.Attachment.loadAgentLibraryImpl(Native Method)
at com.ibm.tools.attach.javaSE.Attachment.loadAgentLibrary(Attachment.java:253)
at com.ibm.tools.attach.javaSE.Attachment.parseLoadAgent(Attachment.java:235)
at com.ibm.tools.attach.javaSE.Attachment.doCommand(Attachment.java:154)
at com.ibm.tools.attach.javaSE.Attachment.run(Attachment.java:116)
Exception in thread "main" java.lang.UnsupportedOperationException: cannot get the capability, performing dispose of the retransforming environment
at sun.instrument.InstrumentationImpl.isRetransformClassesSupported0(Native Method)
at sun.instrument.InstrumentationImpl.isRetransformClassesSupported(InstrumentationImpl.java:124)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:48)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:37)
at java.lang.reflect.Method.invoke(Method.java:600)
at org.apache.openjpa.enhance.ClassRedefiner.canRedefineClasses(ClassRedefiner.java:123)
at org.apache.openjpa.enhance.ManagedClassSubclasser.prepareUnenhancedClasses(ManagedClassSubclasser.java:122)
at org.apache.openjpa.kernel.AbstractBrokerFactory.loadPersistentTypes(AbstractBrokerFactory.java:304)
at org.apache.openjpa.kernel.AbstractBrokerFactory.initializeBroker(AbstractBrokerFactory.java:228)
at org.apache.openjpa.kernel.AbstractBrokerFactory.newBroker(AbstractBrokerFactory.java:202)
at org.apache.openjpa.kernel.DelegatingBrokerFactory.newBroker(DelegatingBrokerFactory.java:156)
at org.apache.openjpa.persistence.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:213)
at com.ibm.ws.persistence.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:45)
at com.ibm.ws.persistence.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:30)
at com.jpa.demo.util.JPAUtil.getEntityManager(JPAUtil.java:32)
at com.jpa.demo.client.JPAClient.main(JPAClient.java:13)
1045 JPAOracleDemo INFO [main] openjpa.Enhance - Creating subclass for "[class com.jpa.demo.model.Student]". This means that your application will be less efficient and will consume more memory than it would if you ran the OpenJPA enhancer. Additionally, lazy loading will not be available for one-to-one and many-to-one persistent attributes in types using field access; they will be loaded eagerly instead.
Done...
Java version
JDK 1.6
Anybody please let me know what is the issue here?
Updated:
I used the IBM Rational Software Architect for Websphere Software for this development. this problem is with this IDE. When I create the JPA project by default it adds the IBM jre. I just removed the IBM jre and tried with the SUN jre then it was success. Please let me know why this function does not support with IBM jre?
<property name="openjpa.RuntimeUnenhancedClasses" value="supported" />
For starters, get rid of that property.
This is my enhancer template, this works properly for OPENJPA:
`
<path id="enhance.cp">
<pathelement location="${basedir}${file.separator}${build.dir}" />
<fileset dir="${basedir}${file.separator}ext_libs/">
<include name="**/*.jar" />
</fileset>
</path>
<property name="cp" refid="enhance.cp" />
<target name="openjpa.libs.check" unless="openjpa.libs">
<fail message="Please set -Dopenjpa.libs in your builder configuration!" />
</target>
<target name="build.dir.check" unless="build.dir">
<fail message="Please set -Dbuild.dir in your builder configuration!" />
</target>
<target name="enhance" depends="openjpa.libs.check, build.dir.check">
<echo message="${cp}" />
<taskdef name="openjpac" classname="org.apache.openjpa.ant.PCEnhancerTask">
<classpath refid="enhance.cp" />
</taskdef>
<openjpac>
<classpath refid="enhance.cp" />
<configpropertiesFile="${basedir}${file.separator}src${file.separator}main${file.separator} resources${file.separator}META-INF${file.separator}persistence.xml" />
</openjpac>
</target>
`
The JPA spec requires some type of monitoring of Entity objects, but the spec does not define how to implement this monitoring. Some JPA providers auto-generate new subclasses or proxy objects that front the user's Entity objects at runtime, while others use byte-code weaving technologies to enhance the actual Entity class objects. OpenJPA supports both mechanisms, but strongly suggests only using the byte-code weaving enhancement. The subclassing support (as provided by OpenJPA) is not recommended (and is disabled by default in OpenJPA 2.0 and beyond).(Source: http://openjpa.apache.org/entity-enhancement.html)
The cause of this issue is I used the subclassing support for the entity enhancement but that is disabled by default in OpenJPA2.0 and beyond.
I found the solution for this issue. We have to enhance the entity class at run time by providing a javaagent when launching the JVM that OpenJPA is going run in.
I put something like the following as a JVM argument
-javaagent:C:/OpenJPA/apache-openjpa-2.0.0/openjpa-2.0.0.jar
And I removed the bellow line from persistence.xml
<property name="openjpa.RuntimeUnenhancedClasses" value="supported" />
Working persistence.xml
<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="DataSourceDemo">
<jta-data-source>oracleDS</jta-data-source>
<class>com.auditlog.model.BatchPrint</class>
<properties>
<property name="openjpa.ConnectionUserName" value="admin" />
<property name="openjpa.ConnectionPassword" value="test" />
<property name="openjpa.jdbc.Schema" value="defaultScheme" />
</properties>
</persistence-unit>
</persistence>

No autodetection of JPA Entities in maven-verify

If I put the persistence.xml in the src/test/META-INF folder, autodetection the Entities does not work with maven-verify. When the persistence.xml is located in the src/main/META-INF folder it works.
Running the tests in eclipse works in both cases.
Is there a way to get autodetection to work for maven-verify when the persistence.xml is located in the src/test Folder?
persistence.xml:
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="1.0">
<persistence-unit name="Unit" transaction-type="RESOURCE_LOCAL">
<properties>
<!-- Scan for annotated classes and Hibernate mapping XML files -->
<property name="hibernate.archive.autodetection" value="class" />
</properties>
</persistence-unit>
</persistence>
By default autodetection works for entities in the same classpath item as persistence.xml. It can be configured by <jar-file> elements.
To enable correct autodetection when persistence.xml is in src/test/resources/META-INF I use the following trick:
persistence.xml:
<persistence ...>
<persistence-unit ...>
<jar-file>${project.build.outputDirectory}</jar-file>
...
</persistence-unit>
</persistence>
pom.xml - enable resource filtering for src/test/resources:
<project ...>
...
<build>
<testResources>
<testResource>
<directory>src/test/resources</directory>
<filtering>true</filtering>
</testResource>
</testResources>
</build>
</project>
Though I'm not sure how to use it if your persistence.xml is actually in src/test/META-INF.
If you use Spring Framework you can do the following with a PersistenceUnitPostProcessor
CustomPersistenceUnitPostProcessor:
package com.yourpackage.utils.jpa.CustomPersistenceUnitPostProcessor;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.persistence.Entity;
import net.sourceforge.stripes.util.ResolverUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.orm.jpa.persistenceunit.MutablePersistenceUnitInfo;
import org.springframework.orm.jpa.persistenceunit.PersistenceUnitPostProcessor;
/**
* This PersistenceUnitPostProcessor is used to search given package list for JPA
* entities and add them as managed entities. By default the JPA engine searches
* for persistent classes only in the same class-path of the location of the
* persistence.xml file. When running unit tests the entities end up in test-classes
* folder which does not get scanned. To avoid specifying each entity in the persistence.xml
* file to scan, this post processor automatically adds the entities for you.
*
*/
public class CustomPersistenceUnitPostProcessor implements PersistenceUnitPostProcessor, InitializingBean {
private static final Logger log = LoggerFactory.getLogger(CustomPersistenceUnitPostProcessor.class);
/** the path of packages to search for persistent classes (e.g. org.springframework). Subpackages will be visited, too */
private List<String> packages;
/** the calculated list of additional persistent classes */
private Set<Class<? extends Object>> persistentClasses;
/**
* Looks for any persistent class in the class-path under the specified packages
*/
#Override
public void afterPropertiesSet() throws Exception {
if (packages == null || packages.isEmpty())
throw new IllegalArgumentException("packages property must be set");
log.debug("Looking for #Entity in " + packages);
persistentClasses = new HashSet<Class<? extends Object>>();
for (String p : packages) {
ResolverUtil<Object> resolver = new ResolverUtil<Object>();
ClassLoader cl = this.getClass().getClassLoader();
log.debug("Using classloader: " + cl);
resolver.setClassLoader(cl);
resolver.findAnnotated(Entity.class, p);
Set<Class<? extends Object>> classes = resolver.getClasses();
log.debug("Annotated classes: " + classes);
persistentClasses.addAll(classes);
}
if (persistentClasses.isEmpty())
throw new IllegalArgumentException("No class annotated with #Entity found in: " + packages);
}
/**
* Add all the persistent classes found to the PersistentUnit
*/
#Override
public void postProcessPersistenceUnitInfo(MutablePersistenceUnitInfo persistenceUnitInfo) {
for (Class<? extends Object> c : persistentClasses)
persistenceUnitInfo.addManagedClassName(c.getName());
}
public void setPackages(List<String> packages) {
this.packages = packages;
}
}
Spring Config:
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="thePersistenceUnitName" />
<property name="persistenceXmlLocation" value="classpath:META-INF/persistence.xml" />
<!-- reference to the XA datasource -->
<property name="dataSource" ref="theDataSource" />
<property name="persistenceUnitPostProcessors">
<list>
<!-- custom implementation to avoid xml entity class declarations -->
<bean class="com.yourpackage.utils.jpa.CustomPersistenceUnitPostProcessor">
<property name="packages">
<list value-type="java.lang.String">
<value>com.yourpackage.model</value>
</list>
</property>
</bean>
</list>
</property>
</bean>
persistence.xml:
<?xml version="1.0" encoding="UTF-8"?> <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="thePersistenceUnitName" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<properties>
<property name="hibernate.format_sql" value="false" />
<property name="hibernate.show_sql" value="false" />
<property name="hibernate.use_sql_comments" value="false" />
<property name="hibernate.generate_ddl" value="false" />
<property name="hibernate.database_platform" value="org.hibernate.dialect.MySQLInnoDBDialect" />
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLInnoDBDialect" />
</persistence-unit>
</persistence>

JPA exception: Object: ... is not a known entity type

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=&apos;refresh&apos;)"/>
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.

Categories

Resources