JPA/Hibernate:如何为 @ManyToOne 插入默认值,其中值表示空条目

Posted

技术标签:

【中文标题】JPA/Hibernate:如何为 @ManyToOne 插入默认值,其中值表示空条目【英文标题】:JPA/Hibernate: How insert a default value for a @ManyToOne where the value represents a null entry 【发布时间】:2015-07-26 18:12:03 【问题描述】:

我对 JPA/Hibernate 还很陌生。我的问题涉及几个现有的数据库表,如下所示:

CREATE TABLE `person` (
  `personId` int(11) NOT NULL,
  `name` varchar(255) CHARACTER SET latin1 NOT NULL DEFAULT '',
  `addressId` int(11) NOT NULL DEFAULT 0,
  PRIMARY KEY (`personId`)
);

CREATE TABLE `address` (
  `addressId` bigint(20) NOT NULL,
  `address` varchar(255) CHARACTER SET latin1 NOT NULL DEFAULT '',
  PRIMARY KEY (`addressId`)
);

实体是这样实现的:

@Entity
public class Person 
  @Id
  private Integer personId;

  private String name;

  @ManyToOne
  @JoinColumn(name="addressId")
  private Address address;


@Entity
public class Address 
  @Id
  private Integer addressId;

  private String address;

多个人可以住在同一个地址。一个人也可以没有地址。 person 表中的 addressId 本质上是一个可选字段。 地址数据库中没有addressId = 0。值 0 基本上就像它是一个空参数一样使用。

我的问题是当我尝试将一个人持久保存到 addressId = 0 的表中时发生这种情况。

如果我将 Person 中的 Address 对象设置为 null,我会收到以下错误:

"addressId 不能为空"

如果我将地址对象的 addressId 设置为 0,我会得到另一个瞬态对象错误,因为地址表中没有 addressId = 0 的条目。

我尝试使用@PrePersist 尝试在对象被持久化之前设置默认值,但是,我得到了上面相同的两个错误。当我在 @ManyToOne 中添加 optional=true 时也是如此。

我不认为插入一个 id=0 的虚拟地址是个好主意。

如果可以使用 @ManyToOne 注释并且仍然具有默认值 0,其中 0 不是数据库中的实际条目,有什么想法吗?

【问题讨论】:

【参考方案1】:

如果您真的必须保留这些 0 而不是 null,也许您可​​以尝试使用 CustomType。见这里:Hibernate Many-To-One Foreign Key Default 0

【讨论】:

感谢您的链接。创建自定义 userType 后,我收到错误消息:“javax.persistence.EntityNotFoundException:无法找到 ID 为 0 的地址”。这似乎类似于没有 ID 为 0 的条目的问题(因为它是一个虚拟行)。【参考方案2】:

我遇到了同样的问题,我使用 @NotFound 注释和操作 NotFoundAction.IGNORE 解决了它,如果关联实体不存在,它将返回 null。

例子:

import org.hibernate.annotations.NotFound;
import org.hibernate.annotations.NotFoundAction;

@ManyToOne
@NotFound( action = NotFoundAction.IGNORE )
private Module module;

【讨论】:

以上是关于JPA/Hibernate:如何为 @ManyToOne 插入默认值,其中值表示空条目的主要内容,如果未能解决你的问题,请参考以下文章

如何用 JPA/Hibernate 映射 XMLType

如何为单元测试覆盖 insertable=false

JPA / Hibernate可以与其他持久性框架(如jOOQ)结合使用

JPA/Hibernate - 删除子删除父(从同一个表)

JPA Hibernate jpa spring data jpa

Spring boot之 JPA/Hibernate/Spring Data