【问题标题】:Hibernate mapping: OneToMany and OneToOne on child object property休眠映射:子对象属性上的 OneToMany 和 OneToOne
【发布时间】:2011-10-04 12:02:17
【问题描述】:

这是父类 Enterprise。它有雇主,其中一位是企业总裁。

@Entity
class Enterprise
{
   // fields

   @OneToMany
   public List<Employee> getEmployers()
   // implementation    

   @OneToOne
   public Employee getPresident()
   // implementation

}

这是子 Employee 类。它只有关于他工作的企业的信息。但问题是我应该使用什么关联?

@Entity
class Employee 
{
   // fields

   // what association should I use?
   public Enterprise getEnterprise()
   // implementation
}

【问题讨论】:

  • @Nathan - 因为在企业中可以有很多员工,而不仅仅是一个。

标签: java hibernate hibernate-mapping


【解决方案1】:

鉴于您已经定义了Enterprise->Employers@OneToMany 的关联,这意味着Employer 只属于一个Enterprise,您应该使用@ManyToOne,这意味着每个Employer 属于最大值。 1 个Enterprise,但一个Enterprise 可以引用多个Employers

您可以使用注释中的mapped-by 属性仅在一侧定义关联细节(连接列等):

@Entity
class Enterprise
{
   @OneToMany(mapped-by="enterprise")
   public List<Employee> getEmployers()
   // implementation    

   @OneToOne
   public Employee getPresident()
   // implementation
}

@Entity
class Employee 
{
   @ManyToOne
   @JoinTable ( name="Enterprise", joinColumns={ @JoinColumn(name="ENT_ID", referencedColumnName="ENT_ID") }
   public Enterprise getEnterprise()
   // implementation
}

如果Employer 可能是他受雇的另一个Enterprise 的总裁(似乎不太可能,除非一个人可以在没有受雇于企业的情况下担任总裁),并且如果您需要访问Enterprise 其中EmployerEmployer 实体的总裁,您需要添加另一个关联,最好使用@OneToOne(您会遇到问题,因为@OneToOne 关系要求两个实体具有相同的@Id班级)。在这种情况下,出于实际原因,我会将Employer 上的getPresidedEnterprise() 方法注释为@ManyToOne

【讨论】:

  • 但是总裁领域呢?我应该使用 OneToOne 关联,但 employee.enterprise 用 ManyToOne 注释...
  • @Artyom - 他们没有连接。不会有问题的。总统是不同的专栏。
  • 只有在雇主可能是他所受雇的不同企业的总裁的情况下才会出现问题。只有这样,如果您需要从 Employer 实体访问 Employer 是其总裁的 Enterprise,您将需要添加另一个关联,最好使用 @OneToOne(您会遇到问题,因为 @OneToOne 关系要求两个实体具有相同的@Id 类)。
  • 确实,getEmployers 是双向的,因为您可以从 Enterprise 获取 Employers,从 Employers(普通雇主)获取 Enterprise。如果一个企业的总裁必须在他主持的同一家企业任职,那么你可以说getPresident也是双向的。如果不是,它将是单向的,因为您无法从 Employer 实体中让 Enterprise 由总裁主持。
  • 正如我在我的 cmets 和我之前在回答中的编辑中所说的那样,您可以使用@OneToOne,以防@Id 的类@ 987654346@和Enterprise是一样的。
【解决方案2】:

使用@ManyToOne 注释。它是一对多关系的反面。它说一个员工可以拥有一个企业,但一个企业可以拥有许多员工。

【讨论】:

  • 但是一个企业有很多雇主,它是oneToMany协会。一名员工是企业总裁 - 这是 oneToOne 协会
  • @Artyom - 是的,使用@ManyToOne。我之前没有正确阅读您的问题。
【解决方案3】:

您应该在 Employee 类上有两个属性。员工表应该有一个企业的引用,广告企业应该有一个员工总裁的引用。

(您也可以根据 isPresident 标志列对 Employee 进行子类化,但我没有这方面的经验)

@Entity    
class Enterprise    
{    
    // fields

    @OneToMany(mappedBy="enterprise")    
    public List<Employee> getEmployees(){} 

    @OneToOne
    @JoinColumn(name="PRESIDENT_ID")
    public Employee getPresident(){}
}    

@Entity 
class Employee  
{ 
    // fields

    @ManyToOne
    @JoinColumn(name="ENTERPRISE_ID")
    public Enterprise getEnterprise(){}

    @OneToOne(mappedBy="President")
    public Enterprise getMyEnterprise(){}
} 

【讨论】:

  • 但是字段 getMyEnterprise 对于非总统雇主的含义是什么?它会返回空值吗?
  • @OneToOne 映射并非在所有情况下都有效,至少在 Hibernate 中是这样,因为 EmployerEnterprise@Id 映射应该属于同一类型。
  • 应该返回 null :)。或者你可以让关系单向。另外,请考虑一下 Xavi 关于 id 类型的说明。
猜你喜欢
  • 2014-12-27
  • 2014-03-12
  • 2011-05-21
  • 1970-01-01
  • 2013-01-02
  • 2017-11-13
  • 2014-04-27
  • 1970-01-01
相关资源
最近更新 更多