Hi Wonsoek,
I will be checking in your fix today.
Your test case actually uncovers an issue with our DDL generation. I
have filed an issue:
https://glassfish.dev.java.net/issues/show_bug.cgi?id=1348.
The test case will be checked in when that issue is fixed.
-Tom
Gordon Yorke wrote:
> Hello Wonseok,
> I reviewed the changes, they look good. I can check it in for you
> if you would like?
> --Gordon
>
>
> -----Original Message-----
> *From:* Wonseok Kim [mailto:guruwons_at_gmail.com]
> *Sent:* Wednesday, October 18, 2006 4:50 AM
> *To:* persistence_at_glassfish.dev.java.net
> *Subject:* Re: Code review for [Issue 1153] Object can't reference
> itself using @EmbeddedId
>
> Gordon, could you review this?
>
> Regards
> - Wonseok
>
> On 10/16/06, *Wonseok Kim* <guruwons_at_gmail.com
> <mailto:guruwons_at_gmail.com>> wrote:
>
> Hi team,
> I believe you had a good weekend.
>
> I'm trying to fix the below issue 1153. The situation and
> cause of this issue are explained in the below message, please
> see it.
>
> To fix this, I added a map member to ObjectBuilder, which
> holds the secondary key field(primary key field of the child
> table) and primary key field(of the root table) mappings.
>
> // Secondary key field to Primary key field map (joined
> inheritance or secondary table)
> protected Map primaryKeyFieldsBySecondaryField;
>
> This map is used in
> ObjectBuilder.extractValueFromObjectForField() to get the
> corresponding primary key field when the child entity's
> primary key field was given.
>
> /**
> * Extract the value of the primary key attribute from the
> specified object.
> */
> public Object extractValueFromObjectForField(Object
> domainObject, DatabaseField field, AbstractSession session)
> throws DescriptorException {
> // Allow for inheritance, the concrete descriptor must
> always be used.
> ClassDescriptor descriptor = null;//this variable will
> be assigned in the final
>
> if (getDescriptor().hasInheritance() &&
> (domainObject.getClass() != getDescriptor().getJavaClass()) &&
> ((descriptor =
> session.getDescriptor(domainObject)).getJavaClass() !=
> getDescriptor().getJavaClass())) {
> return
> descriptor.getObjectBuilder().extractValueFromObjectForField(domainObject,
> field, session);
> } else {
> DatabaseMapping mapping = getMappingForField(field);
> if (mapping == null) {
> throw
> DescriptorException.missingMappingForField(field,
> getDescriptor());
> }
>
> // GF#1153
> // If this entity is a child entity with JOINED
> inheritance strategy and Embedded Id,
> // getting value with the primary key field of
> child table won't succeed
> // for AggregateObjectMapping which only knows
> fields of root entity's table.
> // Therefore we use the primary key field of the
> root entity.
> if(getDescriptor().isChildDescriptor() &&
> mapping.isAggregateObjectMapping()){
> DatabaseField primaryKeyField =
> (DatabaseField) getPrimaryKeyFieldsBySecondaryField().get(field);
> if(primaryKeyField != null) {
> field = primaryKeyField;
> }
> }
> return mapping.valueFromObject(domainObject,
> field, session);
> }
> }
>
> I also added a new test for this - it required new models in
> 'inheritance' package because there is no proper entity for
> this issue.
> All entity-persistence tests including the new test passed
> with this fix.
>
> There are diffs, all modified and new files in the attached file.
> Please review!
>
> Thanks
> - Wonseok Kim
>
> On 13 Oct 2006 11:54:28 -0000, *guruwons_at_dev.java.net
> <mailto:guruwons_at_dev.java.net>* < guruwons_at_dev.java.net
> <mailto:guruwons_at_dev.java.net>> wrote:
>
> https://glassfish.dev.java.net/issues/show_bug.cgi?id=1153
>
> ------- Additional comments from guruwons_at_dev.java.net
> <mailto:guruwons_at_dev.java.net>Fri Oct 13 11:54:28 +0000
> 2006 -------
> This exception occurs for all types of relationships whose
> target is a child
> entity which has JOINED inheritance strategy and Embedded Id.
>
> Following are an exception example.
> ----------
> Caused by: Exception [TOPLINK-45] (Oracle TopLink
> Essentials - 9.1 (Build )):
> oracle.toplink.essentials.exceptions.DescriptorException
> Exception Description: Missing mapping for field [
> NATURALPERSON.ID <http://NATURALPERSON.ID>].
> Descriptor: RelationalDescriptor(jpatests.model.Guid -->
> [DatabaseTable(PERSON)])
> at
> oracle.toplink.essentials.exceptions.DescriptorException.missingMappingForField(DescriptorException.java
> :885)
> at
> oracle.toplink.essentials.internal.descriptors.ObjectBuilder.extractValueFromObjectForField(ObjectBuilder.java:1584)
> at
> oracle.toplink.essentials.mappings.AggregateObjectMapping.valueFromObject
> (AggregateObjectMapping.java:912)
> at
> oracle.toplink.essentials.internal.descriptors.ObjectBuilder.extractValueFromObjectForField(ObjectBuilder.java:1587)
> at
> oracle.toplink.essentials.mappings.OneToOneMapping.writeFromObjectIntoRow
> (OneToOneMapping.java:1058)
> at
> oracle.toplink.essentials.internal.descriptors.ObjectBuilder.buildRow(ObjectBuilder.java:732)
> at
> oracle.toplink.essentials.internal.descriptors.ObjectBuilder.buildRow
> (ObjectBuilder.java:720)
> at
> oracle.toplink.essentials.internal.queryframework.DatabaseQueryMechanism.insertObjectForWrite(DatabaseQueryMechanism.java:425)
> at
> oracle.toplink.essentials.queryframework.InsertObjectQuery.executeCommit
> (InsertObjectQuery.java:74)
> at
> oracle.toplink.essentials.internal.queryframework.DatabaseQueryMechanism.performUserDefinedWrite(DatabaseQueryMechanism.java:635)
> at
> oracle.toplink.essentials.internal.queryframework.DatabaseQueryMechanism.performUserDefinedInsert
> (DatabaseQueryMechanism.java:599)
> at
> oracle.toplink.essentials.internal.queryframework.DatabaseQueryMechanism.insertObjectForWriteWithChangeSet(DatabaseQueryMechanism.java:495)
> at
> oracle.toplink.essentials.queryframework.WriteObjectQuery.executeCommitWithChangeSet
> (WriteObjectQuery.java:130)
> at
> oracle.toplink.essentials.internal.queryframework.DatabaseQueryMechanism.executeWriteWithChangeSet(DatabaseQueryMechanism.java:283)
> at
> oracle.toplink.essentials.queryframework.WriteObjectQuery.executeDatabaseQuery
> (WriteObjectQuery.java:67)
> at
> oracle.toplink.essentials.queryframework.DatabaseQuery.execute(DatabaseQuery.java:609)
> at
> oracle.toplink.essentials.queryframework.DatabaseQuery.executeInUnitOfWork
> (DatabaseQuery.java:536)
> at
> oracle.toplink.essentials.queryframework.ObjectLevelModifyQuery.executeInUnitOfWorkObjectLevelModifyQuery(ObjectLevelModifyQuery.java:123)
> at
> oracle.toplink.essentials.queryframework.ObjectLevelModifyQuery.executeInUnitOfWork
> (ObjectLevelModifyQuery.java:95)
> at
> oracle.toplink.essentials.internal.sessions.UnitOfWorkImpl.internalExecuteQuery(UnitOfWorkImpl.java:2218)
> at
> oracle.toplink.essentials.internal.sessions.AbstractSession.executeQuery
> (AbstractSession.java:937)
> at
> oracle.toplink.essentials.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:894)
> at
> oracle.toplink.essentials.internal.sessions.CommitManager.commitNewObjectsForClassWithChangeSet
> (CommitManager.java:254)
> at
> oracle.toplink.essentials.internal.sessions.CommitManager.commitAllObjectsWithChangeSet(CommitManager.java:175)
> at
> oracle.toplink.essentials.internal.sessions.AbstractSession.writeAllObjectsWithChangeSet
> (AbstractSession.java:2638)
> at
> oracle.toplink.essentials.internal.sessions.UnitOfWorkImpl.commitToDatabase(UnitOfWorkImpl.java:1030)
> at
> oracle.toplink.essentials.internal.ejb.cmp3.base.RepeatableWriteUnitOfWork.commitToDatabase
> (RepeatableWriteUnitOfWork.java:357)
> at
> oracle.toplink.essentials.internal.sessions.UnitOfWorkImpl.commitToDatabaseWithChangeSet(UnitOfWorkImpl.java:1112)
> at
> oracle.toplink.essentials.internal.ejb.cmp3.base.RepeatableWriteUnitOfWork.commitRootUnitOfWork
> (RepeatableWriteUnitOfWork.java:82)
> at
> oracle.toplink.essentials.internal.sessions.UnitOfWorkImpl.commitAndResume(UnitOfWorkImpl.java:842)
> at
> oracle.toplink.essentials.internal.ejb.cmp3.transaction.base.EntityTransactionImpl.commit
> (EntityTransactionImpl.java:90)
> ... 26 more
> ----------
>
> CAUSE
>
> If entity B is a child entity of entity A which has
> composite primary key by
> @EmbeddedId, the internal class descriptor of B inherit
> mappings from the
> descriptor of A. Therefore B has same
> AggregateObjectMapping instance of entity
> A, and the AggregateObjectMapping instance has only fields
> of entity A. For
> example, if the primary key fields of A are A.ID1 and
> A.ID2 (table 'A'), and the
> primary key fields of B are B.ID1 and B.ID2, the
> AggregateObjectMapping has only
> A.ID1 and A.ID2.
>
> If ObjectBuilder.extractValueFromObjectForField() is
> called to get primary key
> value of child entity B with B.ID1, the
> AggregateObjectMapping doesn't find
> corresponding mapping with B.ID1 because it only knows
> A.ID1 and A.ID2. So an
> Exception like belwo is thrown.
>
> [TOPLINK-45]
> oracle.toplink.essentials.exceptions.DescriptorException
> Exception Description: Missing mapping for field [B.ID1].
>
> So we need to call
> ObjectBuilder.extractValueFromObjectForField() of
> AggregateObjectMapping with the field A.ID1 instead of
> given B.ID1.
>
> I'm working on the fix.
>
>
>
>