Spring 数据剩余如何对 @manytomany 关系执行 CRUD,复合 table 与额外的列

Spring Data rest how to perform CRUD on @manytomany relation ,composite table with extra column

我无法通过 json POST 从 restful 客户端 Postman 在具有额外列的 Composite table 上执行 CRUD。我正在使用 Spring 启动,spring 数据休息和 spring JPA。 我在数据库中有 3 tables
-用户
-能力
-user_competency(join/composite table 有额外的列)

这是我的 类

用户

@Entity
@Table(name = "\"user\"", schema = "public")
@JsonIdentityInfo(
          generator = ObjectIdGenerators.IntSequenceGenerator.class, 
          property = "userId")
public class User implements java.io.Serializable {

    private Long userId;

    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)

    @Column(name = "user_id", unique = true, nullable = false)
    public Long getUserId() {
        return this.userId;
    }

    public void setUserId(Long userId) {
        this.userId = userId;
    }

    private Set<UserCompetency> userCompetencies = new HashSet<UserCompetency>(0);

        @OneToMany(fetch = FetchType.EAGER,cascade = {CascadeType.ALL}, mappedBy = "user")
    public Set<UserCompetency> getUserCompetencies() {
        return this.userCompetencies;
    }

    public void setUserCompetencies(Set<UserCompetency> userCompetencies) {
        this.userCompetencies = userCompetencies;
    }

}

能力

@Entity
@Table(name = "competency", schema = "public")
@JsonIdentityInfo(
          generator = ObjectIdGenerators.IntSequenceGenerator.class, 
          property = "competencyId")
public class Competency implements java.io.Serializable {


    private Long competencyId;
    private Set<UserCompetency> userCompetencies = new HashSet<UserCompetency>(0);

    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)

    @Column(name = "competency_id", unique = true, nullable = false)
    public Long getCompetencyId() {
        return this.competencyId;
    }

    public void setCompetencyId(Long competencyId) {
        this.competencyId = competencyId;
    }

        @OneToMany(fetch = FetchType.LAZY, mappedBy = "competency")
    public Set<UserCompetency> getUserCompetencies() {
        return this.userCompetencies;
    }

    public void setUserCompetencies(Set<UserCompetency> userCompetencies) {
        this.userCompetencies = userCompetencies;
    }
}   

用户能力

@Entity
@Table(name = "user_competency", schema = "public")
@JsonIdentityInfo(
          generator =ObjectIdGenerators.IntSequenceGenerator.class, 
          property = "id")
public class UserCompetency implements java.io.Serializable {
    private UserCompetencyId id;
    private Level level;
    private User user;
    private Competency competency;

    @EmbeddedId

    @AttributeOverrides({
            @AttributeOverride(name = "competencyId", column = @Column(name = "competency_id", nullable = false)),
            @AttributeOverride(name = "userId", column = @Column(name = "user_id", nullable = false)) })
    public UserCompetencyId getId() {
        return this.id;
    }

    public void setId(UserCompetencyId id) {
        this.id = id;
    }

    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "level_id")
    public Level getLevel() {
        return this.level;
    }

    public void setLevel(Level level) {
        this.level = level;
    }

    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "user_id", nullable = false, insertable = false, updatable = false)
    public User getUser() {
        return this.user;
    }

    public void setUser(User user) {
        this.user = user;
    }

    @ManyToOne(fetch = FetchType.EAGER,cascade=CascadeType.ALL)
    @JoinColumn(name = "competency_id", nullable = false, insertable = false, updatable = false)
    public Competency getCompetency() {
        return this.competency;
    }

    public void setCompetency(Competency competency) {
        this.competency = competency;
    }
}   

UserCompetencyId

@Embeddable
public class UserCompetencyId implements java.io.Serializable {

    private Long competencyId;
    private Long userId;

    public UserCompetencyId() {
    }

    public UserCompetencyId(Long competencyId, Long userId) {
        this.competencyId = competencyId;
        this.userId = userId;
    }


    @Column(name = "competency_id", nullable = false)
    public Long getCompetencyId() {
        return this.competencyId;
    }

    public void setCompetencyId(Long competencyId) {
        this.competencyId = competencyId;
    }

    @Column(name = "user_id", nullable = false)
    public Long getUserId() {
        return this.userId;
    }

    public void setUserId(Long userId) {
        this.userId = userId;
    }

    public boolean equals(Object other) {
        if ((this == other))
            return true;
        if ((other == null))
            return false;
        if (!(other instanceof UserCompetencyId))
            return false;
        UserCompetencyId castOther = (UserCompetencyId) other;

        return (this.getCompetencyId() == castOther.getCompetencyId()) && (this.getUserId() == castOther.getUserId());
    }    
}

假设我已经在 User 和 Competency tables 中进行了记录,并且我想像这样尝试 post 关联两者,但是它给我错误 405 Method Not Allowed。

需要帮助,json 的结构应该是 posted 用户将已经存在并且能力可能存在,或者可以添加新的并与现有用户关联。

显然似乎没有 "natural/easy" 方法可以得到您想要的东西。但是有一个通过扩展序列化过程来集成嵌入式的有前途的项目:https://github.com/gregturn/embeddable-spring-data-rest

  • UserCompetencyIdJacksonModule, UserCompetencyIdSerializer, ..

那么你应该可以从上面PATCH(不是POST)你的JSON。

使用这段代码,我能够 post 一个新关系:

UserCompetency.class

@Entity
@Table(name = "user_competency")
@IdClass(UserCompetencyId.class)
public class UserCompetency implements java.io.Serializable {

    @Id @ManyToOne
    @JoinColumn(name = "competency_id", nullable = false, insertable = false, updatable = false)
    private Competency competency;

    @Id @ManyToOne
    @JoinColumn(name = "user_id", nullable = false, insertable = false, updatable = false)
    private User user;

UserCompetencyId.class

public class UserCompetencyId implements java.io.Serializable {

    private Long competency;

    private Long user;

    public UserCompetencyId() {
    }

    public UserCompetencyId(Long competency, Long user) {
        this.competency = competency;
        this.user = user;
    }

UserCompetencyRepository.class

public interface UserCompetencyRepository extends JpaRepository<UserCompetency, UserCompetencyId> {

}

POST http://localhost:8080/userCompetencies

{
    "competency": "/competencies/2"
    , "user": "/user/4"
}