Hibernate 4和Postgres 9:Criteria.list()抛出异常

时间:2013-03-28 18:14:26

标签: hibernate postgresql-9.1

我遇到了涉及postgres jdbc驱动程序版本9.1-901.jdbc3的奇怪问题。 这是我的道歉

  @Override
    public List<Products> getProductsListByIds(List<String> ids, Integer storeId) {
    Criteria criteria = getSession().createCriteria(Products.class)
    .add(Restrictions.eq("storeId", storeId))
    .add(Restrictions.in("productId", ids))
    .add(Restrictions.isNotEmpty("createdAt"))
    .add(Restrictions.isNotEmpty("updatedAt"))
    .add(Restrictions.isNotNull("id"))
    return criteria.list();
    }

当我运行SQL语句时,它返回96个结果,我猜测hibernate的固定列表大小为100(即我传递限制的ID数量),并在列表中返回4个空对象。 结果postgres jdbc驱动程序在尝试将null映射到时间戳时出现以下异常:

org.hibernate.exception.DataException: Bad value for type timestamp : 
    at org.hibernate.exception.internal.SQLStateConversionDelegate.convert(SQLStateConversionDelegate.java:134)
    at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:49)
    at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:125)
    at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:110)
    at org.hibernate.engine.jdbc.internal.proxy.AbstractResultSetProxyHandler.continueInvocation(AbstractResultSetProxyHandler.java:108)
    at org.hibernate.engine.jdbc.internal.proxy.AbstractProxyHandler.invoke(AbstractProxyHandler.java:81)
    at com.sun.proxy.$Proxy44.getTimestamp(Unknown Source)
    at org.hibernate.type.descriptor.sql.TimestampTypeDescriptor$2.doExtract(TimestampTypeDescriptor.java:67)
    at org.hibernate.type.descriptor.sql.BasicExtractor.extract(BasicExtractor.java:65)
    at org.hibernate.type.AbstractStandardBasicType.nullSafeGet(AbstractStandardBasicType.java:261)
    at org.hibernate.type.AbstractStandardBasicType.nullSafeGet(AbstractStandardBasicType.java:257)
    at org.hibernate.type.AbstractStandardBasicType.nullSafeGet(AbstractStandardBasicType.java:247)
    at org.hibernate.type.AbstractStandardBasicType.hydrate(AbstractStandardBasicType.java:332)
    at org.hibernate.persister.entity.AbstractEntityPersister.hydrate(AbstractEntityPersister.java:2873)
    at org.hibernate.loader.Loader.loadFromResultSet(Loader.java:1668)
    at org.hibernate.loader.Loader.instanceNotYetLoaded(Loader.java:1600)
    at org.hibernate.loader.Loader.getRow(Loader.java:1500)
    at org.hibernate.loader.Loader.getRowFromResultSet(Loader.java:712)
    at org.hibernate.loader.Loader.processResultSet(Loader.java:940)
    at org.hibernate.loader.Loader.doQuery(Loader.java:910)
    at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:341)
    at org.hibernate.loader.Loader.doList(Loader.java:2516)
    at org.hibernate.loader.Loader.doList(Loader.java:2502)
    at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2332)
    at org.hibernate.loader.Loader.list(Loader.java:2327)
    at org.hibernate.loader.criteria.CriteriaLoader.list(CriteriaLoader.java:124)
    at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1621)
    at org.hibernate.internal.CriteriaImpl.list(CriteriaImpl.java:374)
    at com.insparq.insparqsvc.dao.impl.StoresDAOImpl.getProductsListByIds(StoresDAOImpl.java:115)
    at com.insparq.insparqsvc.service.impl.StoreServiceImpl.getProductsListByIds(StoreServiceImpl.java:112)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:110)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
    at com.sun.proxy.$Proxy38.getProductsListByIds(Unknown Source)
    at com.insparq.jobserver.service.impl.ScheduledJobServiceImpl.normalizeProducts(ScheduledJobServiceImpl.java:446)
    at com.insparq.jobserver.service.impl.ScheduledJobServiceImpl.parseCSV(ScheduledJobServiceImpl.java:415)
    at com.insparq.jobserver.service.impl.ScheduledJobServiceImpl.generateProductsCSV(ScheduledJobServiceImpl.java:214)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:198)
    at com.sun.proxy.$Proxy39.generateProductsCSV(Unknown Source)
    at com.insparq.jobserver.test.ScheduledJobTest.processJob(ScheduledJobTest.java:173)
    at com.insparq.jobserver.test.ScheduledJobTest.test(ScheduledJobTest.java:111)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74)
    at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:83)
    at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:231)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:88)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
    at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
    at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174)
    at org.apache.maven.surefire.junit4.JUnit4TestSet.execute(JUnit4TestSet.java:53)
    at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:123)
    at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:104)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at org.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray(ReflectionUtils.java:164)
    at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:110)
    at org.apache.maven.surefire.booter.SurefireStarter.invokeProvider(SurefireStarter.java:172)
    at org.apache.maven.surefire.booter.SurefireStarter.runSuitesInProcessWhenForked(SurefireStarter.java:104)
    at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:70)
Caused by: org.postgresql.util.PSQLException: Bad value for type timestamp : 
    at org.postgresql.jdbc2.TimestampUtils.loadCalendar(TimestampUtils.java:246)
    at org.postgresql.jdbc2.TimestampUtils.toTimestamp(TimestampUtils.java:321)
    at org.postgresql.jdbc2.AbstractJdbc2ResultSet.getTimestamp(AbstractJdbc2ResultSet.java:437)
    at org.postgresql.jdbc2.AbstractJdbc2ResultSet.getTimestamp(AbstractJdbc2ResultSet.java:2446)
    at org.apache.commons.dbcp.DelegatingResultSet.getTimestamp(DelegatingResultSet.java:229)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at org.hibernate.engine.jdbc.internal.proxy.AbstractResultSetProxyHandler.continueInvocation(AbstractResultSetProxyHandler.java:104)
    ... 82 more
Caused by: java.lang.NumberFormatException: Timestamp has neither date nor time
    at org.postgresql.jdbc2.TimestampUtils.loadCalendar(TimestampUtils.java:243)
    ... 91 more

有没有办法告诉hibernate只加载它得到的结果而不用空值填充其余的元素?

2 个答案:

答案 0 :(得分:0)

Hibernate没有固定的列表大小,只是执行查询。 它无法将行值转换为时间戳。可能是行有日期类型。 在我在数据库中设置了非空限制之后,当行包含零值(00/00/00 ...)时,我在mysql中有类似的错误。

答案 1 :(得分:0)

我认为isNotEmpty不是createdAt等时间戳字段的有效限制。

根据文档,它仅适用于集合属性。

  

将集合值属性约束为非空

你应该在这里使用isNotNull

public List<Products> getProductsListByIds(List<String> ids, Integer storeId) {
    Criteria criteria = getSession().createCriteria(Products.class)  
        .add(Restrictions.eq("storeId", storeId))
        .add(Restrictions.in("productId", ids))
        .add(Restrictions.isNotNull("createdAt"))
        .add(Restrictions.isNotNull("updatedAt"))
        .add(Restrictions.isNotNull("id"))
    return criteria.list();
}

另一方面注意:Postgres驱动程序9.1.901似乎出现了一些系列性能问题,我建议移动到最新版本9.1.902或9.1.903