Spring、Hibernate、TestNG 和 h2:org.dbunit.dataset.NoSuchTableException:用户
Spring, Hibernate, TestNG and h2: org.dbunit.dataset.NoSuchTableException: user
我正在尝试测试 DAO 层。
该项目包括以下技术堆栈:Spring 4、Hibernate 5、MySQL、H2、Mockito、testNG、dbUnit 和其他...
这里是 pom.xml 的依赖片段:
<properties>
<springframework.version>4.2.4.RELEASE</springframework.version>
<hibernate.version>5.1.0.Final</hibernate.version>
<hibernate-jpa.version>1.0.0.Final</hibernate-jpa.version>
<mysql-connector.version>5.1.38</mysql-connector.version>
<mockito.version>1.10.19</mockito.version>
<maven.test.skip>false</maven.test.skip>
<testng.version>6.9.4</testng.version>
<h2.version>1.3.176</h2.version>
<dbunit.version>2.2</dbunit.version>
</properties>
<dependencies>
<!-- Testing -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${springframework.version}</version>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<version>${mockito.version}</version>
</dependency>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>${testng.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>${h2.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>dbunit</groupId>
<artifactId>dbunit</artifactId>
<version>${dbunit.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
测试结果returns出现如下错误堆栈:
org.dbunit.dataset.NoSuchTableException: user
at org.dbunit.database.DatabaseDataSet.getTableMetaData(DatabaseDataSet.java:192)
at org.dbunit.operation.DeleteAllOperation.execute(DeleteAllOperation.java:98)
at org.dbunit.operation.CompositeOperation.execute(CompositeOperation.java:67)
SEE ====> at ru.ts.js.oxaoo.srt.dao.DAOTest.setUp(DAOTest.java:30)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:85)
at org.testng.internal.Invoker.invokeConfigurationMethod(Invoker.java:517)
at org.testng.internal.Invoker.invokeConfigurations(Invoker.java:213)
at org.testng.internal.Invoker.invokeMethod(Invoker.java:601)
at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:845)
at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1153)
at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:125)
at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:108)
at org.testng.TestRunner.privateRun(TestRunner.java:771)
at org.testng.TestRunner.run(TestRunner.java:621)
at org.testng.SuiteRunner.runTest(SuiteRunner.java:357)
at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:352)
at org.testng.SuiteRunner.privateRun(SuiteRunner.java:310)
at org.testng.SuiteRunner.run(SuiteRunner.java:259)
at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86)
at org.testng.TestNG.runSuitesSequentially(TestNG.java:1199)
at org.testng.TestNG.runSuitesLocally(TestNG.java:1124)
at org.testng.TestNG.run(TestNG.java:1032)
at org.testng.IDEARemoteTestNG.run(IDEARemoteTestNG.java:72)
at org.testng.RemoteTestNGStarter.main(RemoteTestNGStarter.java:122)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
Hibernate测试配置说明:
@Configuration
@EnableTransactionManagement
@ComponentScan({"ru.ts.js.oxaoo.srtd.dao"})
public class HibernateTestConfiguration {
//@Autowired
//private Environment environment;
@Bean
public LocalSessionFactoryBean sessionFactory() {
LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
sessionFactory.setDataSource(dataSource());
sessionFactory.setPackagesToScan(new String[]{"ru.ts.js.oxaoo.srtd.entity"});
sessionFactory.setHibernateProperties(hibernateProperties());
return sessionFactory;
}
@Bean
public DataSource dataSource(){
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("org.h2.Driver");
dataSource.setUrl("jdbc:h2:mem:srtd;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE");
dataSource.setUsername("sa");
dataSource.setPassword("");
return dataSource;
}
@Bean
public Properties hibernateProperties() {
Properties properties = new Properties();
properties.put("hibernate.dialect", "org.hibernate.dialect.H2Dialect");
properties.put("hibernate.hbm2ddl.auto", "create-drop");
return properties;
}
@Bean
@Autowired
public HibernateTransactionManager transactionManager(SessionFactory sessionFactory) {
HibernateTransactionManager transactionManager = new HibernateTransactionManager();
transactionManager.setSessionFactory(sessionFactory);
return transactionManager;
}
}
所有DAO测试的摘要class:
//@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {HibernateTestConfiguration.class})
public abstract class DAOTest extends AbstractTransactionalTestNGSpringContextTests {
@Autowired
DataSource dataSource;
@BeforeMethod
public void setUp() throws Exception {
IDatabaseConnection dbConn = new DatabaseDataSourceConnection(dataSource);
IDataSet dataSet = getDataSet();
DatabaseOperation.CLEAN_INSERT.execute(dbConn, dataSet);
}
protected abstract IDataSet getDataSet() throws Exception;
}
错误发生处的相同代码行 #30:
DatabaseOperation.CLEAN_INSERT.execute(dbConn, dataSet);
执行此代码行之前调试期间的变量内容:
img contents of variables。 dbConn 中的几乎所有字段都是空的。
Class 测试用户 DAO:
public class UserDAOTest extends DAOTest {
private final static Logger log = Logger.getLogger(UserDAOTest.class.getName());
@Autowired
private IUserDAO userDAO;
@Override
protected IDataSet getDataSet() throws Exception {
return new FlatXmlDataSet(this.getClass().getClassLoader().getResourceAsStream("user.xml"));
}
@Test
public void findById(){
if (userDAO == null) log.info("user dao is null");
else log.info("user dao is: " + userDAO.toString());
UserEntity ue = userDAO.findByPK("ivan@email.com");
log.debug("Find by id: " + ue.toString());
assertNotNull("Don't found user by id", ue);
}
}
以及user.xml的这些内容:
<?xml version="1.0" encoding="UTF-8"?>
<dataset>
<user email="ivan@email.com" idPassanger="1" password="qwerty"/>
<user email="petr@email.com" idPassanger="2" password="qwerty2"/>
<user email="dmitry@email.com" idPassanger="3" password="12345"/>
</dataset>
据我所知,错误是指此文件中的 "user" 标记。
这里还有用户的POJO:
@Entity
@Table(name = "user", schema = "srtd")
public class UserEntity {
private String email;
private String password;
private PassangerEntity idPassanger;
public UserEntity() {}
public UserEntity(String email, String password, PassangerEntity idPassanger) {
this.email = email;
this.password = password;
this.idPassanger = idPassanger;
}
@Id
@Column(name = "email")
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
@Basic
@Column(name = "password")
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@OneToOne(optional = false, cascade = CascadeType.ALL)
@JoinColumn(name = "idPassanger", unique = true, nullable = false)
public PassangerEntity getIdPassanger(){
return idPassanger;
}
public void setIdPassanger(PassangerEntity idPassanger){
this.idPassanger = idPassanger;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
UserEntity that = (UserEntity) o;
if (email != null ? !email.equals(that.email) : that.email != null) return false;
if (password != null ? !password.equals(that.password) : that.password != null) return false;
return true;
}
@Override
public int hashCode() {
int result = email != null ? email.hashCode() : 0;
result = 31 * result + (password != null ? password.hashCode() : 0);
return result;
}
@Override
public String toString() {
return "UserEntity{" +
"email='" + email + '\'' +
", password='" + password + '\'' +
", idPassanger=" + idPassanger.toString() +
'}';
}
}
在completer stack of errors中有如下一条日志,我觉得需要注意的是:
Caused by: org.h2.jdbc.JdbcSQLException:
Schema "SRTD" not found; SQL statement:
alter table srtd.user add constraint FKec3wluojmxshecxg06rihvlwf foreign key (idPassanger) references srtd.passanger [90079-176]
如果有必要,那我就把错误全贴出来,真相很大...
请帮我解决这个问题,我已经折腾了一整天了。
尝试从 entity
注释中删除属性 schema = "srtd"
,因为 dataSource.setUrl(..)
方法已经有了它。
我正在尝试测试 DAO 层。 该项目包括以下技术堆栈:Spring 4、Hibernate 5、MySQL、H2、Mockito、testNG、dbUnit 和其他...
这里是 pom.xml 的依赖片段:
<properties>
<springframework.version>4.2.4.RELEASE</springframework.version>
<hibernate.version>5.1.0.Final</hibernate.version>
<hibernate-jpa.version>1.0.0.Final</hibernate-jpa.version>
<mysql-connector.version>5.1.38</mysql-connector.version>
<mockito.version>1.10.19</mockito.version>
<maven.test.skip>false</maven.test.skip>
<testng.version>6.9.4</testng.version>
<h2.version>1.3.176</h2.version>
<dbunit.version>2.2</dbunit.version>
</properties>
<dependencies>
<!-- Testing -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${springframework.version}</version>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<version>${mockito.version}</version>
</dependency>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>${testng.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>${h2.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>dbunit</groupId>
<artifactId>dbunit</artifactId>
<version>${dbunit.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
测试结果returns出现如下错误堆栈:
org.dbunit.dataset.NoSuchTableException: user
at org.dbunit.database.DatabaseDataSet.getTableMetaData(DatabaseDataSet.java:192)
at org.dbunit.operation.DeleteAllOperation.execute(DeleteAllOperation.java:98)
at org.dbunit.operation.CompositeOperation.execute(CompositeOperation.java:67)
SEE ====> at ru.ts.js.oxaoo.srt.dao.DAOTest.setUp(DAOTest.java:30)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:85)
at org.testng.internal.Invoker.invokeConfigurationMethod(Invoker.java:517)
at org.testng.internal.Invoker.invokeConfigurations(Invoker.java:213)
at org.testng.internal.Invoker.invokeMethod(Invoker.java:601)
at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:845)
at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1153)
at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:125)
at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:108)
at org.testng.TestRunner.privateRun(TestRunner.java:771)
at org.testng.TestRunner.run(TestRunner.java:621)
at org.testng.SuiteRunner.runTest(SuiteRunner.java:357)
at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:352)
at org.testng.SuiteRunner.privateRun(SuiteRunner.java:310)
at org.testng.SuiteRunner.run(SuiteRunner.java:259)
at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86)
at org.testng.TestNG.runSuitesSequentially(TestNG.java:1199)
at org.testng.TestNG.runSuitesLocally(TestNG.java:1124)
at org.testng.TestNG.run(TestNG.java:1032)
at org.testng.IDEARemoteTestNG.run(IDEARemoteTestNG.java:72)
at org.testng.RemoteTestNGStarter.main(RemoteTestNGStarter.java:122)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
Hibernate测试配置说明:
@Configuration
@EnableTransactionManagement
@ComponentScan({"ru.ts.js.oxaoo.srtd.dao"})
public class HibernateTestConfiguration {
//@Autowired
//private Environment environment;
@Bean
public LocalSessionFactoryBean sessionFactory() {
LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
sessionFactory.setDataSource(dataSource());
sessionFactory.setPackagesToScan(new String[]{"ru.ts.js.oxaoo.srtd.entity"});
sessionFactory.setHibernateProperties(hibernateProperties());
return sessionFactory;
}
@Bean
public DataSource dataSource(){
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("org.h2.Driver");
dataSource.setUrl("jdbc:h2:mem:srtd;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE");
dataSource.setUsername("sa");
dataSource.setPassword("");
return dataSource;
}
@Bean
public Properties hibernateProperties() {
Properties properties = new Properties();
properties.put("hibernate.dialect", "org.hibernate.dialect.H2Dialect");
properties.put("hibernate.hbm2ddl.auto", "create-drop");
return properties;
}
@Bean
@Autowired
public HibernateTransactionManager transactionManager(SessionFactory sessionFactory) {
HibernateTransactionManager transactionManager = new HibernateTransactionManager();
transactionManager.setSessionFactory(sessionFactory);
return transactionManager;
}
}
所有DAO测试的摘要class:
//@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {HibernateTestConfiguration.class})
public abstract class DAOTest extends AbstractTransactionalTestNGSpringContextTests {
@Autowired
DataSource dataSource;
@BeforeMethod
public void setUp() throws Exception {
IDatabaseConnection dbConn = new DatabaseDataSourceConnection(dataSource);
IDataSet dataSet = getDataSet();
DatabaseOperation.CLEAN_INSERT.execute(dbConn, dataSet);
}
protected abstract IDataSet getDataSet() throws Exception;
}
错误发生处的相同代码行 #30:
DatabaseOperation.CLEAN_INSERT.execute(dbConn, dataSet);
执行此代码行之前调试期间的变量内容: img contents of variables。 dbConn 中的几乎所有字段都是空的。
Class 测试用户 DAO:
public class UserDAOTest extends DAOTest {
private final static Logger log = Logger.getLogger(UserDAOTest.class.getName());
@Autowired
private IUserDAO userDAO;
@Override
protected IDataSet getDataSet() throws Exception {
return new FlatXmlDataSet(this.getClass().getClassLoader().getResourceAsStream("user.xml"));
}
@Test
public void findById(){
if (userDAO == null) log.info("user dao is null");
else log.info("user dao is: " + userDAO.toString());
UserEntity ue = userDAO.findByPK("ivan@email.com");
log.debug("Find by id: " + ue.toString());
assertNotNull("Don't found user by id", ue);
}
}
以及user.xml的这些内容:
<?xml version="1.0" encoding="UTF-8"?>
<dataset>
<user email="ivan@email.com" idPassanger="1" password="qwerty"/>
<user email="petr@email.com" idPassanger="2" password="qwerty2"/>
<user email="dmitry@email.com" idPassanger="3" password="12345"/>
</dataset>
据我所知,错误是指此文件中的 "user" 标记。
这里还有用户的POJO:
@Entity
@Table(name = "user", schema = "srtd")
public class UserEntity {
private String email;
private String password;
private PassangerEntity idPassanger;
public UserEntity() {}
public UserEntity(String email, String password, PassangerEntity idPassanger) {
this.email = email;
this.password = password;
this.idPassanger = idPassanger;
}
@Id
@Column(name = "email")
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
@Basic
@Column(name = "password")
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@OneToOne(optional = false, cascade = CascadeType.ALL)
@JoinColumn(name = "idPassanger", unique = true, nullable = false)
public PassangerEntity getIdPassanger(){
return idPassanger;
}
public void setIdPassanger(PassangerEntity idPassanger){
this.idPassanger = idPassanger;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
UserEntity that = (UserEntity) o;
if (email != null ? !email.equals(that.email) : that.email != null) return false;
if (password != null ? !password.equals(that.password) : that.password != null) return false;
return true;
}
@Override
public int hashCode() {
int result = email != null ? email.hashCode() : 0;
result = 31 * result + (password != null ? password.hashCode() : 0);
return result;
}
@Override
public String toString() {
return "UserEntity{" +
"email='" + email + '\'' +
", password='" + password + '\'' +
", idPassanger=" + idPassanger.toString() +
'}';
}
}
在completer stack of errors中有如下一条日志,我觉得需要注意的是:
Caused by: org.h2.jdbc.JdbcSQLException:
Schema "SRTD" not found; SQL statement:
alter table srtd.user add constraint FKec3wluojmxshecxg06rihvlwf foreign key (idPassanger) references srtd.passanger [90079-176]
如果有必要,那我就把错误全贴出来,真相很大...
请帮我解决这个问题,我已经折腾了一整天了。
尝试从 entity
注释中删除属性 schema = "srtd"
,因为 dataSource.setUrl(..)
方法已经有了它。