org.h2.jdbc.JdbcSQLException:Column" X"在视图+ H2数据库1.4.190 + Hibernate 4.2.0.Final上找不到

时间:2015-11-09 17:11:42

标签: java spring hibernate jdbc h2

我直接使用目标数据库运行我的单元测试:Oracle 10g,我被要求在H2数据库下运行它们。

因此,在生成了不同的SQL脚本并配置了H2数据库(通过XML配置。使用Spring)后,我意识到我的一些测试失败了,而其中一些测试失败了......

我有以下视图(视图视图),它返回不同的列:

CREATE OR REPLACE FORCE VIEW ##.VIEW_OLB_SAT_COVERAGE
(
   SAT_CODE,
   ORBITAL_POSITION,
   COVERAGE_DOWN,
   COVERAGE_UP
)
AS
     SELECT DISTINCT sat_code,
                     orbital_position,
                     coverage_down,
                     coverage_up
       FROM ##.VIEW_OLB_TXP_COVERAGE
   ORDER BY sat_code ASC;

视图" VIEW_OLB_TXP_COVERAGE"如下:

CREATE OR REPLACE FORCE VIEW ##.VIEW_OLB_TXP_COVERAGE
(
   SAT_CODE,
   ORBITAL_POSITION,
   TXP_NO,
   COVERAGE_DOWN,
   COVERAGE_UP,
   POLARIZATION_DOWN,
   POLARIZATION_UP
)
AS
     SELECT DISTINCT ##.OLB_AVAILABLE_TXP.SAT_CODE,
                     ###.SAT_DEP.ORBIT_LOC / 3600 ORBITAL_POSITION,
                     ##.OLB_AVAILABLE_TXP.TXP_NO,
                     ###.TXP.CUR_DN_COVERAGE COVERAGE_DOWN,
                     ###.TXP.CUR_UP_COVERAGE COVERAGE_UP,
                     ###.TXP.TXP_DN_POL,
                     ###.TXP.TXP_UP_POL

      ... The rest is omitted for clarity

Hibernate实体如下:

@Component(value = "viewOlbSatCoverage")
@Scope("prototype")
@Entity
@Table(name = "VIEW_OLB_SAT_COVERAGE", schema = "##")
public class ViewOlbSatCoverage implements Serializable {

    private static final long serialVersionUID = -6728959649786852446L;

    @Id
    private ViewOlbSatCoverageId viewOlbSatCoverageId;

    public ViewOlbSatCoverageId getViewOlbSatCoverageId() {
        return viewOlbSatCoverageId;
    }

    public void setViewOlbSatCoverageId(ViewOlbSatCoverageId viewOlbSatCoverageId) {
        this.viewOlbSatCoverageId = viewOlbSatCoverageId;
    }

    @Override
    public String toString() {
        return "ViewOlbSatCoverage : [viewOlbSatCoverageId=" + viewOlbSatCoverageId == null ? "null"
                : viewOlbSatCoverageId.toString() + "]";
    }
}

@Component(value = "viewOlbSatCoverageId")
@Scope("prototype")
@Embeddable
public class ViewOlbSatCoverageId implements Serializable {

    private static final long serialVersionUID = 2822316442843031126L;

    @Column(name = "COVERAGE_DOWN")
    private String coverageDown;

    @Column(name = "COVERAGE_UP")
    private String coverageUp;

    @Column(name = "SAT_CODE")
    private String satCode;

    @Column(name = "ORBITAL_POSITION")
    private BigDecimal orbitalPosition;

    public ViewOlbSatCoverageId() {

    }

    public ViewOlbSatCoverageId(String satCode, BigDecimal orbitalPosition, String coverageDown, String coverageUp) {
        setSatCode(satCode);
        setOrbitalPosition(orbitalPosition);
        setCoverageDown(coverageDown);
        setCoverageUp(coverageUp);
    }

// Getters, setters omitted for clarity ...

}

正如我所提到的,目标数据库是Oracle 10g,并且一切正常(当应用程序运行时)。 但是当我运行H2数据库进行单元测试时,以下方法(findDistinctAllOrbitalPositions)不起作用:

    @Repository
    public class ViewOlbSatCoverageDaoImpl extends GenericDaoImpl<ViewOlbSatCoverage> implements ViewOlbSatCoverageDao {

        public ViewOlbSatCoverageDaoImpl() {
            setGenericClass(ViewOlbSatCoverage.class);
            setDaoLogger(ViewOlbSatCoverageDaoImpl.class);
        }

        @Override
        @SuppressWarnings("unchecked")
        public List<BigDecimal> findDistinctAllOrbitalPositions() {
            Query query = sessionFactory.getCurrentSession().createQuery(
                    "select distinct(viewOlbSatCoverageId.orbitalPosition) from " + genericClass.getSimpleName()
                    + " order by viewOlbSatCoverageId.orbitalPosition asc"); // genericClass is ViewOlbSatCoverage
            return query.list();
        }

}

如您所见,我使用的是HQL,但也使用了Criteria API。

当我从命令行启动maven时:

mvn clean -Dtest=ViewOlbSatCoverageDaoImplTestCase test

它给了我以下内容:

