How do I cure the cause of Hibernate exception "IllegalArgumentException occurred while calling setter"?
How do I cure the cause of the occasional exception IllegalArgumentException occurred while calling setter
that Hibernate throws when my program attempts to load a user by name from the database?
Am I incorrectly mapping column USER_RV
in table User
to class Integer
instead of BigDecimal
or some other integer type? Note that the same application maps NUMBER
columns in other tables to Integer
objects, but Hibernate does not throw this exception when populating an object with a row from those tables.
Further note that the program enables RMI cache replication for the User cache only. Might this exception be related to cache replication? Is it a bug in Ehcache or Hibernate?
Caused by: org.springframework.orm.hibernate3.HibernateSystemException: IllegalArgumentException occurred while calling setter of com.db.spgit.abstrack.model.User.rv; nested exception is org.hibernate.PropertyAccessException: IllegalArgumentException occurred while calling setter of com.db.spgit.abstrack.model.User.rv
at org.springframework.orm.hibernate3.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:676)
at org.springframework.orm.hibernate3.HibernateAccessor.convertHibernateAccessException(HibernateAccessor.java:412)
at org.springframework.orm.hibernate3.HibernateTemplate.doExecute(HibernateTemplate.java:424)
at org.springframework.orm.hibernate3.HibernateTemplate.executeWithNativeSession(HibernateTemplate.java:374)
at org.springframework.orm.hibernate3.HibernateTemplate.findByCriteria(HibernateTemplate.java:1055)
at org.springframework.orm.hibernate3.HibernateTemplate.findByCriteria(HibernateTemplate.java:1048)
at com.db.abstrack.dao.hibernate.AbstrackDaoHibernate.findByCriteria(AbstrackDaoHibernate.java:57)
at com.db.abstrack.dao.hibernate.UserDaoHibernate.loadByName(UserDaoHibernate.java:63)
at com.db.spgit.abstrack.manager.QuoteManager.populateUser(QuoteManager.java:330)
at com.db.spgit.abstrack.manager.QuoteManager.populateOwnerUK(QuoteManager.java:307)
at com.db.spgit.abstrack.manager.QuoteManager.populateGuids(QuoteManager.java:254)
at com.db.spgit.abstrack.manager.QuoteManager.addQuoteReturnVwRfqUK(QuoteManager.java:429)
at com.db.spgit.abstrack.manager.QuoteManager$$FastClassByCGLIB$$d817accb.invoke(<generated>)
at net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:149)
at org.springframework.aop.framework.Cglib2AopProxy$CglibMethodInvocation.invokeJoinpoint(Cglib2AopProxy.java:700)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:149)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:106)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:635)
at com.db.spgit.abstrack.manager.QuoteManager$$EnhancerByCGLIB$$cc8d0025.addQuoteReturnVwRfqUK(<generated>)
at com.db.abstrack.ejb.RfqBean.addRfqDraftListUK(RfqBean.java:370)
... 59 more
Caused by: org.hibernate.PropertyAccessException: IllegalArgumentException occurred while calling setter of com.db.spgit.abstrack.model.User.rv
at org.hibernate.property.BasicPropertyAccessor$BasicSetter.set(BasicPropertyAccessor.java:104)
at org.hibernate.tuple.entity.AbstractEntityTuplizer.setPropertyValues(AbstractEntityTuplizer.java:337)
at org.hibernate.tuple.entity.PojoEntityTuplizer.setPropertyValues(PojoEntityTuplizer.java:200)
at org.hibernate.persister.entity.AbstractEntityPersister.setPropertyValues(AbstractEntityPersister.java:3514)
at org.hibernate.cache.entry.CacheEntry.assemble(CacheEntry.java:116)
at org.hibernate.cache.entry.CacheEntry.assemble(CacheEntry.java:82)
at org.hibernate.event.def.DefaultLoadEventListener.assembleCacheEntry(DefaultLoadEventListener.java:553)
at org.hibernate.event.def.DefaultLoadEventListener.loadFromSecondLevelCache(DefaultLoadEventListener.java:508)
at org.hibernate.event.def.DefaultLoadEventListener.doLoad(DefaultLoadEventListener.java:357)
at org.hibernate.event.def.DefaultLoadEventListener.load(DefaultLoadEventListener.java:139)
at org.hibernate.event.def.DefaultLoadEventListener.proxyOrLoad(DefaultLoadEventListener.java:179)
at org.hibernate.event.def.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:103)
at org.hibernate.impl.SessionImpl.fireLoad(SessionImpl.java:878)
at org.hibernate.impl.SessionImpl.internalLoad(SessionImpl.java:846)
at org.hibernate.type.EntityType.resolveIdentifier(EntityType.java:557)
at org.hibernate.type.ManyToOneType.assemble(ManyToOneType.java:196)
at org.hibernate.cache.StandardQueryCache.get(StandardQueryCache.java:130)
at org.hibernate.loader.Loader.getResultFromQueryCache(Loader.java:2152)
at org.hibernate.loader.Loader.listUsingQueryCache(Loader.java:2117)
at org.hibernate.loade开发者_开发技巧r.Loader.list(Loader.java:2087)
at org.hibernate.loader.criteria.CriteriaLoader.list(CriteriaLoader.java:95)
at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1569)
at org.hibernate.impl.CriteriaImpl.list(CriteriaImpl.java:283)
at org.springframework.orm.hibernate3.HibernateTemplate$36.doInHibernate(HibernateTemplate.java:1065)
at org.springframework.orm.hibernate3.HibernateTemplate.doExecute(HibernateTemplate.java:419)
... 77 more
Caused by: java.lang.IllegalArgumentException: java.lang.ClassCastException@6be0d6
at sun.reflect.GeneratedMethodAccessor104.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.hibernate.property.BasicPropertyAccessor$BasicSetter.set(BasicPropertyAccessor.java:42)
... 101 more
Definition of class User
:
@Entity
@Proxy(lazy=false)
@Cache(usage=CacheConcurrencyStrategy.TRANSACTIONAL)
@Table(name="TB_USER"
,schema="ABSOL_USER"
)
public class User implements java.io.Serializable {
private String id;
private String userName;
private Integer rv;
public User() {
}
public User(String userName, Integer rv) {
this.userName = userName;
this.rv = rv;
}
@GenericGenerator(name="generator", strategy="guid")@Id @GeneratedValue(generator="generator")
@Column(name="USER_ID", unique=true, nullable=false)
public String getId() {
return this.id;
}
public void setId(String id) {
this.id = id;
}
@Column(name="USER_NAME", nullable=false, length=20)
public String getUserName() {
return this.userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
@Column(name="USER_RV", precision=22, scale=0)
public Integer getRv() {
return this.rv;
}
public void setRv(Integer rv) {
this.rv = rv;
}
}
Definition of table TB_USER
:
CREATE TABLE "ABSOL_OWNER"."TB_USER" (
"USER_ID" RAW(16) DEFAULT SYS_GUID(),
"USER_NAME" VARCHAR2(20 CHAR) NOT NULL ENABLE,
"USER_RV" NUMBER NOT NULL ENABLE,
PRIMARY KEY ("USER_ID")
)
Environment:
- Hibernate 3.3.2.GA
- Ehcache 2.2.0
- WebLogic Server 10.3.2
- Oracle database
- Caching User objects
- Enabled RMI cache replication via remote key invalidation
It turns out that this exception is due to a bug in Hibernate. One of my teammates found a related bug report, Re-assembling entity from clustered JBoss Cache may fail with "argument type mismatch", that occurs when using Hibernate and JBoss Cache.
According to the report, setting Hibernate property hibernate.cache.use_structured_entries
to true avoids the exception. According to the Hibernate documentation, this property "forces Hibernate to store data in the second-level cache in a more human-friendly format". Apparently, structured cache entries also ensure that Hibernate correctly maps properties of an object in the second-level cache to the corresponding property in an entity.
Javalobby has an interesting article that explains how Hibernate uses the second-level cache.
Do versions of Hibernate after 3.3.2GA also exhibit this behaviour?
I don't think that a NUMBER
column type can be cast into an Integer
. Try a NUMBER(10,0)
instead.
精彩评论