IllegalArgumentException occurred while calling setter当我的程序尝试从数据库中按名称加载用户时,如何解决Hibernate 偶尔引发的异常的原因?
IllegalArgumentException occurred while calling setter
我将USER_RV表中的列错误地映射User到类Integer而不是BigDecimal其他某种整数类型吗?请注意,同一应用程序将NUMBER其他表中的列映射到Integer对象,但是当用来自这些表的行填充对象时,Hibernate 不会 引发此异常。
USER_RV
User
Integer
BigDecimal
NUMBER
进一步注意到,该方案使 RMI缓存复制 的 唯一用户缓存 。此异常可能与缓存复制有关吗?它是Ehcache还是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.loader.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
类的定义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; } }
表的定义TB_USER:
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") )
环境:
事实证明,此异常是由于Hibernate中的错误所致。我的一个队友发现了一个相关的错误报告: 从群集的JBoss Cache重新组装实体可能会因“参数类型不匹配”而失败 ,这是在使用Hibernate和JBoss Cache时发生的。
根据该报告,将Hibernate属性设置hibernate.cache.use_structured_entries为 true 可以避免该异常。根据Hibernate 文档,此属性“强制Hibernate以更人性化的格式将数据存储在二级缓存中”。显然,结构化缓存条目还可以确保Hibernate将第二级缓存中的对象属性正确映射到实体中的相应属性。
hibernate.cache.use_structured_entries
Javalobby有一篇有趣的文章,解释了Hibernate如何使用二级缓存。
3.3.2GA之后的Hibernate版本是否也表现出这种行为?