Get id's of a ManyToMany mapping table

徘徊边缘 提交于 2019-12-11 08:14:43

问题


I'm writing an API using Spring Boot and Hibernate where my persisted entity objects are also used as DTOs sent to and from the client. This is a simplified version of a typical entity I use:

@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
}

and this is the associated class:

@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
}

As you can see, there is a @ManyToMany association between Student and Group.

Since I send objects like these to the client, I choose to send only the id's of the associations and not the associations themselves. I've solved this using this answer and it works as expected.

The problem is this. When hibernate tries to persist a Student object, it inserts the groups as expected, but it also tries to insert the groupIds into the mapping table GROUP_STUDENT. This will of course fail because of the unique constraint of the mapping table composite id. And it isn't possible to mark the groupIds as insertable = false since it is an @ElementCollection. And I don't think I can use @Formula since I require a Set and not a reduced value.

This can of course be solved by always emptying either the groups of the groupIds before saving or persisting such an entity, but this is extremely risky and easy to forget.

So what I want is basically a read only groupIds in the Student class that loads the data from the GROUP_STUDENT mapping table. Is this possible? I'm grateful for any suggestions and glad to ellaborate on the question if it seems unclear.


回答1:


I've managed to solve this by making the id-collection @Transient and populating it using @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
}


来源:https://stackoverflow.com/questions/45548787/get-ids-of-a-manytomany-mapping-table

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!