Hibernate JPA Annotations 1到0..1的关系

时间:2011-10-27 09:22:14

标签: java hibernate jpa

我正在尝试设置1to0..1(零或一)关系,但遇到了问题。

现在我的假设是使用@OneToMany,而不是@OneToOne。

基本上我希望我的“子”表将外键保存到“父”(我非常松散地使用子和父)。我永远不需要加载“儿童”独立

这是我想要实现的基本表结构

ITEM {
  ID
  RELATED_ITEM_ID
}

INVOICE {
  ID
}
CATALOGUE {
  ID
}

作为Java类重新命名,如下所示

class Item {
...
}

class Invoice {
  @OneToMany(fetch=FetchType.EAGER, orphanRemoval = true, cascade = { javax.persistence.CascadeType.ALL })
  @Fetch(FetchMode.JOIN)
  @JoinColumn(name="RELATED_ITEM_ID", nullable=false)
  Set<Item> items;
}

class Catalogue {
  @OneToMany(fetch=FetchType.EAGER, orphanRemoval = true, cascade = { javax.persistence.CascadeType.ALL })
  @Fetch(FetchMode.JOIN)
  @JoinColumn(name="RELATED_ITEM_ID", nullable=false)
  Set<Item> items;
}

上面的代码,如果我只在Hibernate中注册了Invoice或Catalog,将按照我的意愿创建表,并且工作完美。但是,只要我同时注册了Invoice和Catalog,hibernate就会抛出错误

org.hibernate.MappingException: Duplicate property mapping of _itemsBackref found in package.name.Item

2 个答案:

答案 0 :(得分:0)

我认为用Hibernate映射这个模式是不可能的(至少,只要CustomerRecepient不扩展同一个实体)。

使用以下架构会更容易:

ADDRESSES {
  ID
}

CUSTOMER {
  ID
  ADDRESS_ID
}
RECIPIENT {
  ID
  ADDRESS_ID
}

class Customer {
  @OneToOne(fetch=FetchType.EAGER, orphanRemoval = true, cascade = { javax.persistence.CascadeType.ALL })
  @Fetch(FetchMode.JOIN)
  @JoinColumn(name="ADDRESS_ID")
  Address address;
}

class Recipient {
  @OneToOne(fetch=FetchType.EAGER, orphanRemoval = true, cascade = { javax.persistence.CascadeType.ALL })
  @Fetch(FetchMode.JOIN)
  @JoinColumn(name="ADDRESS_ID")
  Address address;
}

答案 1 :(得分:0)

我最后还是为了让我的工作得到满足而最终作弊。理想情况下,我不希望这样的层次结构,但我需要让它工作,我觉得这是一个解决hibernate的妥协。

ITEM {
  ID
  RELATED_ITEM_ID
  DTYPE
}

INVOICE {
  ID
}

CATALOGUE {
  ID
}

作为Java类重新命名,如下所示

@Entity
@Table(name="RECIPIENTS")
abstract class Item {
  ...
}

@Entity
  public class InvoiceItem extends Item {
}

@Entity
  public class CatalogueItem extends Item {
}


class Invoice {
  @OneToMany(fetch=FetchType.EAGER, orphanRemoval = true, cascade = { javax.persistence.CascadeType.ALL })
  @Fetch(FetchMode.JOIN)
  @JoinColumn(name="RELATED_ITEM_ID", nullable=false)
  Set<InvoiceItem> items;
}

class Catalogue {
  @OneToMany(fetch=FetchType.EAGER, orphanRemoval = true, cascade = { javax.persistence.CascadeType.ALL })
  @Fetch(FetchMode.JOIN)
  @JoinColumn(name="RELATED_ITEM_ID", nullable=false)
  Set<CatalogueItem> items;
}