为什么 HSQLDB 中的数据库约束在 Hibernate 中使用事务时仅在提交期间检查?
Why database contraints in HSQLDB are only checked during a commit when using transactions in Hibernate?
我在 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_with_no_name的回答,只是为了能够关闭这个问题]。
我的 ORM (Hibernate) 在提交之前不会向数据库发送查询。如果事务以回滚结束,则查询根本不会发送到数据库。确保在每个 persis()
解决问题后调用 flush()
(FlushMode.ALWAYS
)。
我在 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_with_no_name的回答,只是为了能够关闭这个问题]。
我的 ORM (Hibernate) 在提交之前不会向数据库发送查询。如果事务以回滚结束,则查询根本不会发送到数据库。确保在每个 persis()
解决问题后调用 flush()
(FlushMode.ALWAYS
)。