You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@openjpa.apache.org by Krzysztof <ya...@gmail.com> on 2009/08/19 19:30:00 UTC

Re: Enum as a Key in a Map

Hello,
I'm reviving this as @MapKeyEnumerated has been introduced recently which
seemed addressing this issue.
Unfortunately, if I use enum as a key where Source is amended with following
annotation for the map:


        @OneToMany(mappedBy = "source",cascade={ CascadeType.ALL },fetch =
FetchType.LAZY, orphanRemoval = true)
        @MapKeyEnumerated(EnumType.ORDINAL)     
        @MapKey(name = "tsType") 	


objects are committed gracefully and generated data and schema looks ok, but
the exception reappears during retrieval:

java.lang.ClassCastException: TSType cannot be cast to
org.apache.openjpa.util.ObjectId
    
gaia.cu7.omimpl.ClassificationResultsImpl.pcCopyKeyFieldsToObjectId(ClassificationResultsImpl.java)
    
org.apache.openjpa.enhance.PCRegistry.copyKeyFieldsToObjectId(PCRegistry.java:172)
    
org.apache.openjpa.util.ApplicationIds.fromPKValues(ApplicationIds.java:219)
    
org.apache.openjpa.jdbc.meta.ClassMapping.getObjectId(ClassMapping.java:216)
    
org.apache.openjpa.jdbc.meta.ClassMapping.getObjectId(ClassMapping.java:147)
    
org.apache.openjpa.jdbc.kernel.JDBCStoreManager.load(JDBCStoreManager.java:934)
    
org.apache.openjpa.jdbc.sql.AbstractResult.load(AbstractResult.java:280)
    
org.apache.openjpa.jdbc.sql.SelectImpl$SelectResult.load(SelectImpl.java:2349)
org.apache.openjpa.jdbc.meta.strats.RelationToManyInverseKeyFieldStrategy.loadElement(RelationToManyInverseKeyFieldStrategy.java:87)
org.apache.openjpa.jdbc.meta.strats.StoreCollectionFieldStrategy.load(StoreCollectionFieldStrategy.java:554)
     org.apache.openjpa.jdbc.meta.FieldMapping.load(FieldMapping.java:919)
    
org.apache.openjpa.jdbc.kernel.JDBCStoreManager.load(JDBCStoreManager.java:641)
    
org.apache.openjpa.kernel.DelegatingStoreManager.load(DelegatingStoreManager.java:116)
     org.apache.openjpa.kernel.ROPStoreManager.load(ROPStoreManager.java:78)
    
org.apache.openjpa.kernel.StateManagerImpl.loadFields(StateManagerImpl.java:3035)
    
org.apache.openjpa.kernel.StateManagerImpl.loadField(StateManagerImpl.java:3113)
    
org.apache.openjpa.kernel.StateManagerImpl.beforeAccessField(StateManagerImpl.java:1606)
    
org.apache.openjpa.kernel.StateManagerImpl.accessingField(StateManagerImpl.java:1591)
     Source.pcGetclassificationResultsMap(SourceImpl.java)


2.0.0 trunk version.

Is is possible to use enumeration as a Key in a directly mapped (no join
table), bidirectional Map? Anybody with a workaround?

Best regards,
Krzysztof


Krzysztof wrote:
> 
> Indeed, changing the map to be keyed on a plain type does not solve the
> problem until the owning 'source' field becomes plain type too.
> So,
> 
> <Source>
> ...
>         @OneToMany(mappedBy="source",cascade=CascadeType.ALL)
> 	@MapKey(name="tsType")
> 
> 	private Map<Integer, TSImpl> tsMap;
> ...
> </Source>
> <TSimpl>
>         @Id
>     	@Basic(optional=false)
> 	@Enumerated(EnumType.ORDINAL)
> 	@Column(name="tsType",updatable=false)
> 	private TSType tsType; //stays as enum, same exception thrown
> </TSImpl>
> gives exactly same cast exception, but if we change this part of Id to int
> it works. Also calling persist on root persists map elements properly.
> 	@Id
>         @Basic(optional=false)
> //	@Enumerated(EnumType.ORDINAL)
> 	@Column(name="tsType",updatable=false)
> //	private TSType tsType;
> 	private int tsType;
> 
> This is not really elegant and affects a lot of code. Could you please
> suggest any workaround so enum could be used as a key and is compatible
> with ObjectId? Annotating enum as Embeddable gives enhancer error and
> creating class wrapping an enum is also questionable in this particular
> case.
> 
> Best regards,
> Krzysztof
> 
> 
> 

-- 
View this message in context: http://n2.nabble.com/Enum-as-a-Key-in-a-Map-tp1639596p3474057.html
Sent from the OpenJPA Users mailing list archive at Nabble.com.

Re: Enum as a Key in a Map

Posted by Michael Dick <mi...@gmail.com>.
Hi Krysztof,

The update policy is "at least" nightly (when there are changes). I have a
couple of machines that do builds after every change and publish them to a
snapshot repository on people.apache.org. 

So the fix should be available now. The last build I published was revision
806022 which contains Fay's changes. 

Regards,
-mike



Krzysztof wrote:
> 
> Big thanks Fay!
> 
> Will it be included in the tomorrows snapshot in maven repository? - I am
> not sure about the repository update policy - is it a nightly build
> version there, isn't it? It would simplify deployment in our test
> environment.
> Best regards,
> Krzysztof
> 
> 
> Fay Wang wrote:
>> 
>> hi Krzysztof,
>>        I have checked the fix into the trunk (r-806011). Please extract
>> the fix, enhance your entities and run the test case again. Please let me
>> know if you still have problem.
>> 
>> Regards,
>> Fay
>> 
>> 
>> 
>> 
>> 
>> ----- Original Message ----
>> From: Krzysztof <ya...@gmail.com>
>> To: users@openjpa.apache.org
>> Sent: Wednesday, August 19, 2009 1:28:44 PM
>> Subject: Re: Enum as a Key in a Map
>> 
>> 
>> Thank you Fay,
>> Probably ApplicationIdTool could be updated as well - it actually creates
>> some code for such cases, but not digestible by the compiler.
>> Best regards,
>> Krzysztof
>> 
>> 
>> Fay Wang wrote:
>>> 
>>> Hi Krzysztof,
>>>     This is a generic problem in openjpa. If an entity, say EntityA, has
>>> an IdClass which contains an Enum type, and EntityB has a one-to-one
>>> relationship with EntityA. This problem will surface during retrieval of
>>> EntityA when doing the findBy for EntityB. Apparently there is a bug in
>>> the Enhancer code.  I will open a JIRA for this problem.
>>> 
>>> Regards,
>>> Fay
>>> 
>>> 
>>>  
>>> 
>>> 
>>> 
>>> ----- Original Message ----
>>> From: Krzysztof <ya...@gmail.com>
>>> To: users@openjpa.apache.org
>>> Sent: Wednesday, August 19, 2009 12:07:31 PM
>>> Subject: Re: Enum as a Key in a Map
>>> 
>>> 
>>> Thank you, 
>>> I just tried to add Id class to the enum as a dirty hack but it's not
>>> doable
>>> of course.
>>> Good luck!
>>> Krzysztof
>>> 
>>> 
>>> Fay Wang wrote:
>>>> 
>>>> Hi Krzysztof,
>>>>     Given your description below, I am able to reproduce this problem.
>>>> I
>>>> will take a look at it. Thanks!
>>>> 
>>>> Regards,
>>>> Fay
>>>> 
>>>> 
>>>> 
>>>> 
>>>> 
>>>> ----- Original Message ----
>>>> From: Krzysztof <ya...@gmail.com>
>>>> To: users@openjpa.apache.org
>>>> Sent: Wednesday, August 19, 2009 11:38:36 AM
>>>> Subject: Re: Enum as a Key in a Map
>>>> 
>>>> 
>>>> Thanks Kevin,
>>>> 
>>>> Certainly, I have checked your roadmap and the relevant JIRA issue,
>>>> also
>>>> test cases you have in the trunk - have not seen @MapKeyEnumerated used
>>>> with
>>>> @OneToMany though.
>>>> 
>>>> In the Id class of the child I kept enum as a field and used ordinal()
>>>> obviously. 
>>>> 
>>>> I'm debugging this now and can see that _key enum field of the oid
>>>> passed
>>>> to
>>>> pcCopyKeyFieldsToObjectId is null. As mentioned before, value in the DB
>>>> looks ok. 
>>>> 
>>>> After dissasembling public void pcCopyKeyFieldsToObjectId(FieldSupplier
>>>> fieldsupplier, Object obj)
>>>> of that class I can see that 
>>>> 
>>>>   TSimplId.tsType = (TSType)((ObjectId)fieldsupplier.fetchObjectField(2
>>>> +
>>>> i)).getId();
>>>> 
>>>> for some reason enum is treated as a composite Id and cast to ObjectId
>>>> fails?
>>>> 
>>>> 
>>>> 
>>>> Cheers,
>>>> Krzysztof
>>>> 
>>>> 
>>>> Kevin Sutter wrote:
>>>>> 
>>>>> Hi Krzysztof,
>>>>> The MapKeyEnumerated support was introduced as part of JPA 2.0.  It
>>>>> looks
>>>>> like this was committed via OPENJPA-1055.  I've pinged Fay (owner of
>>>>> the
>>>>> JIRA) to take a look to see if she has any ideas.  If you are
>>>>> interested
>>>>> in
>>>>> what's been done for JPA 2.0 already, you can reference our roadmap
>>>>> [1].
>>>>> I'm bringing this up in case you try some other JPA 2.0 items that
>>>>> haven't
>>>>> even been touched yet...  :-)
>>>>> 
>>>>> Thanks,
>>>>> Kevin
>>>>> 
>>>>> [1]  http://openjpa.apache.org/jpa-20-roadmap.html
>>>>> 
>>>>> On Wed, Aug 19, 2009 at 12:30 PM, Krzysztof <ya...@gmail.com> wrote:
>>>>> 
>>>>>>
>>>>>> Hello,
>>>>>> I'm reviving this as @MapKeyEnumerated has been introduced recently
>>>>>> which
>>>>>> seemed addressing this issue.
>>>>>> Unfortunately, if I use enum as a key where Source is amended with
>>>>>> following
>>>>>> annotation for the map:
>>>>>>
>>>>>>
>>>>>>        @OneToMany(mappedBy = "source",cascade={ CascadeType.ALL
>>>>>> },fetch
>>>>>> =
>>>>>> FetchType.LAZY, orphanRemoval = true)
>>>>>>        @MapKeyEnumerated(EnumType.ORDINAL)
>>>>>>        @MapKey(name = "tsType")
>>>>>>
>>>>>>
>>>>>> objects are committed gracefully and generated data and schema looks
>>>>>> ok,
>>>>>> but
>>>>>> the exception reappears during retrieval:
>>>>>>
>>>>>> java.lang.ClassCastException: TSType cannot be cast to
>>>>>> org.apache.openjpa.util.ObjectId
>>>>>>
>>>>>>
>>>>>> gaia.cu7.omimpl.ClassificationResultsImpl.pcCopyKeyFieldsToObjectId(ClassificationResultsImpl.java)
>>>>>>
>>>>>>
>>>>>> org.apache.openjpa.enhance.PCRegistry.copyKeyFieldsToObjectId(PCRegistry.java:172)
>>>>>>
>>>>>>
>>>>>> org.apache.openjpa.util.ApplicationIds.fromPKValues(ApplicationIds.java:219)
>>>>>>
>>>>>>
>>>>>> org.apache.openjpa.jdbc.meta.ClassMapping.getObjectId(ClassMapping.java:216)
>>>>>>
>>>>>>
>>>>>> org.apache.openjpa.jdbc.meta.ClassMapping.getObjectId(ClassMapping.java:147)
>>>>>>
>>>>>>
>>>>>> org.apache.openjpa.jdbc.kernel.JDBCStoreManager.load(JDBCStoreManager.java:934)
>>>>>>
>>>>>> org.apache.openjpa.jdbc.sql.AbstractResult.load(AbstractResult.java:280)
>>>>>>
>>>>>>
>>>>>> org.apache.openjpa.jdbc.sql.SelectImpl$SelectResult.load(SelectImpl.java:2349)
>>>>>>
>>>>>> org.apache.openjpa.jdbc.meta.strats.RelationToManyInverseKeyFieldStrategy.loadElement(RelationToManyInverseKeyFieldStrategy.java:87)
>>>>>>
>>>>>> org.apache.openjpa.jdbc.meta.strats.StoreCollectionFieldStrategy.load(StoreCollectionFieldStrategy.java:554)
>>>>>>    
>>>>>> org.apache.openjpa.jdbc.meta.FieldMapping.load(FieldMapping.java:919)
>>>>>>
>>>>>>
>>>>>> org.apache.openjpa.jdbc.kernel.JDBCStoreManager.load(JDBCStoreManager.java:641)
>>>>>>
>>>>>>
>>>>>> org.apache.openjpa.kernel.DelegatingStoreManager.load(DelegatingStoreManager.java:116)
>>>>>>
>>>>>> org.apache.openjpa.kernel.ROPStoreManager.load(ROPStoreManager.java:78)
>>>>>>
>>>>>>
>>>>>> org.apache.openjpa.kernel.StateManagerImpl.loadFields(StateManagerImpl.java:3035)
>>>>>>
>>>>>>
>>>>>> org.apache.openjpa.kernel.StateManagerImpl.loadField(StateManagerImpl.java:3113)
>>>>>>
>>>>>>
>>>>>> org.apache.openjpa.kernel.StateManagerImpl.beforeAccessField(StateManagerImpl.java:1606)
>>>>>>
>>>>>>
>>>>>> org.apache.openjpa.kernel.StateManagerImpl.accessingField(StateManagerImpl.java:1591)
>>>>>>     Source.pcGetclassificationResultsMap(SourceImpl.java)
>>>>>>
>>>>>>
>>>>>> 2.0.0 trunk version.
>>>>>>
>>>>>> Is is possible to use enumeration as a Key in a directly mapped (no
>>>>>> join
>>>>>> table), bidirectional Map? Anybody with a workaround?
>>>>>>
>>>>>> Best regards,
>>>>>> Krzysztof
>>>>>>
>>>>>>
>>>>>> Krzysztof wrote:
>>>>>> >
>>>>>> > Indeed, changing the map to be keyed on a plain type does not solve
>>>>>> the
>>>>>> > problem until the owning 'source' field becomes plain type too.
>>>>>> > So,
>>>>>> >
>>>>>> > <Source>
>>>>>> > ...
>>>>>> >         @OneToMany(mappedBy="source",cascade=CascadeType.ALL)
>>>>>> >       @MapKey(name="tsType")
>>>>>> >
>>>>>> >       private Map<Integer, TSImpl> tsMap;
>>>>>> > ...
>>>>>> > </Source>
>>>>>> > <TSimpl>
>>>>>> >         @Id
>>>>>> >       @Basic(optional=false)
>>>>>> >       @Enumerated(EnumType.ORDINAL)
>>>>>> >       @Column(name="tsType",updatable=false)
>>>>>> >       private TSType tsType; //stays as enum, same exception thrown
>>>>>> > </TSImpl>
>>>>>> > gives exactly same cast exception, but if we change this part of Id
>>>>>> to
>>>>>> int
>>>>>> > it works. Also calling persist on root persists map elements
>>>>>> properly.
>>>>>> >       @Id
>>>>>> >         @Basic(optional=false)
>>>>>> > //    @Enumerated(EnumType.ORDINAL)
>>>>>> >       @Column(name="tsType",updatable=false)
>>>>>> > //    private TSType tsType;
>>>>>> >       private int tsType;
>>>>>> >
>>>>>> > This is not really elegant and affects a lot of code. Could you
>>>>>> please
>>>>>> > suggest any workaround so enum could be used as a key and is
>>>>>> compatible
>>>>>> > with ObjectId? Annotating enum as Embeddable gives enhancer error
>>>>>> and
>>>>>> > creating class wrapping an enum is also questionable in this
>>>>>> particular
>>>>>> > case.
>>>>>> >
>>>>>> > Best regards,
>>>>>> > Krzysztof
>>>>>> >
>>>>>> >
>>>>>> >
>>>>>>
>>>>>> --
>>>>>> View this message in context:
>>>>>> http://n2.nabble.com/Enum-as-a-Key-in-a-Map-tp1639596p3474057.html
>>>>>> Sent from the OpenJPA Users mailing list archive at Nabble.com.
>>>>>>
>>>>> 
>>>>> 
>>>> 
>>>> -- 
>>>> View this message in context:
>>>> http://n2.nabble.com/Enum-as-a-Key-in-a-Map-tp1639596p3474458.html
>>>> Sent from the OpenJPA Users mailing list archive at Nabble.com.
>>>> 
>>>> 
>>>> 
>>>>      
>>>> 
>>>> 
>>> 
>>> -- 
>>> View this message in context:
>>> http://n2.nabble.com/Enum-as-a-Key-in-a-Map-tp1639596p3474663.html
>>> Sent from the OpenJPA Users mailing list archive at Nabble.com.
>>> 
>>> 
>>> 
>>>      
>>> 
>>> 
>> 
>> -- 
>> View this message in context:
>> http://n2.nabble.com/Enum-as-a-Key-in-a-Map-tp1639596p3475105.html
>> Sent from the OpenJPA Users mailing list archive at Nabble.com.
>> 
>> 
>> __________________________________________________
>> Do You Yahoo!?
>> Tired of spam?  Yahoo! Mail has the best spam protection around 
>> http://mail.yahoo.com 
>> 
>> 
> 
> 