Caused by: org.h2.jdbc.JdbcSQLException: Column "VIEWOLBSAT0_.ORBITAL_POSITION" not found; SQL state
ment:
select distinct viewolbsat0_.ORBITAL_POSITION as col_0_0_ from ##.VIEW_OLB_SAT_COVERAGE viewolbsat0_
 order by viewolbsat0_.ORBITAL_POSITION asc [42122-190]
        at org.h2.message.DbException.getJdbcSQLException(DbException.java:345)
        at org.h2.message.DbException.get(DbException.java:179)
        at org.h2.message.DbException.get(DbException.java:155)
        at org.h2.expression.ExpressionColumn.optimize(ExpressionColumn.java:147)
        at org.h2.expression.Alias.optimize(Alias.java:51)
        at org.h2.command.dml.Select.prepare(Select.java:835)
        at org.h2.command.Parser.prepareCommand(Parser.java:246)
        at org.h2.engine.Session.prepareLocal(Session.java:460)
        at org.h2.engine.Session.prepareCommand(Session.java:402)
        at org.h2.jdbc.JdbcConnection.prepareCommand(JdbcConnection.java:1188)
        at org.h2.jdbc.JdbcPreparedStatement.<init>(JdbcPreparedStatement.java:72)
        at org.h2.jdbc.JdbcConnection.prepareStatement(JdbcConnection.java:276)
        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:606)
        at org.hibernate.engine.jdbc.internal.proxy.ConnectionProxyHandler.continueInvocation(Connec
tionProxyHandler.java:138)
        ... 64 more

以下是我的applicationContext-test.xml示例:

    <jdbc:embedded-database id="h2TestDataSource" type="H2"/>
        <jdbc:initialize-database data-source="h2TestDataSource">
    <jdbc:script location="classpath:com/eutelsat/olb/sql/create/views/VIEW_OLB_SAT_COVERAGE.sql" />
<jdbc:script location="classpath:com/eutelsat/olb/sql/create/views/VIEW_OLB_TXP_COVERAGE.sql" />
        <!-- Other .sql files omitted for clarity -->
        </jdbc:initialize-database>

                                       <!-- Connection pool -->

    <bean id="pooledDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">       
        <property name="driverClass" value="org.h2.Driver" />
        <property name="jdbcUrl" value="jdbc:h2:mem:h2TestDataSource;INIT=RUNSCRIPT FROM 'com/eutelsat/olb/sql/create/schemas/INIT.sql'" />
        <property name="user" value="sa" />
        <property name="password" value="" />
        <property name="acquireIncrement" value="1" />
        <property name="minPoolSize" value="1" />
        <property name="maxPoolSize" value="5" />
        <property name="maxIdleTime" value="30" />
        <property name="maxIdleTimeExcessConnections" value="10" />
        <property name="numHelperThreads" value="3" />
        <property name="unreturnedConnectionTimeout" value="0" />
    </bean>

                                       <!-- Session factory -->

    <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
      <property name="dataSource" ref="h2TestDataSource" />
      <property name="packagesToScan" value="com.eutelsat.olb.server.model" />
      <property name="hibernateProperties">
         <props>
            <prop key="hibernate.hbm2ddl.auto">none</prop>
            <prop key="hibernate.jdbc.batch_size">20</prop>
            <prop key="hibernate.use_outer_join">true</prop>
            <prop key="hibernate.order_inserts">true</prop>
            <prop key="hibernate.order_updates">true</prop>
            <prop key="hibernate.dialect">org.hibernate.dialect.H2Dialect</prop>
            <prop key="hibernate.show_sql">true</prop>
            <prop key="format_sql">true</prop>
            <prop key="hibernate.id.new_generator_mappings">true</prop>
         </props>
      </property>
   </bean>

                                    <!-- Transaction Manager -->

    <bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>

我已经阅读了很多内容,但我无法找到问题所在(错误的SQL脚本需要适应H2数据库,或者可能是H2数据库配置。列别名很重要?)。

注意:模式已被混淆。

提前感谢指针。

1 个答案:

答案 0 :(得分:0)

我找到了解决问题的方法。 在我的“applicationContext-test.xml”文件中声明的SQL脚本(其中一些在SOF中发布的示例中被省略)没有很好地排序,导致视图具有INVALID状态。 - &GT;导致Hibernate完成生成的SQL查询,抱怨某些表和/或列未找到。

由于优秀的H2网络服务器允许我查看内存数据,我发现了问题(以及解决方案)。在SCHEMA_INFORMATION部分,我看到了VIEWS,当点击它时,我看到STATUS = INVALID。

为了使用Spring XML配置添加H2 Web服务器,您可以轻松添加:

<bean id="h2Server" class="org.h2.tools.Server" factory-method="createTcpServer" init-method="start" destroy-method="stop" depends-on="h2WebServer">
        <constructor-arg value="-tcp,-tcpAllowOthers,-tcpPort,9992"/>
    </bean>

    <bean id="h2WebServer" class="org.h2.tools.Server" factory-method="createWebServer" init-method="start" destroy-method="stop">
        <constructor-arg value="-web,-webAllowOthers,-webPort,8882"/>
    </bean>

不要忘记将值为“h2Server”的依赖属性(所以:depends-on =“h2Server”)添加到数据源bean ,否则它将无法按预期工作!< / p>