-->
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.  [ 14 posts ] 
Author Message
 Post subject: PropertyAccessException from CGLIB,Component = java.sql.Date
PostPosted: Wed Feb 01, 2006 8:24 pm 
Newbie

Joined: Wed Feb 01, 2006 8:00 pm
Posts: 2
Location: Auckland
I am getting a PropertyAccessException exception from CGLIB when I have a Component that contains a java.sql.Date property that is mapped as a "timestamp".

I have observed the following facts:
1) If I use java.util.Date instead of java.sql.Date it works.
2) If I map as a "date" instead of a "timestamp" it works.
3) I only get this problem for Components, top level properties work as "date" and "timestamp" for both java.sql.Date and java.util.Date


Therefore it appears the exception is limited to "timestamp" mapped java.sql.Date properties within a component. All other variations work.



I have included relevant code snippets below. This is trivial to reproduce. I can forward the complete code if necessary.

I am using Hibernate version: 3.1.2 Java: 1.4.2 MS SQLServer database. I am using the new Microsoft JDBC driver.


Example code snippets
==

import java.sql.Date;

public class Person {
private String name;
private Date dob;
private Changed changed;

// has appropriate getters and setters

}

==

import java.sql.Date;

public class Changed {
private Date addedOn; // this property is the problem!
private String chgdBy;

// has appropriate getters and setters

}

==

<property name="name" type="string" column="p_name" />
<property name="dob" type="date" column="p_dob" />
<component name="changed" class="Changed">
<property name="addedOn" type="timestamp" column="p_added_on" />
<property name="chgdBy" type="string" column="p_chgd_by" />
</component>

==

The log file contains this exception

2006-02-02 13:01:59,474 - INFO - Error performing load command
org.hibernate.PropertyAccessException: exception setting property value with CGLIB (set hibernate.cglib.use_reflection_optimizer=false for more info) setter of com.fujitsu.lis.nz.cv.model.Changed.setAddedOn
at org.hibernate.tuple.PojoComponentTuplizer.setPropertyValues(PojoComponentTuplizer.java:101)
at org.hibernate.type.ComponentType.setPropertyValues(ComponentType.java:312)
at org.hibernate.type.ComponentType.resolve(ComponentType.java:530)
at org.hibernate.engine.TwoPhaseLoad.initializeEntity(TwoPhaseLoad.java:113)
at org.hibernate.loader.Loader.initializeEntitiesAndCollections(Loader.java:842)
at org.hibernate.loader.Loader.doQuery(Loader.java:717)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:224)
at org.hibernate.loader.Loader.loadEntity(Loader.java:1785)
at org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java:93)
at org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java:81)
at org.hibernate.persister.entity.AbstractEntityPersister.load(AbstractEntityPersister.java:2730)
at org.hibernate.event.def.DefaultLoadEventListener.loadFromDatasource(DefaultLoadEventListener.java:365)
at org.hibernate.event.def.DefaultLoadEventListener.doLoad(DefaultLoadEventListener.java:346)
at org.hibernate.event.def.DefaultLoadEventListener.load(DefaultLoadEventListener.java:123)
at org.hibernate.event.def.DefaultLoadEventListener.proxyOrLoad(DefaultLoadEventListener.java:177)
at org.hibernate.event.def.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:87)
at org.hibernate.impl.SessionImpl.fireLoad(SessionImpl.java:891)
at org.hibernate.impl.SessionImpl.get(SessionImpl.java:828)
at org.hibernate.impl.SessionImpl.get(SessionImpl.java:821)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:324)
at org.hibernate.context.ThreadLocalSessionContext$TransactionProtectionWrapper.invoke(ThreadLocalSessionContext.java:301)
at $Proxy0.get(Unknown Source)
at com.fujitsu.lis.nz.cv.model.dao.PersonDAO.getById(PersonDAO.java:16)
at com.fujitsu.lis.nz.cv.model.dao.ScratchPad.checkDAO(ScratchPad.java:37)
at com.fujitsu.lis.nz.cv.model.dao.ScratchPad.main(ScratchPad.java:14)
Caused by: net.sf.cglib.beans.BulkBeanException
at com.fujitsu.lis.nz.cv.model.Changed$$BulkBeanByCGLIB$$1259f2a9.setPropertyValues(<generated>)
at org.hibernate.tuple.PojoComponentTuplizer.setPropertyValues(PojoComponentTuplizer.java:97)
... 27 more
Caused by: java.lang.ClassCastException
... 29 more


Top
 Profile  
 
 Post subject:
PostPosted: Wed Feb 01, 2006 9:39 pm 
Expert
Expert

Joined: Thu Dec 23, 2004 9:08 pm
Posts: 2008
Follow the exception's tip and turn off the optimizer. That will give you more detail. That said, there is rarely a reason to use java.sql.Date; if you don't need to use it, then you should switch to java.util.Date. Especially seeing as you've determined that that fixes the problem.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Feb 01, 2006 10:07 pm 
Newbie