-- 
View this message in context: http://n2.nabble.com/Enum-as-a-Key-in-a-Map-tp1639596p3480935.html
Sent from the OpenJPA Users mailing list archive at Nabble.com.

Re: Enum as a Key in a Map

Posted by Krzysztof <ya...@gmail.com>.
Big thanks Fay!

Will it be included in the tomorrows snapshot in maven repository? - I am
not sure about the repository update policy - is it a nightly build version
there, isn't it? It would simplify deployment in our test environment.
Best regards,
Krzysztof


Fay Wang wrote:
> 
> hi Krzysztof,
>        I have checked the fix into the trunk (r-806011). Please extract
> the fix, enhance your entities and run the test case again. Please let me
> know if you still have problem.
> 
> Regards,
> Fay
> 
> 
> 
> 
> 
> ----- Original Message ----
> From: Krzysztof <ya...@gmail.com>
> To: users@openjpa.apache.org
> Sent: Wednesday, August 19, 2009 1:28:44 PM
> Subject: Re: Enum as a Key in a Map
> 
> 
> Thank you Fay,
> Probably ApplicationIdTool could be updated as well - it actually creates
> some code for such cases, but not digestible by the compiler.
> Best regards,
> Krzysztof
> 
> 
> Fay Wang wrote:
>> 
>> Hi Krzysztof,
>>     This is a generic problem in openjpa. If an entity, say EntityA, has
>> an IdClass which contains an Enum type, and EntityB has a one-to-one
>> relationship with EntityA. This problem will surface during retrieval of
>> EntityA when doing the findBy for EntityB. Apparently there is a bug in
>> the Enhancer code.  I will open a JIRA for this problem.
>> 
>> Regards,
>> Fay
>> 
>> 
>>  
>> 
>> 
>> 
>> ----- Original Message ----
>> From: Krzysztof <ya...@gmail.com>
>> To: users@openjpa.apache.org
>> Sent: Wednesday, August 19, 2009 12:07:31 PM
>> Subject: Re: Enum as a Key in a Map
>> 
>> 
>> Thank you, 
>> I just tried to add Id class to the enum as a dirty hack but it's not
>> doable
>> of course.
>> Good luck!
>> Krzysztof
>> 
>> 
>> Fay Wang wrote:
>>> 
>>> Hi Krzysztof,
>>>     Given your description below, I am able to reproduce this problem. I
>>> will take a look at it. Thanks!
>>> 
>>> Regards,
>>> Fay
>>> 
>>> 
>>> 
>>> 
>>> 
>>> ----- Original Message ----
>>> From: Krzysztof <ya...@gmail.com>
>>> To: users@openjpa.apache.org
>>> Sent: Wednesday, August 19, 2009 11:38:36 AM
>>> Subject: Re: Enum as a Key in a Map
>>> 
>>> 
>>> Thanks Kevin,
>>> 
>>> Certainly, I have checked your roadmap and the relevant JIRA issue, also
>>> test cases you have in the trunk - have not seen @MapKeyEnumerated used
>>> with
>>> @OneToMany though.
>>> 
>>> In the Id class of the child I kept enum as a field and used ordinal()
>>> obviously. 
>>> 
>>> I'm debugging this now and can see that _key enum field of the oid
>>> passed
>>> to
>>> pcCopyKeyFieldsToObjectId is null. As mentioned before, value in the DB
>>> looks ok. 
>>> 
>>> After dissasembling public void pcCopyKeyFieldsToObjectId(FieldSupplier
>>> fieldsupplier, Object obj)
>>> of that class I can see that 
>>> 
>>>   TSimplId.tsType = (TSType)((ObjectId)fieldsupplier.fetchObjectField(2
>>> +
>>> i)).getId();
>>> 
>>> for some reason enum is treated as a composite Id and cast to ObjectId
>>> fails?
>>> 
>>> 
>>> 
>>> Cheers,
>>> Krzysztof
>>> 
>>> 
>>> Kevin Sutter wrote:
>>>> 
>>>> Hi Krzysztof,
>>>> The MapKeyEnumerated support was introduced as part of JPA 2.0.  It
>>>> looks
>>>> like this was committed via OPENJPA-1055.  I've pinged Fay (owner of
>>>> the
>>>> JIRA) to take a look to see if she has any ideas.  If you are
>>>> interested
>>>> in
>>>> what's been done for JPA 2.0 already, you can reference our roadmap
>>>> [1].
>>>> I'm bringing this up in case you try some other JPA 2.0 items that
>>>> haven't
>>>> even been touched yet...  :-)
>>>> 
>>>> Thanks,
>>>> Kevin
>>>> 
>>>> [1]  http://openjpa.apache.org/jpa-20-roadmap.html
>>>> 
>>>> On Wed, Aug 19, 2009 at 12:30 PM, Krzysztof <ya...@gmail.com> wrote:
>>>> 
>>>>>
>>>>> Hello,
>>>>> I'm reviving this as @MapKeyEnumerated has been introduced recently
>>>>> which
>>>>> seemed addressing this issue.
>>>>> Unfortunately, if I use enum as a key where Source is amended with
>>>>> following
>>>>> annotation for the map:
>>>>>
>>>>>
>>>>>        @OneToMany(mappedBy = "source",cascade={ CascadeType.ALL
>>>>> },fetch
>>>>> =
>>>>> FetchType.LAZY, orphanRemoval = true)
>>>>>        @MapKeyEnumerated(EnumType.ORDINAL)
>>>>>        @MapKey(name = "tsType")
>>>>>
>>>>>
>>>>> objects are committed gracefully and generated data and schema looks
>>>>> ok,
>>>>> but
>>>>> the exception reappears during retrieval:
>>>>>
>>>>> java.lang.ClassCastException: TSType cannot be cast to
>>>>> org.apache.openjpa.util.ObjectId
>>>>>
>>>>>
>>>>> gaia.cu7.omimpl.ClassificationResultsImpl.pcCopyKeyFieldsToObjectId(ClassificationResultsImpl.java)
>>>>>
>>>>>
>>>>> org.apache.openjpa.enhance.PCRegistry.copyKeyFieldsToObjectId(PCRegistry.java:172)
>>>>>
>>>>>
>>>>> org.apache.openjpa.util.ApplicationIds.fromPKValues(ApplicationIds.java:219)
>>>>>
>>>>>
>>>>> org.apache.openjpa.jdbc.meta.ClassMapping.getObjectId(ClassMapping.java:216)
>>>>>
>>>>>
>>>>> org.apache.openjpa.jdbc.meta.ClassMapping.getObjectId(ClassMapping.java:147)
>>>>>
>>>>>
>>>>> org.apache.openjpa.jdbc.kernel.JDBCStoreManager.load(JDBCStoreManager.java:934)
>>>>>
>>>>> org.apache.openjpa.jdbc.sql.AbstractResult.load(AbstractResult.java:280)
>>>>>
>>>>>
>>>>> org.apache.openjpa.jdbc.sql.SelectImpl$SelectResult.load(SelectImpl.java:2349)
>>>>>
>>>>> org.apache.openjpa.jdbc.meta.strats.RelationToManyInverseKeyFieldStrategy.loadElement(RelationToManyInverseKeyFieldStrategy.java:87)
>>>>>
>>>>> org.apache.openjpa.jdbc.meta.strats.StoreCollectionFieldStrategy.load(StoreCollectionFieldStrategy.java:554)
>>>>>    
>>>>> org.apache.openjpa.jdbc.meta.FieldMapping.load(FieldMapping.java:919)
>>>>>
>>>>>
>>>>> org.apache.openjpa.jdbc.kernel.JDBCStoreManager.load(JDBCStoreManager.java:641)
>>>>>
>>>>>
>>>>> org.apache.openjpa.kernel.DelegatingStoreManager.load(DelegatingStoreManager.java:116)
>>>>>
>>>>> org.apache.openjpa.kernel.ROPStoreManager.load(ROPStoreManager.java:78)
>>>>>
>>>>>
>>>>> org.apache.openjpa.kernel.StateManagerImpl.loadFields(StateManagerImpl.java:3035)
>>>>>
>>>>>
>>>>> org.apache.openjpa.kernel.StateManagerImpl.loadField(StateManagerImpl.java:3113)
>>>>>
>>>>>
>>>>> org.apache.openjpa.kernel.StateManagerImpl.beforeAccessField(StateManagerImpl.java:1606)
>>>>>
>>>>>
>>>>> org.apache.openjpa.kernel.StateManagerImpl.accessingField(StateManagerImpl.java:1591)
>>>>>     Source.pcGetclassificationResultsMap(SourceImpl.java)
>>>>>
>>>>>
>>>>> 2.0.0 trunk version.
>>>>>
>>>>> Is is possible to use enumeration as a Key in a directly mapped (no
>>>>> join
>>>>> table), bidirectional Map? Anybody with a workaround?
>>>>>
>>>>> Best regards,
>>>>> Krzysztof
>>>>>
>>>>>
>>>>> Krzysztof wrote:
>>>>> >
>>>>> > Indeed, changing the map to be keyed on a plain type does not solve
>>>>> the
>>>>> > problem until the owning 'source' field becomes plain type too.
>>>>> > So,
>>>>> >
>>>>> > <Source>
>>>>> > ...
>>>>> >         @OneToMany(mappedBy="source",cascade=CascadeType.ALL)
>>>>> >       @MapKey(name="tsType")
>>>>> >
>>>>> >       private Map<Integer, TSImpl> tsMap;
>>>>> > ...
>>>>> > </Source>
>>>>> > <TSimpl>
>>>>> >         @Id
>>>>> >       @Basic(optional=false)
>>>>> >       @Enumerated(EnumType.ORDINAL)
>>>>> >       @Column(name="tsType",updatable=false)
>>>>> >       private TSType tsType; //stays as enum, same exception thrown
>>>>> > </TSImpl>
>>>>> > gives exactly same cast exception, but if we change this part of Id
>>>>> to
>>>>> int
>>>>> > it works. Also calling persist on root persists map elements
>>>>> properly.
>>>>> >       @Id
>>>>> >         @Basic(optional=false)
>>>>> > //    @Enumerated(EnumType.ORDINAL)
>>>>> >       @Column(name="tsType",updatable=false)
>>>>> > //    private TSType tsType;
>>>>> >       private int tsType;
>>>>> >
>>>>> > This is not really elegant and affects a lot of code. Could you
>>>>> please
>>>>> > suggest any workaround so enum could be used as a key and is
>>>>> compatible
>>>>> > with ObjectId? Annotating enum as Embeddable gives enhancer error
>>>>> and
>>>>> > creating class wrapping an enum is also questionable in this
>>>>> particular
>>>>> > case.
>>>>> >
>>>>> > Best regards,
>>>>> > Krzysztof
>>>>> >
>>>>> >
>>>>> >
>>>>>
>>>>> --
>>>>> View this message in context:
>>>>> http://n2.nabble.com/Enum-as-a-Key-in-a-Map-tp1639596p3474057.html
>>>>> Sent from the OpenJPA Users mailing list archive at Nabble.com.
>>>>>
>>>> 
>>>> 
>>> 
>>> -- 
>>> View this message in context:
>>> http://n2.nabble.com/Enum-as-a-Key-in-a-Map-tp1639596p3474458.html
>>> Sent from the OpenJPA Users mailing list archive at Nabble.com.
>>> 
>>> 
>>> 
>>>      
>>> 
>>> 
>> 
>> -- 
>> View this message in context:
>> http://n2.nabble.com/Enum-as-a-Key-in-a-Map-tp1639596p3474663.html
>> Sent from the OpenJPA Users mailing list archive at Nabble.com.
>> 
>> 
>> 
>>      
>> 
>> 
> 
> -- 
> View this message in context:
> http://n2.nabble.com/Enum-as-a-Key-in-a-Map-tp1639596p3475105.html
> Sent from the OpenJPA Users mailing list archive at Nabble.com.
> 
> 
> __________________________________________________
> Do You Yahoo!?
> Tired of spam?  Yahoo! Mail has the best spam protection around 
> http://mail.yahoo.com 
> 
> 

