Hi,
thanks for your reply. I found your documentation pretty good. I
came across the RuntimeUnenhancedClasses property but overlooked the
UN of Unenhanced and thus didn't give it a try.
However the adjusted example (see attachment) still gives me:
The type "...Person" has not been enhanced.
- the properties passed to Persistence.createEntityManagerFactory()
now have the openjpa.RuntimeUnenhancedClasses=supported
setting.
- on the MetaDataRepsoitory of the EntityManagerFactory, I
call addMetaData( Person.class ).
what else am I missing?
Cheers,
Rüdiger
Pinaki Poddar wrote:
Hi,
The configuration property name is "openjpa.RuntimeUnenhancedClasses" and
possible values are "supported", "unsupported" and "warn". With "supported",
OpenJPA will be able to work with normal user-defined classes i.e. without
any byte-code enhancement.
MetaDataRepository#addMetaData() or
MetaDataRepository#addPersistenceAware() (no idea what the
difference is)
PersistenceCapable refers to classes that are managed by JPA provider. To
manage them properly, JPA provider needs to intercept any read/write access
to fields of PersistenceCapable class. Different techniques (e.g. proxying,
subclassing, byte-code enhancement) can be used to intercept without
impacting user-defined classes. OpenJPA traditionally used build-time (i.e.
post-compile, pre-runtime) byte-code enhancement as the only mechanics for
interception. Later, more choices have been added that allows you to choose
when byte-code enhancement takes place [1] or even using other technique
such as subclassing rather than byte-code enhancement [2].
PersistenceAware refers to classes that *directly* access/mutate fields of
PersistenceCapable instances. This can happen when fields of
PersistenceCapable classes are declared at public or package level access.
OpenJPA requires PersistenceAware classes also to be enhanced.
I couldn't find further information on how to disable class enhancement.
This is not good news for our documentation effort :)
[1]
http://openjpa.apache.org/docs/latest/manual/manual.html#ref_guide_pc_enhance
[2]
http://openjpa.apache.org/docs/latest/manual/manual.html#ref_guide_pc_enhance_unenhanced_types
Rüdiger Herrmann wrote:
Hi,
using OpenJPA in a JavaSE (Eclipse RCP) environment, I would like to
register JPA-annotated classes that will participate in the
persistence mechanism at runtime.
Background:
Presistence-aware classes are contributed via Eclipse Extension
Points. All these classes have JPA annotations.
Furthermore I don't want to use class enhancement as I don't have
control over the VM startup parameters (like -javaagent) in which
the application is running in.
Though there seems to be an effort to make class enhancement
optional ([1]), I couldn't find further information on how to
disable class enhancement.
I played around with the attached code (persist one instance of
class Person that has no further dependencies/references) but I
couldn't get it to work.
The various attempts resulted either in
Attempt to cast instance "...Person..." to
PersistenceCapable failed. Ensure that it
has been enhanced.
or
The type "class org.example.openjpatest.Person"
has not been enhanced.
depending on wether I called MetaDataRepository#addMetaData() or
MetaDataRepository#addPersistenceAware() (no idea what the
difference is) and wether I called mernge() before persist().
If desired I can send the full (Eclipse) project with all required
jars (HSQL, OpenJPA plus dependencies, JTA) that runs out-of-the-box.
Thanks in advance
Rüdiger
[1] https://issues.apache.org/jira/browse/OPENJPA-293
package org.example.openjpatest;
import java.util.HashMap;
import java.util.Map;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import org.apache.openjpa.meta.MetaDataRepository;
import org.apache.openjpa.persistence.EntityManagerFactoryImpl;
public class NoEnhancerExample {
public static void main( String[] args ) {
NoEnhancerExample example = new NoEnhancerExample();
EntityManagerFactory factory = example.createEntityManagerFactory();
EntityManager manager = factory.createEntityManager();
Person person = new Person();
person.setName( "first person" );
manager.merge( person );
manager.persist( person );
factory.close();
}
private EntityManagerFactory createEntityManagerFactory() {
Map<String, String> properties = new HashMap<String, String>();
properties.put( "openjpa.ConnectionUserName", "sa" );
properties.put( "openjpa.ConnectionPassword", "" );
properties.put( "openjpa.ConnectionURL",
"jdbc:hsqldb:mem:SqlModelStore_Test" );
properties.put( "openjpa.ConnectionDriverName",
"org.hsqldb.jdbcDriver" );
properties.put( "openjpa.ConnectionFactoryProperties",
"PrettyPrint=true, PrettyPrintLineLength=80" );
properties.put( "openjpa.Log",
"DefaultLevel=WARN, Runtime=INFO, Tool=INFO,
SQL=TRACE" );
EntityManagerFactory result
= Persistence.createEntityManagerFactory( "model", properties );
initOpenJpa( result );
return result;
}
private void initOpenJpa( EntityManagerFactory factory ) {
EntityManagerFactoryImpl factoryImpl
= ( EntityManagerFactoryImpl )factory;
MetaDataRepository metaDataRepository
= factoryImpl.getConfiguration().getMetaDataRepositoryInstance();
// metaDataRepository.addPersistenceAware( Person.class );
metaDataRepository.addMetaData( Person.class );
}
}
package org.example.openjpatest;
import java.util.UUID;
import javax.persistence.Entity;
import javax.persistence.Id;
@Entity
public class Person {
@Id
private String id;
private String name;
public Person() {
id = UUID.randomUUID().toString();
}
public String getId() {
return id;
}
public void setName( String name ) {
this.name = name;
}
public String getName() {
return name;
}
}
package org.example.openjpatest;
import java.util.HashMap;
import java.util.Map;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import org.apache.openjpa.meta.MetaDataRepository;
import org.apache.openjpa.persistence.EntityManagerFactoryImpl;
public class NoEnhancerExample {
public static void main( String[] args ) {
NoEnhancerExample example = new NoEnhancerExample();
EntityManagerFactory factory = example.createEntityManagerFactory();
EntityManager manager = factory.createEntityManager();
Person person = new Person();
person.setName( "first person" );
manager.merge( person );
manager.persist( person );
factory.close();
}
private EntityManagerFactory createEntityManagerFactory() {
Map<String, String> properties = new HashMap<String, String>();
properties.put( "openjpa.RuntimeUnenhancedClasses", "supported" );
properties.put( "openjpa.ConnectionUserName", "sa" );
properties.put( "openjpa.ConnectionPassword", "" );
properties.put( "openjpa.ConnectionURL",
"jdbc:hsqldb:mem:SqlModelStore_Test" );
properties.put( "openjpa.ConnectionDriverName", "org.hsqldb.jdbcDriver" );
properties.put( "openjpa.ConnectionFactoryProperties",
"PrettyPrint=true, PrettyPrintLineLength=80" );
properties.put( "openjpa.Log",
"DefaultLevel=WARN, Runtime=INFO, Tool=INFO, SQL=TRACE" );
EntityManagerFactory result
= Persistence.createEntityManagerFactory( "model", properties );
initOpenJpa( result );
return result;
}
private void initOpenJpa( EntityManagerFactory factory ) {
EntityManagerFactoryImpl factoryImpl
= ( EntityManagerFactoryImpl )factory;
MetaDataRepository metaDataRepository
= factoryImpl.getConfiguration().getMetaDataRepositoryInstance();
// metaDataRepository.addPersistenceAware( Person.class );
metaDataRepository.addMetaData( Person.class );
}
}
package org.example.openjpatest;
import java.util.UUID;
import javax.persistence.Entity;
import javax.persistence.Id;
@Entity
public class Person {
@Id
private String id;
private String name;
public Person() {
id = UUID.randomUUID().toString();
}
public String getId() {
return id;
}
public void setName( String name ) {
this.name = name;
}
public String getName() {
return name;
}
}