java 绑定到同一实体类型的Hibernate Multiple @OneToMany

mspsb9vt  于 2023-02-18  发布在  Java
关注(0)|答案(2)|浏览(138)

我还有另一个@OneToMany问题。在本例中,我尝试为一个人建模,该人拥有一个不允许向其发送邮件的排除人员列表。这是一个使用JPA的Spring Boot应用程序。
在下面的代码中,exclusions列表填充正确,但excludedBy列表填充不正确。因此,我认为这会导致删除被其他人排除的Person失败,因为excludedBy中的Exclusion没有正确Map到对象上。

@Entity
@Table(name = "person")
public class Person {

    @Id
    @GeneratedValue
    @Column(nullable = false)
    Long id;

    ...

    @OneToMany(mappedBy = "sender", cascade = { CascadeType.ALL })
    List<Exclusion> exclusions = new ArrayList<>();

    //This is not getting populated
    @JsonIgnore
    @OneToMany(mappedBy = "receiver", cascade = { CascadeType.ALL })
    List<Exclusion> excludedBy = new ArrayList<>();

    ...
}
@Entity
@Table(name = "exclusions")
public class Exclusion {
    @Id
    @GeneratedValue
    @Column(nullable = false)
    Long id;

    @ManyToOne
    @JsonIgnore
    Person sender;

    @ManyToOne
    Person receiver;

    ...
}

我希望这样就能正确Map双向关系,并且excludedBy列表也会被填充。
在这件事上有任何智慧都是伟大的!

m0rkklqb

m0rkklqb1#

1 -默认情况下,@Id不是nullable,不需要:

@Column(nullable = false)

2 -此类中不需要@Id。排除的两侧在一起是唯一的。不需要:

@Id
@GeneratedValue
Long id;

3 -“Exclusion”需要excludedBy和excluded,给予它们匹配的名称,它们就是你的@Id。这是一个双向的多对多关系。

@Entity
@Table(name = "exclusions")
public class Exclusion {
    @Id
    @ManyToMany // An ID so not optional, so no need for (optional = false)
    Person excludedBy;

    @Id
    @ManyToMany // An ID so not optional, so no need for (optional = false)
    Person excluded;
}

实体Exclusion总是知道事情的两面。

@ManyToMany(mappedBy = "excludedBy", cascade = { CascadeType.ALL })
List<Exclusion> excluded = new ArrayList<>();

@ManyToMany(mappedBy = "excluded", cascade = { CascadeType.ALL })
List<Exclusion> excludedBy = new ArrayList<>();

提示:JSON DTO不应该在JPA DTO中定义,否则您无法独立于外部API模型更改内部数据模型。

4nkexdtk

4nkexdtk2#

我以前遇到过这个问题。你的关键问题是你的ORMMap器休眠不知道你的数据库条目中哪些需要分配给exclusions,哪些需要分配给excludedBy。你需要一个discriminator,并在你的select中添加约束。我建议一个解决方案,看起来像这样:

@OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JoinColumn(name = "PRIMARY_KEX_IN_EXCLUSION_TABLE", referencedColumnName = "id")
@Where(clause = "is_excluded_by = 0")
private Set<Exclusion> exclusions; 

@OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JoinColumn(name = "PRIMARY_KEX_IN_EXCLUSION_TABLE", referencedColumnName = "id")
@Where(clause = "is_excluded_by = 1")
private Set<Exclusion> excludedBy;

isExcludedBy需要是数据库列,是实体的一部分,并在代码中手动设置。
我认为当一个实体中有多个集合时,您还需要使用Set而不是Listhttps://vladmihalcea.com/spring-data-jpa-multiplebagfetchexception/

相关问题