-- 
View this message in context: http://n2.nabble.com/Enum-as-a-Key-in-a-Map-tp1639596p3480093.html
Sent from the OpenJPA Users mailing list archive at Nabble.com.

Re: Enum as a Key in a Map

Posted by Fay Wang <fy...@yahoo.com>.
hi Krzysztof,
       I have checked the fix into the trunk (r-806011). Please extract the fix, enhance your entities and run the test case again. Please let me know if you still have problem.

Regards,
Fay





----- Original Message ----
From: Krzysztof <ya...@gmail.com>
To: users@openjpa.apache.org
Sent: Wednesday, August 19, 2009 1:28:44 PM
Subject: Re: Enum as a Key in a Map


Thank you Fay,
Probably ApplicationIdTool could be updated as well - it actually creates
some code for such cases, but not digestible by the compiler.
Best regards,
Krzysztof


Fay Wang wrote:
> 
> Hi Krzysztof,
>     This is a generic problem in openjpa. If an entity, say EntityA, has
> an IdClass which contains an Enum type, and EntityB has a one-to-one
> relationship with EntityA. This problem will surface during retrieval of
> EntityA when doing the findBy for EntityB. Apparently there is a bug in
> the Enhancer code.  I will open a JIRA for this problem.
> 
> Regards,
> Fay
> 
> 
>  
> 
> 
> 
> ----- Original Message ----
> From: Krzysztof <ya...@gmail.com>
> To: users@openjpa.apache.org
> Sent: Wednesday, August 19, 2009 12:07:31 PM
> Subject: Re: Enum as a Key in a Map
> 
> 
> Thank you, 
> I just tried to add Id class to the enum as a dirty hack but it's not
> doable
> of course.
> Good luck!
> Krzysztof
> 
> 
> Fay Wang wrote:
>> 
>> Hi Krzysztof,
>>     Given your description below, I am able to reproduce this problem. I
>> will take a look at it. Thanks!
>> 
>> Regards,
>> Fay
>> 
>> 
>> 
>> 
>> 
>> ----- Original Message ----
>> From: Krzysztof <ya...@gmail.com>
>> To: users@openjpa.apache.org
>> Sent: Wednesday, August 19, 2009 11:38:36 AM
>> Subject: Re: Enum as a Key in a Map
>> 
>> 
>> Thanks Kevin,
>> 
>> Certainly, I have checked your roadmap and the relevant JIRA issue, also
>> test cases you have in the trunk - have not seen @MapKeyEnumerated used
>> with
>> @OneToMany though.
>> 
>> In the Id class of the child I kept enum as a field and used ordinal()
>> obviously. 
>> 
>> I'm debugging this now and can see that _key enum field of the oid passed
>> to
>> pcCopyKeyFieldsToObjectId is null. As mentioned before, value in the DB
>> looks ok. 
>> 
>> After dissasembling public void pcCopyKeyFieldsToObjectId(FieldSupplier
>> fieldsupplier, Object obj)
>> of that class I can see that 
>> 
>>   TSimplId.tsType = (TSType)((ObjectId)fieldsupplier.fetchObjectField(2 +
>> i)).getId();
>> 
>> for some reason enum is treated as a composite Id and cast to ObjectId
>> fails?
>> 
>> 
>> 
>> Cheers,
>> Krzysztof
>> 
>> 
>> Kevin Sutter wrote:
>>> 
>>> Hi Krzysztof,
>>> The MapKeyEnumerated support was introduced as part of JPA 2.0.  It
>>> looks
>>> like this was committed via OPENJPA-1055.  I've pinged Fay (owner of the
>>> JIRA) to take a look to see if she has any ideas.  If you are interested
>>> in
>>> what's been done for JPA 2.0 already, you can reference our roadmap [1].
>>> I'm bringing this up in case you try some other JPA 2.0 items that
>>> haven't
>>> even been touched yet...  :-)
>>> 
>>> Thanks,
>>> Kevin
>>> 
>>> [1]  http://openjpa.apache.org/jpa-20-roadmap.html
>>> 
>>> On Wed, Aug 19, 2009 at 12:30 PM, Krzysztof <ya...@gmail.com> wrote:
>>> 
>>>>
>>>> Hello,
>>>> I'm reviving this as @MapKeyEnumerated has been introduced recently
>>>> which
>>>> seemed addressing this issue.
>>>> Unfortunately, if I use enum as a key where Source is amended with
>>>> following
>>>> annotation for the map:
>>>>
>>>>
>>>>        @OneToMany(mappedBy = "source",cascade={ CascadeType.ALL },fetch
>>>> =
>>>> FetchType.LAZY, orphanRemoval = true)
>>>>        @MapKeyEnumerated(EnumType.ORDINAL)
>>>>        @MapKey(name = "tsType")
>>>>
>>>>
>>>> objects are committed gracefully and generated data and schema looks
>>>> ok,
>>>> but
>>>> the exception reappears during retrieval:
>>>>
>>>> java.lang.ClassCastException: TSType cannot be cast to
>>>> org.apache.openjpa.util.ObjectId
>>>>
>>>>
>>>> gaia.cu7.omimpl.ClassificationResultsImpl.pcCopyKeyFieldsToObjectId(ClassificationResultsImpl.java)
>>>>
>>>>
>>>> org.apache.openjpa.enhance.PCRegistry.copyKeyFieldsToObjectId(PCRegistry.java:172)
>>>>
>>>>
>>>> org.apache.openjpa.util.ApplicationIds.fromPKValues(ApplicationIds.java:219)
>>>>
>>>>
>>>> org.apache.openjpa.jdbc.meta.ClassMapping.getObjectId(ClassMapping.java:216)
>>>>
>>>>
>>>> org.apache.openjpa.jdbc.meta.ClassMapping.getObjectId(ClassMapping.java:147)
>>>>
>>>>
>>>> org.apache.openjpa.jdbc.kernel.JDBCStoreManager.load(JDBCStoreManager.java:934)
>>>>
>>>> org.apache.openjpa.jdbc.sql.AbstractResult.load(AbstractResult.java:280)
>>>>
>>>>
>>>> org.apache.openjpa.jdbc.sql.SelectImpl$SelectResult.load(SelectImpl.java:2349)
>>>>
>>>> org.apache.openjpa.jdbc.meta.strats.RelationToManyInverseKeyFieldStrategy.loadElement(RelationToManyInverseKeyFieldStrategy.java:87)
>>>>
>>>> org.apache.openjpa.jdbc.meta.strats.StoreCollectionFieldStrategy.load(StoreCollectionFieldStrategy.java:554)
>>>>    
>>>> org.apache.openjpa.jdbc.meta.FieldMapping.load(FieldMapping.java:919)
>>>>
>>>>
>>>> org.apache.openjpa.jdbc.kernel.JDBCStoreManager.load(JDBCStoreManager.java:641)
>>>>
>>>>
>>>> org.apache.openjpa.kernel.DelegatingStoreManager.load(DelegatingStoreManager.java:116)
>>>>
>>>> org.apache.openjpa.kernel.ROPStoreManager.load(ROPStoreManager.java:78)
>>>>
>>>>
>>>> org.apache.openjpa.kernel.StateManagerImpl.loadFields(StateManagerImpl.java:3035)
>>>>
>>>>
>>>> org.apache.openjpa.kernel.StateManagerImpl.loadField(StateManagerImpl.java:3113)
>>>>
>>>>
>>>> org.apache.openjpa.kernel.StateManagerImpl.beforeAccessField(StateManagerImpl.java:1606)
>>>>
>>>>
>>>> org.apache.openjpa.kernel.StateManagerImpl.accessingField(StateManagerImpl.java:1591)
>>>>     Source.pcGetclassificationResultsMap(SourceImpl.java)
>>>>
>>>>
>>>> 2.0.0 trunk version.
>>>>
>>>> Is is possible to use enumeration as a Key in a directly mapped (no
>>>> join
>>>> table), bidirectional Map? Anybody with a workaround?
>>>>
>>>> Best regards,
>>>> Krzysztof
>>>>
>>>>
>>>> Krzysztof wrote:
>>>> >
>>>> > Indeed, changing the map to be keyed on a plain type does not solve
>>>> the
>>>> > problem until the owning 'source' field becomes plain type too.
>>>> > So,
>>>> >
>>>> > <Source>
>>>> > ...
>>>> >         @OneToMany(mappedBy="source",cascade=CascadeType.ALL)
>>>> >       @MapKey(name="tsType")
>>>> >
>>>> >       private Map<Integer, TSImpl> tsMap;
>>>> > ...
>>>> > </Source>
>>>> > <TSimpl>
>>>> >         @Id
>>>> >       @Basic(optional=false)
>>>> >       @Enumerated(EnumType.ORDINAL)
>>>> >       @Column(name="tsType",updatable=false)
>>>> >       private TSType tsType; //stays as enum, same exception thrown
>>>> > </TSImpl>
>>>> > gives exactly same cast exception, but if we change this part of Id
>>>> to
>>>> int
>>>> > it works. Also calling persist on root persists map elements
>>>> properly.
>>>> >       @Id
>>>> >         @Basic(optional=false)
>>>> > //    @Enumerated(EnumType.ORDINAL)
>>>> >       @Column(name="tsType",updatable=false)
>>>> > //    private TSType tsType;
>>>> >       private int tsType;
>>>> >
>>>> > This is not really elegant and affects a lot of code. Could you
>>>> please
>>>> > suggest any workaround so enum could be used as a key and is
>>>> compatible
>>>> > with ObjectId? Annotating enum as Embeddable gives enhancer error and
>>>> > creating class wrapping an enum is also questionable in this
>>>> particular
>>>> > case.
>>>> >
>>>> > Best regards,
>>>> > Krzysztof
>>>> >
>>>> >
>>>> >
>>>>
>>>> --
>>>> View this message in context:
>>>> http://n2.nabble.com/Enum-as-a-Key-in-a-Map-tp1639596p3474057.html
>>>> Sent from the OpenJPA Users mailing list archive at Nabble.com.
>>>>
>>> 
>>> 
>> 
>> -- 
>> View this message in context:
>> http://n2.nabble.com/Enum-as-a-Key-in-a-Map-tp1639596p3474458.html
>> Sent from the OpenJPA Users mailing list archive at Nabble.com.
>> 
>> 
>> 
>>      
>> 
>> 
> 
> -- 
> View this message in context:
> http://n2.nabble.com/Enum-as-a-Key-in-a-Map-tp1639596p3474663.html
> Sent from the OpenJPA Users mailing list archive at Nabble.com.
> 
> 
> 
>      
> 
> 

