我正在使用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)
答案 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。