Joined: Wed Feb 01, 2006 8:00 pm
Posts: 2
Location: Auckland
I usually use GregorianCalendar / "calendar" but on this current project I am having to use dates and timestamps.

I turned off the optimizer and I now get the following log trace

2006-02-02 14:45:35,330 - ERROR - IllegalArgumentException in class: com.fujitsu.lis.nz.cv.model.Changed, setter method of property: addedOn
2006-02-02 14:45:35,330 - ERROR - IllegalArgumentException in class: com.fujitsu.lis.nz.cv.model.Changed, setter method of property: addedOn
2006-02-02 14:45:35,330 - ERROR - expected type: java.sql.Date, actual value: java.sql.Timestamp
2006-02-02 14:45:35,330 - ERROR - expected type: java.sql.Date, actual value: java.sql.Timestamp
2006-02-02 14:45:35,345 - INFO - Error performing load command
org.hibernate.PropertyAccessException: IllegalArgumentException occurred while calling setter of com.fujitsu.lis.nz.cv.model.Changed.addedOn
at org.hibernate.property.BasicPropertyAccessor$BasicSetter.set(BasicPropertyAccessor.java:104)
at etc...


java.sql.Timestamp to java.sql.Date obviously will not go. I will change my mapping. Doh!

Thanks for the help.


Top
 Profile  
 
 Post subject: org.hibernate.PropertyAccessException:
PostPosted: Tue Mar 03, 2009 5:45 pm 
Beginner
Beginner

Joined: Wed Oct 03, 2007 4:10 am
Posts: 46
My mapping is:

<class name="domain.ActElem" table="NOM_ACT_ELEM">

<meta attribute="implements">Auditable</meta>

<id name="id" type="java.lang.Long">
<column name="ACT_ELEM_ID"/>
<generator class="sequence">
<param name="sequence">APPLICATION_SEQ</param>
</generator>
</id>

<many-to-one name="actiune" class="ro.ucs.xcard.domain.Actiune"
foreign-key="FK_ACT_ELEM_ACTIUNE">
<column name="ACTIUNE_ID"/>
</many-to-one>

<property name="descriere" type="java.lang.String">
<column name="DESCRIERE" length="512"/>
</property>

<property name="userCreator" type="string" update="false">
<column name="USER_CREATOR"/>
</property>

<property name="userModif" type="string">
<column name="USER_MODIF"/>
</property>

<property name="dataCreare" type="timestamp" update="false">
<column name="DATA_CREARE" sql-type="DATE"/>
</property>

<property name="dataModif" type="timestamp">
<column name="DATA_MODIF" sql-type="DATE"/>
</property>

</class>
</hibernate-mapping>


in the class

dataCreare and dataModif has java.util.Date type.



and i have the following error(the error (appears from time to time) when I call save on an instance of this object

Caused by: org.hibernate.PropertyAccessException: IllegalArgumentException occurred while calling setter of ro.ucs.xcard.domain.ActElem.descriere
at org.hibernate.property.BasicPropertyAccessor$BasicSetter.set(BasicPropertyAccessor.java(Compiled Code))
at org.hibernate.tuple.entity.AbstractEntityTuplizer.setPropertyValues(AbstractEntityTuplizer.java(Compiled Code))
at org.hibernate.tuple.entity.PojoEntityTuplizer.setPropertyValues(PojoEntityTuplizer.java(Compiled Code))
at org.hibernate.persister.entity.AbstractEntityPersister.setPropertyValues(AbstractEntityPersister.java(Compiled Code))
at org.hibernate.event.def.DefaultFlushEntityEventListener.onFlushEntity(DefaultFlushEntityEventListener.java(Compiled Code))
at org.hibernate.event.def.AbstractFlushingEventListener.flushEntities(AbstractFlushingEventListener.java(Compiled Code))


After the error appears it will appear at every call until the application is restarted. I didn't manage to reproduce this error in a standalone test case. Something trigger this error and I didn;t find what.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Mar 03, 2009 6:01 pm 
Expert
Expert

Joined: Thu Dec 23, 2004 9:08 pm
Posts: 2008
You must have code in your setDescriere() method, since IllegalArgument is being thrown. You can't do that (well, technically you can, but it's really, really tricky and not worth the trouble). All the getters/setters that hibernate calls should always just get/set the variable. If you need logic in your setter, provide a different method for API users to call (when I have to do it, I map "internalProperty" for hibernate, and have getProperty/setProperty methods that provide the logic and delegate to getInternalProperty/setInternalProperty).

But all that's an aside. What type is your DB column?

_________________
Code tags are your friend. Know them and use them.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Mar 03, 2009 7:00 pm 
Beginner
Beginner

Joined: Wed Oct 03, 2007 4:10 am
Posts: 46
I have no logic in the ActElem bean, just getters and setters

private Long id;
private Actiune actiune;
private Long index;
private String denumire;
private String descriere;
private String sql;
private String conditieContinuare;
private String userCreator;
private String userModif;
private Date dataCreare;
private Date dataModif;

public String getDescriere() {
return this.descriere;
}

public void setDescriere(String descriere) {
this.descriere = descriere;
}

