You are viewing a plain text version of this content. The canonical link for it is here.
Posted to ojb-user@db.apache.org by Rajesh T V <rt...@gmail.com> on 2006/05/08 12:24:17 UTC

Re: IllegalAccess error setting field in db-ojb-1.0.3

Hi Armin,

I did see the more detailed error from OJB. The error happened on
a different set of classes this time.

[try to set 'object value' in 'target object'
target obj class: com.cisco.ipce.engine.datamodel.CUEUserGroup
target field name: lnkCUEPrivilege*
target field type: class com.cisco.ipce.engine.datamodel.CUEPrivilege
*target field declared in: com.cisco.ipce.engine.datamodel.CUEUserGroup
*object value class: com.cisco.ipce.engine.datamodel.CUEUserGroup
*object value: com.cisco.ipce.engine.datamodel.CUEUserGroup@1c7d5b2
]

After a lot of debugging the root cause seems to be a corrupted
cache caused by a duplicate OID for a class in the same hierarchy.

In the above example, CUEUserGroup holds a reference to CUEPrivilege and
both are instances of the same base class.

During insertion of the CUEUserGroup, the SequenceManager allocates a
primary key id to CUEUserGroup but needs a trip to the OJB_HL_SEQ to get
an ID for the CUEPrivilege.

Due to the way our application is designed, we end up removing the OJB_HL_SEQ
from the database before this operation. OJB hence calculates the new
highest primary key value by searching across all extent classes in
the database.

SequenceManagerHelper.getMaxForExtent
does not take into account the ID allocated to the CUEUserGroup since
it only searches in the database for the maximum primary key allocated
so far. It hence ends up allocating the same ID to the CUEPrivilege
inserted next.

This finally causes the cache to pick up a CUEUserGroup class instead
of the CUEPrivilege while setting the linkCUEPrivilege data member on
CUEUserGroup and leads to the exception from Java.

I would think that either the OJB documentation should warn against
deletion of the OJB_HL_SEQ entry OR ensure that this corner case is handled.

Pls let me know what you feel.

Rgds,
Rajesh

Hi Rajesh,

Rajesh T V wrote:
> Hi Armin,
> Thanks for your reply.Reply inline.
> -Rajesh
>
> does OJB log a more detailed error message?
>>>> no

Please search for this message in your log file again. If you use OJB
1.0.3 or higher OJB will log a detailed error message before the
exception was thrown.
For 1.0.3 it begins with "try to set 'object value' in 'target
object..." or something similar.

Please post the whole stack trace with the logging messages before the
exception occur.

regards,
Armin



On 4/27/06, Rajesh T V <rt...@gmail.com> wrote:
>
> Hi,
>
> We are hitting an intermittent issue with db-ojb-1.0.3.
>
> At random times we hit the following exception while ojb
> tries to create an object from a Derby db.
>
> org.apache.ojb.broker.PersistenceBrokerException:
> org.apache.ojb.broker.metadata.MetadataException: IllegalAccess error
> setting field:userAccount in
> object:com.cisco.ipce.engine.datamodel.EndUser
> at org.apache.ojb.broker.core.QueryReferenceBroker.getCollectionByQuery
> (Unknown
> Source)
> at org.apache.ojb.broker.core.QueryReferenceBroker.getCollectionByQuery
> (Unknown
> Source)
> at org.apache.ojb.broker.core.PersistenceBrokerImpl.getCollectionByQuery
> (Unknown
> Source)
> at
> org.apache.ojb.broker.core.DelegatingPersistenceBroker.getCollectionByQuery
> (Unknown
> Source)
> at
> org.apache.ojb.broker.core.DelegatingPersistenceBroker.getCollectionByQuery
> (Unknown
> Source)
> at com.cisco.ipce.engine.sal.dataaccess.DBDAO.get(DBDAO.java:367)
>
> The root cause being a
> Caused by: java.lang.IllegalArgumentException at
> sun.reflect.UnsafeObjectFieldAccessorImpl.set(
> UnsafeObjectFieldAccessorImpl.java:63)
>         at java.lang.reflect.Field.set(Field.java:656)
>         ... 59 more
>
> The error occurs on different classes at different times. Once we hit
> the error, it does
> not go away no matter what we do (tomcat restart etc). Once the
> problem stops happening
> (sometimes on pc restart) it never happens again for a long time.
>
> Our repository_user.xml for all classes are similar.
>
> <class-descriptor class="com.cisco.ipce.engine.datamodel.EndUser"
>   table="UserBase">
>   <field-descriptor column="OID" jdbc-type="INTEGER" name="OID"
> autoincrement="true" primarykey="true"/>
> <field-descriptor column="userAccountId" jdbc-type="INTEGER"
> name="userAccountId"/>
>   <reference-descriptor name="userAccount"
> class-ref="com.cisco.ipce.engine.datamodel.IPCEUserAccount"
> auto-retrieve="true" auto-update="object" auto-delete="object" >
>          <foreignkey field-ref="userAccountId"/>
>     </reference-descriptor>
>   <field-descriptor column="type" jdbc-type="INTEGER" name="type"/>
>
>
> public class EndUser extends UserBase {
> ...
> ...
>
> }
>
> public abstract class UserBase extends IPCEObject{
> ...
> ....
>
> protected UserAccount userAccount;
> ...
> }
>
> I am not sure what we are doing wrong and even if we are why is the
> error intermittent ?
>
> All classes where the error occurs have the same pattern where a
> protected attribute
> of the super-class is being set via the sub-class repository_user.xml
> entry. The attribute
> is always an auto-retrieve=true; auto-update="object" and
> auto-delete="object" class to
> which the offending class holds a foreign key.
>
> Any help appreciated.
>
> Thanks,
> Rajesh
>

