Thanks for responding quickly! Please check in.
Cheers,
- Wonseok
On 10/19/06, Gordon Yorke <gordon.yorke_at_oracle.com> 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> 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 <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 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].
> > > 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.
> > >
> > >
> >
> >
>