-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 5 posts ] 
Author Message
 Post subject: ClassCastException in ComponentType.isModified(...)
PostPosted: Tue Oct 12, 2004 3:00 am 
Newbie

Joined: Mon Sep 27, 2004 9:40 am
Posts: 11
Location: Ostrava, Czech Republic
Hi,
I have many-to-one relation to a class with composite id. While trying to persist, I get this exception:

java.lang.ClassCastException
at net.sf.hibernate.type.ComponentType.isModified(ComponentType.java:420)
at net.sf.hibernate.type.ManyToOneType.isModified(ManyToOneType.java:81)
at net.sf.hibernate.type.TypeFactory.findModified(TypeFactory.java:249)
at net.sf.hibernate.persister.AbstractEntityPersister.findModified(AbstractEntityPersister.java:291)
at net.sf.hibernate.impl.SessionImpl.flushEntity(SessionImpl.java:2532)
at net.sf.hibernate.impl.SessionImpl.flushEntities(SessionImpl.java:2477)
at net.sf.hibernate.impl.SessionImpl.flushEverything(SessionImpl.java:2279)
at net.sf.hibernate.impl.SessionImpl.flush(SessionImpl.java:2258)
at net.sf.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:61)
at org.springframework.orm.hibernate.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:460)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:373)
at
.....


If I try to debug, the ComponentType.isModified(...) method gets old and current object to compare and they are the same type (instances of the composite ID class). So far it is OK, I think. But why the current values are extracted in different way than the old ones?
Because this is the reason why I get the ClassCastException, I can't cast instance of my composite ID class to Object[].

Shouldn't be the old values extracted like "Object[] oldValues = getPropertyValues(old, session);" instead of "Object[] oldValues = (Object[]) old;".
If I make a new build of Hibernate with this change, everything gets persisted correctly.
So I don't know if this is a bug or if I'm doing something wrong? Maybe mappings are wrong?

This is example of my mappings:

many side:

.....
<many-to-one
name="myPropertyName"
class="OneSideClass"
cascade="none"
outer-join="auto"
update="true"
insert="true"
access="property"
>
<column
name="column_1"
/>
<column
name="column_2"
/>
</many-to-one>
.....

one side:

<class
name="OneSideClass"
table="OneSideClassTable"
dynamic-update="false"
dynamic-insert="false"
mutable="false"
>
<composite-id
name="id"
class="composite_ID_class"
unsaved-value="none"
>
<key-property
name="property_1"
type="java.lang.String"
column="column_1"
/>

<key-property
name="property_2"
type="java.lang.String"
column="column_2"
/>

</composite-id>
.....

Thanks for any ideas or comments.

Pavel


Top
 Profile  
 
 Post subject:
PostPosted: Tue Oct 12, 2004 11:13 pm 
Regular
Regular

Joined: Tue Sep 09, 2003 9:37 pm
Posts: 56
Location: Ogden, Utah, USA
It might be that your equals method doesn't first check to see that it's comparing objects of the same type? I've gotten a ClassCastException for that reason but I don't remember the stack trace.

What version of hibernate are you using? I use 2.1 and that line number isn't valid, so that must not be your version. :)

Jenica


Top
 Profile  
 
 Post subject:
PostPosted: Tue Oct 12, 2004 11:14 pm 
Regular
Regular

Joined: Tue Sep 09, 2003 9:37 pm
Posts: 56
Location: Ogden, Utah, USA
It might be that your equals method doesn't first check to see that it's comparing objects of the same type? I've gotten a ClassCastException for that reason but I don't remember the stack trace.

What version of hibernate are you using? I use 2.1 and that line number isn't valid, so that must not be your version. :)

Jenica


Top
 Profile  
 
 Post subject:
PostPosted: Wed Oct 13, 2004 5:58 am 
Newbie

Joined: Mon Sep 27, 2004 9:40 am
Posts: 11
Location: Ostrava, Czech Republic
Thanks Jenica, but I don't believe it solves my problem. In every equals method I have I check the compared object to be an instance of the same class as this.

Sorry for not stating my Hibernate version - it's 2.1.6.

I found a workaround, the object on many side is used only for reading purposes (mapping with attributes insert="false" and update="false") and then I have two additional getter and setter method to persist both properties of composite ID key. The setters are empty and getters return values from the object. Although it works, I don't really like the solution much, I believe there has to be the way to force the object to persist its composite ID properties itself.

As I see it, the ComponentType.isModified(...) is used for dirty data checking, but I don't know why are old and new values (which are instances of the same class) extracted differently and why the old value is cast to Object[]. I'm really confused how this can work...

Maybe it's really my bug somewhere in mappings or I understand the dirty data checking problem wrong, so I would be grateful for any other ideas.

Thanks,
Pavel


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jan 03, 2007 10:32 am 
Newbie

Joined: Wed Jan 03, 2007 9:37 am
Posts: 1
I also got the same exception: ClassCastException.
I'm using Hibernate-Version: 3.1.2

--- description ---

I tried to implement a custom authorization check using a PreUpdate listener and tried to see which fields are changed.
I have a component field (a contained object) that is changed.

The first lines of the stacktrace looks like

Code:
Thread [http-0.0.0.0-80-Processor23] (Suspended (exception ClassCastException))
   ComponentType.isModified(Object, Object, boolean[], SessionImplementor) line: 212
   TypeFactory.findModified(StandardProperty[], Object[], Object[], boolean[][], boolean, SessionImplementor) line: 520
   JoinedSubclassEntityPersister(AbstractEntityPersister).findModified(Object[], Object[], Object, SessionImplementor) line: 2832
   CheckUpdate.onPreUpdate(PreUpdateEvent) line: 44
   EntityUpdateAction.preUpdate() line: 209

...


The method isModified looks like (>>> indicates exception)

Code:
   public boolean isModified(Object old, Object current, boolean[] checkable, SessionImplementor session)
         throws HibernateException {
      
      if ( current == null ) return old != null;
      if ( old == null ) return current != null;
      Object[] currentValues = getPropertyValues( current, session );
>>>      Object[] oldValues = ( Object[] ) old;
      int loc = 0;
      for ( int i = 0; i < currentValues.length; i++ ) {
         int len = propertyTypes[i].getColumnSpan( session.getFactory() );
         boolean[] subcheckable = new boolean[len];
         System.arraycopy(checkable, loc, subcheckable, 0, len);
         if ( propertyTypes[i].isModified( oldValues[i], currentValues[i], subcheckable, session ) ) {
            return true;
         }
         loc += len;
      }
      return false;
      
   }



And my local variables are:

Code:
this= ComponentType  (id=466)
old= ValidPeriodImpl  (id=471)
current= ValidPeriodImpl  (id=474)
checkable= boolean[2]  (id=475)
session= SessionImpl  (id=476)
currentValues= Object[2]  (id=484)


The componenttype contained object is the ValidPeriodImpl that is successfully transformed to an object array for the current state (currentValues) but the old state (that also is a ValidPeriodImpl) is cast to an object array and therefore causing a classcastexception.

---

I have now changed my code in my eventlistener to use findDirty instead of findModified and it seems to work better! I still get back an array of changed indexes so I think it could be used as a workaround. Maybe?

If someone has another opinion I would gladely read it.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 5 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.