【问题标题】:Hibernate: enforcing unique data membersHibernate:强制执行唯一的数据成员
【发布时间】:2011-09-30 18:04:40
【问题描述】:

我在使用 Hibernate 并在插入时强制执行唯一数据成员时遇到问题。

这是我删减的 Entity 对象:

工作流程:

@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;
  }

我的问题:

虽然我在每个对象中都说明了什么是唯一的,但它并没有被强制执行。

在我的 Workflow 对象中,我维护了一组服务。每个服务维护一个操作列表。当工作流被保存到数据库时,我需要它来检查它当前使用的服务和操作是否已经在数据库中,如果是,则将其自身与这些行关联。

目前,我的服务和操作表中出现重复。

我尝试过使用注释: @Table(uniqueConstraints)

但运气为零。

任何帮助将不胜感激

【问题讨论】:

  • 您使用的是哪个数据库和方言?您是如何在数据库中创建表的? hbm2ddl?你能显示用于生成表的查询吗?我不认为 hibernate 本身会检查唯一性,但它应该在您的数据库中生成具有适当唯一性约束的表。

标签: java hibernate unique


【解决方案1】:

unique 或 uniqueConstraints 属性不用于强制数据库中的唯一性,但如果您从 hibernate 生成它,则创建正确的 DDL(也用于文档,但这是有争议的)。

如果你在 hibernate 中声明某些东西是唯一的,你也应该在 DB 中通过添加一个约束来声明它。

把这个发挥到极致,你可以创建一个映射,其中PK在DB中不是唯一的,当hibernate尝试调用Session.load加载一个item时,突然发现有2 项。

【讨论】:

    【解决方案2】:

    在我的 Workflow 对象中,我维护了一组服务。每个服务维护一个操作列表。当工作流被保存到数据库时,我需要它来检查它当前使用的服务和操作是否已经在数据库中,如果是,则将其自身与这些行关联。

    认为当您将重复对象添加到 Set 时,您是在要求 Hibernate 检测重复对象,是吗?换句话说,当您将一个对象放入 Set 中时,您希望 Hibernate 去寻找该对象的持久版本并使用它。然而,这不是 Hibernate 的工作方式。如果您希望它“重用”一个对象,您必须自己查找它然后使用它。 Hibernate 不这样做。

    我建议在类似 DAO 的对象上使用一个辅助方法,该方法接受父对象和子对象,然后为您进行查找和设置。

    【讨论】:

    • 这就是我现在正在做的事情。我现在的问题是 Hibernate 在尝试重新添加对象时抛出错误,并且我收到“重复键”错误。我正在使用'session.saveOrUpdate(workflow)',这很好,但我相信这仅适用于工作流本身,而不适用于它的子元素。即服务和操作。有什么想法吗?
    • 听起来您可能正在将分离的对象设置到工作流对象中。您需要获取子对象(通过查询、ID 等),然后在同一个会话中将它们添加到相应的集合中并保存父对象。只要您的级联设置正确,Hibernate 就应该对子对象“做正确的事”。这有意义吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-19
    • 1970-01-01
    • 2010-09-10
    • 1970-01-01
    • 1970-01-01
    • 2018-03-07
    相关资源
    最近更新 更多