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

Posted

技术标签:

【中文标题】为啥在这个 Hibernate 映射中使用 @ManyToOne 而不是 @OneToOne?【英文标题】:Why in this Hibernate mapping it is used @ManyToOne instead @OneToOne?为什么在这个 Hibernate 映射中使用 @ManyToOne 而不是 @OneToOne? 【发布时间】:2014-12-29 11:37:47 【问题描述】:

我是 Hibernate 开发的新手,遇到以下问题。

我有 2 个实体类映射 2 个数据库表:

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


所以,正如您在前面的 sn-p 中看到的,KM_ProjectInfoStatussKM_ProjectInfo 的一个字段,因为我希望它包含该表的主键作为外键。

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

在我的代码中:

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

但我认为这是错误的,因为在我的第一个表的一行中,它与第二个表的特定单行相关联。但也许我错过了有关 Hibernate 工作原理的一些信息。

你能帮我理解我缺少什么吗?它有什么作用?为什么我使用 @ManyToOne 而不是 @OneToOne

Tnx

【问题讨论】:

【参考方案1】:

这完全取决于您想如何建模。在Database结构方面,OneToOneManyToOne实现方式相同:

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

所以这两种解决方案都正确映射到您的数据库,但这取决于您是要允许多个KM_ProjectInfo 指向同一个KM_ProjectInfoStatus,还是只允许一个。

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

这里你没有声明反向关系,但如果你声明了,那么声明就必须不同:

如果是OneToOne,您将拥有KM_ProjectInfo 成员 如果是OneToManyManyToOne 的反面),您将拥有一个Collection<KM_ProjectInfo> 成员

【讨论】:

嗯,你的意思是说使用 OneToMany 更多的 KM_ProjectInfo 实例可以与同一个 KM_ProjectInfoStatus 实例相关联吗?如果我使用 OneToOne 单行 KM_ProjectInfo 与 KM_ProjectInfoStatus 的单个特定实例相关,并且没有其他 KM_ProjectInfo 实例(表行)可能与 KM_ProjectInfoStatus 的此实例(行)相关?这就是你解释的意思吗?【参考方案2】:

从描述看来,您希望建立一对一的关系。也就是说,项目实体应该有自己的状态,不被任何其他项目共享。您可以通过使用@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。

【讨论】:

以上是关于为啥在这个 Hibernate 映射中使用 @ManyToOne 而不是 @OneToOne?的主要内容,如果未能解决你的问题,请参考以下文章

hibernate映射postgreSQL数据库中的表时,表名是大写的时候为啥hibernate不能映射实体

为啥我在尝试实现 Hibernate 多对多映射时遇到此错误?

为啥 MyEclipse 的 Hibernate 逆向工程在映射某些表时会创建多个类?

为啥人们继续使用 xml 映射文件而不是注释? [关闭]

hibernate工作原理及为啥要用

为啥 delete-orphan 需要“全部级联”才能在 JPA/Hibernate 中运行?