Wicket, Spring и Hibernate — тестирование с помощью Unitils — ошибка: таблица не найдена в операторе [выберите relname из pg_class]

Я следил за учебным пособием и примером приложения, а именно 5 Days of Wicket — Написание тестов: http://www.mysticcoders.com/blog/2009/03/10/5-days-of-wicket-writing-the-tests/< /а>

Я создал свой собственный небольшой проект с простым чатом, который сохраняет сообщения в базе данных. Затем я хотел настроить пару тестов, которые бы удостоверились, что если сообщение хранится в базе данных, извлеченный объект будет содержать точно такие же данные.

После запуска mvn test все мои тесты завершаются ошибкой. Исключение было вставлено в первое поле кода внизу. Я заметил, что, несмотря на то, что в файле unitils.properties указано использовать диалект 'hdqldb', это сообщение все еще выводится в окне консоли при запуске тестов: ИНФОРМАЦИЯ - Диалект - Использование диалекта: org.hibernate.dialect .PostgreSQLДиалект. Я также добавил весь дамп из консоли внизу этого поста (который продолжается много миль :-)).

При запуске mvn test все мои тесты завершаются неудачей, за исключением:

Caused by: java.sql.SQLException: Table not found in statement [select relname from pg_class]
 at org.hsqldb.jdbc.Util.sqlException(Unknown Source)
 at org.hsqldb.jdbc.jdbcStatement.fetchResult(Unknown Source)
 at org.hsqldb.jdbc.jdbcStatement.executeQuery(Unknown Source)
 at org.apache.commons.dbcp.DelegatingStatement.executeQuery(DelegatingStatement.java:188)
 at org.hibernate.tool.hbm2ddl.DatabaseMetadata.initSequences(DatabaseMetadata.java:151)
 at org.hibernate.tool.hbm2ddl.DatabaseMetadata.(DatabaseMetadata.java:69)
 at org.hibernate.tool.hbm2ddl.DatabaseMetadata.(DatabaseMetadata.java:62)
 at org.springframework.orm.hibernate3.LocalSessionFactoryBean$3.doInHibernate(LocalSessionFactoryBean.java:958)
 at org.springframework.orm.hibernate3.HibernateTemplate.doExecute(HibernateTemplate.java:419)
 ... 49 more

Я настроил свой файл unitils.properties следующим образом:

database.driverClassName=org.hsqldb.jdbcDriver

database.url=jdbc:hsqldb:mem:PUBLIC
database.userName=sa
database.password=

database.dialect=hsqldb

database.schemaNames=PUBLIC

Мой абстрактный класс IntegrationTest:

@SpringApplicationContext({"/com/upbeat/shoutbox/spring/applicationContext.xml", "applicationContext-test.xml"})
public abstract class AbstractIntegrationTest extends UnitilsJUnit4 {
 private ApplicationContext applicationContext;
}

applicationContext-test.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
   <bean id="dataSource" class="org.unitils.database.UnitilsDataSourceFactoryBean"/>
</beans>

и, наконец, один из тестовых классов:

package com.upbeat.shoutbox.web;

import org.apache.wicket.spring.injection.annot.test.AnnotApplicationContextMock;
import org.apache.wicket.util.tester.WicketTester;
import org.junit.Before;
import org.junit.Test;
import org.unitils.spring.annotation.SpringBeanByType;

import com.upbeat.shoutbox.HomePage;
import com.upbeat.shoutbox.integrations.AbstractIntegrationTest;
import com.upbeat.shoutbox.persistence.ShoutItemDao;
import com.upbeat.shoutbox.services.ShoutService;

public class TestHomePage extends AbstractIntegrationTest
{
 @SpringBeanByType
 private ShoutService svc;

 @SpringBeanByType
 private ShoutItemDao dao;

 protected WicketTester tester;

 @Before
 public void setUp()
 {
  AnnotApplicationContextMock appctx = new AnnotApplicationContextMock();

  appctx.putBean("shoutItemDao", dao);
  appctx.putBean("shoutService", svc);
  tester = new WicketTester();
 }

 @Test
 public void testRenderMyPage()
 {
  //start and render the test page
  tester.startPage(HomePage.class);

  //assert rendered page class
  tester.assertRenderedPage(HomePage.class);

  //assert rendered label component
  tester.assertLabel("message", "If you see this message wicket is properly configured and running");
 }
}

Дамп из консоли при запуске mvn test:

