为什么在这个Hibernate映射中使用@ManyToOne而不是@OneToOne?

时间:2014-12-29 11:37:48

标签: java entity-framework hibernate orm hibernate-mapping

我在Hibernate开发方面绝对是新手,我遇到了以下问题。

我有2个映射2个DB表的实体类:

1)第一个实体类(主要类)命名为 KM_ProjectInfo ,并映射名为 KM_PROJECT 的数据库表。

2)第二个实体类名为 KM_ProjectInfoStatus ,并映射名为 KM_PROJECT_INFO_STATUS 的数据库表。

因此,第二个表示第一个的特定字段(由KM_ProjectInfo类的实例表示的行的状态)。事实上我有这样的事情:

1) KM_ProjectInfo 类:

@Entity
@Table(name = "KM_PROJECT")
public class KM_ProjectInfo implements Serializable {

    @Id
    @GeneratedValue
    private Long idProjectInfo;

    @Column(name = "name")
    private String name;

    @Column(name = "technology")
    private String technology;

    @ManyToOne
    @JoinColumn(name = "idCountry")
    private KMCountry country;

    @Column(name = "power")
    private long power;

    @Column(name = "cod")
    private String cod;

    @ManyToOne
    @JoinColumn(name = "idProjectInfoStatus")
    private KM_ProjectInfoStatus status;

    // GETTERS & SETTERS

}

2) KM_ProjectInfoStatus

@Entity
@Table(name = "KM_PROJECT_INFO_STATUS")
public class KM_ProjectInfoStatus implements Serializable {

    @Id
    @GeneratedValue
    private Long idProjectInfoStatus;

    @Column(name = "foldertech")
    private Long foldertech;

    @Column(name = "folderproject")
    private Long folderproject;

    // GETTERS & SETTERS

}

因此,正如您在前面的代码段中所看到的, KM_ProjectInfoStatuss KM_ProjectInfo 的字段,因为我希望它包含此表的主键作为外来键。

在我的应用程序的逻辑中,我希望在 KM_PROJECT 表的一行(因此在 KM_ProjectInfo 实体类的一个实例中)与一行相关联 KM_PROJECT_INFO_STATUS KM_ProjectInfoStatus 实体类的一个实例),因为它代表 KM_PROJECT 行的特定状态。

在我的代码中,我有:

@ManyToOne
@JoinColumn(name = "idProjectInfoStatus")
private KM_ProjectInfoStatus status;

但我认为这是错误的,因为在我的第一个表的一行,它与第二个表的特定单行相关联。但也许我错过了Hibernate的工作方式。

你能帮我理解我错过的东西吗?它有什么用?为什么我 @ManyToOne 而非 @OneToOne

TNX

2 个答案:

答案 0 :(得分:2)

这完全取决于你想要如何建模。在数据库结构方面,OneToOneManyToOne以相同的方式实现:

  • 一个或多个JoinColumns,它使外键指向另一个表的主键。

因此,这两个解决方案都正确映射到您的数据库,但这取决于您是希望允许多个KM_ProjectInfo指向同一个KM_ProjectInfoStatus,还是只允许一个KM_ProjectInfo

请注意,即使您要声明OneToOne,如果您没有正确操作Hibernate,仍然可能会有多个KM_ProjectInfoStatus指向同一个OneToOne

在这里你没有声明反向关系,但如果你这样做了,声明必须是不同的:

  • 如果是KM_ProjectInfo,您将拥有OneToMany成员
  • 如果是ManyToOne(与Collection<KM_ProjectInfo>相反),您将拥有{{1}}成员

答案 1 :(得分:0)

根据描述,您似乎希望拥有一对一的关系。也就是说,项目实体应该拥有自己的状态,而不是任何其他项目共享。您可以通过使用@OneToOne实现此目的。

@Entity
@Table(name = "KM_PROJECT")
public class KM_ProjectInfo implements Serializable {

    @Id
    @GeneratedValue
    private Long idProjectInfo;

    @OneToOne
    @JoinColumn(name = "idProjectInfoStatus")
    private KM_ProjectInfoStatus status;
}

@Entity
@Table(name = "KM_PROJECT_INFO_STATUS")
public class KM_ProjectInfoStatus implements Serializable {

    @Id
    @GeneratedValue
    private Long idProjectInfoStatus;

   @OneToOne(mappedBy="idProjectInfoStatus")
   private KM_ProjectInfo project;
}

这样您就可以拥有KM_PROJECT的特定状态。

回到@ManyToOne,如果你想与多个项目共享相同的状态,你会想要这个,但这不是你想要的。我试图在这里以简单的方式解释映射One-to-One mapping