为啥在这个 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_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
【问题讨论】:
【参考方案1】:这完全取决于您想如何建模。在Database结构方面,OneToOne
和ManyToOne
实现方式相同:
JoinColumns
使外键指向另一个表的主键。
所以这两种解决方案都正确映射到您的数据库,但这取决于您是要允许多个KM_ProjectInfo
指向同一个KM_ProjectInfoStatus
,还是只允许一个。
请注意,即使您声明了 OneToOne,如果您没有正确操作 Hibernate,您仍然可能会得到多个 KM_ProjectInfo
指向同一个 KM_ProjectInfoStatus
。
这里你没有声明反向关系,但如果你声明了,那么声明就必须不同:
如果是OneToOne
,您将拥有KM_ProjectInfo
成员
如果是OneToMany
(ManyToOne
的反面),您将拥有一个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 多对多映射时遇到此错误?