2009-10-01 64 views
1

我有一个JUnit测试,它在从mvn测试开始时成功,但从Eclipse开始时失败(请参阅下面的堆栈跟踪)。我想要做的是用entityManager.persist()和entityManager.flush()(当调用flush时,我得到错误)插入新元素到数据库中。从Eclipse开始与mvn测试不同的JUnit结果

我config.properties看起来如下:

db.url=jdbc:derby:target/testdb;create=true;territory=en_US;collation=TERRITORY_BASED 
db.username= 
db.password= 

# Hibernate 
hibernate.show_sql=true 
hibernate.hbm2ddl.auto=create 

通过这种结构,在Eclipse中我的测试失败,但 “MVN测试” 运行;如果我删除了“hibernate.hbm2ddl.auto = create”这一行,那么测试在“mvn test”和Eclipse中都是成功的。运行应用程序时,它可以工作;在启用“hibernate.hbm2ddl.auto = create”的情况下运行JUnit-Test时,它确实只会失败。

在我的测试类,有一个设置,方法看下面:

@Before 
    @Transactional(propagation = Propagation.REQUIRED, readOnly = false) 
    public void setUpDatabase() { 
    final Resource deleteScript = applicationContext.getResource("delete.sql"); 
    final Resource insertScript = applicationContext.getResource("insert.sql"); 
    SimpleJdbcTestUtils.executeSqlScript(simpleJdbcTemplate, deleteScript, true); 
    SimpleJdbcTestUtils.executeSqlScript(simpleJdbcTemplate, insertScript, false); 
    } 

delete.sql包含了一些语句,insert.sql再次插入statments“从删除”。

Java版本1.6.0_16,maven 2.1.0。

任何想法?

非常感谢,

斯特凡

javax.persistence.PersistenceException: org.hibernate.exception.ConstraintViolationException: could not insert: [ch.netcetera.gisab.masterdata.model.security.RuleTarget] 
    at org.hibernate.ejb.AbstractEntityManagerImpl.throwPersistenceException(AbstractEntityManagerImpl.java:614) 
    at org.hibernate.ejb.AbstractEntityManagerImpl.flush(AbstractEntityManagerImpl.java:307) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) 
    at java.lang.reflect.Method.invoke(Method.java:597) 
    at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:198) 
    at $Proxy47.flush(Unknown Source) 
    at ch.netcetera.gisab.masterdata.dao.RuleDAOImpl.updateRuleTargetsOfRule(RuleDAOImpl.java:84) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) 
    at java.lang.reflect.Method.invoke(Method.java:597) 
    at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:307) 
    at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:182) 
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:149) 
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:106) 
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171) 
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204) 
    at $Proxy72.updateRuleTargetsOfRule(Unknown Source) 
    at ch.netcetera.gisab.masterdata.services.RoleServiceImpl.updateUserRoleTO(RoleServiceImpl.java:145) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) 
    at java.lang.reflect.Method.invoke(Method.java:597) 
    at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:307) 
    at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:182) 
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:149) 
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:106) 
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171) 
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204) 
    at $Proxy74.updateUserRoleTO(Unknown Source) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) 
    at java.lang.reflect.Method.invoke(Method.java:597) 
    at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:307) 
    at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:182) 
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:149) 
    at org.springframework.aop.interceptor.CustomizableTraceInterceptor.invokeUnderTrace(CustomizableTraceInterceptor.java:255) 
    at org.springframework.aop.interceptor.AbstractTraceInterceptor.invoke(AbstractTraceInterceptor.java:110) 
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171) 
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204) 
    at $Proxy74.updateUserRoleTO(Unknown Source) 
    at ch.netcetera.gisab.masterdata.services.RoleServiceTest.testUpdateUserRoleTO(RoleServiceTest.java:140) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) 
    at java.lang.reflect.Method.invoke(Method.java:597) 
    at org.springframework.test.context.junit4.SpringTestMethod.invoke(SpringTestMethod.java:160) 
    at org.springframework.test.context.junit4.SpringMethodRoadie.runTestMethod(SpringMethodRoadie.java:233) 
    at org.springframework.test.context.junit4.SpringMethodRoadie$RunBeforesThenTestThenAfters.run(SpringMethodRoadie.java:333) 
    at org.springframework.test.context.junit4.SpringMethodRoadie.runWithRepetitions(SpringMethodRoadie.java:217) 
    at org.springframework.test.context.junit4.SpringMethodRoadie.runTest(SpringMethodRoadie.java:197) 
    at org.springframework.test.context.junit4.SpringMethodRoadie.run(SpringMethodRoadie.java:143) 
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.invokeTestMethod(SpringJUnit4ClassRunner.java:160) 
    at org.junit.internal.runners.JUnit4ClassRunner.runMethods(JUnit4ClassRunner.java:51) 
    at org.junit.internal.runners.JUnit4ClassRunner$1.run(JUnit4ClassRunner.java:44) 
    at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:27) 
    at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:37) 
    at org.junit.internal.runners.JUnit4ClassRunner.run(JUnit4ClassRunner.java:42) 
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:97) 
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:46) 
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197) 
Caused by: org.hibernate.exception.ConstraintViolationException: could not insert: [ch.netcetera.gisab.masterdata.model.security.RuleTarget] 
    at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:94) 
    at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66) 
    at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2295) 
    at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2688) 
    at org.hibernate.action.EntityInsertAction.execute(EntityInsertAction.java:79) 
    at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:279) 
    at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:263) 
    at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:167) 
    at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:321) 
    at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:50) 
    at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1027) 
    at org.hibernate.ejb.AbstractEntityManagerImpl.flush(AbstractEntityManagerImpl.java:304) 
    ... 66 more 
