Hibernate如何防止使用生成的id重复输入
有没有办法防止在具有自动生成主键的实体上使用休眠功能重复输入数据?
更具体地说,我在数据库中有一个持久对象,并且有一个临时对象(尚未插入数据库),这两个对象在 equals 和 hashcode 方法方面是相同的。但是,由于这些对象的实体类的 id 是用生成值注释进行注释的,因此 hibernate 仍然会在数据库中为瞬态对象创建一个新实例。因此,数据库具有具有不同主键的重复条目(相对于 equals 和 hashcode 方法)。
是的,我知道如果我不自动生成 PK,或者如果我使用 UUID,那么我就会实现我的目标。但我只是想问为什么 equals 和 hashcode 方法不适用于具有自动生成主键的实体?或者我做错了什么?
Is there a way to prevent duplicate data entry with hibernate on entities that have auto generated primary key?
To be more specific, i have a persistent object in the database and have a transient object (not inserted to the database yet) and those two objects are same with respect to equals and hashcode methods. But, since the id of the entity class of those objects is annotated with generated value annotation, hibernate still creates a new instance for the transient object in the database. As a result the database has duplicate entries (with respect to equals and hashcode methods) with different primary keys.
Yes, I know if I make the PK not auto generated, of if I use UUID, then i would achieve my goal. But I just wanna ask why equals and hashcode methods do not work for the entities with auto generated primary key? Or am i doing something wrong?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
Hibernate 在这里不尊重
equals()
/hashCode()
,因为没有有效的方法来做到这一点。Hibernate 如何检查数据库中是否已存在具有相同标识(就
equals()
而言)的对象?由于 equals() 可以包含任意条件,Hibernate 无法将其转换为 SQL 查询,因此检查它的唯一方法是将所有对象加载到内存中并调用 equals()< /code> 将它们与您要保存的对象进行比较。因此 Hibernate 使用主键来定义对象的身份。
目前还不清楚你要实现什么目标。如果您希望 Hibernate 使用传入的对象状态更新数据库中的对象,则需要使用
merge()
。另请参阅:
Hibernate doesn't respect
equals()
/hashCode()
here, because there are no efficient ways to do so.How can Hibernate check that object with the same identity (in terms of
equals()
) already exists in the database? Sinceequals()
can contain arbitrary conditions, Hibernate can't turn it into SQL query, so that the only way to check it is to load all objects into memory and callequals()
on them to compare them with the object you are going to save.Therefore Hibernate uses primary keys to define objects' identity.
It's not clear what are you going to achieve. If you want Hibernate to update objects in the database with the state of objects you pass in, you need to use
merge()
.See also:
数据库级别的主键应使用与在应用程序级别测试相等性时使用的相同字段。如果您确实需要代理键(也许是出于性能原因?),请在这些字段上强制执行“唯一索引”,并让 hibernate 抛出异常。
You primary key at the database level should use the same fields you use to test for equality at the application level. If you really need a surrogate key (for performance reasons, perhaps?) enforce a "unique index" over those fields and let hibernate throw and exception.
在数据库级别强制执行约束。如果没有这个,就很难(不可能?)避免重复,特别是如果您的应用程序是集群的。
Enforce the constraint at DB level. Without this it is hard(impossible?) to avoid duplicates especially if your app is clustered.