![]() |
|
|
|
[
Permlink
| « Hide
]
Andy Jefferson - 22/Nov/05 09:53 AM
As mentioned in the JPOX docs, embedded inheritance and embedded reference fields are not supported and are very low priority.
Taken from [
Five classes: base classe A B inherits from A, C inherits from B D inherits from A, E inherits from D Inheritance strategy: A new-table B subclass-table, C new-table D new-table, E superclass-table E references one C (embedded). org.jpox.metadata.InvalidMetaDataException: Class org.jpox.test.C has field B.dimension declared in MetaData, but this field doesnt exist in the class! at org.jpox.metadata.EmbeddedMetaData.populate(EmbeddedMetaData.java:316) at org.jpox.metadata.AbstractPropertyMetaData.populate(AbstractPropertyMetaData.java:909) at org.jpox.enhancer.bcel.metadata.BCELFieldMetaData.populate(BCELFieldMetaData.java:287) at org.jpox.metadata.ClassMetaData.populatePropertyMetaData(ClassMetaData.java:562) at org.jpox.metadata.ClassMetaData.populate(ClassMetaData.java:258) at org.jpox.metadata.MetaDataManager.populateFileMetaData(MetaDataManager.java:1547) at org.jpox.metadata.MetaDataManager.initialise(MetaDataManager.java:291) at org.jpox.enhancer.JPOXEnhancer.getFileMetaDataForInput(JPOXEnhancer.java:716) at org.jpox.enhancer.JPOXEnhancer.main(JPOXEnhancer.java:531) Provided testcase from user "nicolas" on [
CVS HEAD had some changes recently to allow some level of interface fields being embedded, but was in the context of "persistent-interfaces" which is differend to your situation. You could try a nightly build to see what the situation is now
Hi Andy,
Thanks, I am still at version 1.1.8 and it will be a while (few months) before I move Teneo over to the newest jpox version (1.2). I will probably retry it then. gr. Martin I am trying to add support for derived embedded objects as for http://www.jpox.org/servlet/forum/viewthread_thread,5462
I have modified org.datanucleus.metadata.EmbeddedMetaData populate() method traversing inheritance tree instead of searching in the candidate class only: Field cls_field = null; Class tgtcls = embeddedClass; while (tgtcls != null && cls_field == null) { try { cls_field = tgtcls.getDeclaredField(fieldFmd.getName()); } catch (Exception e) { tgtcls = tgtcls.getSuperclass(); if (!PersistenceCapable.class.isAssignableFrom(tgtcls)) { // MetaData field doesn't exist in the class! throw new InvalidMetaDataException(LOCALISER, "044071", embeddedClass.getName(), fieldFmd.getFullFieldName()); } } Well, I can create the table, persist object and retrieve instances without problems in case of 1 -> 1 (container -> embedded) relationship. Is it a correct approach ? What about during enhancement ? is the embedded object superclass PC yet ? Don't think so.
Use metadata to know if the embedded class superclass is persistent. Be careful when loading metadata of other classes during populate/initialise since they probably won't be initialised at that point and so you cant refer to some attributes (pcSuperclassName for example) Yes, you are right, even if I am not sure how I obtained enhanced classes (maybe when I was simply navigating up to java.lang.Object class)
I have modified the inheritance traversal as: Field cls_field = null; Class tgtcls = embeddedClass; AbstractClassMetaData tgtCmd = embCmd; while (tgtcls != null && cls_field == null) { if (!tgtCmd.isPopulated()) { tgtCmd.populate(clr, primary); } if (!tgtCmd.isInitialised()) { tgtCmd.initialise(clr); } try { cls_field = tgtcls.getDeclaredField(fieldFmd.getName()); } catch (Exception e) { tgtcls = tgtcls.getSuperclass(); tgtCmd = embCmd.getMetaDataManager().getMetaDataForClass(tgtcls, clr); if (!PersistenceCapable.class.isAssignableFrom(tgtcls) && tgtCmd == null) { // MetaData field doesn't exist in the class! throw new InvalidMetaDataException(LOCALISER, "044071", embeddedClass.getName(), fieldFmd.getFullFieldName()); } } } and now seems to be OK. Anyway, considering the runtime aspects only, what do you think about the approach ? Tables are automatically created, but I guess that using schema tool wont make any difference. I have tried both <embedded/> tag and explicit specification of columns for members of subclass and superclass. I not sure but I am quite confident to be not so far from the solution... Don't populate/initialise ANY other metadata from within populate/initialise of a different class. The only place this should be done is when we have a class and it populates/initialises its superclass. Adding populate/initialise of other classes will result in cyclic relations, and we just removed all such things just before 1.1.0. You only need to know if the particular class is persistable, so no need to do anything with the metadata is there?
No problem with the basic approach of going up to superclasses and filling in the fields/properties default mapping info. Patch to allow inheritance in embedded objects.
Standard test case missing, even if tested in local env with 1-1 relation Thx for the patch.
Tests required : "test.jdo.rdbms.datastore" SchemaTest - test the schema generation (datastore id) "test.jdo.rdbms.application" SchemaTest - test the schema generation (app id) "test.jdo.orm.datastore" EmbeddedTest - test the persistence (datastore id) "test.jdo.orm.application" EmbeddedTest - test the persistence (app id) |
||||||||||||||||||||||||||||||||||||||||||||