Java 为什么在Hibernate中使用事务时,仅在提交期间检查HSQLDB中的数据库约束?

Java 为什么在Hibernate中使用事务时,仅在提交期间检查HSQLDB中的数据库约束?,java,spring,hibernate,hsqldb,Java,Spring,Hibernate,Hsqldb,我在HSQL中发现了一个奇怪的行为,当使用数据库事务时,似乎在SQL插入期间不检查数据库约束,而是在SQL提交期间检查数据库约束,并且在回滚事务时根本不检查数据库约束 我有一个Spring集成测试: @RunWith(SpringJUnit4ClassRunner.class) @TransactionConfiguration(defaultRollback=true, transactionManager="transactionManager") @Transactional public

我在HSQL中发现了一个奇怪的行为,当使用数据库事务时,似乎在SQL插入期间不检查数据库约束,而是在SQL提交期间检查数据库约束,并且在回滚事务时根本不检查数据库约束

我有一个Spring集成测试:

@RunWith(SpringJUnit4ClassRunner.class)
@TransactionConfiguration(defaultRollback=true, transactionManager="transactionManager")
@Transactional
public class IntegrationTest {
通过创建新实体实例并调用Hibernate的
persist
的测试

它工作正常,但是当我将
defaultRollback
更改为
false
时失败:

Caught exception while allowing TestExecutionListener [org.springframework.test.context.transaction.TransactionalTestExecutionListener@517a2b0] to process 'after' execution for test: method [public void MyIntegrationTest.test()], instance [MyIntegrationTest@546e61d5], exception [null]
org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint [null]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement
  at org.springframework.orm.hibernate4.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:161)
  at org.springframework.orm.hibernate4.HibernateTransactionManager.convertHibernateAccessException(HibernateTransactionManager.java:681)
  at org.springframework.orm.hibernate4.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:563)
  at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:757)
  at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:726)
...
Caused by: java.sql.SQLIntegrityConstraintViolationException: integrity constraint violation: NOT NULL check constraint; SYS_CT_10120 table: MYTABLE column: MYCOLUMN
这似乎是正确的,因为实际上我的代码在对实体调用
persist
之前没有在实体中设置mycolumn属性

问题:

  • 为什么在插入期间而在提交期间不检查数据库约束
  • 为什么在执行回滚时不检查数据库约束
[在@a_horse_上贴上没有名字的答案,以便能够结束这个问题]


在提交之前,我的ORM(Hibernate)没有向数据库发送查询。如果事务以回滚结束,则查询根本不会发送到数据库。确保在每次
persis()
修复问题后调用
flush()
FlushMode.ALWAYS
)。

由于HSQLDB没有延迟约束,因此在运行insert或update语句时会检查这些约束。我的猜测是,您的混淆层(也称为“ORM”)不会立即发送这些语句,而是在稍后尝试提交时发送。当然,在回滚事务时检查约束是没有意义的,因为所有可能导致约束失败的更改都已撤消,所以这无关紧要。@a_horse_,带有_no_名称,这是可能的,因为当我启用查询日志记录并使用
defaultRollback=false
运行测试时,不会记录任何查询,当我用
defaultRollback=false
运行它时,查询被记录下来了。@a_horse_,带有_no_name是的,我想你是对的。在MyLovely的Hibernate特性中,插入和更新直到提交或在非缓存实体上选择后才会发送。非常感谢你!使用ORM时,查询仅在执行提交时刷新到数据库(这是可配置的)。当没有发出任何查询时,就没有要测试的内容。执行回滚时,没有刷新任何内容,也没有要测试的内容。