Hello list,
after upgrade from v0.9.4 to v0.9.6 castor some strange error occurs.
Actually we have a bug with updating entity 'BradenScale' [1]. Let me
explain the situation.
Steps:
1. run server & client instance(of our software)
2. create an object type BradenScale
3. try to update created[4] object BradenScale - no problem
4. restart client&server instance
5. try to update created[4] object BradenScale - crash due
ClassCastException
Sugesstions:
Step 1-3 runs in one instance (withs one castor cache). The attributes
BradenScale#createdFrom and BradenScale#invalidatedFrom ares type
CareGiver[2]. Indentity for CareGiver are also java.lang.Integer. Castor
use in step 1-3 for this two members the SQL Type=4
(java.sql.Types.INTEGER) in SQLEngine.ColumnInfo#sqlType. Thats ok and
expected. After restart application castor use for this member SQL Type
2 (java.sql.Types.NUMERIC) in SQLEngine.ColumnInfo#sqlType, but the
identity for CareGiver stills java.lang.Integer! This behaviour leads to
a ClassCastException[3], because castor use BigDecimal as default for
Nummerics.
Please have a look on mapping. I can't find any wrong configuration. It
must be an bug inside castor.
Thank in advance for any hints, solutions or wathever. Iam at lost
(oncemore again).
Greets
Andre Teubner
Appendix:
[1] BradenScale mapping
<class name="com.morixs.mcare.bo.holder.care.braden.BradenScale"
identity="id">
<map-to xml="BradenScale" table="BRADEN_SCALE"/>
<field name="id" type="java.lang.Integer">
<sql name="ID"/>
<bind-xml name="id" node="attribute"/>
</field>
<field name="createdFrom" type="com.morixs.mcare.bo.holder.misc.CareGiver">
<sql name="CREATED_FROM"/>
<bind-xml name="createdFrom" node="element"/>
</field>
<field name="createdOn" type="date">
<sql name="CREATED_ON"/>
<bind-xml name="createdOn" node="element"/>
</field>
<field name="invalidatedFrom"
type="com.morixs.mcare.bo.holder.misc.CareGiver">
<sql name="INVALIDATED_FROM"/>
<bind-xml name="invalidatedFrom" node="element"/>
</field>
<field name="invalidatedOn" type="date">
<sql name="INVALIDATED_ON"/>
<bind-xml name="invalidatedOn" node="element"/>
</field>
<field name="invalidScale" type="boolean" get-method="isInvalidScale"
set-method="setInvalidScale">
<sql name="IS_INVALID"/>
<bind-xml name="invalidScale" node="element"/>
</field>
<field name="patientId" type="java.lang.Integer">
<sql name="PATIENT_ID"/>
<bind-xml name="patientId" node="element"/>
</field>
<field name="questionsList"
type="com.morixs.mcare.bo.holder.misc.scalelist.AnsweredQuestionList">
<sql name="QUESTION_LIST"/>
<bind-xml name="questionsList" node="element"/>
</field>
</class>
[2] CareGiver mapping
<class name="com.morixs.mcare.bo.holder.misc.CareGiver"
extends="com.morixs.mcare.util.usermanagement.User" identity="id">
<description>Eine Pflegekraft</description>
<map-to table="CARE_GIVER" xml="CareGiver"/>
<field name="id" type="java.lang.Integer">
<sql name="ID"/>
<bind-xml name="id" node="attribute" transient="true"/>
</field>
<field name="externalKey" type="java.lang.Integer">
<sql name="EXTERNAL_KEY"/>
<bind-xml name="externalKey" node="element" transient="true"/>
</field>
<field name="memberInWards" type="com.morixs.mcare.bo.holder.misc.Ward"
collection="collection">
<sql many-table="CAREGIVERS_TO_WARDS" many-key="CAREGIVER_ID"/>
<bind-xml name="memberInWards" node="element" transient="true"/>
</field>
</class>
[3] stacktrace
2005-04-27 10:12:25,998 [RMI TCP Connection(88)-127.0.0.1] FATAL A1 -
CanÂt commit transaction || SessionCastorContext.commitTransaction() L: 268
org.exolab.castor.jdo.TransactionAbortedException: Nested error:
java.lang.ClassCastException: java.lang.Integer: java.lang.Integer
at
org.exolab.castor.persist.TransactionContext.prepare(TransactionContext.java:1654)
at org.exolab.castor.jdo.engine.DatabaseImpl.commit(DatabaseImpl.java:545)
at
com.morixs.mcare.ct.SessionCastorContext.commitTransaction(SessionCastorContext.java:264)
at
com.morixs.mcare.uc.care.braden.BradenScaleUC.invalidateBradenScale(BradenScaleUC.java:306)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at sun.rmi.server.UnicastServerRef.dispatch(Unknown Source)
at sun.rmi.transport.Transport$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.Transport.serviceCall(Unknown Source)
at sun.rmi.transport.tcp.TCPTransport.handleMessages(Unknown Source)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.ClassCastException: java.lang.Integer
at org.exolab.castor.jdo.engine.SQLTypes$13.convert(SQLTypes.java:733)
at org.exolab.castor.jdo.engine.SQLEngine.toJava(SQLEngine.java:471)
at org.exolab.castor.jdo.engine.SQLEngine.store(SQLEngine.java:922)
at org.exolab.castor.persist.ClassMolder.store(ClassMolder.java:1620)
at org.exolab.castor.persist.LockEngine.store(LockEngine.java:755)
at
org.exolab.castor.persist.TransactionContext.prepare(TransactionContext.java:1599)
... 14 more
java.lang.ClassCastException: java.lang.Integer
at org.exolab.castor.jdo.engine.SQLTypes$13.convert(SQLTypes.java:733)
at org.exolab.castor.jdo.engine.SQLEngine.toJava(SQLEngine.java:471)
at org.exolab.castor.jdo.engine.SQLEngine.store(SQLEngine.java:922)
at org.exolab.castor.persist.ClassMolder.store(ClassMolder.java:1620)
at org.exolab.castor.persist.LockEngine.store(LockEngine.java:755)
at
org.exolab.castor.persist.TransactionContext.prepare(TransactionContext.java:1599)
at org.exolab.castor.jdo.engine.DatabaseImpl.commit(DatabaseImpl.java:545)
at
com.morixs.mcare.ct.SessionCastorContext.commitTransaction(SessionCastorContext.java:264)
at
com.morixs.mcare.uc.care.braden.BradenScaleUC.invalidateBradenScale(BradenScaleUC.java:306)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at sun.rmi.server.UnicastServerRef.dispatch(Unknown Source)
at sun.rmi.transport.Transport$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.Transport.serviceCall(Unknown Source)
at sun.rmi.transport.tcp.TCPTransport.handleMessages(Unknown Source)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
[4] update code
/*
* (non-Javadoc)
*
* @see
com.morixs.mcare.ds.IBradenScaleDS#updateBradenScale(com.morixs.mcare.bo.holder.care.braden.BradenScale,
* com.morixs.mcare.ct.ISessionContext)
*/
public BradenScale updateBradenScale(BradenScale pScale, ISessionContext
pCtx) throws DataStorageException
{
try
{
ISessionCastorContext ctx = (ISessionCastorContext) pCtx;
Database db = ctx.getDatabase();
BradenScale bradenScale = (BradenScale) db.load(BradenScale.class,
pScale.getId());
bradenScale.setInvalidScale(pScale.isInvalidScale());
bradenScale.setInvalidatedOn(pScale.getInvalidatedOn());
if(pScale.getInvalidatedFrom()!=null){
CareGiver careGiver = (CareGiver)
db.load(CareGiver.class,pScale.getInvalidatedFrom().getId());
bradenScale.setInvalidatedFrom(careGiver);
}else{
bradenScale.setInvalidatedFrom(null);
}
return pScale;
} catch (Exception ex)
{
pCtx.errorOccurred();
Log.getInstance().fatal(ex.getMessage(), ex);
throw new DataStorageException("Fehler beim Update der Bradenskala");
}
}