代码之家  ›  专栏  ›  技术社区  ›  pirho

测试Hibernate@Check约束时无法生成约束冲突异常

  •  1
  • pirho  · 技术社区  · 7 年前

    @Check 注释但是 . 目前只使用H2数据库的默认Spring引导配置。

    我错过了什么?应该有某种 save(..) ?

    当运行测试时,我看到正确创建的表。如果我从日志中复制创建行并使用它创建一个表到我的'real'Postgres数据库中,我可以测试不同的插入,并看到这一行在约束条件下都是好的。

    @Getter @Setter
    @Entity @Check(constraints = "a IS NOT NULL OR b IS NOT NULL")
    public class Constrained {
    
        @Id @GeneratedValue
        private Long id;
    
        private String a, b;
    }
    

    @DataJpaTest
    @RunWith(SpringRunner.class)
    public class HibernateCheckTest {
    
        @Resource // this repo is just some boiler plate code but attached at 
                  // the bottom of question
        private ConstrainedRepository repo;
    
        @Test @Transactional // also tried without @Transactional
        public void test() {
            Constrained c = new Constrained();
            repo.save(c); // Am I wrong to expect some constraint exception here?
        }
    }
    

    创建表约束(id bigint not null,a varchar(255),b varchar(255)、主键(id)、检查(a不为空或b不为空)

    存储库 (在回购中看不到多少,只是为了展示一下):

    public interface ConstrainedRepository
                extends CrudRepository<Constrained, Long> {
    }
    

    如果我使用 EntityManager 在我的测试课上:

    @PersistenceContext
    private EntityManager em;
    

    em.persist(c);
    em.flush();
    

    repo.save(c) 我会得到例外。

    以及

    从原始测试中学习日志 更仔细的节目:

    org.springframework.test.context.transaction.TransactionContext:139-测试的回滚事务:
    ...

    2 回复  |  直到 7 年前
        1
  •  5
  •   codemonkey    7 年前

    在里面 ConstrainedRepository 延伸 JpaRepository CrudRepository

    repo.saveAndFlush(c);
    

    而不是:

    repo.save(c);
    

    没有明显的同花顺, Hibernate will defer 将语句发送到数据库,直到提交事务或执行查询为止。

    然而,从春天 DataJpaTest 文档:

    每次测试的结果。

    所以,在这种情况下,没有提交。事务被回滚,语句永远不会刷新到数据库,因此永远不会引发异常。

        2
  •  4
  •   pirho    7 年前

    多亏了 answer 从…起

    @org.springframework.transaction.annotation.Transactional(propagation = 
                                                         Propagation.NOT_SUPPORTED)
    

    去我的测试班。