-- 
View this message in context: http://n2.nabble.com/Enum-as-a-Key-in-a-Map-tp1639596p3475105.html
Sent from the OpenJPA Users mailing list archive at Nabble.com.


__________________________________________________
Do You Yahoo!?
Tired of spam?  Yahoo! Mail has the best spam protection around 
http://mail.yahoo.com 

Re: Enum as a Key in a Map

Posted by Krzysztof <ya...@gmail.com>.
Thank you Fay,
Probably ApplicationIdTool could be updated as well - it actually creates
some code for such cases, but not digestible by the compiler.
Best regards,
Krzysztof


Fay Wang wrote:
> 
> Hi Krzysztof,
>     This is a generic problem in openjpa. If an entity, say EntityA, has
> an IdClass which contains an Enum type, and EntityB has a one-to-one
> relationship with EntityA. This problem will surface during retrieval of
> EntityA when doing the findBy for EntityB. Apparently there is a bug in
> the Enhancer code.  I will open a JIRA for this problem.
> 
> Regards,
> Fay
> 
> 
>  
> 
> 
> 
> ----- Original Message ----
> From: Krzysztof <ya...@gmail.com>
> To: users@openjpa.apache.org
> Sent: Wednesday, August 19, 2009 12:07:31 PM
> Subject: Re: Enum as a Key in a Map
> 
> 
> Thank you, 
> I just tried to add Id class to the enum as a dirty hack but it's not
> doable
> of course.
> Good luck!
> Krzysztof
> 
> 
> Fay Wang wrote:
>> 
>> Hi Krzysztof,
>>     Given your description below, I am able to reproduce this problem. I
>> will take a look at it. Thanks!
>> 
>> Regards,
>> Fay
>> 
>> 
>> 
>> 
>> 
>> ----- Original Message ----
>> From: Krzysztof <ya...@gmail.com>
>> To: users@openjpa.apache.org
>> Sent: Wednesday, August 19, 2009 11:38:36 AM
>> Subject: Re: Enum as a Key in a Map
>> 
>> 
>> Thanks Kevin,
>> 
>> Certainly, I have checked your roadmap and the relevant JIRA issue, also
>> test cases you have in the trunk - have not seen @MapKeyEnumerated used
>> with
>> @OneToMany though.
>> 
>> In the Id class of the child I kept enum as a field and used ordinal()
>> obviously. 
>> 
>> I'm debugging this now and can see that _key enum field of the oid passed
>> to
>> pcCopyKeyFieldsToObjectId is null. As mentioned before, value in the DB
>> looks ok. 
>> 
>> After dissasembling public void pcCopyKeyFieldsToObjectId(FieldSupplier
>> fieldsupplier, Object obj)
>> of that class I can see that 
>> 
>>   TSimplId.tsType = (TSType)((ObjectId)fieldsupplier.fetchObjectField(2 +
>> i)).getId();
>> 
>> for some reason enum is treated as a composite Id and cast to ObjectId
>> fails?
>> 
>> 
>> 
>> Cheers,
>> Krzysztof
>> 
>> 
>> Kevin Sutter wrote:
>>> 
>>> Hi Krzysztof,
>>> The MapKeyEnumerated support was introduced as part of JPA 2.0.  It
>>> looks
>>> like this was committed via OPENJPA-1055.  I've pinged Fay (owner of the
>>> JIRA) to take a look to see if she has any ideas.  If you are interested
>>> in
>>> what's been done for JPA 2.0 already, you can reference our roadmap [1].
>>> I'm bringing this up in case you try some other JPA 2.0 items that
>>> haven't
>>> even been touched yet...  :-)
>>> 
>>> Thanks,
>>> Kevin
>>> 
>>> [1]  http://openjpa.apache.org/jpa-20-roadmap.html
>>> 
>>> On Wed, Aug 19, 2009 at 12:30 PM, Krzysztof <ya...@gmail.com> wrote:
>>> 
>>>>
>>>> Hello,
>>>> I'm reviving this as @MapKeyEnumerated has been introduced recently
>>>> which
>>>> seemed addressing this issue.
>>>> Unfortunately, if I use enum as a key where Source is amended with
>>>> following
>>>> annotation for the map:
>>>>
>>>>
>>>>        @OneToMany(mappedBy = "source",cascade={ CascadeType.ALL },fetch
>>>> =
>>>> FetchType.LAZY, orphanRemoval = true)
>>>>        @MapKeyEnumerated(EnumType.ORDINAL)
>>>>        @MapKey(name = "tsType")
>>>>
>>>>
>>>> objects are committed gracefully and generated data and schema looks
>>>> ok,
>>>> but
>>>> the exception reappears during retrieval:
>>>>
>>>> java.lang.ClassCastException: TSType cannot be cast to
>>>> org.apache.openjpa.util.ObjectId
>>>>
>>>>
>>>> gaia.cu7.omimpl.ClassificationResultsImpl.pcCopyKeyFieldsToObjectId(ClassificationResultsImpl.java)
>>>>
>>>>
>>>> org.apache.openjpa.enhance.PCRegistry.copyKeyFieldsToObjectId(PCRegistry.java:172)
>>>>
>>>>
>>>> org.apache.openjpa.util.ApplicationIds.fromPKValues(ApplicationIds.java:219)
>>>>
>>>>
>>>> org.apache.openjpa.jdbc.meta.ClassMapping.getObjectId(ClassMapping.java:216)
>>>>
>>>>
>>>> org.apache.openjpa.jdbc.meta.ClassMapping.getObjectId(ClassMapping.java:147)
>>>>
>>>>
>>>> org.apache.openjpa.jdbc.kernel.JDBCStoreManager.load(JDBCStoreManager.java:934)
>>>>
>>>> org.apache.openjpa.jdbc.sql.AbstractResult.load(AbstractResult.java:280)
>>>>
>>>>
>>>> org.apache.openjpa.jdbc.sql.SelectImpl$SelectResult.load(SelectImpl.java:2349)
>>>>
>>>> org.apache.openjpa.jdbc.meta.strats.RelationToManyInverseKeyFieldStrategy.loadElement(RelationToManyInverseKeyFieldStrategy.java:87)
>>>>
>>>> org.apache.openjpa.jdbc.meta.strats.StoreCollectionFieldStrategy.load(StoreCollectionFieldStrategy.java:554)
>>>>    
>>>> org.apache.openjpa.jdbc.meta.FieldMapping.load(FieldMapping.java:919)
>>>>
>>>>
>>>> org.apache.openjpa.jdbc.kernel.JDBCStoreManager.load(JDBCStoreManager.java:641)
>>>>
>>>>
>>>> org.apache.openjpa.kernel.DelegatingStoreManager.load(DelegatingStoreManager.java:116)
>>>>
>>>> org.apache.openjpa.kernel.ROPStoreManager.load(ROPStoreManager.java:78)
>>>>
>>>>
>>>> org.apache.openjpa.kernel.StateManagerImpl.loadFields(StateManagerImpl.java:3035)
>>>>
>>>>
>>>> org.apache.openjpa.kernel.StateManagerImpl.loadField(StateManagerImpl.java:3113)
>>>>
>>>>
>>>> org.apache.openjpa.kernel.StateManagerImpl.beforeAccessField(StateManagerImpl.java:1606)
>>>>
>>>>
>>>> org.apache.openjpa.kernel.StateManagerImpl.accessingField(StateManagerImpl.java:1591)
>>>>     Source.pcGetclassificationResultsMap(SourceImpl.java)
>>>>
>>>>
>>>> 2.0.0 trunk version.
>>>>
>>>> Is is possible to use enumeration as a Key in a directly mapped (no
>>>> join
>>>> table), bidirectional Map? Anybody with a workaround?
>>>>
>>>> Best regards,
>>>> Krzysztof
>>>>
>>>>
>>>> Krzysztof wrote:
>>>> >
>>>> > Indeed, changing the map to be keyed on a plain type does not solve
>>>> the
>>>> > problem until the owning 'source' field becomes plain type too.
>>>> > So,
>>>> >
>>>> > <Source>
>>>> > ...
>>>> >         @OneToMany(mappedBy="source",cascade=CascadeType.ALL)
>>>> >       @MapKey(name="tsType")
>>>> >
>>>> >       private Map<Integer, TSImpl> tsMap;
>>>> > ...
>>>> > </Source>
>>>> > <TSimpl>
>>>> >         @Id
>>>> >       @Basic(optional=false)
>>>> >       @Enumerated(EnumType.ORDINAL)
>>>> >       @Column(name="tsType",updatable=false)
>>>> >       private TSType tsType; //stays as enum, same exception thrown
>>>> > </TSImpl>
>>>> > gives exactly same cast exception, but if we change this part of Id
>>>> to
>>>> int
>>>> > it works. Also calling persist on root persists map elements
>>>> properly.
>>>> >       @Id
>>>> >         @Basic(optional=false)
>>>> > //    @Enumerated(EnumType.ORDINAL)
>>>> >       @Column(name="tsType",updatable=false)
>>>> > //    private TSType tsType;
>>>> >       private int tsType;
>>>> >
>>>> > This is not really elegant and affects a lot of code. Could you
>>>> please
>>>> > suggest any workaround so enum could be used as a key and is
>>>> compatible
>>>> > with ObjectId? Annotating enum as Embeddable gives enhancer error and
>>>> > creating class wrapping an enum is also questionable in this
>>>> particular
>>>> > case.
>>>> >
>>>> > Best regards,
>>>> > Krzysztof
>>>> >
>>>> >
>>>> >
>>>>
>>>> --
>>>> View this message in context:
>>>> http://n2.nabble.com/Enum-as-a-Key-in-a-Map-tp1639596p3474057.html
>>>> Sent from the OpenJPA Users mailing list archive at Nabble.com.
>>>>
>>> 
>>> 
>> 
>> -- 
>> View this message in context:
>> http://n2.nabble.com/Enum-as-a-Key-in-a-Map-tp1639596p3474458.html
>> Sent from the OpenJPA Users mailing list archive at Nabble.com.
>> 
>> 
>> 
>>      
>> 
>> 
> 
> -- 
> View this message in context:
> http://n2.nabble.com/Enum-as-a-Key-in-a-Map-tp1639596p3474663.html
> Sent from the OpenJPA Users mailing list archive at Nabble.com.
> 
> 
> 
>       
> 
> 

