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 <[email protected]> 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.
