Hibernate不会在重复的主键上引发异常

时间:2018-10-04 16:08:43

标签: java hibernate jpa spring-data-jpa

我正在使用Spring Data JPA。鉴于此设置:

@Entity
public class Role
{
    @Id
    @Column(nullable = false, unique = true)
    private String name;

    @Column
    private String info;
}

@Repository
public interface RoleRepository extends CrudRepository<Role, String>
{
}

我可以简单地两次插入具有相同主键(Role)的name。它只是更新数据库中的条目。我希望它引发异常。尝试在数据库级别插入具有相同主键的两个条目会产生所需的“重复键”错误。


示例:

角色表为空

MariaDB [logz]> select * from role;
Empty set (0.00 sec)

第一次保存

roleRepository.save(new Role("name1", "info0"));

休眠先检查,然后保存

Hibernate: select role0_.name as name1_3_0_, role0_.info as info2_3_0_ from role role0_ where role0_.name=?
Hibernate: insert into role (info, name) values (?, ?)

角色表已填充

MariaDB [logz]> select * from role;
+-------+-------+
| name  | info  |
+-------+-------+
| name1 | info0 |
+-------+-------+
1 row in set (0.00 sec)

第二次保存

roleRepository.save(new Role("name1", "info1"));

休眠检查和更新-不过我想在这里例外!

Hibernate: select role0_.name as name1_3_0_, role0_.info as info2_3_0_ from role role0_ where role0_.name=?
Hibernate: update role set info=? where name=?

角色表只需更新:(

MariaDB [logz]> select * from role;
+-------+-------+
| name  | info  |
+-------+-------+
| name1 | info1 |
+-------+-------+
1 row in set (0.00 sec)

1 个答案:

答案 0 :(得分:1)

如果您查看save方法的实现,则如下所示:

@Transactional
public <S extends T> S save(S entity) {

    if (entityInformation.isNew(entity)) {
        em.persist(entity);
        return entity;
    } else {
        return em.merge(entity);
    }
}

,因此您可以注意到,如果数据库中已经存在具有特定ID的对象,它将进行更新。如果您进一步感兴趣,可以找到来源here