【问题标题】:@ManyToOne and @OneToOne on the same entity@ManyToOne 和 @OneToOne 在同一个实体上
【发布时间】:2023-03-28 22:10:01
【问题描述】:

假设我们有这两个实体:

@Entity
class Address{
   @Id
   @GeneratedValue(strategy = GenerationType.IDENTITY)
   private Long bookId;

   @ManyToOne
   @OneToOne
   private User user;

   ...
}

@Entity
class User{
   @Id
   @GeneratedValue(strategy = GenerationType.IDENTITY)
   private Long userId;

   @OneToMany(mappedBy = "user", cascade = CascadeType.ALL)
   private List<Address> addresses;

   @OneToOne(mappedBy = "user", cascade = CascadeType.ALL)
   private Address principalAddress;

   ...
}

如您所见,我在 Address 类(@ManyToOne 和 @OneToOne)内的 User 实体顶部有两个注释。关键是,我知道这是错误的,但我不知道如何正确映射它。有设计问题吗?逻辑是用户有一个地址列表和一个且唯一的主体地址。我怎样才能正确映射它?有什么想法吗?

【问题讨论】:

  • 我想您应该考虑向用户表添加额外的外键,该表将引用地址表的主要地址。想象以下情况:您有两个用户 - u1、u2。两者都有地址 - adr1,adr2。 adr1 是 u1 的主体,而 adr2 是 u2 的主体。

标签: java spring hibernate jpa


【解决方案1】:

在这种情况下,您可以做的是设置标志“isPrincipalAddress”。

@Entity
class Address{
   @Id
   @GeneratedValue(strategy = GenerationType.IDENTITY)
   private Long bookId;

   private Boolean isPrincipalAddress;

   @ManyToOne
   private User user;

   ...
}

@Entity
class User{
   @Id
   @GeneratedValue(strategy = GenerationType.IDENTITY)
   private Long userId;

   @OneToMany(mappedBy = "user", cascade = CascadeType.ALL)
   private List<Address> addresses;

   ...
}

【讨论】:

    【解决方案2】:

    只需在Address 类中创建一个boolean isPrimaryAddress 字段

    【讨论】:

      【解决方案3】:

      在库类中添加标志不是一个好的解决方案。这是一个非常糟糕的提议。 所有用户都依赖一个库类地址。并且它们都具有(或可能具有)不同的“主地址”。因此,您需要在 User 类中创建关系结构(表)或字段。 我认为您的初始变体更好,只需在依赖用户字段的@OneToOne 选项“mappedBy”中使用(例如,“primaryAddress” - 对地址(bookId)的引用)。

      补充:如果你使用注解@OneToOne(以及其他),则不需要有两个方向的关系,你可以在User类中有@OneToOne但在Address类中没有它,通常它没有任何感觉。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-03-27
        • 1970-01-01
        • 1970-01-01
        • 2020-04-10
        • 1970-01-01
        相关资源
        最近更新 更多