Caused by: java.sql.SQLIntegrityConstraintViolationException: The statement was aborted because it would have caused a duplicate key value in a unique or primary key constraint or unique index identified by 'SQL091001075326220' defined on 'RULETARGET'. 
    at org.apache.derby.impl.jdbc.SQLExceptionFactory40.getSQLException(Unknown Source) 
    at org.apache.derby.impl.jdbc.Util.generateCsSQLException(Unknown Source) 
    at org.apache.derby.impl.jdbc.TransactionResourceImpl.wrapInSQLException(Unknown Source) 
    at org.apache.derby.impl.jdbc.TransactionResourceImpl.handleException(Unknown Source) 
    at org.apache.derby.impl.jdbc.EmbedConnection.handleException(Unknown Source) 
    at org.apache.derby.impl.jdbc.ConnectionChild.handleException(Unknown Source) 
    at org.apache.derby.impl.jdbc.EmbedStatement.executeStatement(Unknown Source) 
    at org.apache.derby.impl.jdbc.EmbedPreparedStatement.executeStatement(Unknown Source) 
    at org.apache.derby.impl.jdbc.EmbedPreparedStatement.executeUpdate(Unknown Source) 
    at org.apache.commons.dbcp.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:102) 
    at org.hibernate.jdbc.NonBatchingBatcher.addToBatch(NonBatchingBatcher.java:46) 
    at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2275) 
    ... 75 more 
Caused by: java.sql.SQLException: The statement was aborted because it would have caused a duplicate key value in a unique or primary key constraint or unique index identified by 'SQL091001075326220' defined on 'RULETARGET'. 
    at org.apache.derby.impl.jdbc.SQLExceptionFactory.getSQLException(Unknown Source) 
    at org.apache.derby.impl.jdbc.SQLExceptionFactory40.wrapArgsForTransportAcrossDRDA(Unknown Source) 
    ... 87 more 
Caused by: ERROR 23505: The statement was aborted because it would have caused a duplicate key value in a unique or primary key constraint or unique index identified by 'SQL091001075326220' defined on 'RULETARGET'. 
    at org.apache.derby.iapi.error.StandardException.newException(Unknown Source) 
    at org.apache.derby.impl.sql.execute.IndexChanger.insertAndCheckDups(Unknown Source) 
    at org.apache.derby.impl.sql.execute.IndexChanger.doInsert(Unknown Source) 
    at org.apache.derby.impl.sql.execute.IndexChanger.insert(Unknown Source) 
    at org.apache.derby.impl.sql.execute.IndexSetChanger.insert(Unknown Source) 
    at org.apache.derby.impl.sql.execute.RowChangerImpl.insertRow(Unknown Source) 
    at org.apache.derby.impl.sql.execute.InsertResultSet.normalInsertCore(Unknown Source) 
    at org.apache.derby.impl.sql.execute.InsertResultSet.open(Unknown Source) 
    at org.apache.derby.impl.sql.GenericPreparedStatement.execute(Unknown Source) 
    ... 81 more 

编辑:

我忘了:在启动过程中没有错误,但失败的测试方法中,我得到了以下警告日志:

