无法使用 Hibernate createQuery 实例化类
Posted
技术标签:
【中文标题】无法使用 Hibernate createQuery 实例化类【英文标题】:Can't instantiate class using Hibernate createQuery 【发布时间】:2014-10-08 23:06:21 【问题描述】:我正在尝试使用 hibernate 创建对象,这些对象不是域模型,但我收到了一条难以理解的错误消息。
我的 Java 代码:
public BoxMeasureStat getBoxStat(long box_id, long )
TypedQuery<BoxMeasureStat> data = em.createQuery(
"SELECT NEW org.massema.util.BoxMeasureStat(MIN(bm.value), AVG(bm.value) , MAX(bm.value), MAX(bm.start_time) ) "
+ "FROM bm WHERE bm.box_id = :box_id "
+ "AND bm.type_id = :type_id "
+ "order by start_time desc limit 1", BoxMeasureStat.class)
.setParameter("box_id", box_id)
.setParameter("type_id", type_id);
BoxMeasureStat result = data.getSingleResult();
return result;
班级:
package org.massema.util;
import java.lang.Float;
import java.util.Date;
import org.joda.time.DateTime;
public class BoxMeasureStat
private String type;
private Float min;
private Double avg;
private Float max;
private String time;
public BoxMeasureStat( Float min, Double avg, Float max, DateTime time)
super();
this.min = (min);
this.avg = (avg);
this.max = (max);
this.time = time.toString(QueryResultConverter.dateFormatter);
public String getType()
return type;
public void setType(String type)
this.type = type;
public Float getMin()
return min;
public void setMin(Float min)
this.min = min;
public Double getAvg()
return avg;
public void setAvg(Double avg)
this.avg = avg;
public Float getMax()
return max;
public void setMax(Float max)
this.max = max;
public String getTime()
return time;
public void setTime(String time)
this.time = time;
public void setTime(DateTime time)
this.time = time.toString(QueryResultConverter.dateFormatter);
堆栈跟踪:
IllegalArgumentException occured : org.hibernate.QueryException: could not instantiate class [org.massema.util.BoxMeasureStat] from tuple
play.exceptions.JavaExecutionException: org.hibernate.QueryException: could not instantiate class [org.massema.util.BoxMeasureStat] from tuple
at play.mvc.ActionInvoker.invoke(ActionInvoker.java:237)
at Invocation.HTTP Request(Play!)
Caused by: java.lang.IllegalArgumentException: org.hibernate.QueryException: could not instantiate class [org.massema.util.BoxMeasureStat] from tuple
at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1364)
at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1300)
at org.hibernate.ejb.QueryImpl.getSingleResult(QueryImpl.java:312)
at org.massema.dao.BoxMeasurementsDAO.getBoxStat(BoxMeasurementsDAO.java:509)
at org.massema.dao.BoxMeasurementsDAO.getBoxStat(BoxMeasurementsDAO.java:492)
at org.massema.dao.BoxMeasurementsDAO$$FastClassByCGLIB$$f92487e3.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:698)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
at org.massema.platform.tx.ISTransactionInterceptor$1.proceedWithInvocation(ISTransactionInterceptor.java:78)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:260)
at org.massema.platform.tx.ISTransactionInterceptor.invoke(ISTransactionInterceptor.java:73)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:161)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:91)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:631)
at org.massema.dao.BoxMeasurementsDAO$$EnhancerByCGLIB$$5d23bcc4.getBoxStat(<generated>)
at controllers.API.boxMeasures(API.java:190)
at play.mvc.ActionInvoker.invokeWithContinuation(ActionInvoker.java:557)
at play.mvc.ActionInvoker.invoke(ActionInvoker.java:508)
at play.mvc.ActionInvoker.invokeControllerMethod(ActionInvoker.java:484)
at play.mvc.ActionInvoker.invokeControllerMethod(ActionInvoker.java:479)
at play.mvc.ActionInvoker.invoke(ActionInvoker.java:161)
... 1 more
Caused by: org.hibernate.QueryException: could not instantiate class [org.massema.util.BoxMeasureStat] from tuple
at org.hibernate.transform.AliasToBeanConstructorResultTransformer.transformTuple(AliasToBeanConstructorResultTransformer.java:57)
at org.hibernate.hql.internal.HolderInstantiator.instantiate(HolderInstantiator.java:95)
at org.hibernate.loader.hql.QueryLoader.getResultList(QueryLoader.java:458)
at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2332)
at org.hibernate.loader.Loader.list(Loader.java:2327)
at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:490)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:355)
at org.hibernate.engine.query.spi.HQLQueryPlan.performList(HQLQueryPlan.java:195)
at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1247)
at org.hibernate.internal.QueryImpl.list(QueryImpl.java:101)
at org.hibernate.ejb.QueryImpl.getSingleResult(QueryImpl.java:283)
... 21 more
Caused by: java.lang.reflect.InvocationTargetException
at org.hibernate.transform.AliasToBeanConstructorResultTransformer.transformTuple(AliasToBeanConstructorResultTransformer.java:54)
... 31 more
Caused by: java.lang.NullPointerException
at org.massema.util.BoxMeasureStat.<init>(BoxMeasureStat.java:24)
... 32 more
表的架构:
CREATE TABLE boxmeasurements
(
box_id bigint NOT NULL,
type_id bigint NOT NULL,
start_time timestamp with time zone NOT NULL,
value real,
last_modified timestamp with time zone,
CONSTRAINT boxmeasurements_pkey PRIMARY KEY (box_id, type_id, start_time),
CONSTRAINT fkdb5acd82c1990d35 FOREIGN KEY (type_id)
REFERENCES boxmeasurementtypes (id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION,
CONSTRAINT fkdb5acd82e3f182be FOREIGN KEY (box_id)
REFERENCES box (id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION,
CONSTRAINT chk_lastmodified CHECK (date_part('timezone'::text, last_modified) = 0::double precision),
CONSTRAINT chk_start_time CHECK (date_part('timezone'::text, start_time) = 0::double precision)
)
WITH (
OIDS=FALSE
);
ALTER TABLE boxmeasurements
OWNER TO postgres;
版本:
Hibernate: 4.19
Hibernate-jpa-2.0-api
Java: 1.7
PostgreSql: 9.3.5
Ubuntu: 12.04
坦率地说,我不知道为什么它不能实例化这个类。
【问题讨论】:
正如其他人所指出的,这里的空指针异常也可能是由于试图将null传递给原始类型字段,即long或int,不能为null。请改用 Long 或 Integer。 【参考方案1】:您在构造函数中获得 NullPointerException,因此您的查询从数据库中检索到的 time
参数可能为 NULL。尝试更改构造函数以处理 NULL 值:
public BoxMeasureStat( Float min, Double avg, Float max, DateTime time)
super();
this.min = (min);
this.avg = (avg);
this.max = (max);
if (time != null)
this.time = time.toString(QueryResultConverter.dateFormatter);
【讨论】:
我不敢相信我没有看到。我从未注意到该堆栈跟踪中的最后两行。谢谢。 我遇到了同样的问题,你的解决方案解决了。谢谢。但我的问题是这是否仅适用于 Date 或适用于所有类型? @nilesh 如果您在构造函数中取消引用参数,其他类型也可能发生这种情况。例如,如果您从查询中获得String
并且您想要 toUppercase
的值,则必须确保它不是 null
。
因此构造函数中的任何异常都会导致“无法实例化类”错误。对吗?【参考方案2】:
另一种可能是构造函数中有主类型,而不是预期的 Java 对象。
构造函数参数示例:int
、long
、boolean
、char
..
你应该替换为Integer
、Long
、Boolean
、Char
...
【讨论】:
这为我解决了这个问题。我用Integer
和Double
替换了int
和double
等原始类型,我的问题得到了解决以上是关于无法使用 Hibernate createQuery 实例化类的主要内容,如果未能解决你的问题,请参考以下文章
Java / Hibernate:无法使用嵌套对象标准解析属性
无法使用 Hibernate 访问 Postgres 数据库
无法使用 Hibernate createQuery 实例化类