Re: IllegalAccess error setting field in db-ojb-1.0.3

Posted by Armin Waibel <ar...@apache.org>.
Hi Rajesh,

Rajesh T V wrote:
> Hi Armin,
> 
> I did see the more detailed error from OJB. The error happened on
> a different set of classes this time.
> 
> [try to set 'object value' in 'target object'
> target obj class: com.cisco.ipce.engine.datamodel.CUEUserGroup
> target field name: lnkCUEPrivilege*
> target field type: class com.cisco.ipce.engine.datamodel.CUEPrivilege
> *target field declared in: com.cisco.ipce.engine.datamodel.CUEUserGroup
> *object value class: com.cisco.ipce.engine.datamodel.CUEUserGroup
> *object value: com.cisco.ipce.engine.datamodel.CUEUserGroup@1c7d5b2
> ]
> 
> After a lot of debugging the root cause seems to be a corrupted
> cache caused by a duplicate OID for a class in the same hierarchy.
> 
> In the above example, CUEUserGroup holds a reference to CUEPrivilege and
> both are instances of the same base class.
> 
> During insertion of the CUEUserGroup, the SequenceManager allocates a
> primary key id to CUEUserGroup but needs a trip to the OJB_HL_SEQ to get
> an ID for the CUEPrivilege.
> 
> Due to the way our application is designed, we end up removing the 
> OJB_HL_SEQ
> from the database before this operation. OJB hence calculates the new
> highest primary key value by searching across all extent classes in
> the database.
> 
> SequenceManagerHelper.getMaxForExtent
> does not take into account the ID allocated to the CUEUserGroup since
> it only searches in the database for the maximum primary key allocated
> so far. It hence ends up allocating the same ID to the CUEPrivilege
> inserted next.
> 
> This finally causes the cache to pick up a CUEUserGroup class instead
> of the CUEPrivilege while setting the linkCUEPrivilege data member on
> CUEUserGroup and leads to the exception from Java.
> 
> I would think that either the OJB documentation should warn against
> deletion of the OJB_HL_SEQ entry OR ensure that this corner case is 
> handled.

This isn't the intended use of OJB's HL-sequence manager ;-) Sorry, but 
it's nearly impossible to document all side-effects of "specific usage".

Anyway it's strange. The SequenceManagerHelper.getMaxForExtent call in 
HL-SMImpl use the same broker instance (connection) thus it should find 
all uncommitted ID's too. Only if the ID was assigned to CUEUserGroup 
and the OJB_HL_SEQ entry was removed before the insert call.

This behavior (internally) changed in 1.0.4, because OJB have to be more 
strict in assign of sequence keys (to fix a inheritance problem and be 
more compatible with database identity column based SM). Now OJB assign 
the sequence key directly before the insert call.

regards,
Armin

