使用模式中的表执行查询时找不到对象

时间:2016-06-21 15:49:44

标签: hibernate hsqldb

我正在尝试使用ddl auto create使用hsqldb设置一个简单的Spring上下文。这仅适用于单元测试,因为在生产中我们使用的是postgresql。

<beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xmlns:context="http://www.springframework.org/schema/context"
   xsi:schemaLocation="
   http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
   http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
   ">
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
    <property name="driverClassName" value="org.hsqldb.jdbcDriver" />
    <property name="url" value="jdbc:hsqldb:mem:unittest;sql.syntax_pgs=true" />
    <property name="username" value="sa" />
    <property name="password" value="" />
</bean>

<bean id="entityManagerFactoryBean" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="dataSource" ref="dataSource" />
    <property name="packagesToScan" value="com.foo.service.analytics.google" />
    <property name="jpaVendorAdapter">
        <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
    </property>
    <property name="jpaProperties">
        <props>
            <prop key="hibernate.archive.autodetection">class,hbm</prop>
            <prop key="hibernate.hbm2ddl.auto">create</prop>
            <prop key="hibernate.show_sql">true</prop>
            <prop key="hibernate.dialect">org.hibernate.dialect.HSQLDialect</prop>
        </props>
    </property>
</bean>

<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
    <property name="entityManagerFactory" ref="entityManagerFactoryBean" />
</bean>

<bean class="com.foo.service.analytics.google.GaDimensionDaoImpl" />
<bean class="com.foo.service.analytics.google.GaHibernateAdapterImpl" />

<context:annotation-config />
</beans>

根据日志创建数据库成功:

Hibernate: drop table analytics.dim_date if exists
Hibernate: drop sequence seq_dim_location_sequence
Hibernate: create table analytics.dim_date (dim_date_id integer not null, date timestamp, hour integer, minute integer, primary key (dim_date_id))
Hibernate: create sequence seq_dim_location_sequence

这是我的实体:

package com.foo.service.analytics.google.dimensions;

import com.foo.service.analytics.google.DimensionAttribute;
import com.foo.service.analytics.google.GaDimensionDao;

import javax.persistence.*;
import java.util.Calendar;

@Entity
@NamedQueries({
    @NamedQuery(
            name = GaDimensionDao.GET_BY_DIM_ATTRIBUTES,
            query = "SELECT dim FROM DateDimension dim " +
                    "WHERE dim.date = :date " +
                    "AND (:hour IS NULL OR dim.hour = :hour) " +
                    "AND (:minute IS NULL OR dim.minute = :minute)"
    )
})
@SequenceGenerator(name = "seq_dim_location", sequenceName = "seq_dim_location_sequence",
    schema = "analytics", allocationSize = 1)
@Table(name = "dim_date", schema = "analytics")
public class DateDimension {

    @Id
    @Column(name = "dim_date_id", nullable = false)
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "seq_dim_location")
    private Integer id;

    @Column(name = "date")
    private Calendar date;

    @Column(name = "hour")
    private Integer hour;

    @Column(name = "minute")
    private Integer minute;
}

使用NamedQuery后,我得到以下stacktrace:

javax.persistence.PersistenceException: org.hibernate.exception.SQLGrammarException: user lacks privilege or object not found: DIM_DATE in statement [select datedimens0_.dim_date_id as dim1_0_, datedimens0_.date as date0_, datedimens0_.hour as hour0_, datedimens0_.minute as minute0_ from analytics.dim_date datedimens0_ where datedimens0_.date=? and (? is null or datedimens0_.hour=?) and (? is null or datedimens0_.minute=?) limit ?]
    at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1367)
    at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1295)
    at org.hibernate.ejb.QueryImpl.getSingleResult(QueryImpl.java:317)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at org.springframework.orm.jpa.SharedEntityManagerCreator$DeferredQueryInvocationHandler.invoke(SharedEntityManagerCreator.java:360)
    at com.sun.proxy.$Proxy30.getSingleResult(Unknown Source)
    at com.foo.service.analytics.google.GaDimensionDaoImpl.createOrGet(GaDimensionDaoImpl.java:50)
    at com.foo.service.analytics.google.GaHibernateAdapterImpl.processRow(GaHibernateAdapterImpl.java:79)
    at com.foo.service.analytics.google.GaHibernateAdapterImpl.convert(GaHibernateAdapterImpl.java:40)
    at com.foo.service.analytics.google.GaHibernateAdapterTest.createHibernateObjectFromGaTest(GaHibernateAdapterTest.java:30)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:72)
    at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:81)
    at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:216)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:82)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:60)
    at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:67)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:162)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:68)
