【问题标题】:Get id's of a ManyToMany mapping table获取多对多映射表的 id
【发布时间】:2018-01-14 20:53:42
【问题描述】:

我正在使用 Spring Boot 和 Hibernate 编写一个 API,其中我的持久实体对象也用作发送到客户端和从客户端发送的 DTO。这是我使用的典型实体的简化版本:

@Entity
@Table(name = "STUDENT")
public class Student {
    @Id
    @GeneratedValue
    @Column(name = "ID")
    private Long id;

    @ElementCollection
    @CollectionTable(name = "GROUP_STUDENT",
                     joinColumns = @JoinColumn(name = "GROUP_ID"))
    @Column(name="STUDENT_ID")
    private Set<Long> groupIds;

    @JsonIgnore
    @ManyToMany(fetch = FetchType.LAZY)
    @JoinTable(name="GROUP_STUDENT",
               joinColumns = @JoinColumn(name="GROUP_ID"),
               inverseJoinColumns = @JoinColumn(name="STUDENT_ID")
    )
    private Set<Group> groups = new HashSet<>();

    // getters and setters
}

这是相关的类:

@Entity
@Table(name = "GROUP")
public class Group {
    @Id
    @GeneratedValue
    @Column(name = "ID")
    private Long id;

    @JsonIgnore
    @ManyToMany(fetch = FetchType.LAZY, mappedBy = "groups")
    private Set<Student> students = new HashSet<>();

    // getters and setters
}

如您所见,StudentGroup 之间存在 @ManyToMany 关联。

由于我将此类对象发送给客户端,因此我选择仅发送关联的 id 而不是关联本身。我已经使用this answer 解决了这个问题,它按预期工作。

问题是这样的。当 hibernate 尝试持久化一个Student 对象时,它会按预期插入groups,但它也会尝试将groupIds 插入到映射表GROUP_STUDENT 中。由于映射表复合 id 的唯一约束,这当然会失败。并且不可能将groupIds 标记为insertable = false,因为它是@ElementCollection。而且我认为我不能使用@Formula,因为我需要Set,而不是减少值。

这当然可以通过在保存或持久化这样的实体之前始终清空groupIdsgroups 来解决,但这是非常冒险且容易忘记的。

所以我想要的基本上是Student 类中的只读groupIds,它从GROUP_STUDENT 映射表加载数据。这可能吗?我很感谢您提出的任何建议,如果问题看起来不清楚,我很乐意详细说明。

【问题讨论】:

    标签: java spring hibernate jpa many-to-many


    【解决方案1】:

    我已经设法通过创建 id-collection @Transient 并使用 @PostLoad 填充它来解决这个问题:

    @Entity
    @Table(name = "STUDENT")
    public class Student {
        @PostLoad
        private void postLoad() {
            groupIds = groups.stream().map(Group::getId).collect(Collectors.toSet());
        }
    
        @Id
        @GeneratedValue
        @Column(name = "ID")
        private Long id;
    
        @Transient
        private Set<Long> groupIds;
    
        @JsonIgnore
        @ManyToMany(fetch = FetchType.LAZY)
        @JoinTable(name="GROUP_STUDENT",
                   joinColumns = @JoinColumn(name="GROUP_ID"),
                   inverseJoinColumns = @JoinColumn(name="STUDENT_ID")
        )
        private Set<Group> groups = new HashSet<>();
    
        // getters and setters
    }
    

    【讨论】:

      猜你喜欢
      • 2012-07-08
      • 1970-01-01
      • 2013-06-04
      • 2023-03-14
      • 1970-01-01
      • 1970-01-01
      • 2019-02-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多