> 
> Pls let me know what you feel.
> 
> Rgds,
> Rajesh
> 
> Hi Rajesh,
> 
> Rajesh T V wrote:
>> Hi Armin,
>> Thanks for your reply.Reply inline.
>> -Rajesh
>>
>> does OJB log a more detailed error message?
>>>>> no
> 
> Please search for this message in your log file again. If you use OJB
> 1.0.3 or higher OJB will log a detailed error message before the
> exception was thrown.
> For 1.0.3 it begins with "try to set 'object value' in 'target
> object..." or something similar.
> 
> Please post the whole stack trace with the logging messages before the
> exception occur.
> 
> regards,
> Armin
> 
> 
> 
> On 4/27/06, Rajesh T V <rt...@gmail.com> wrote:
>>
>> Hi,
>>
>> We are hitting an intermittent issue with db-ojb-1.0.3.
>>
>> At random times we hit the following exception while ojb
>> tries to create an object from a Derby db.
>>
>> org.apache.ojb.broker.PersistenceBrokerException:
>> org.apache.ojb.broker.metadata.MetadataException: IllegalAccess error
>> setting field:userAccount in
>> object:com.cisco.ipce.engine.datamodel.EndUser
>> at org.apache.ojb.broker.core.QueryReferenceBroker.getCollectionByQuery
>> (Unknown
>> Source)
>> at org.apache.ojb.broker.core.QueryReferenceBroker.getCollectionByQuery
>> (Unknown
>> Source)
>> at org.apache.ojb.broker.core.PersistenceBrokerImpl.getCollectionByQuery
>> (Unknown
>> Source)
>> at
>> org.apache.ojb.broker.core.DelegatingPersistenceBroker.getCollectionByQuery 
>>
>> (Unknown
>> Source)
>> at
>> org.apache.ojb.broker.core.DelegatingPersistenceBroker.getCollectionByQuery 
>>
>> (Unknown
>> Source)
>> at com.cisco.ipce.engine.sal.dataaccess.DBDAO.get(DBDAO.java:367)
>>
>> The root cause being a
>> Caused by: java.lang.IllegalArgumentException at
>> sun.reflect.UnsafeObjectFieldAccessorImpl.set(
>> UnsafeObjectFieldAccessorImpl.java:63)
>>         at java.lang.reflect.Field.set(Field.java:656)
>>         ... 59 more
>>
>> The error occurs on different classes at different times. Once we hit
>> the error, it does
>> not go away no matter what we do (tomcat restart etc). Once the
>> problem stops happening
>> (sometimes on pc restart) it never happens again for a long time.
>>
>> Our repository_user.xml for all classes are similar.
>>
>> <class-descriptor class="com.cisco.ipce.engine.datamodel.EndUser"
>>   table="UserBase">
>>   <field-descriptor column="OID" jdbc-type="INTEGER" name="OID"
>> autoincrement="true" primarykey="true"/>
>> <field-descriptor column="userAccountId" jdbc-type="INTEGER"
>> name="userAccountId"/>
>>   <reference-descriptor name="userAccount"
>> class-ref="com.cisco.ipce.engine.datamodel.IPCEUserAccount"
>> auto-retrieve="true" auto-update="object" auto-delete="object" >
>>          <foreignkey field-ref="userAccountId"/>
>>     </reference-descriptor>
>>   <field-descriptor column="type" jdbc-type="INTEGER" name="type"/>
>>
>>
>> public class EndUser extends UserBase {
>> ...
>> ...
>>
>> }
>>
>> public abstract class UserBase extends IPCEObject{
>> ...
>> ....
>>
>> protected UserAccount userAccount;
>> ...
>> }
>>
>> I am not sure what we are doing wrong and even if we are why is the
>> error intermittent ?
>>
>> All classes where the error occurs have the same pattern where a
>> protected attribute
>> of the super-class is being set via the sub-class repository_user.xml
>> entry. The attribute
>> is always an auto-retrieve=true; auto-update="object" and
>> auto-delete="object" class to
>> which the offending class holds a foreign key.
>>
>> Any help appreciated.
>>
>> Thanks,
>> Rajesh
>>
> 

---------------------------------------------------------------------
To unsubscribe, e-mail: ojb-user-unsubscribe@db.apache.org
For additional commands, e-mail: ojb-user-help@db.apache.org