[INFO] Scanning for projects...
[INFO] ------------------------------------------------------------------------
[INFO] Building shoutbox
[INFO]    task-segment: [test]
[INFO] ------------------------------------------------------------------------
[INFO] [resources:resources {execution: default-resources}]
[WARNING] File encoding has not been set, using platform encoding Cp1252, i.e. build is platform dependent!
[WARNING] Using platform encoding (Cp1252 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] Copying 3 resources
[INFO] Copying 4 resources
[INFO] [compiler:compile {execution: default-compile}]
[INFO] Nothing to compile - all classes are up to date
[INFO] [resources:testResources {execution: default-testResources}]
[WARNING] File encoding has not been set, using platform encoding Cp1252, i.e. build is platform dependent!
[WARNING] Using platform encoding (Cp1252 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] Copying 2 resources
[INFO] [compiler:testCompile {execution: default-testCompile}]
[INFO] Nothing to compile - all classes are up to date
[INFO] [surefire:test {execution: default-test}]
[INFO] Surefire report directory: F:\Projects\shoutbox\target\surefire-reports
INFO  - ConfigurationLoader        - Loaded main configuration file unitils-default.properties from classpath.
INFO  - ConfigurationLoader        - Loaded custom configuration file unitils.properties from classpath.
INFO  - ConfigurationLoader        - No local configuration file unitils-local.properties found.

-------------------------------------------------------
 T E S T S
