openjpa-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Christian Defoy" <christian.de...@gmail.com>
Subject Re: Persistence of EnumSet
Date Fri, 13 Jul 2007 18:17:13 GMT
Hi Patrick,

Thanks for the answer.  You guess correctly when you say that I want a
stringified version of my EnumSet. :)

I tried to simply mark it @Persistent instead of @PersistentCollection
but I got a different error message:

 org.apache.openjpa.util.MetaDataException: The type of field
"Shape.types" isn't supported by declared persistence strategy
"Persistent".  Please choose a different strategy.
	at org.apache.openjpa.persistence.AnnotationPersistenceMetaDataParser.parsePersistent(AnnotationPersistenceMetaDataParser.java:1351)
	at org.apache.openjpa.persistence.AnnotationPersistenceMetaDataParser.parseMemberAnnotations(AnnotationPersistenceMetaDataParser.java:952)
	at org.apache.openjpa.persistence.AnnotationPersistenceMetaDataParser.parseClassAnnotations(AnnotationPersistenceMetaDataParser.java:599)
	at org.apache.openjpa.persistence.AnnotationPersistenceMetaDataParser.parse(AnnotationPersistenceMetaDataParser.java:349)
	at org.apache.openjpa.persistence.PersistenceMetaDataFactory.load(PersistenceMetaDataFactory.java:227)
	at org.apache.openjpa.meta.MetaDataRepository.getMetaDataInternal(MetaDataRepository.java:421)
	at org.apache.openjpa.meta.MetaDataRepository.getMetaData(MetaDataRepository.java:277)
	at org.apache.openjpa.enhance.PCEnhancer.<init>(PCEnhancer.java:221)
	at org.apache.openjpa.enhance.PCEnhancer.<init>(PCEnhancer.java:194)
	at org.apache.openjpa.enhance.PCClassFileTransformer.transform(PCClassFileTransformer.java:127)
	at sun.instrument.TransformerManager.transform(TransformerManager.java:122)
	at sun.instrument.InstrumentationImpl.transform(InstrumentationImpl.java:155)
	at java.lang.ClassLoader.defineClass1(Native Method)
	at java.lang.ClassLoader.defineClass(ClassLoader.java:620)
	at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:124)
	at java.net.URLClassLoader.defineClass(URLClassLoader.java:260)
	at java.net.URLClassLoader.access$100(URLClassLoader.java:56)
	at java.net.URLClassLoader$1.run(URLClassLoader.java:195)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
	at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:268)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:251)
	at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:319)
	at java.lang.Class.forName0(Native Method)
	at java.lang.Class.forName(Class.java:242)
	at org.apache.openjpa.meta.MetaDataRepository.classForName(MetaDataRepository.java:1234)
	at org.apache.openjpa.meta.MetaDataRepository.loadPersistentTypes(MetaDataRepository.java:1222)
	at org.apache.openjpa.kernel.AbstractBrokerFactory.loadPersistentTypes(AbstractBrokerFactory.java:240)
	at org.apache.openjpa.kernel.AbstractBrokerFactory.newBroker(AbstractBrokerFactory.java:192)
	at org.apache.openjpa.kernel.DelegatingBrokerFactory.newBroker(DelegatingBrokerFactory.java:142)
	at org.apache.openjpa.persistence.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:190)
	at org.apache.openjpa.persistence.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:143)
	at org.apache.openjpa.persistence.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:55)
	at ShapeHelper.main(ShapeHelper.java:21)

Could it be that I need to specify something in my persistence.xml or
put annotations in my enum?  I tried a few variations but without
success...

Christian

On 7/13/07, Patrick Linskey <plinskey@gmail.com> wrote:
> Hi,
>
> Externalizers and factories apply to the entire instance, not to the
> innards of the collection. I think that you've got things in a bit of
> a hybrid state right now.
>
> First, the problem is happening because EnumSet is an abstract type.
> The only way to get EnumSet instances is by using the static methods
> in the EnumSet class. Sadly, this is in stark contrast to the
> contracts outlined in the Javadoc for java.util.Collection, and
> OpenJPA requires compliance with some of those contracts. Put more
> simply, OpenJPA does not natively support EnumSet at this time. IMO,
> it would be worthwhile to add support for EnumSet (and EnumMap) at
> some point. However, this might be difficult / limiting due to the
> lack of extensibility of the EnumSet type and its subtypes.
>
> So, in terms of a solution: how do you want this data to be mapped to
> the database? Are you looking to have a single column in a table that
> contains the Stringified representation of the EnumSet, or are you
> looking to have a join table with rows for each Stringified enum value
> in the set? Given the method names in your externalizer and factory,
> I'm going to assume the former.
>
> In this case, the field is not really a persistent collection from
> OpenJPA's standpoint. You'll want to just mark it as @Persistent
> instead of @PersistentCollection. Once you've done this, one of two
> things will happen:
>
> 1. you will still get the second-class object problem
>
> or 2. it will work without an exception, but changes you make to the
> collection will not be noticed. If you set the field to a new value,
> the change will be detected, but mutations to the data structure
> itself will not. Currently, there is no way around this -- you'll need
> to explicitly dirty the field (OpenJPAEntityManager.dirty(o,
> "nameOfEnumSetField")) when you mutate the record.
>
>
> If you run into the first case, we'll need to change OpenJPA to allow
> bypassing of proxy logic somehow.
>
> Also, we should probably allow field-by-field enabling of a
> more-expensive dirty checking strategy so that you don't need to
> manually mark the field as dirty.
>
> -Patrick
>
> On 7/13/07, Christian Defoy <christian.defoy@gmail.com> wrote:
> > Hello!
> >
> > Is there a way to persist an EnumSet easily with OpenJPA?  I tried
> > with an externalizer:
> >
> >     @PersistentCollection
> >     @Externalizer( "test.Shape.typesToString" )
> >     @Factory( "test.Shape.typesFromString" )
> >     @ElementType( String.class )
> >     @Column( name="shape_types" )
> >     private EnumSet<ShapeTypes> types;
> >
> > When I try to run this, I get the following error message, which makes
> > me believe I am doing something wrong...
> >
> > Caused by: <0.9.7-incubating fatal general error>
> > org.apache.openjpa.persistence.PersistenceException: Unable to create
> > a second class object proxy for abstract type "class
> > java.util.EnumSet".  You must use a concrete type or a recognized
> > interface.
> >         at org.apache.openjpa.util.ProxyManagerImpl.toProxyableCollectionType(ProxyManagerImpl.java:320)
> >         at org.apache.openjpa.util.ProxyManagerImpl.newCollectionProxy(ProxyManagerImpl.java:191)
> >         at org.apache.openjpa.kernel.StateManagerImpl.newFieldProxy(StateManagerImpl.java:1571)
> >         at org.apache.openjpa.kernel.SingleFieldManager.proxy(SingleFieldManager.java:104)
> >         at org.apache.openjpa.kernel.StateManagerImpl.proxyFields(StateManagerImpl.java:2624)
> >         at org.apache.openjpa.kernel.PNonTransState.initialize(PNonTransState.java:44)
> >         at org.apache.openjpa.kernel.StateManagerImpl.setPCState(StateManagerImpl.java:213)
> >         at org.apache.openjpa.kernel.StateManagerImpl.commit(StateManagerImpl.java:919)
> >         at org.apache.openjpa.kernel.BrokerImpl.endTransaction(BrokerImpl.java:2194)
> >         ... 8 more
> >
> > Thanks in advance!
> >
> > Christian
> >
>
>
> --
> Patrick Linskey
> 202 669 5907
>

Mime
View raw message