-- 
View this message in context: http://n2.nabble.com/Enum-as-a-Key-in-a-Map-tp1639596p3475105.html
Sent from the OpenJPA Users mailing list archive at Nabble.com.

Re: Enum as a Key in a Map

Posted by Fay Wang <fy...@yahoo.com>.
Hi Krzysztof,
    This is a generic problem in openjpa. If an entity, say EntityA, has an IdClass which contains an Enum type, and EntityB has a one-to-one relationship with EntityA. This problem will surface during retrieval of EntityA when doing the findBy for EntityB. Apparently there is a bug in the Enhancer code.  I will open a JIRA for this problem.

Regards,
Fay


 



----- Original Message ----
From: Krzysztof <ya...@gmail.com>
To: users@openjpa.apache.org
Sent: Wednesday, August 19, 2009 12:07:31 PM
Subject: Re: Enum as a Key in a Map


Thank you, 
I just tried to add Id class to the enum as a dirty hack but it's not doable
of course.
Good luck!
Krzysztof


Fay Wang wrote:
> 
> Hi Krzysztof,
>     Given your description below, I am able to reproduce this problem. I
> will take a look at it. Thanks!
> 
> Regards,
> Fay
> 
> 
> 
> 
> 
> ----- Original Message ----
> From: Krzysztof <ya...@gmail.com>
> To: users@openjpa.apache.org
> Sent: Wednesday, August 19, 2009 11:38:36 AM
> Subject: Re: Enum as a Key in a Map
> 
> 
> Thanks Kevin,
> 
> Certainly, I have checked your roadmap and the relevant JIRA issue, also
> test cases you have in the trunk - have not seen @MapKeyEnumerated used
> with
> @OneToMany though.
> 
> In the Id class of the child I kept enum as a field and used ordinal()
> obviously. 
> 
> I'm debugging this now and can see that _key enum field of the oid passed
> to
> pcCopyKeyFieldsToObjectId is null. As mentioned before, value in the DB
> looks ok. 
> 
> After dissasembling public void pcCopyKeyFieldsToObjectId(FieldSupplier
> fieldsupplier, Object obj)
> of that class I can see that 
> 
>   TSimplId.tsType = (TSType)((ObjectId)fieldsupplier.fetchObjectField(2 +
> i)).getId();
> 
> for some reason enum is treated as a composite Id and cast to ObjectId
> fails?
> 
> 
> 
> Cheers,
> Krzysztof
> 
> 
> Kevin Sutter wrote:
>> 
>> Hi Krzysztof,
>> The MapKeyEnumerated support was introduced as part of JPA 2.0.  It looks
>> like this was committed via OPENJPA-1055.  I've pinged Fay (owner of the
>> JIRA) to take a look to see if she has any ideas.  If you are interested
>> in
>> what's been done for JPA 2.0 already, you can reference our roadmap [1].
>> I'm bringing this up in case you try some other JPA 2.0 items that
>> haven't
>> even been touched yet...  :-)
>> 
>> Thanks,
>> Kevin
>> 
>> [1]  http://openjpa.apache.org/jpa-20-roadmap.html
>> 
>> On Wed, Aug 19, 2009 at 12:30 PM, Krzysztof <ya...@gmail.com> wrote:
>> 
>>>
>>> Hello,
>>> I'm reviving this as @MapKeyEnumerated has been introduced recently
>>> which
>>> seemed addressing this issue.
>>> Unfortunately, if I use enum as a key where Source is amended with
>>> following
>>> annotation for the map:
>>>
>>>
>>>        @OneToMany(mappedBy = "source",cascade={ CascadeType.ALL },fetch
>>> =
>>> FetchType.LAZY, orphanRemoval = true)
>>>        @MapKeyEnumerated(EnumType.ORDINAL)
>>>        @MapKey(name = "tsType")
>>>
>>>
>>> objects are committed gracefully and generated data and schema looks ok,
>>> but
>>> the exception reappears during retrieval:
>>>
>>> java.lang.ClassCastException: TSType cannot be cast to
>>> org.apache.openjpa.util.ObjectId
>>>
>>>
>>> gaia.cu7.omimpl.ClassificationResultsImpl.pcCopyKeyFieldsToObjectId(ClassificationResultsImpl.java)
>>>
>>>
>>> org.apache.openjpa.enhance.PCRegistry.copyKeyFieldsToObjectId(PCRegistry.java:172)
>>>
>>>
>>> org.apache.openjpa.util.ApplicationIds.fromPKValues(ApplicationIds.java:219)
>>>
>>>
>>> org.apache.openjpa.jdbc.meta.ClassMapping.getObjectId(ClassMapping.java:216)
>>>
>>>
>>> org.apache.openjpa.jdbc.meta.ClassMapping.getObjectId(ClassMapping.java:147)
>>>
>>>
>>> org.apache.openjpa.jdbc.kernel.JDBCStoreManager.load(JDBCStoreManager.java:934)
>>>
>>> org.apache.openjpa.jdbc.sql.AbstractResult.load(AbstractResult.java:280)
>>>
>>>
>>> org.apache.openjpa.jdbc.sql.SelectImpl$SelectResult.load(SelectImpl.java:2349)
>>>
>>> org.apache.openjpa.jdbc.meta.strats.RelationToManyInverseKeyFieldStrategy.loadElement(RelationToManyInverseKeyFieldStrategy.java:87)
>>>
>>> org.apache.openjpa.jdbc.meta.strats.StoreCollectionFieldStrategy.load(StoreCollectionFieldStrategy.java:554)
>>>    
>>> org.apache.openjpa.jdbc.meta.FieldMapping.load(FieldMapping.java:919)
>>>
>>>
>>> org.apache.openjpa.jdbc.kernel.JDBCStoreManager.load(JDBCStoreManager.java:641)
>>>
>>>
>>> org.apache.openjpa.kernel.DelegatingStoreManager.load(DelegatingStoreManager.java:116)
>>>
>>> org.apache.openjpa.kernel.ROPStoreManager.load(ROPStoreManager.java:78)
>>>
>>>
>>> org.apache.openjpa.kernel.StateManagerImpl.loadFields(StateManagerImpl.java:3035)
>>>
>>>
>>> org.apache.openjpa.kernel.StateManagerImpl.loadField(StateManagerImpl.java:3113)
>>>
>>>
>>> org.apache.openjpa.kernel.StateManagerImpl.beforeAccessField(StateManagerImpl.java:1606)
>>>
>>>
>>> org.apache.openjpa.kernel.StateManagerImpl.accessingField(StateManagerImpl.java:1591)
>>>     Source.pcGetclassificationResultsMap(SourceImpl.java)
>>>
>>>
>>> 2.0.0 trunk version.
>>>
>>> Is is possible to use enumeration as a Key in a directly mapped (no join
>>> table), bidirectional Map? Anybody with a workaround?
>>>
>>> Best regards,
>>> Krzysztof
>>>
>>>
>>> Krzysztof wrote:
>>> >
>>> > Indeed, changing the map to be keyed on a plain type does not solve
>>> the
>>> > problem until the owning 'source' field becomes plain type too.
>>> > So,
>>> >
>>> > <Source>
>>> > ...
>>> >         @OneToMany(mappedBy="source",cascade=CascadeType.ALL)
>>> >       @MapKey(name="tsType")
>>> >
>>> >       private Map<Integer, TSImpl> tsMap;
>>> > ...
>>> > </Source>
>>> > <TSimpl>
>>> >         @Id
>>> >       @Basic(optional=false)
>>> >       @Enumerated(EnumType.ORDINAL)
>>> >       @Column(name="tsType",updatable=false)
>>> >       private TSType tsType; //stays as enum, same exception thrown
>>> > </TSImpl>
>>> > gives exactly same cast exception, but if we change this part of Id to
>>> int
>>> > it works. Also calling persist on root persists map elements properly.
>>> >       @Id
>>> >         @Basic(optional=false)
>>> > //    @Enumerated(EnumType.ORDINAL)
>>> >       @Column(name="tsType",updatable=false)
>>> > //    private TSType tsType;
>>> >       private int tsType;
>>> >
>>> > This is not really elegant and affects a lot of code. Could you please
>>> > suggest any workaround so enum could be used as a key and is
>>> compatible
>>> > with ObjectId? Annotating enum as Embeddable gives enhancer error and
>>> > creating class wrapping an enum is also questionable in this
>>> particular
>>> > case.
>>> >
>>> > Best regards,
>>> > Krzysztof
>>> >
>>> >
>>> >
>>>
>>> --
>>> View this message in context:
>>> http://n2.nabble.com/Enum-as-a-Key-in-a-Map-tp1639596p3474057.html
>>> Sent from the OpenJPA Users mailing list archive at Nabble.com.
>>>
>> 
>> 
> 
> -- 
> View this message in context:
> http://n2.nabble.com/Enum-as-a-Key-in-a-Map-tp1639596p3474458.html
> Sent from the OpenJPA Users mailing list archive at Nabble.com.
> 
> 
> 
>      
> 
> 

