[ 
https://issues.apache.org/jira/browse/CAY-2964?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Andrus Adamchik updated CAY-2964:
---------------------------------
    Description: 
Given this mapping (meaningful PK that is not an Integer or a Long) :
{noformat}
<db-entity name="MEANINGFUL_PK_BIGINT">
  <db-attribute name="PK" type="INTEGER" isPrimaryKey="true" 
isMandatory="true"/>
</db-entity>
...
<obj-entity name="MeaningfulPkBigint" 
className="org.apache.cayenne.testdo.meaningful_pk.MeaningfulPkBigint" 
dbEntityName="MEANINGFUL_PK_BIGINT">
  <obj-attribute name="pk" type="java.math.BigInteger" db-attribute-path="PK"/>
</obj-entity>{noformat}
Committing a new object throws:
{noformat}
Caused by: java.lang.ClassCastException: class java.lang.Integer cannot be cast 
to class java.math.BigInteger
    at 
org.apache.cayenne.testdo.meaningful_pk.auto._MeaningfulPkBigint.writePropertyDirectly(_MeaningfulPkBigint.java:65)
    at 
org.apache.cayenne.reflect.generic.PersistentObjectBaseProperty.writePropertyDirectly(PersistentObjectBaseProperty.java:84)
    at 
org.apache.cayenne.access.flush.ReplacementIdVisitor.updateId(ReplacementIdVisitor.java:106)
    at 
org.apache.cayenne.access.flush.ReplacementIdVisitor.visitInsert(ReplacementIdVisitor.java:56)
    at 
org.apache.cayenne.access.flush.ReplacementIdVisitor.visitInsert(ReplacementIdVisitor.java:42)
    at 
org.apache.cayenne.access.flush.operation.InsertDbRowOp.accept(InsertDbRowOp.java:40)
    at 
org.apache.cayenne.access.flush.DefaultDataDomainFlushAction.lambda$createReplacementIds$0(DefaultDataDomainFlushAction.java:211){noformat}
Root cause: JdbcPkGenerator.generatePk() types the generated value from the DB 
column only (Long for BIGINT, Integer otherwise). 
ReplacementIdVisitor.updateId() then writes it directly into the meaningful-PK 
property without coercion.

JDBC generated keys are unaffected because BatchAction.typeForGeneratedPK() 
already coerces to the ObjAttribute type.

  was:
Given this mapping:
{noformat}
<db-entity name="MEANINGFUL_PK_BIGINT_GENERATED">
    <db-attribute name="PK" type="INTEGER" isPrimaryKey="true" 
isGenerated="true" isMandatory="true"/>
    <db-attribute name="TEST_ATTR" type="VARCHAR" length="255"/>
</db-entity>

<obj-entity name="MeaningfulPkBigintGenerated" 
className="org.apache.cayenne.testdo.meaningful_pk.MeaningfulPkBigintGenerated" 
dbEntityName="MEANINGFUL_PK_BIGINT_GENERATED">
  <obj-attribute name="pk" type="java.math.BigInteger" db-attribute-path="PK"/>
  <obj-attribute name="testAttr" type="java.lang.String" 
db-attribute-path="TEST_ATTR"/>
</obj-entity> {noformat}
On adapters that do not support JDBC-generated keys (Oracle, Firebird, 
FrontBase and default JdbcAdapter), committing a new object whose generated 
meaningful PK is mapped to an ObjAttribute Java type different from the DB 
column type throws:
{noformat}
java.lang.ClassCastException: class java.lang.Integer cannot be cast 
to class java.math.BigInteger
at ReplacementIdVisitor.updateId(ReplacementIdVisitor.java:106){noformat}
Root cause: JdbcPkGenerator.generatePk() types the generated value from the DB 
column only (Long for BIGINT, Integer otherwise). 
ReplacementIdVisitor.updateId() then writes it directly into the meaningful-PK 
property without coercion. Adapters using JDBC generated keys are unaffected 
because BatchAction.typeForGeneratedPK() already coerces to the ObjAttribute 
type.

 

_Does it also affect every other DbAdapter for tables with meaningful PKs that 
are not auto-incremented?_


> ClassCastException for non-generated meaningful PKs
> ---------------------------------------------------
>
>                 Key: CAY-2964
>                 URL: https://issues.apache.org/jira/browse/CAY-2964
>             Project: Cayenne
>          Issue Type: Bug
>            Reporter: Andrus Adamchik
>            Assignee: Andrus Adamchik
>            Priority: Major
>             Fix For: 5.0-M3
>
>
> Given this mapping (meaningful PK that is not an Integer or a Long) :
> {noformat}
> <db-entity name="MEANINGFUL_PK_BIGINT">
>   <db-attribute name="PK" type="INTEGER" isPrimaryKey="true" 
> isMandatory="true"/>
> </db-entity>
> ...
> <obj-entity name="MeaningfulPkBigint" 
> className="org.apache.cayenne.testdo.meaningful_pk.MeaningfulPkBigint" 
> dbEntityName="MEANINGFUL_PK_BIGINT">
>   <obj-attribute name="pk" type="java.math.BigInteger" 
> db-attribute-path="PK"/>
> </obj-entity>{noformat}
> Committing a new object throws:
> {noformat}
> Caused by: java.lang.ClassCastException: class java.lang.Integer cannot be 
> cast to class java.math.BigInteger
>     at 
> org.apache.cayenne.testdo.meaningful_pk.auto._MeaningfulPkBigint.writePropertyDirectly(_MeaningfulPkBigint.java:65)
>     at 
> org.apache.cayenne.reflect.generic.PersistentObjectBaseProperty.writePropertyDirectly(PersistentObjectBaseProperty.java:84)
>     at 
> org.apache.cayenne.access.flush.ReplacementIdVisitor.updateId(ReplacementIdVisitor.java:106)
>     at 
> org.apache.cayenne.access.flush.ReplacementIdVisitor.visitInsert(ReplacementIdVisitor.java:56)
>     at 
> org.apache.cayenne.access.flush.ReplacementIdVisitor.visitInsert(ReplacementIdVisitor.java:42)
>     at 
> org.apache.cayenne.access.flush.operation.InsertDbRowOp.accept(InsertDbRowOp.java:40)
>     at 
> org.apache.cayenne.access.flush.DefaultDataDomainFlushAction.lambda$createReplacementIds$0(DefaultDataDomainFlushAction.java:211){noformat}
> Root cause: JdbcPkGenerator.generatePk() types the generated value from the 
> DB column only (Long for BIGINT, Integer otherwise). 
> ReplacementIdVisitor.updateId() then writes it directly into the 
> meaningful-PK property without coercion.
> JDBC generated keys are unaffected because BatchAction.typeForGeneratedPK() 
> already coerces to the ObjAttribute type.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to