【问题标题】:Unique constraint check fails too late with Spring Boot Starter Data JPASpring Boot Starter Data JPA 的唯一约束检查​​为时已晚
【发布时间】:2018-06-11 15:06:22
【问题描述】:

我对独特的约束功能感到非常惊讶。我正在开发一个带有 H2 数据库的 Spring Boot 应用程序以进行单元测试。

我的一个实体有一个独特的约束。 在 User 类的标题下方。

@Entity
@Table(name = "user", uniqueConstraints = { @UniqueConstraint(columnNames = { "identifier" }) })
@SequenceGenerator(name = "user_pkey", sequenceName = "user_id_seq")

我编写了一个小单元测试来检查唯一性约束。

测试前功能

@Before
public void before() {
        User user1 = new User();
        user1.setBlackListed(false);
        user1.setIdentifier("test@tby.com");
        user1.setRefreshToken("azerty");          
        this.userDao.save(user1);
}

我的测试

@Test(expected = DataIntegrityViolationException.class)
public void user_identifierUnicityTest() {
    User user4 = new User();
    user4.setBlackListed(false);
    user4.setIdentifier("test@tby.com");
    user4.setRefreshToken("azerty4");
    User response = this.userDao.save(user4);
    this.userDao.findByIdentifier("test@tby.com");
}

我很惊讶,我认为在保存请求期间会抛出异常。或者在查找请求过程中抛出异常。

在选择请求期间检查约束完整性,而不是在插入期间检查。结果看不懂。

这是唯一约束的正常行为吗?

感谢您的回答:)

【问题讨论】:

    标签: hibernate spring-boot spring-data h2 unique-constraint


    【解决方案1】:

    唯一约束由数据库维护。如果 insert 违反约束,这将导致失败。 Hibernate 不会将实体写入数据库,直到它必须这样做,当这种情况发生时,它被称为flushing。当您发出搜索查询时,Hibernate 的默认行为是在查询之前刷新,以便在查询时对持久上下文所做的任何更改都是可见的。

    因此,您的更改将作为执行查询的副作用插入到数据库中。这将导致此时失败,可能会被认为比预期的要晚...

    【讨论】:

    • 不客气!使用 hibernate 编码愉快,这是一个了不起的框架!
    • Soory,我知道这个问题很老,但我遇到了完全相同的问题,我想知道如果数据库中已经存在数据,那么防止休眠持久化数据的解决方案是什么.谁应该进行手动检查,或者自定义验证器?
    • @AlainDuguine 这取决于很多事情...创建一个新问题,包含您的用例和代码的更多详细信息!
    • 谢谢!我通过在我的服务层中创建一个 repository.flush() 找到了答案。
    猜你喜欢
    • 2018-08-06
    • 2017-08-06
    • 2017-11-29
    • 2021-01-18
    • 2021-02-09
    • 2021-11-11
    • 1970-01-01
    • 2018-07-25
    • 1970-01-01
    相关资源
    最近更新 更多