-- 
View this message in context: http://n2.nabble.com/Enum-as-a-Key-in-a-Map-tp1639596p3474663.html
Sent from the OpenJPA Users mailing list archive at Nabble.com.



      

Re: Enum as a Key in a Map

Posted by Krzysztof <ya...@gmail.com>.
Thank you, 
I just tried to add Id class to the enum as a dirty hack but it's not doable
of course.
Good luck!
Krzysztof


Fay Wang wrote:
> 
> Hi Krzysztof,
>     Given your description below, I am able to reproduce this problem. I
> will take a look at it. Thanks!
> 
> Regards,
> Fay
> 
> 
> 
> 
> 
> ----- Original Message ----
> From: Krzysztof <ya...@gmail.com>
> To: users@openjpa.apache.org
> Sent: Wednesday, August 19, 2009 11:38:36 AM
> Subject: Re: Enum as a Key in a Map
> 
> 
> Thanks Kevin,
> 
> Certainly, I have checked your roadmap and the relevant JIRA issue, also
> test cases you have in the trunk - have not seen @MapKeyEnumerated used
> with
> @OneToMany though.
> 
> In the Id class of the child I kept enum as a field and used ordinal()
> obviously. 
> 
> I'm debugging this now and can see that _key enum field of the oid passed
> to
> pcCopyKeyFieldsToObjectId is null. As mentioned before, value in the DB
> looks ok. 
> 
> After dissasembling public void pcCopyKeyFieldsToObjectId(FieldSupplier
> fieldsupplier, Object obj)
> of that class I can see that 
> 
>   TSimplId.tsType = (TSType)((ObjectId)fieldsupplier.fetchObjectField(2 +
> i)).getId();
> 
> for some reason enum is treated as a composite Id and cast to ObjectId
> fails?
> 
> 
> 
> Cheers,
> Krzysztof
> 
> 
> Kevin Sutter wrote:
>> 
>> Hi Krzysztof,
>> The MapKeyEnumerated support was introduced as part of JPA 2.0.  It looks
>> like this was committed via OPENJPA-1055.  I've pinged Fay (owner of the
>> JIRA) to take a look to see if she has any ideas.  If you are interested
>> in
>> what's been done for JPA 2.0 already, you can reference our roadmap [1].
>> I'm bringing this up in case you try some other JPA 2.0 items that
>> haven't
>> even been touched yet...  :-)
>> 
>> Thanks,
>> Kevin
>> 
>> [1]  http://openjpa.apache.org/jpa-20-roadmap.html
>> 
>> On Wed, Aug 19, 2009 at 12:30 PM, Krzysztof <ya...@gmail.com> wrote:
>> 
>>>
>>> Hello,
>>> I'm reviving this as @MapKeyEnumerated has been introduced recently
>>> which
>>> seemed addressing this issue.
>>> Unfortunately, if I use enum as a key where Source is amended with
>>> following
>>> annotation for the map:
>>>
>>>
>>>        @OneToMany(mappedBy = "source",cascade={ CascadeType.ALL },fetch
>>> =
>>> FetchType.LAZY, orphanRemoval = true)
>>>        @MapKeyEnumerated(EnumType.ORDINAL)
>>>        @MapKey(name = "tsType")
>>>
>>>
>>> objects are committed gracefully and generated data and schema looks ok,
>>> but
>>> the exception reappears during retrieval:
>>>
>>> java.lang.ClassCastException: TSType cannot be cast to
>>> org.apache.openjpa.util.ObjectId
>>>
>>>
>>> gaia.cu7.omimpl.ClassificationResultsImpl.pcCopyKeyFieldsToObjectId(ClassificationResultsImpl.java)
>>>
>>>
>>> org.apache.openjpa.enhance.PCRegistry.copyKeyFieldsToObjectId(PCRegistry.java:172)
>>>
>>>
>>> org.apache.openjpa.util.ApplicationIds.fromPKValues(ApplicationIds.java:219)
>>>
>>>
>>> org.apache.openjpa.jdbc.meta.ClassMapping.getObjectId(ClassMapping.java:216)
>>>
>>>
>>> org.apache.openjpa.jdbc.meta.ClassMapping.getObjectId(ClassMapping.java:147)
>>>
>>>
>>> org.apache.openjpa.jdbc.kernel.JDBCStoreManager.load(JDBCStoreManager.java:934)
>>>
>>> org.apache.openjpa.jdbc.sql.AbstractResult.load(AbstractResult.java:280)
>>>
>>>
>>> org.apache.openjpa.jdbc.sql.SelectImpl$SelectResult.load(SelectImpl.java:2349)
>>>
>>> org.apache.openjpa.jdbc.meta.strats.RelationToManyInverseKeyFieldStrategy.loadElement(RelationToManyInverseKeyFieldStrategy.java:87)
>>>
>>> org.apache.openjpa.jdbc.meta.strats.StoreCollectionFieldStrategy.load(StoreCollectionFieldStrategy.java:554)
>>>    
>>> org.apache.openjpa.jdbc.meta.FieldMapping.load(FieldMapping.java:919)
>>>
>>>
>>> org.apache.openjpa.jdbc.kernel.JDBCStoreManager.load(JDBCStoreManager.java:641)
>>>
>>>
>>> org.apache.openjpa.kernel.DelegatingStoreManager.load(DelegatingStoreManager.java:116)
>>>
>>> org.apache.openjpa.kernel.ROPStoreManager.load(ROPStoreManager.java:78)
>>>
>>>
>>> org.apache.openjpa.kernel.StateManagerImpl.loadFields(StateManagerImpl.java:3035)
>>>
>>>
>>> org.apache.openjpa.kernel.StateManagerImpl.loadField(StateManagerImpl.java:3113)
>>>
>>>
>>> org.apache.openjpa.kernel.StateManagerImpl.beforeAccessField(StateManagerImpl.java:1606)
>>>
>>>
>>> org.apache.openjpa.kernel.StateManagerImpl.accessingField(StateManagerImpl.java:1591)
>>>     Source.pcGetclassificationResultsMap(SourceImpl.java)
>>>
>>>
>>> 2.0.0 trunk version.
>>>
>>> Is is possible to use enumeration as a Key in a directly mapped (no join
>>> table), bidirectional Map? Anybody with a workaround?
>>>
>>> Best regards,
>>> Krzysztof
>>>
>>>
>>> Krzysztof wrote:
>>> >
>>> > Indeed, changing the map to be keyed on a plain type does not solve
>>> the
>>> > problem until the owning 'source' field becomes plain type too.
>>> > So,
>>> >
>>> > <Source>
>>> > ...
>>> >         @OneToMany(mappedBy="source",cascade=CascadeType.ALL)
>>> >       @MapKey(name="tsType")
>>> >
>>> >       private Map<Integer, TSImpl> tsMap;
>>> > ...
>>> > </Source>
>>> > <TSimpl>
>>> >         @Id
>>> >       @Basic(optional=false)
>>> >       @Enumerated(EnumType.ORDINAL)
>>> >       @Column(name="tsType",updatable=false)
>>> >       private TSType tsType; //stays as enum, same exception thrown
>>> > </TSImpl>
>>> > gives exactly same cast exception, but if we change this part of Id to
>>> int
>>> > it works. Also calling persist on root persists map elements properly.
>>> >       @Id
>>> >         @Basic(optional=false)
>>> > //    @Enumerated(EnumType.ORDINAL)
>>> >       @Column(name="tsType",updatable=false)
>>> > //    private TSType tsType;
>>> >       private int tsType;
>>> >
>>> > This is not really elegant and affects a lot of code. Could you please
>>> > suggest any workaround so enum could be used as a key and is
>>> compatible
>>> > with ObjectId? Annotating enum as Embeddable gives enhancer error and
>>> > creating class wrapping an enum is also questionable in this
>>> particular
>>> > case.
>>> >
>>> > Best regards,
>>> > Krzysztof
>>> >
>>> >
>>> >
>>>
>>> --
>>> View this message in context:
>>> http://n2.nabble.com/Enum-as-a-Key-in-a-Map-tp1639596p3474057.html
>>> Sent from the OpenJPA Users mailing list archive at Nabble.com.
>>>
>> 
>> 
> 
> -- 
> View this message in context:
> http://n2.nabble.com/Enum-as-a-Key-in-a-Map-tp1639596p3474458.html
> Sent from the OpenJPA Users mailing list archive at Nabble.com.
> 
> 
> 
>       
> 
> 

-- 
View this message in context: http://n2.nabble.com/Enum-as-a-Key-in-a-Map-tp1639596p3474663.html
Sent from the OpenJPA Users mailing list archive at Nabble.com.

Re: Enum as a Key in a Map

Posted by Fay Wang <fy...@yahoo.com>.
Hi Krzysztof,
    Given your description below, I am able to reproduce this problem. I will take a look at it. Thanks!

Regards,
Fay





----- Original Message ----
From: Krzysztof <ya...@gmail.com>
To: users@openjpa.apache.org
Sent: Wednesday, August 19, 2009 11:38:36 AM
Subject: Re: Enum as a Key in a Map


Thanks Kevin,

Certainly, I have checked your roadmap and the relevant JIRA issue, also
test cases you have in the trunk - have not seen @MapKeyEnumerated used with
@OneToMany though.

In the Id class of the child I kept enum as a field and used ordinal()
obviously. 

I'm debugging this now and can see that _key enum field of the oid passed to
pcCopyKeyFieldsToObjectId is null. As mentioned before, value in the DB
looks ok. 

After dissasembling public void pcCopyKeyFieldsToObjectId(FieldSupplier
fieldsupplier, Object obj)
of that class I can see that 

  TSimplId.tsType = (TSType)((ObjectId)fieldsupplier.fetchObjectField(2 +
i)).getId();

for some reason enum is treated as a composite Id and cast to ObjectId
fails?



Cheers,
Krzysztof


