Matt Watson created CAY-2667:
--------------------------------

             Summary: Fix Wrong ObjEntity with Generic Vertical Inheritance
                 Key: CAY-2667
                 URL: https://issues.apache.org/jira/browse/CAY-2667
             Project: Cayenne
          Issue Type: Bug
          Components: Core Library
            Reporter: Matt Watson


When using Generic Classes (Java),

with the following db entities:
{code:xml}
        <db-entity name="student" schema="poly">
                <db-attribute name="name" type="VARCHAR" isMandatory="true" 
length="50"/>
                <db-attribute name="reference" type="VARCHAR" 
isMandatory="true" length="10"/>
                <db-attribute name="type" type="CHAR" isMandatory="true" 
length="1"/>
                <db-attribute name="uuid" type="BINARY" isPrimaryKey="true" 
isMandatory="true" length="16"/>
        </db-entity>

        <db-entity name="boy" schema="poly">
                <db-attribute name="toy_trucks" type="SMALLINT" length="4"/>
                <db-attribute name="uuid" type="BINARY" isPrimaryKey="true" 
isMandatory="true" length="16"/>
        </db-entity>
        <db-entity name="girl" schema="poly">
                <db-attribute name="toy_dolls" type="SMALLINT" length="4"/>
                <db-attribute name="uuid" type="BINARY" isPrimaryKey="true" 
isMandatory="true" length="16"/>
        </db-entity>
{code}
and the following obj entities:
{code:xml}
        <obj-entity name="Student" abstract="true" dbEntityName="student">
                <obj-attribute name="name" type="java.lang.String" 
db-attribute-path="name"/>
                <obj-attribute name="reference" type="java.lang.String" 
db-attribute-path="reference"/>
                <obj-attribute name="type" type="java.lang.String" 
db-attribute-path="type"/>
        </obj-entity>
        <obj-entity name="Boy" superEntityName="Student">
                <qualifier><![CDATA[type = "B"]]></qualifier>
                <obj-attribute name="toyTrucks" type="java.lang.Short" 
db-attribute-path="boy.toy_trucks"/>
        </obj-entity>
        <obj-entity name="Girl" superEntityName="Student">
                <qualifier><![CDATA[type = "G"]]></qualifier>
                <obj-attribute name="toyDolls" type="java.lang.Short" 
db-attribute-path="girl.toy_dolls"/>
        </obj-entity>
{code}
and proper db/obj relationships setup ..

 using the Test:
{code:java}
        final DataContext dataContext = (DataContext) runtime.newContext();
        final DataObject girlEmma = (DataObject) dataContext.newObject("Girl");
        girlEmma.writeProperty("reference", "g1");
        girlEmma.writeProperty("name", "Emma");
        girlEmma.writeProperty("toyDolls", 5);

        final DataObject boyLuke = (DataObject) dataContext.newObject("Boy");
        boyLuke.writeProperty("reference", "b1");
        boyLuke.writeProperty("name", "Luke");
        boyLuke.writeProperty("toyTrucks", 12);

        dataContext.commitChanges();
{code}
{noformat}
15:43:22.418 [main] INFO  org.apache.cayenne.log.JdbcEventLogger - --- 
transaction started.
15:43:22.420 [main] INFO  org.apache.cayenne.log.JdbcEventLogger - INSERT INTO 
poly.student (name, reference, type, uuid) VALUES (?, ?, ?, ?)
15:43:22.429 [main] INFO  org.apache.cayenne.log.JdbcEventLogger - [bind: 
1->name:'Emma', 2->reference:'g1', 3->type:'G', 
4->uuid:3fed46ae-a9d6-45c7-a306-402a0710e5a1]
15:43:22.435 [main] INFO  org.apache.cayenne.log.JdbcEventLogger - === updated 
1 row.
15:43:22.437 [main] INFO  org.apache.cayenne.log.JdbcEventLogger - [bind: 
1->name:'Luke', 2->reference:'b1', 3->type:'G', 
4->uuid:f113e95a-8727-414d-8ed4-ed08ba80c48b]
15:43:22.443 [main] INFO  org.apache.cayenne.log.JdbcEventLogger - === updated 
1 row.
15:43:22.445 [main] INFO  org.apache.cayenne.log.JdbcEventLogger - INSERT INTO 
poly.girl (toy_dolls, uuid) VALUES (?, ?)
15:43:22.450 [main] INFO  org.apache.cayenne.log.JdbcEventLogger - [bind: 
1->toy_dolls:5, 2->uuid:3fed46ae-a9d6-45c7-a306-402a0710e5a1]
15:43:22.454 [main] INFO  org.apache.cayenne.log.JdbcEventLogger - === updated 
1 row.
15:43:22.455 [main] INFO  org.apache.cayenne.log.JdbcEventLogger - INSERT INTO 
poly.boy (toy_trucks, uuid) VALUES (?, ?)
15:43:22.460 [main] INFO  org.apache.cayenne.log.JdbcEventLogger - [bind: 
1->toy_trucks:12, 2->uuid:f113e95a-8727-414d-8ed4-ed08ba80c48b]
15:43:22.464 [main] INFO  org.apache.cayenne.log.JdbcEventLogger - === updated 
1 row.
15:43:22.487 [main] INFO  org.apache.cayenne.log.JdbcEventLogger - +++ 
transaction committed.
{noformat}
 

It inserts 2 records into [student], 1 record into [boy], 1 record into [boy], 
but the [type] on both student records is "G", instead of one "B" and one "G".

Its doing this because of a bug during BaseContext.injectInitialValue when 
creating the Boy ... the line:
 getEntityResolver().getObjEntity(object.getClass()) its returning the "Girl" 
ObjEntity
 the MappingCache.objEntitiesByClassName holds an entry for "CayenneDataObject" 
with value for Girl ObjEntity. When using Generics there will be many 
ObjEntities that use CayenneDataObject, so we shouldn't be asking for it from 
this cache Map.

we should use: getEntityResolver().getObjEntity((Persistent)object) because 
that one is properly getting the correct ObjEntity from the ObjectId, in 
MappingCache.getObjEntity(Persistent object)

I can work on a breaking test, and potential fix



--
This message was sent by Atlassian Jira
(v8.3.4#803005)

Reply via email to