2009-10-01 10:16:38,924 | main   | WARN | JDBCExceptionReporter   | SQL Warning: 10000, SQLState: 01J01 
2009-10-01 10:16:38,924 | main   | WARN | JDBCExceptionReporter   | Database 'target/testdb' not created, connection made to existing database instead. 
Hibernate: insert into RuleTarget (ruleid, targetid, type, version, id) values (?, ?, ?, ?, ?) 
2009-10-01 10:16:38,939 | main   | WARN | JDBCExceptionReporter   | SQL Error: 20000, SQLState: 23505 
2009-10-01 10:16:38,939 | main   | ERROR | JDBCExceptionReporter   | The statement was aborted because it would have caused a duplicate key value in a unique or primary key constraint or unique index identified by 'SQL091001101631840' defined on 'RULETARGET'. 
2009-10-01 10:16:38,939 | main   | ERROR | AbstractFlushingEventListener | Could not synchronize database state with session 
org.hibernate.exception.ConstraintViolationException: could not insert: [ch.netcetera.gisab.masterdata.model.security.RuleTarget] 
+0

启动期间执行脚本时是否崩溃? – 2009-10-01 07:32:11

+0

不...但有一个警告,我忘了提及...(我把它添加到原始发布) – swalkner 2009-10-01 08:19:02

回答

2

基于SQLIntegrityConstraintViolationException它看起来好像你的delete语句没有被执行,你是否有两个delete.sql文件,或者没有在Eclipse中配置src/test/resources作为源位置?

applicationContext.getResource("delete.sql")通话将希望找到输出目录delete.sql。在一个Maven构建的src /测试的内容/资源将被复制到目标/测试类,这将仅在一个Eclipse完成构筑如果源位置被定义。

true在第一个executeSqlScript调用结束时意味着进程将继续运行,但不会在发生错误时抛出异常,因此可能是找不到资源,并且删除语句未执行。如果运行构建时将选项设置为false(和现有内容),它会失败吗?

注意您可以配置Eclipse的.classpath文件输出测试内容为目标/测试类,以避免冲突。

做到这一点的步骤是:

  1. 打开项目属性(ALT-进入
    • 选择Java构建路径
    • 选择来源标签
    • 点击允许输出源文件夹文件夹。这会向源文件夹树添加一个新条目。
    • 展开源文件夹树。在输出文件夹
    • 双击:条目。
    • 对话框会询问您是否要使用项目的默认输出文件夹或特定的输出文件夹。选择第二个选项,然后单击浏览...
    • 选择所需的文件夹,然后单击确定,然后单击完成。

您应该结束了在.classpath文件包含以下条目:

<classpathentry kind="src" output="target/test-classes" path="src/test/java"/> 
<classpathentry kind="src" output="target/test-classes" path="src/test/resources"/> 
+0

非常感谢那些信息! 我检查了 - 只有一个delete.sql文件,并且在调试时变得清楚,它确实找到了。 – swalkner 2009-10-01 08:28:26

+0

老兄!非常感谢! – TraderJoeChicago 2010-07-19 00:16:05

0

什么我我注意到有时我的单元测试输出会根据使用的测试工具所做的沙箱级别而变化。例如,Eclipse似乎将当前选择(类,包,项目)更改为在同一环境中的单个setup-test-teardown循环,而我们的CI似乎将每个单元测试循环为setup-test-teardown循环。

这意味着,如果你的test1有副作用,然后在test2使用,它可以工作在Eclipse中,但它也可能失败别处。如果是这样的话,你需要重写你的单元测试,至少部分是为了将它们彼此解耦。

+0

非常感谢您的回答... 我想过这样的事情;但如果我只运行Eclipse的特定方法,它也不能工作... – swalkner 2009-10-01 07:59:43

0

我的备注/问题:

  • 当您删除行“hibernate.hbm2ddl.auto” - 默认操作是没有
  • 你用什么基础测试类?尝试扩展类org.springframework.test.jpa.AbstractJpaTests - 它不从异常堆栈跟踪每个方法
  • 后回滚似乎表不插入您的数据库(文件)存储
  • 之前干净吗?也许maven构建干净的数据库文件。
  • 你使用在Maven的运行,而不是在eclipse(如Hibernate3中,Maven的插件)任何Maven插件?

编辑: 在我看来试验应在干净的数据库中运行,并留下数据库干净,所以执行以后的每个测试/方法应该回滚。看看my qestion和回复。我认为使用hibernate3-maven-plugin是可选的。

+0

- 我的Test类扩展了AbstractTransactionalJUnit4SpringContextTests - 数据库文件存储在本地; maven clean并没有帮助... - 最有意思的是,使用hibernate3-maven! – swalkner 2009-10-01 08:20:58

0

这是发生在我身上了几个月,我最终意识到被测代码并不相当

  1. 我的代码是容易返回如果输入错误的东西:,因为我以为确定性s是在不同的顺序
  2. 该代码迭代了一个集合,而不是一个列表。

因此,在任何给定的会话中,来自Eclipse和Maven的JVM通常会以一致的方式排序集合,但并不总是彼此相同。