我直接使用目标数据库运行我的单元测试: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数据库配置。列别名很重要?)。
注意:模式已被混淆。
提前感谢指针。
答案 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>