Hibernate:强制执行唯一数据成员
我在使用 Hibernate 并在插入时强制执行唯一数据成员时遇到问题。
以下是我删节的实体对象:
工作流程:
@Entity
public class Workflow {
private long wfId;
private Set<Service> services;
/** Getter/Setter for wfId */
...
@OneToMany(cascade = CascadeType.ALL)
@JoinTable(name = "workflow_services",
joinColumns = @JoinColumn(name = "workflow_id"),
inverseJoinColumns = @JoinColumn(name = "service_id"))
public Set<Service> getServices() {
return services;
}
服务:
@Entity
public class Service {
private long serviceId;
private String serviceName;
/** Getter/Setter for serviceId */
...
@Column(unique=true,nullable=false)
public String getServiceName() {
return serviceName;
}
@OneToMany(cascade = CascadeType.ALL)
@JoinTable(name = "service_operations",
joinColumns = { @JoinColumn(name = "serviceId") },
inverseJoinColumns = { @JoinColumn(name = "operationId") })
public Set<Operation> getOperations() {
return operations;
}
操作:
@Entity
public class Operation {
private long operationId;
private String operationName;
/** Getter/Setter for operationId */
@Column(unique=true,nullable=false)
public String getOperationName() {
return operationName;
}
我的问题:
虽然我在每个对象中声明了哪些内容应该是唯一的,但它并没有被强制执行。
在我的工作流对象中,我维护一组服务。每个服务维护一个操作列表。当工作流保存到数据库时,我需要它检查它当前使用的服务和操作是否已在数据库中,如果是,则将其自身与这些行相关联。
目前,我的服务和运营表中出现重复。
我尝试过使用注释: @Table( uniqueConstraints)
但运气为零。
任何帮助将不胜感激
I am having an issue working with Hibernate and enforcing unique data members when inserting.
Here are my abridged Entity objects:
Workflow:
@Entity
public class Workflow {
private long wfId;
private Set<Service> services;
/** Getter/Setter for wfId */
...
@OneToMany(cascade = CascadeType.ALL)
@JoinTable(name = "workflow_services",
joinColumns = @JoinColumn(name = "workflow_id"),
inverseJoinColumns = @JoinColumn(name = "service_id"))
public Set<Service> getServices() {
return services;
}
Service:
@Entity
public class Service {
private long serviceId;
private String serviceName;
/** Getter/Setter for serviceId */
...
@Column(unique=true,nullable=false)
public String getServiceName() {
return serviceName;
}
@OneToMany(cascade = CascadeType.ALL)
@JoinTable(name = "service_operations",
joinColumns = { @JoinColumn(name = "serviceId") },
inverseJoinColumns = { @JoinColumn(name = "operationId") })
public Set<Operation> getOperations() {
return operations;
}
Operation:
@Entity
public class Operation {
private long operationId;
private String operationName;
/** Getter/Setter for operationId */
@Column(unique=true,nullable=false)
public String getOperationName() {
return operationName;
}
My issue:
Although I have stated in each object what is SUPPOSED to be unique, it is not being enforced.
Inside my Workflow object, I maintain a Set of Services. Each Service maintains a list of Operations. When a Workflow is saved to the database, I need it to check if the Services and Operations it currently uses are already in the database, if so, associate itself with those rows.
Currently I am getting repeats within my Services and Operations tables.
I have tried using the annotation:
@Table( uniqueConstraints)
but have had zero luck with it.
Any help would be greatly appreciated
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
unique 或 uniqueConstraints 属性不用于强制数据库中的唯一性,但如果您从 hibernate 生成它,则会创建正确的 DDL(也用于文档,但这是有争议的)。
如果您在 hibernate 中声明某些内容是唯一的,那么您也应该通过添加约束在数据库中声明它。
将这一点发挥到极致,您可以创建一个映射,其中 PK 在数据库中不是唯一的,并且当 hibernate 尝试通过调用 Session.load 加载一项时会抛出异常,并突然发现有 2 个项。
The unique or uniqueConstraints attributes are not used to enforce the uniqueness in the DB, but create the correct DDL if you generate it from hibernate (and for documentation too, but that's arguable).
If you declare something as unique in hibernate, you should declare it too in the DB, by adding a constraint.
Taking this to the extreme, you can create a mapping in which the PK is not unique in the DB, and hibernate will throw an exception when it tries to load one item by calling Session.load, and sudently finding that there are 2 items.
我认为您在将重复对象添加到 Set 时要求 Hibernate 检测它们,是吗?换句话说,当您将一个对象放入 Set 中时,您希望 Hibernate 去查找该对象的持久版本并使用它。然而,这不是 Hibernate 的工作方式。如果你想让它“重用”一个对象,你必须自己查找它然后使用它。 Hibernate 不这样做。
我建议在类似 DAO 的对象上使用一个辅助方法,该方法获取父对象和子对象,然后为您进行查找和设置。
I think you're asking Hibernate to detect duplicate objects when you add them to the Set, yes? In other words, when you put an object in the Set, you want Hibernate to go look for a persistent version of that object and use it. However, this is not the way Hibernate works. If you want it to "reuse" an object, you have to look it up yourself and then use it. Hibernate doesn't do this.
I would suggest having a helper method on a DAO-like object that takes the parent and the child object, and then does the lookup and setting for you.