...

I use Oracle10g and the type of dataCreare, dataModif is DATE

and the type for descriere is varchar2(512)


The main problem is that the error does not appear always.. something trigger the error and then only after restarting application it will work until next error.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Mar 05, 2009 4:50 pm 
Beginner
Beginner

Joined: Wed Oct 03, 2007 4:10 am
Posts: 46
I still need an answer please, the error is still there, now I have to restart the web application to get rid of that error:

org.springframework.orm.hibernate3.HibernateSystemException cause: java.lang.ClassCastException@11575d6 msg: IllegalArgumentException occurred while calling setter of domain.ActElem.descriere; nested exception is org.hibernate.PropertyAccessException: IllegalArgumentException occurred while calling setter of domain.ActElem.descriere ].

There are details in previous posts.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Mar 05, 2009 4:55 pm 
Expert
Expert

Joined: Thu Dec 23, 2004 9:08 pm
Posts: 2008
The only other explanation I can think of is that the column doesn't always contain a string. Do you have a query (HQL or SQL) that returns a result set that is mapped to these objects (as opposed to a plain old table mapping)? Maybe there's a mistake in the columns of the query. Or maybe you've got a bad union somewhere.

_________________
Code tags are your friend. Know them and use them.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Mar 05, 2009 5:09 pm 
Beginner
Beginner

Joined: Wed Oct 03, 2007 4:10 am
Posts: 46
The error appear when the session it is flushed.

It has nothing to do with query but with saving the ActElem object by hibernate.


the saving it is something like that

1. load ActElem from db using id
2. set the properties on ActElem
3. save ActElem


and the error it appear at 3)

I cannot isolate that error into testcase. The error appear after the web application it is used for about several hours.

for session management i use OpenSessionInView.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Mar 05, 2009 5:25 pm 
Expert
Expert

Joined: Thu Dec 23, 2004 9:08 pm
Posts: 2008
I wouldn't assume that it has anything to do with saving just because that's when the exception is thrown. Hibernate does a lot of things when flushing to the DB. Why would any simple property be set into your POJO when saving it? I can't think of a reason. More likely, there's a deferred deproxying going on; some object, possibly the one you're saving or possibly a completely different one, is being populated immediately prior to the save/flush.

If reviewing your code doesn't help, I suggest changing the type of descriere to Object, then putting in some logging/debug code in setDescriere that tells you when a non-string is passed in, and what the non-string's value is. Hopefully from that you'll be able to deduce what's going wrong.

_________________
Code tags are your friend. Know them and use them.


Top
 Profile  
 
 Post subject:
PostPosted: Sun Mar 08, 2009 7:22 pm 
Beginner
Beginner

Joined: Wed Oct 03, 2007 4:10 am
Posts: 46
i did as you told and the object passed to setDescriere was a java.util.Date instance

public void setDescriere(Object desc) {

try {
this.descriere = (String) desc;
} catch (Exception e) {
logger.error("ActElem descriere setter: " + desc, e);
if (desc != null) {
logger.error("ActElem descriere setter class: " + desc.getClass().getName());
this.descriere = desc + "";
} else {
this.descriere = null;
}
}

}


the application failed at setDataCreare with ClassCasTException

it seems that for the fields get messed up for an unknown reason... so I still need help.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Mar 09, 2009 10:04 am 
Beginner
Beginner

Joined: Wed Oct 03, 2007 4:10 am
Posts: 46
I still get ClassCastException from time to time in the web application. I want to reproduce the error in TestCase but I failed till now. May be somebody can give me a hint.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Mar 09, 2009 7:37 pm 
Expert
Expert

Joined: Thu Dec 23, 2004 9:08 pm
Posts: 2008
A date, hmm. And the stack trace tells you that it's coming from hibernate via cglib. There's no chance that you've using an old jar somewhere, maybe one version of your data access code with a different version of your business logic? Or a property with type="Any"? I think you'll have to apply some deductive reasoning and perhaps some debugging.

This is not something that I've ever heard of, it almost certainly isn't an hibernate issue. It's highly unlikely that hibernate would create a Date object then knowingly pass it into a String parameter.

You might also try creating a new topic. Piggybacked topics often get ignored.

_________________
Code tags are your friend. Know them and use them.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Mar 10, 2009 2:57 pm 
Beginner
Beginner

Joined: Wed Oct 03, 2007 4:10 am
Posts: 46
Great news :).
I solved the problem.

First I identified what was the trigger for the ClassCastException.

How I previously told it is a web application and after sometime of error free
working something mess up the hibernate fields and I get ClassCastException.


The trigger was

ClassMetadata neta = ..getSessionFactory().getClassMetadata(clazz);
String[] propertyNames = meta.getPropertyNames();

Arrays.sort(propertyNames); <--- this triggers the malfunction

....



this is done because I made a dynamic Projection which includes all the selected class fields for a csv export.

It seems that meta.getPropertyNames() return the original array from
hibernate configuration and it cannot be manipulated directly because doing so it get into some tricky errors.


Thank you for your support.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 14 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.