Kevin Sutter wrote:
> 
> Hi Krzysztof,
> The MapKeyEnumerated support was introduced as part of JPA 2.0.  It looks
> like this was committed via OPENJPA-1055.  I've pinged Fay (owner of the
> JIRA) to take a look to see if she has any ideas.  If you are interested
> in
> what's been done for JPA 2.0 already, you can reference our roadmap [1].
> I'm bringing this up in case you try some other JPA 2.0 items that haven't
> even been touched yet...  :-)
> 
> Thanks,
> Kevin
> 
> [1]  http://openjpa.apache.org/jpa-20-roadmap.html
> 
> On Wed, Aug 19, 2009 at 12:30 PM, Krzysztof <ya...@gmail.com> wrote:
> 
>>
>> Hello,
>> I'm reviving this as @MapKeyEnumerated has been introduced recently which
>> seemed addressing this issue.
>> Unfortunately, if I use enum as a key where Source is amended with
>> following
>> annotation for the map:
>>
>>
>>        @OneToMany(mappedBy = "source",cascade={ CascadeType.ALL },fetch =
>> FetchType.LAZY, orphanRemoval = true)
>>        @MapKeyEnumerated(EnumType.ORDINAL)
>>        @MapKey(name = "tsType")
>>
>>
>> objects are committed gracefully and generated data and schema looks ok,
>> but
>> the exception reappears during retrieval:
>>
>> java.lang.ClassCastException: TSType cannot be cast to
>> org.apache.openjpa.util.ObjectId
>>
>>
>> gaia.cu7.omimpl.ClassificationResultsImpl.pcCopyKeyFieldsToObjectId(ClassificationResultsImpl.java)
>>
>>
>> org.apache.openjpa.enhance.PCRegistry.copyKeyFieldsToObjectId(PCRegistry.java:172)
>>
>>
>> org.apache.openjpa.util.ApplicationIds.fromPKValues(ApplicationIds.java:219)
>>
>>
>> org.apache.openjpa.jdbc.meta.ClassMapping.getObjectId(ClassMapping.java:216)
>>
>>
>> org.apache.openjpa.jdbc.meta.ClassMapping.getObjectId(ClassMapping.java:147)
>>
>>
>> org.apache.openjpa.jdbc.kernel.JDBCStoreManager.load(JDBCStoreManager.java:934)
>>
>> org.apache.openjpa.jdbc.sql.AbstractResult.load(AbstractResult.java:280)
>>
>>
>> org.apache.openjpa.jdbc.sql.SelectImpl$SelectResult.load(SelectImpl.java:2349)
>>
>> org.apache.openjpa.jdbc.meta.strats.RelationToManyInverseKeyFieldStrategy.loadElement(RelationToManyInverseKeyFieldStrategy.java:87)
>>
>> org.apache.openjpa.jdbc.meta.strats.StoreCollectionFieldStrategy.load(StoreCollectionFieldStrategy.java:554)
>>     org.apache.openjpa.jdbc.meta.FieldMapping.load(FieldMapping.java:919)
>>
>>
>> org.apache.openjpa.jdbc.kernel.JDBCStoreManager.load(JDBCStoreManager.java:641)
>>
>>
>> org.apache.openjpa.kernel.DelegatingStoreManager.load(DelegatingStoreManager.java:116)
>>
>> org.apache.openjpa.kernel.ROPStoreManager.load(ROPStoreManager.java:78)
>>
>>
>> org.apache.openjpa.kernel.StateManagerImpl.loadFields(StateManagerImpl.java:3035)
>>
>>
>> org.apache.openjpa.kernel.StateManagerImpl.loadField(StateManagerImpl.java:3113)
>>
>>
>> org.apache.openjpa.kernel.StateManagerImpl.beforeAccessField(StateManagerImpl.java:1606)
>>
>>
>> org.apache.openjpa.kernel.StateManagerImpl.accessingField(StateManagerImpl.java:1591)
>>     Source.pcGetclassificationResultsMap(SourceImpl.java)
>>
>>
>> 2.0.0 trunk version.
>>
>> Is is possible to use enumeration as a Key in a directly mapped (no join
>> table), bidirectional Map? Anybody with a workaround?
>>
>> Best regards,
>> Krzysztof
>>
>>
>> Krzysztof wrote:
>> >
>> > Indeed, changing the map to be keyed on a plain type does not solve the
>> > problem until the owning 'source' field becomes plain type too.
>> > So,
>> >
>> > <Source>
>> > ...
>> >         @OneToMany(mappedBy="source",cascade=CascadeType.ALL)
>> >       @MapKey(name="tsType")
>> >
>> >       private Map<Integer, TSImpl> tsMap;
>> > ...
>> > </Source>
>> > <TSimpl>
>> >         @Id
>> >       @Basic(optional=false)
>> >       @Enumerated(EnumType.ORDINAL)
>> >       @Column(name="tsType",updatable=false)
>> >       private TSType tsType; //stays as enum, same exception thrown
>> > </TSImpl>
>> > gives exactly same cast exception, but if we change this part of Id to
>> int
>> > it works. Also calling persist on root persists map elements properly.
>> >       @Id
>> >         @Basic(optional=false)
>> > //    @Enumerated(EnumType.ORDINAL)
>> >       @Column(name="tsType",updatable=false)
>> > //    private TSType tsType;
>> >       private int tsType;
>> >
>> > This is not really elegant and affects a lot of code. Could you please
>> > suggest any workaround so enum could be used as a key and is compatible
>> > with ObjectId? Annotating enum as Embeddable gives enhancer error and
>> > creating class wrapping an enum is also questionable in this particular
>> > case.
>> >
>> > Best regards,
>> > Krzysztof
>> >
>> >
>> >
>>
>> --
>> View this message in context:
>> http://n2.nabble.com/Enum-as-a-Key-in-a-Map-tp1639596p3474057.html
>> Sent from the OpenJPA Users mailing list archive at Nabble.com.
>>
> 
> 

-- 
View this message in context: http://n2.nabble.com/Enum-as-a-Key-in-a-Map-tp1639596p3474458.html
Sent from the OpenJPA Users mailing list archive at Nabble.com.



      

Re: Enum as a Key in a Map

Posted by Krzysztof <ya...@gmail.com>.
Thanks Kevin,

Certainly, I have checked your roadmap and the relevant JIRA issue, also
test cases you have in the trunk - have not seen @MapKeyEnumerated used with
@OneToMany though.

In the Id class of the child I kept enum as a field and used ordinal()
obviously. 

I'm debugging this now and can see that _key enum field of the oid passed to
pcCopyKeyFieldsToObjectId is null. As mentioned before, value in the DB
looks ok. 

After dissasembling public void pcCopyKeyFieldsToObjectId(FieldSupplier
fieldsupplier, Object obj)
of that class I can see that 

  TSimplId.tsType = (TSType)((ObjectId)fieldsupplier.fetchObjectField(2 +
i)).getId();

for some reason enum is treated as a composite Id and cast to ObjectId
fails?



Cheers,
Krzysztof


Kevin Sutter wrote:
> 
> Hi Krzysztof,
> The MapKeyEnumerated support was introduced as part of JPA 2.0.  It looks
> like this was committed via OPENJPA-1055.  I've pinged Fay (owner of the
> JIRA) to take a look to see if she has any ideas.  If you are interested
> in
> what's been done for JPA 2.0 already, you can reference our roadmap [1].
> I'm bringing this up in case you try some other JPA 2.0 items that haven't
> even been touched yet...  :-)
> 
> Thanks,
> Kevin
> 
> [1]  http://openjpa.apache.org/jpa-20-roadmap.html
> 
> On Wed, Aug 19, 2009 at 12:30 PM, Krzysztof <ya...@gmail.com> wrote:
> 
>>
>> Hello,
>> I'm reviving this as @MapKeyEnumerated has been introduced recently which
>> seemed addressing this issue.
>> Unfortunately, if I use enum as a key where Source is amended with
>> following
>> annotation for the map:
>>
>>
>>        @OneToMany(mappedBy = "source",cascade={ CascadeType.ALL },fetch =
>> FetchType.LAZY, orphanRemoval = true)
>>        @MapKeyEnumerated(EnumType.ORDINAL)
>>        @MapKey(name = "tsType")
>>
>>
>> objects are committed gracefully and generated data and schema looks ok,
>> but
>> the exception reappears during retrieval:
>>
>> java.lang.ClassCastException: TSType cannot be cast to
>> org.apache.openjpa.util.ObjectId
>>
>>
>> gaia.cu7.omimpl.ClassificationResultsImpl.pcCopyKeyFieldsToObjectId(ClassificationResultsImpl.java)
>>
>>
>> org.apache.openjpa.enhance.PCRegistry.copyKeyFieldsToObjectId(PCRegistry.java:172)
>>
>>
>> org.apache.openjpa.util.ApplicationIds.fromPKValues(ApplicationIds.java:219)
>>
>>
>> org.apache.openjpa.jdbc.meta.ClassMapping.getObjectId(ClassMapping.java:216)
>>
>>
>> org.apache.openjpa.jdbc.meta.ClassMapping.getObjectId(ClassMapping.java:147)
>>
>>
>> org.apache.openjpa.jdbc.kernel.JDBCStoreManager.load(JDBCStoreManager.java:934)
>>
>> org.apache.openjpa.jdbc.sql.AbstractResult.load(AbstractResult.java:280)
>>
>>
>> org.apache.openjpa.jdbc.sql.SelectImpl$SelectResult.load(SelectImpl.java:2349)
>>
>> org.apache.openjpa.jdbc.meta.strats.RelationToManyInverseKeyFieldStrategy.loadElement(RelationToManyInverseKeyFieldStrategy.java:87)
>>
>> org.apache.openjpa.jdbc.meta.strats.StoreCollectionFieldStrategy.load(StoreCollectionFieldStrategy.java:554)
>>     org.apache.openjpa.jdbc.meta.FieldMapping.load(FieldMapping.java:919)
>>
>>
>> org.apache.openjpa.jdbc.kernel.JDBCStoreManager.load(JDBCStoreManager.java:641)
>>
>>
>> org.apache.openjpa.kernel.DelegatingStoreManager.load(DelegatingStoreManager.java:116)
>>
>> org.apache.openjpa.kernel.ROPStoreManager.load(ROPStoreManager.java:78)
>>
>>
>> org.apache.openjpa.kernel.StateManagerImpl.loadFields(StateManagerImpl.java:3035)
>>
>>
>> org.apache.openjpa.kernel.StateManagerImpl.loadField(StateManagerImpl.java:3113)
>>
>>
>> org.apache.openjpa.kernel.StateManagerImpl.beforeAccessField(StateManagerImpl.java:1606)
>>
>>
>> org.apache.openjpa.kernel.StateManagerImpl.accessingField(StateManagerImpl.java:1591)
>>     Source.pcGetclassificationResultsMap(SourceImpl.java)
>>
>>
>> 2.0.0 trunk version.
>>
>> Is is possible to use enumeration as a Key in a directly mapped (no join
>> table), bidirectional Map? Anybody with a workaround?
>>
>> Best regards,
>> Krzysztof
>>
>>
>> Krzysztof wrote:
>> >
>> > Indeed, changing the map to be keyed on a plain type does not solve the
>> > problem until the owning 'source' field becomes plain type too.
>> > So,
>> >
>> > <Source>
>> > ...
>> >         @OneToMany(mappedBy="source",cascade=CascadeType.ALL)
>> >       @MapKey(name="tsType")
>> >
>> >       private Map<Integer, TSImpl> tsMap;
>> > ...
>> > </Source>
>> > <TSimpl>
>> >         @Id
>> >       @Basic(optional=false)
>> >       @Enumerated(EnumType.ORDINAL)
>> >       @Column(name="tsType",updatable=false)
>> >       private TSType tsType; //stays as enum, same exception thrown
>> > </TSImpl>
>> > gives exactly same cast exception, but if we change this part of Id to
>> int
>> > it works. Also calling persist on root persists map elements properly.
>> >       @Id
>> >         @Basic(optional=false)
>> > //    @Enumerated(EnumType.ORDINAL)
>> >       @Column(name="tsType",updatable=false)
>> > //    private TSType tsType;
>> >       private int tsType;
>> >
>> > This is not really elegant and affects a lot of code. Could you please
>> > suggest any workaround so enum could be used as a key and is compatible
>> > with ObjectId? Annotating enum as Embeddable gives enhancer error and
>> > creating class wrapping an enum is also questionable in this particular
>> > case.
>> >
>> > Best regards,
>> > Krzysztof
>> >
>> >
>> >
>>
>> --
>> View this message in context:
>> http://n2.nabble.com/Enum-as-a-Key-in-a-Map-tp1639596p3474057.html
>> Sent from the OpenJPA Users mailing list archive at Nabble.com.
>>
> 
> 

