0

我是 Spring JPA 和 Hibernate 的新手,我遇到了以下行为。我成功地CrudRepository在 org.mypackage.repository 中为我的 JPA 注释实体创建了 s,并在 org.mypackage.service.jpa 中成功创建了基于注释的事务服务,后者又从注入CrudRepository的 s 中调用方法。这是我的配置文件的片段(我基本上复制了 Pro Spring 3 中的示例):

<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
    <property name="entityManagerFactory" ref="emf"/>
</bean>
<tx:annotation-driven transaction-manager="transactionManager"/>
<context:annotation-config/>
<context:component-scan base-package="org.mypackage.service.jpa"/>
<jpa:repositories base-package="org.mypackage.repository"
                  entity-manager-factory-ref="emf"
                  transaction-manager-ref="transactionManager"/>

CrudRepository我省略了 emf bean,因为到目前为止,对于s 中的所有方法(包装在我的服务中的事务方法中),它与我的所有实体都工作得很好。所以看起来每次我创建一个实体时,服务都会启动一个事务并提交我的更改(如果有的话)。

现在我正在尝试测试错误条件,因此我创建了一个具有违反约束的字段的实体,例如不可为空的列中的空值,然后尝试使用我的服务中的适当(事务性)方法将其持久化并且没有抛出异常。在我@After调用findAll和繁荣的方法中,有一个例外:

org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint [null]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement
...
Caused by: org.hibernate.exception.ConstraintViolationException: could not execute statement
...
Caused by: org.h2.jdbc.JdbcSQLException: NULL not allowed for column "FKSOMEID"; SQL statement:
INSERT INTO ....

我尝试更改 Hibernate 的 JPA 参数,例如,设置hibernate.jdbc.batch_size为 1 但这似乎没有做任何事情。看起来插入在我调用之前不会被执行findAll(),而我希望从保存坏记录的事务中得到一个异常。这种行为非常违反直觉,会使调试我的应用程序变得非常困难,所以我猜我在这里搞砸了。有没有人有想法?

谢谢

乔瓦尼

4

1 回答 1

0

我想通了:我应该提到我正在从一个AbstractTransactionalJUnit4SpringContextTests带有注释的实例中测试它:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:config.xml"})

并带有注入DataSource和 JPA 服务。

我没有意识到 Spring 在测试结束时会自动回滚所有更改(我猜是在任何@After方法之后),我猜这意味着它在一个事务或类似的东西中执行所有 SQL。底线,如果我不扩展,AbstractTransactionalJUnit4SpringContextTests我会立即看到预期的异常。我现在正在使用AbstractJUnit4SpringContextTests

于 2013-07-27T19:06:24.647 回答