-------------------------------------------------------
Running com.upbeat.shoutbox.web.TestViewShoutsPage
Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 0.02 sec 
INFO  - Version                    - Hibernate Annotations 3.4.0.GA
INFO  - Environment                - Hibernate 3.3.0.SP1
INFO  - Environment                - hibernate.properties not found
INFO  - Environment                - Bytecode provider name : javassist
INFO  - Environment                - using JDK 1.4 java.sql.Timestamp handling
INFO  - Version                    - Hibernate Commons Annotations 3.1.0.GA
INFO  - AnnotationBinder           - Binding entity from annotated class: com.upbeat.shoutbox.models.ShoutItem
INFO  - QueryBinder                - Binding Named query: item.getById => from ShoutItem item where item.id = :id
INFO  - QueryBinder                - Binding Named query: item.find => from ShoutItem item order by item.timestamp desc
INFO  - QueryBinder                - Binding Named query: item.count => select count(item) from ShoutItem item
INFO  - EntityBinder               - Bind entity com.upbeat.shoutbox.models.ShoutItem on table SHOUT_ITEMS
INFO  - AnnotationConfiguration    - Hibernate Validator not found: ignoring
INFO  - notationSessionFactoryBean - Building new Hibernate SessionFactory
INFO  - earchEventListenerRegister - Unable to find org.hibernate.search.event.FullTextIndexEventListener on the classpath. Hibernate Search is not enabled.
INFO  - ConnectionProviderFactory  - Initializing connection provider: org.springframework.orm.hibernate3.LocalDataSourceConnectionProvider
INFO  - SettingsFactory            - RDBMS: HSQL Database Engine, version: 1.8.0
INFO  - SettingsFactory            - JDBC driver: HSQL Database Engine Driver, version: 1.8.0
INFO  - Dialect                    - Using dialect: org.hibernate.dialect.PostgreSQLDialect
INFO  - TransactionFactoryFactory  - Transaction strategy: org.springframework.orm.hibernate3.SpringTransactionFactory
INFO  - actionManagerLookupFactory - No TransactionManagerLookup configured (in JTA environment, use of read-write or transactional second-level cache is not recommended)
INFO  - SettingsFactory            - Automatic flush during beforeCompletion(): disabled
INFO  - SettingsFactory            - Automatic session close at end of transaction: disabled
INFO  - SettingsFactory            - JDBC batch size: 1000
INFO  - SettingsFactory            - JDBC batch updates for versioned data: disabled
INFO  - SettingsFactory            - Scrollable result sets: enabled
INFO  - SettingsFactory            - JDBC3 getGeneratedKeys(): disabled
INFO  - SettingsFactory            - Connection release mode: auto
INFO  - SettingsFactory            - Default batch fetch size: 1
INFO  - SettingsFactory            - Generate SQL with comments: disabled
INFO  - SettingsFactory            - Order SQL updates by primary key: disabled
INFO  - SettingsFactory            - Order SQL inserts for batching: disabled
INFO  - SettingsFactory            - Query translator: org.hibernate.hql.ast.ASTQueryTranslatorFactory
INFO  - ASTQueryTranslatorFactory  - Using ASTQueryTranslatorFactory
INFO  - SettingsFactory            - Query language substitutions: {}
INFO  - SettingsFactory            - JPA-QL strict compliance: disabled
INFO  - SettingsFactory            - Second-level cache: enabled
INFO  - SettingsFactory            - Query cache: enabled
INFO  - SettingsFactory            - Cache region factory : org.hibernate.cache.impl.bridge.RegionFactoryCacheProviderBridge
INFO  - FactoryCacheProviderBridge - Cache provider: org.hibernate.cache.HashtableCacheProvider
INFO  - SettingsFactory            - Optimize cache for minimal puts: disabled
INFO  - SettingsFactory            - Structured second-level cache entries: disabled
INFO  - SettingsFactory            - Query cache factory: org.hibernate.cache.StandardQueryCacheFactory
INFO  - SettingsFactory            - Echoing all SQL to stdout
INFO  - SettingsFactory            - Statistics: disabled
INFO  - SettingsFactory            - Deleted entity synthetic identifier rollback: disabled
INFO  - SettingsFactory            - Default entity-mode: pojo
INFO  - SettingsFactory            - Named query checking : enabled
INFO  - SessionFactoryImpl         - building session factory
INFO  - essionFactoryObjectFactory - Not binding factory to JNDI, no JNDI name configured
INFO  - UpdateTimestampsCache      - starting update timestamps cache at region: org.hibernate.cache.UpdateTimestampsCache
INFO  - StandardQueryCache         - starting query cache at region: org.hibernate.cache.StandardQueryCache
INFO  - notationSessionFactoryBean - Updating database schema for Hibernate SessionFactory
INFO  - Dialect                    - Using dialect: org.hibernate.dialect.PostgreSQLDialect
INFO  - XmlBeanDefinitionReader    - Loading XML bean definitions from class path resource [org/springframework/jdbc/support/sql-error-codes.xml]
INFO  - SQLErrorCodesFactory       - SQLErrorCodes loaded: [DB2, Derby, H2, HSQL, Informix, MS-SQL, MySQL, Oracle, PostgreSQL, Sybase]
INFO  - DefaultListableBeanFactory - Destroying singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@3e0ebb: defining beans [propertyConfigurer,dataSource,sessionFactory,shoutService,shoutItemDao,wicketApplication,org.springframework.aop.config.internalAutoProxyCreator,org.springframework.transaction.annotation.AnnotationTransactionAttributeSource#0,org.springframework.transaction.interceptor.TransactionInterceptor#0,org.springframework.transaction.config.internalTransactionAdvisor,transactionManager]; root of factory hierarchy
INFO  - sPathXmlApplicationContext - Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@a8e586: display name [org.springframework.context.support.ClassPathXmlApplicationContext@a8e586]; startup date [Tue May 04 18:19:58 CEST 2010]; root of context hierarchy
INFO  - XmlBeanDefinitionReader    - Loading XML bean definitions from class path resource [com/upbeat/shoutbox/spring/applicationContext.xml]
INFO  - XmlBeanDefinitionReader    - Loading XML bean definitions from class path resource [applicationContext-test.xml]
INFO  - DefaultListableBeanFactory - Overriding bean definition for bean 'dataSource': replacing [Generic bean: class [org.apache.commons.dbcp.BasicDataSource]; scope=singleton; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=close; defined in class path resource [com/upbeat/shoutbox/spring/applicationContext.xml]] with [Generic bean: class [org.unitils.database.UnitilsDataSourceFactoryBean]; scope=singleton; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in class path resource [applicationContext-test.xml]]
INFO  - sPathXmlApplicationContext - Bean factory for application context [org.springframework.context.support.ClassPathXmlApplicationContext@a8e586]: org.springframework.beans.factory.support.DefaultListableBeanFactory@5dfaf1
INFO  - pertyPlaceholderConfigurer - Loading properties file from class path resource [application.properties]
INFO  - DefaultListableBeanFactory - Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@5dfaf1: defining beans [propertyConfigurer,dataSource,sessionFactory,shoutService,shoutItemDao,wicketApplication,org.springframework.aop.config.internalAutoProxyCreator,org.springframework.transaction.annotation.AnnotationTransactionAttributeSource#0,org.springframework.transaction.interceptor.TransactionInterceptor#0,org.springframework.transaction.config.internalTransactionAdvisor,transactionManager]; root of factory hierarchy
INFO  - AnnotationBinder           - Binding entity from annotated class: com.upbeat.shoutbox.models.ShoutItem
INFO  - QueryBinder                - Binding Named query: item.getById => from ShoutItem item where item.id = :id
INFO  - QueryBinder                - Binding Named query: item.find => from ShoutItem item order by item.timestamp desc
INFO  - QueryBinder                - Binding Named query: item.count => select count(item) from ShoutItem item
INFO  - EntityBinder               - Bind entity com.upbeat.shoutbox.models.ShoutItem on table SHOUT_ITEMS
INFO  - AnnotationConfiguration    - Hibernate Validator not found: ignoring
INFO  - notationSessionFactoryBean - Building new Hibernate SessionFactory
INFO  - earchEventListenerRegister - Unable to find org.hibernate.search.event.FullTextIndexEventListener on the classpath. Hibernate Search is not enabled.
INFO  - ConnectionProviderFactory  - Initializing connection provider: org.springframework.orm.hibernate3.LocalDataSourceConnectionProvider
INFO  - SettingsFactory            - RDBMS: HSQL Database Engine, version: 1.8.0
INFO  - SettingsFactory            - JDBC driver: HSQL Database Engine Driver, version: 1.8.0
INFO  - Dialect                    - Using dialect: org.hibernate.dialect.PostgreSQLDialect
INFO  - TransactionFactoryFactory  - Transaction strategy: org.springframework.orm.hibernate3.SpringTransactionFactory
INFO  - actionManagerLookupFactory - No TransactionManagerLookup configured (in JTA environment, use of read-write or transactional second-level cache is not recommended)
INFO  - SettingsFactory            - Automatic flush during beforeCompletion(): disabled
INFO  - SettingsFactory            - Automatic session close at end of transaction: disabled
INFO  - SettingsFactory            - JDBC batch size: 1000
INFO  - SettingsFactory            - JDBC batch updates for versioned data: disabled
INFO  - SettingsFactory            - Scrollable result sets: enabled
INFO  - SettingsFactory            - JDBC3 getGeneratedKeys(): disabled
INFO  - SettingsFactory            - Connection release mode: auto
INFO  - SettingsFactory            - Default batch fetch size: 1
INFO  - SettingsFactory            - Generate SQL with comments: disabled
INFO  - SettingsFactory            - Order SQL updates by primary key: disabled
INFO  - SettingsFactory            - Order SQL inserts for batching: disabled
INFO  - SettingsFactory            - Query translator: org.hibernate.hql.ast.ASTQueryTranslatorFactory
INFO  - ASTQueryTranslatorFactory  - Using ASTQueryTranslatorFactory
INFO  - SettingsFactory            - Query language substitutions: {}
INFO  - SettingsFactory            - JPA-QL strict compliance: disabled
INFO  - SettingsFactory            - Second-level cache: enabled
INFO  - SettingsFactory            - Query cache: enabled
INFO  - SettingsFactory            - Cache region factory : org.hibernate.cache.impl.bridge.RegionFactoryCacheProviderBridge
INFO  - FactoryCacheProviderBridge - Cache provider: org.hibernate.cache.HashtableCacheProvider
INFO  - SettingsFactory            - Optimize cache for minimal puts: disabled
INFO  - SettingsFactory            - Structured second-level cache entries: disabled
INFO  - SettingsFactory            - Query cache factory: org.hibernate.cache.StandardQueryCacheFactory
INFO  - SettingsFactory            - Echoing all SQL to stdout
INFO  - SettingsFactory            - Statistics: disabled
INFO  - SettingsFactory            - Deleted entity synthetic identifier rollback: disabled
INFO  - SettingsFactory            - Default entity-mode: pojo
INFO  - SettingsFactory            - Named query checking : enabled
INFO  - SessionFactoryImpl         - building session factory
INFO  - essionFactoryObjectFactory - Not binding factory to JNDI, no JNDI name configured
INFO  - UpdateTimestampsCache      - starting update timestamps cache at region: org.hibernate.cache.UpdateTimestampsCache
INFO  - StandardQueryCache         - starting query cache at region: org.hibernate.cache.StandardQueryCache
INFO  - notationSessionFactoryBean - Updating database schema for Hibernate SessionFactory
INFO  - Dialect                    - Using dialect: org.hibernate.dialect.PostgreSQLDialect
INFO  - DefaultListableBeanFactory - Destroying singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@5dfaf1: defining beans [propertyConfigurer,dataSource,sessionFactory,shoutService,shoutItemDao,wicketApplication,org.springframework.aop.config.internalAutoProxyCreator,org.springframework.transaction.annotation.AnnotationTransactionAttributeSource#0,org.springframework.transaction.interceptor.TransactionInterceptor#0,org.springframework.transaction.config.internalTransactionAdvisor,transactionManager]; root of factory hierarchy
Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 1.34 sec <<< FAILURE!
Running com.upbeat.shoutbox.integrations.ShoutItemIntegrationTest
Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 0 sec <<< FAILURE!
Running com.upbeat.shoutbox.mocks.ShoutServiceTest
Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 0.01 sec <<< FAILURE!

Results :

Tests in error: 
  initializationError(com.upbeat.shoutbox.web.TestViewShoutsPage)
  testRenderMyPage(com.upbeat.shoutbox.web.TestHomePage)
  initializationError(com.upbeat.shoutbox.integrations.ShoutItemIntegrationTest)
  initializationError(com.upbeat.shoutbox.mocks.ShoutServiceTest)

Tests run: 4, Failures: 0, Errors: 4, Skipped: 0

[INFO] ------------------------------------------------------------------------
[ERROR] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] There are test failures.

Please refer to F:\Projects\shoutbox\target\surefire-reports for the individual test results.
[INFO] ------------------------------------------------------------------------
[INFO] For more information, run Maven with the -e switch
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 3 seconds
[INFO] Finished at: Tue May 04 18:19:58 CEST 2010
[INFO] Final Memory: 13M/31M
[INFO] ------------------------------------------------------------------------

Любая помощь приветствуется.


person John    schedule 04.05.2010    source источник


Ответы (1)


В то время как applicationContext-test.xml переопределяет источник данных по умолчанию для предоставления источника данных Unitils, applicationContext.xml по-прежнему объявляет следующее свойство (которое заменяется во время фильтрации Maven):

<prop key="hibernate.dialect">${hibernate.dialect}</prop>

Итак, если вы хотите запустить интеграционные тесты для базы данных HSQLDB (похоже, Unitils настроен для этого), насколько я понимаю, вы должны использовать фильтр filters-LOCAL.properties, который срабатывает при использовании LOCAL и объявляет:

hibernate.dialect=org.hibernate.dialect.HSQLDialect

Вы можете проверить target/classes/applicationContext.xml, чтобы подтвердить это, но кажется очевидным, что вы получаете не указанное выше значение, а PostgreSQLDialect.

Странно то, что pom.xml mysticpaste объявляет профиль LOCAL как activeByDefault (по крайней мере, версия в репозитории проекта):

<profile>
  <id>LOCAL</id>
  <activation>
    <activeByDefault>true</activeByDefault>
  </activation>
  <properties>
    <env>LOCAL</env>
  </properties>
</profile> 

Это должно просто работать. Итак, вопрос:

  • что говорит mvn help:active-profiles?
  • у вас есть этот ЛОКАЛЬНЫЙ профиль (и ЛОКАЛЬНЫЙ фильтр)?
  • у вас есть последняя версия этого pom.xml?
person Pascal Thivent    schedule 04.05.2010
comment
Я удалил фильтры, которые mysticpaste использует в своих помпонах, поэтому я их не использую. Я сделал это на основе более раннего вопроса, в котором было предложено воздержаться от использования фильтров. Вместо этих фильтров я использую один единственный файл application.properties (который содержит hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect). Я создам ЛОКАЛЬНЫЙ фильтр, как вы предложили, с соответствующим набором HSQLDialect :-) - person John; 04.05.2010
comment
Предложение, которое вы получили здесь на SO, является лишь одним мнением и не обязательно отражает все мнения :) Лично я разделяю точку зрения, выраженную автором этой серии Wicket в этот комментарий и предпочесть профили PropertyPlaceholderConfigurer. - person Pascal Thivent; 04.05.2010
comment
Большое спасибо, Паскаль, за помощь с исходной проблемой и замечание по использованию профилей. Ваше предложение создать профиль с соответствующим диалектом, похоже, помогло! - person John; 04.05.2010
comment
@John Чтобы было ясно, использование профиля для переключения с одного диалекта на другой - это всего лишь один из способов, ничто не заставляет вас использовать это решение (даже если я думаю, что профили хороши). Но дело в том, что нужно менять значение свойства hibernate.dialect в зависимости от окружения. - person Pascal Thivent; 04.05.2010
comment
@Pascal Использование профилей кажется разумным выбором, поскольку у меня есть несколько сред (разработка, тестирование, подготовка к производству и производство). При развертывании на рабочем сервере достаточно ли использовать параметр -P только для команды развертывания, или мне нужно установить для профиля, содержащего мои рабочие параметры, значение activeByDefault, прежде чем отправлять его на tomcat? - person John; 05.05.2010
comment
@John: Работа со средами действительно является идеальным вариантом использования профилей. Что касается вашего вопроса, я бы порекомендовал не изменять activeByDefault, использовать его для профиля, который вы используете наиболее часто (скорее всего, профиль разработки), не меняйте свой pom для выпуска в другую среду. Вместо этого используйте -P, когда вам нужен другой профиль (это отключит любой профиль, активный по умолчанию). На всякий случай ознакомьтесь с Введение в создание профилей. - person Pascal Thivent; 05.05.2010