[ 
https://issues.apache.org/jira/browse/OPENJPA-1061?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12706137#action_12706137
 ] 

Jody Grassel commented on OPENJPA-1061:
---------------------------------------

What seems to be happening is that during entity enhancement, the MSC type 
acquires an ObjectIDType.  When the enhancer reaches the entity types extending 
the MSC, the if-block:

if (_meta.getIdentityType() == ClassMetaData.ID_APPLICATION
            && (_meta.getPCSuperclass() == null || getCreateSubclass() ||
                _meta.getObjectIdType() !=
                    _meta.getPCSuperclassMetaData().getObjectIdType())) {

compares the entity type's ObjectIDType with its MSC, finds they are 
equivalent, so the entity enhancement does not add the app-id methods; the leaf 
entity types defer to the MSC's app-id methods.  So when a new entity is being 
inserted into the persistence context, its initial ObjectID has the MSC in its 
type field, instead of the leaf entity type.  If another entity extending from 
the same MSC has the same PK-value, OpenJPAId's implentation of equals() will 
think it is equivalent, failing the checkForDuplicateId() check.

I've included a potential fix for the above issue.  It adds an additional 
check, looking for PKFields that are defined by a MSC.  If it finds such 
PKFields, it walks up the inheritance tree, stopping at either the MSC defining 
the PKField, or at an entity type (to avoid breaking entity inheritance 
mechanisms).  Stopping at the MSC defining the PKField qualifies the entity 
type for app-id method inclusion during enhancement.  This way, the leaf 
entities use their own pcNewObjectIdInstance() methods (with the appropriate 
type coded into the method) instead of relying on the mapped superclass's 
version of the method.

However, there is a degree of uncertainty I have with the fix.  While it fixes 
the described problem, and it does not fail any of the existing JUnit tests, I 
rely on the ClassMetaData.isEmbeddedOnly() method to determine if a type is a 
MSC or a genuine entity.  From what I could tell, the 
ClassMetaData.setEmbeddedOnly() method is called only during annotation and ORL 
XML metadata processing (it is set explicitly false for MappedSuperClass 
types).  However, the methods ClassMetaData.isEmbeddedOnly() and 
ClassMetaData.resolveMeta() are capable of mutating the ClassMetaData._embedded 
field; so there needs to be verification that relying on the _embedded field is 
the correct method of identifying a MSC type for this processing.


> Entities extending from a Mapped Superclass that defines the ID fields share 
> the same ObjectID type parameter
> -------------------------------------------------------------------------------------------------------------
>
>                 Key: OPENJPA-1061
>                 URL: https://issues.apache.org/jira/browse/OPENJPA-1061
>             Project: OpenJPA
>          Issue Type: Bug
>          Components: jpa
>    Affects Versions: 1.2.0, 1.2.1
>            Reporter: Jody Grassel
>            Assignee: Jody Grassel
>         Attachments: unitttest.patch
>
>
> When a mapped superclass (MSC) defines @Id fields, it appears that entities 
> extending the MSC use the MSC's type in the generated ObjectID's type field.  
> This can result in unexpected primary key collissions between entities that 
> are not intended to be related in an entity inheritance hierarchy.  Attached 
> to the JIRA is a junit test case that demonstrates the problem. 

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.

Reply via email to