Caused by: org.hibernate.exception.SQLGrammarException: user lacks privilege or object not found: DIM_DATE in statement [select datedimens0_.dim_date_id as dim1_0_, datedimens0_.date as date0_, datedimens0_.hour as hour0_, datedimens0_.minute as minute0_ from analytics.dim_date datedimens0_ where datedimens0_.date=? and (? is null or datedimens0_.hour=?) and (? is null or datedimens0_.minute=?) limit ?]
    at org.hibernate.exception.internal.SQLExceptionTypeDelegate.convert(SQLExceptionTypeDelegate.java:82)
    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.ConnectionProxyHandler.continueInvocation(ConnectionProxyHandler.java:146)
    at org.hibernate.engine.jdbc.internal.proxy.AbstractProxyHandler.invoke(AbstractProxyHandler.java:81)
    at com.sun.proxy.$Proxy31.prepareStatement(Unknown Source)
    at org.hibernate.engine.jdbc.internal.StatementPreparerImpl$5.doPrepare(StatementPreparerImpl.java:147)
    at org.hibernate.engine.jdbc.internal.StatementPreparerImpl$StatementPreparationTemplate.prepareStatement(StatementPreparerImpl.java:166)
    at org.hibernate.engine.jdbc.internal.StatementPreparerImpl.prepareQueryStatement(StatementPreparerImpl.java:145)
    at org.hibernate.loader.Loader.prepareQueryStatement(Loader.java:1711)
    at org.hibernate.loader.Loader.doQuery(Loader.java:828)
    at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:289)
    at org.hibernate.loader.Loader.doList(Loader.java:2438)
    at org.hibernate.loader.Loader.doList(Loader.java:2424)
    at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2254)
    at org.hibernate.loader.Loader.list(Loader.java:2249)
    at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:470)
    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:1248)
    at org.hibernate.internal.QueryImpl.list(QueryImpl.java:101)
    at org.hibernate.ejb.QueryImpl.getSingleResult(QueryImpl.java:284)
    ... 37 more
Caused by: java.sql.SQLSyntaxErrorException: user lacks privilege or object not found: DIM_DATE in statement [select datedimens0_.dim_date_id as dim1_0_, datedimens0_.date as date0_, datedimens0_.hour as hour0_, datedimens0_.minute as minute0_ from analytics.dim_date datedimens0_ where datedimens0_.date=? and (? is null or datedimens0_.hour=?) and (? is null or datedimens0_.minute=?) limit ?]
    at org.hsqldb.jdbc.JDBCUtil.sqlException(Unknown Source)
    at org.hsqldb.jdbc.JDBCUtil.sqlException(Unknown Source)
    at org.hsqldb.jdbc.JDBCPreparedStatement.<init>(Unknown Source)
    at org.hsqldb.jdbc.JDBCConnection.prepareStatement(Unknown Source)
    at org.apache.commons.dbcp.DelegatingConnection.prepareStatement(DelegatingConnection.java:281)
    at org.apache.commons.dbcp.PoolingDataSource$PoolGuardConnectionWrapper.prepareStatement(PoolingDataSource.java:313)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at org.hibernate.engine.jdbc.internal.proxy.ConnectionProxyHandler.continueInvocation(ConnectionProxyHandler.java:138)
    ... 55 more
Caused by: org.hsqldb.HsqlException: user lacks privilege or object not found: DIM_DATE
    at org.hsqldb.error.Error.error(Unknown Source)
    at org.hsqldb.error.Error.error(Unknown Source)
    at org.hsqldb.ParserDQL.readTableName(Unknown Source)
    at org.hsqldb.ParserDQL.readTableOrSubquery(Unknown Source)
    at org.hsqldb.ParserDQL.XreadTableReference(Unknown Source)
    at org.hsqldb.ParserDQL.XreadFromClause(Unknown Source)
    at org.hsqldb.ParserDQL.XreadTableExpression(Unknown Source)
    at org.hsqldb.ParserDQL.XreadQuerySpecification(Unknown Source)
    at org.hsqldb.ParserDQL.XreadSimpleTable(Unknown Source)
    at org.hsqldb.ParserDQL.XreadQueryPrimary(Unknown Source)
    at org.hsqldb.ParserDQL.XreadQueryTerm(Unknown Source)
    at org.hsqldb.ParserDQL.XreadQueryExpressionBody(Unknown Source)
    at org.hsqldb.ParserDQL.XreadQueryExpression(Unknown Source)
    at org.hsqldb.ParserDQL.compileCursorSpecification(Unknown Source)
    at org.hsqldb.ParserCommand.compilePart(Unknown Source)
    at org.hsqldb.ParserCommand.compileStatement(Unknown Source)
    at org.hsqldb.Session.compileStatement(Unknown Source)
    at org.hsqldb.StatementManager.compile(Unknown Source)
    at org.hsqldb.Session.execute(Unknown Source)
    ... 64 more

schema注释中删除@Table值可以使此操作成功。我在生成的ddl语句以及stacktrace中的查询中看到了模式创建。是否还需要做其他事情才能使用hsqldb启用模式而不更改绑定本身?

供参考,我使用的是Spring 4.1.1.Release,hsqldb 2.3.4和Hibernate 4.1.3.Final。

更新 通过在this answer中所述的INIT参数中手动创建模式,我确实通过从HSQLDB切换到H2来实现我的目标。保持这个问题,以防有人得到HSQLDB的答案,因为我无法在任何地方找到解决方案。

0 个答案:

没有答案