-- 
View this message in context: http://n2.nabble.com/Enum-as-a-Key-in-a-Map-tp1639596p3474458.html
Sent from the OpenJPA Users mailing list archive at Nabble.com.

Re: Enum as a Key in a Map

Posted by Kevin Sutter <kw...@gmail.com>.
Hi Krzysztof,
The MapKeyEnumerated support was introduced as part of JPA 2.0.  It looks
like this was committed via OPENJPA-1055.  I've pinged Fay (owner of the
JIRA) to take a look to see if she has any ideas.  If you are interested in
what's been done for JPA 2.0 already, you can reference our roadmap [1].
I'm bringing this up in case you try some other JPA 2.0 items that haven't
even been touched yet...  :-)

Thanks,
Kevin

[1]  http://openjpa.apache.org/jpa-20-roadmap.html

On Wed, Aug 19, 2009 at 12:30 PM, Krzysztof <ya...@gmail.com> wrote:

>
> Hello,
> I'm reviving this as @MapKeyEnumerated has been introduced recently which
> seemed addressing this issue.
> Unfortunately, if I use enum as a key where Source is amended with
> following
> annotation for the map:
>
>
>        @OneToMany(mappedBy = "source",cascade={ CascadeType.ALL },fetch =
> FetchType.LAZY, orphanRemoval = true)
>        @MapKeyEnumerated(EnumType.ORDINAL)
>        @MapKey(name = "tsType")
>
>
> objects are committed gracefully and generated data and schema looks ok,
> but
> the exception reappears during retrieval:
>
> java.lang.ClassCastException: TSType cannot be cast to
> org.apache.openjpa.util.ObjectId
>
>
> gaia.cu7.omimpl.ClassificationResultsImpl.pcCopyKeyFieldsToObjectId(ClassificationResultsImpl.java)
>
>
> org.apache.openjpa.enhance.PCRegistry.copyKeyFieldsToObjectId(PCRegistry.java:172)
>
>
> org.apache.openjpa.util.ApplicationIds.fromPKValues(ApplicationIds.java:219)
>
>
> org.apache.openjpa.jdbc.meta.ClassMapping.getObjectId(ClassMapping.java:216)
>
>
> org.apache.openjpa.jdbc.meta.ClassMapping.getObjectId(ClassMapping.java:147)
>
>
> org.apache.openjpa.jdbc.kernel.JDBCStoreManager.load(JDBCStoreManager.java:934)
>
> org.apache.openjpa.jdbc.sql.AbstractResult.load(AbstractResult.java:280)
>
>
> org.apache.openjpa.jdbc.sql.SelectImpl$SelectResult.load(SelectImpl.java:2349)
>
> org.apache.openjpa.jdbc.meta.strats.RelationToManyInverseKeyFieldStrategy.loadElement(RelationToManyInverseKeyFieldStrategy.java:87)
>
> org.apache.openjpa.jdbc.meta.strats.StoreCollectionFieldStrategy.load(StoreCollectionFieldStrategy.java:554)
>     org.apache.openjpa.jdbc.meta.FieldMapping.load(FieldMapping.java:919)
>
>
> org.apache.openjpa.jdbc.kernel.JDBCStoreManager.load(JDBCStoreManager.java:641)
>
>
> org.apache.openjpa.kernel.DelegatingStoreManager.load(DelegatingStoreManager.java:116)
>
> org.apache.openjpa.kernel.ROPStoreManager.load(ROPStoreManager.java:78)
>
>
> org.apache.openjpa.kernel.StateManagerImpl.loadFields(StateManagerImpl.java:3035)
>
>
> org.apache.openjpa.kernel.StateManagerImpl.loadField(StateManagerImpl.java:3113)
>
>
> org.apache.openjpa.kernel.StateManagerImpl.beforeAccessField(StateManagerImpl.java:1606)
>
>
> org.apache.openjpa.kernel.StateManagerImpl.accessingField(StateManagerImpl.java:1591)
>     Source.pcGetclassificationResultsMap(SourceImpl.java)
>
>
> 2.0.0 trunk version.
>
> Is is possible to use enumeration as a Key in a directly mapped (no join
> table), bidirectional Map? Anybody with a workaround?
>
> Best regards,
> Krzysztof
>
>
> Krzysztof wrote:
> >
> > Indeed, changing the map to be keyed on a plain type does not solve the
> > problem until the owning 'source' field becomes plain type too.
> > So,
> >
> > <Source>
> > ...
> >         @OneToMany(mappedBy="source",cascade=CascadeType.ALL)
> >       @MapKey(name="tsType")
> >
> >       private Map<Integer, TSImpl> tsMap;
> > ...
> > </Source>
> > <TSimpl>
> >         @Id
> >       @Basic(optional=false)
> >       @Enumerated(EnumType.ORDINAL)
> >       @Column(name="tsType",updatable=false)
> >       private TSType tsType; //stays as enum, same exception thrown
> > </TSImpl>
> > gives exactly same cast exception, but if we change this part of Id to
> int
> > it works. Also calling persist on root persists map elements properly.
> >       @Id
> >         @Basic(optional=false)
> > //    @Enumerated(EnumType.ORDINAL)
> >       @Column(name="tsType",updatable=false)
> > //    private TSType tsType;
> >       private int tsType;
> >
> > This is not really elegant and affects a lot of code. Could you please
> > suggest any workaround so enum could be used as a key and is compatible
> > with ObjectId? Annotating enum as Embeddable gives enhancer error and
> > creating class wrapping an enum is also questionable in this particular
> > case.
> >
> > Best regards,
> > Krzysztof
> >
> >
> >
>
> --
> View this message in context:
> http://n2.nabble.com/Enum-as-a-Key-in-a-Map-tp1639596p3474057.html
> Sent from the OpenJPA Users mailing list archive at Nabble.com.
>

Re: Enum as a Key in a Map

Posted by Fay Wang <fy...@yahoo.com>.
Hi Krzysztof,
    I could not reproduce your problem using my own test case.  From your annotation, I would suppose that tsType is a persistent field of the map value, and it is of EnumType. Could you provide your domain model for further investigation?

 
Regards,
Fay


----- Original Message ----
From: Krzysztof <ya...@gmail.com>
To: users@openjpa.apache.org
Sent: Wednesday, August 19, 2009 10:30:00 AM
Subject: Re: Enum as a Key in a Map


Hello,
I'm reviving this as @MapKeyEnumerated has been introduced recently which
seemed addressing this issue.
Unfortunately, if I use enum as a key where Source is amended with following
annotation for the map:


        @OneToMany(mappedBy = "source",cascade={ CascadeType.ALL },fetch =
FetchType.LAZY, orphanRemoval = true)
        @MapKeyEnumerated(EnumType.ORDINAL)    
        @MapKey(name = "tsType")     


objects are committed gracefully and generated data and schema looks ok, but
the exception reappears during retrieval:

java.lang.ClassCastException: TSType cannot be cast to
org.apache.openjpa.util.ObjectId
    
gaia.cu7.omimpl.ClassificationResultsImpl.pcCopyKeyFieldsToObjectId(ClassificationResultsImpl.java)
    
org.apache.openjpa.enhance.PCRegistry.copyKeyFieldsToObjectId(PCRegistry.java:172)
    
org.apache.openjpa.util.ApplicationIds.fromPKValues(ApplicationIds.java:219)
    
org.apache.openjpa.jdbc.meta.ClassMapping.getObjectId(ClassMapping.java:216)
    
org.apache.openjpa.jdbc.meta.ClassMapping.getObjectId(ClassMapping.java:147)
    
org.apache.openjpa.jdbc.kernel.JDBCStoreManager.load(JDBCStoreManager.java:934)
    
org.apache.openjpa.jdbc.sql.AbstractResult.load(AbstractResult.java:280)
    
org.apache.openjpa.jdbc.sql.SelectImpl$SelectResult.load(SelectImpl.java:2349)
org.apache.openjpa.jdbc.meta.strats.RelationToManyInverseKeyFieldStrategy.loadElement(RelationToManyInverseKeyFieldStrategy.java:87)
org.apache.openjpa.jdbc.meta.strats.StoreCollectionFieldStrategy.load(StoreCollectionFieldStrategy.java:554)
     org.apache.openjpa.jdbc.meta.FieldMapping.load(FieldMapping.java:919)
    
org.apache.openjpa.jdbc.kernel.JDBCStoreManager.load(JDBCStoreManager.java:641)
    
org.apache.openjpa.kernel.DelegatingStoreManager.load(DelegatingStoreManager.java:116)
     org.apache.openjpa.kernel.ROPStoreManager.load(ROPStoreManager.java:78)
    
org.apache.openjpa.kernel.StateManagerImpl.loadFields(StateManagerImpl.java:3035)
    
org.apache.openjpa.kernel.StateManagerImpl.loadField(StateManagerImpl.java:3113)
    
org.apache.openjpa.kernel.StateManagerImpl.beforeAccessField(StateManagerImpl.java:1606)
    
org.apache.openjpa.kernel.StateManagerImpl.accessingField(StateManagerImpl.java:1591)
     Source.pcGetclassificationResultsMap(SourceImpl.java)


2.0.0 trunk version.

Is is possible to use enumeration as a Key in a directly mapped (no join
table), bidirectional Map? Anybody with a workaround?

Best regards,
Krzysztof


Krzysztof wrote:
> 
> Indeed, changing the map to be keyed on a plain type does not solve the
> problem until the owning 'source' field becomes plain type too.
> So,
> 
> <Source>
> ...
>         @OneToMany(mappedBy="source",cascade=CascadeType.ALL)
>     @MapKey(name="tsType")
> 
>     private Map<Integer, TSImpl> tsMap;
> ...
> </Source>
> <TSimpl>
>         @Id
>         @Basic(optional=false)
>     @Enumerated(EnumType.ORDINAL)
>     @Column(name="tsType",updatable=false)
>     private TSType tsType; //stays as enum, same exception thrown
> </TSImpl>
> gives exactly same cast exception, but if we change this part of Id to int
> it works. Also calling persist on root persists map elements properly.
>     @Id
>         @Basic(optional=false)
> //    @Enumerated(EnumType.ORDINAL)
>     @Column(name="tsType",updatable=false)
> //    private TSType tsType;
>     private int tsType;
> 
> This is not really elegant and affects a lot of code. Could you please
> suggest any workaround so enum could be used as a key and is compatible
> with ObjectId? Annotating enum as Embeddable gives enhancer error and
> creating class wrapping an enum is also questionable in this particular
> case.
> 
> Best regards,
> Krzysztof
> 
> 
> 

-- 
View this message in context: http://n2.nabble.com/Enum-as-a-Key-in-a-Map-tp1639596p3474057.html
Sent from the OpenJPA Users mailing list archive at Nabble.com.