提问者:小点点

无法通过Spring Data rest json post将数据保存到复合表


我有3表在db
训练
-training_id(pk)

user_profile
-profile_id(pk)

-training_profile(复合表)
-training_id
-profile_id

我已经在user_profile表中记录了profile_id=44,并想为训练表创建新记录,并将此新训练与已存在的user_profile记录相关联,该记录具有id 44,但后数据保存到训练表中,但未插入查找表user_training。
我的对象类是-训练类

@Entity
@Table(name = "training", schema = "public")
public class Training implements java.io.Serializable {

    @Id @GeneratedValue
    @Column(name = "training_id", unique = true, nullable = false)
    private Long trainingId;


    @ManyToMany(fetch = FetchType.LAZY, mappedBy = "trainings")
    private Set<UserProfile> userProfiles = new HashSet<UserProfile>(0);

    @Column(name = "training_subject", length = 200)
    private String trainingSubject;

    public Training() {
    }

    public Long getTrainingId() {
        return this.trainingId;
    }

    public void setTrainingId(Long trainingId) {
        this.trainingId = trainingId;
    }


    public String getTrainingSubject() {
        return this.trainingSubject;
    }

    public void setTrainingSubject(String trainingSubject) {
        this.trainingSubject = trainingSubject;
    }


    public Set<UserProfile> getUserProfiles() {
        return this.userProfiles;
    }

    public void setUserProfiles(Set<UserProfile> userProfiles) {
        this.userProfiles = userProfiles;
    }
}

>

  • 用户配置文件

    @Entity@Table(name="user_profile", schema="public")
    public class UserProfile实现java.io.Serializable{

    @Id @GeneratedValue
    @Column(name = "profile_id", unique = true, nullable = false)
    private Long profileId;
    
    @Column(name = "profile_description")
    private String profileDescription;
    
    @ManyToMany(fetch = FetchType.EAGER, cascade = { CascadeType.ALL })
    @JoinTable(name = "user_training", schema = "public", joinColumns = {
            @JoinColumn(name = "profile_id", nullable = false, updatable = false) }, inverseJoinColumns = {
                    @JoinColumn(name = "training_id", nullable = false, updatable = false) })
    private Set<Training> trainings = new HashSet<Training>(0);
    
    public UserProfile() {
    }
    
    
    public String getProfileDescription() {
        return this.profileDescription;
    }
    
    public void setProfileDescription(String profileDescription) {
        this.profileDescription = profileDescription;
    }
    
    
    public Set<Training> getTrainings() {
        return this.trainings;
    }
    
    public void setTrainings(Set<Training> trainings) {
        this.trainings = trainings;
    }
    

    }

    我得到了回应

    它再次创建了新的训练记录,并且不与现有用户配置文件相关联,我发布curl-i-X POST-H"Content-Type: application/json"-d"{\"trainingSub\" : \"Oracle\",\"userProfiles\":[\"/userProfiles/44\"] }" http://localhost:8080/api/trainings


  • 共1个答案

    匿名用户

    您可以使用相对url分配:

    {
        "trainingSubject": "oracle",
        "userProfiles":["/userProfiles/44"]
    }
    

    也许也可以尝试使用完整的url:http://localhost:8080/api/userProfiles/44

    编辑

    如果您将ManyTo很多关系的拥有站点移动到培训,它将与上述JSON一起工作。所以目前允许所有者设置区域。如果你这样做:

    @ManyToMany
    @JoinTable(name = "user_training"
    , joinColumns = {@JoinColumn(name = "profile_id") }
    , inverseJoinColumns = {@JoinColumn(name = "training_id") })
    private List<UserProfile> userProfiles = new ArrayList<>();
    

    加上

    @ManyToMany(mappedBy = "userProfiles")
    private List<Training> trainings = new ArrayList<>();
    

    训练拥有userProfiles中的关系。

    我认为在你的情况下,这是目前最好的选择。另一种选择是,当将所有者站点保留在UserProfile上的交易时,更新那里的关系,例如:

    PATCH http://localhost:8080/api/userProfiles/44
    {
        "trainings": ["trainings/66", "trainings/67"]
    }
    

    但是有了这个,您将需要多次rest调用(1.发布新培训并获取新Id 2.获取当前培训列表3.使用新添加的培训修补培训列表)

    最后一个选择是自己添加REST控制器。

    第一种方法的完整文件:

    @Entity
    @Table
    public class Training implements Serializable {
    
        @Id
        @GeneratedValue
        private Long trainingId;
    
        @ManyToMany
        @JoinTable(name = "user_training"
        , joinColumns = {@JoinColumn(name = "profile_id") }
        , inverseJoinColumns = {@JoinColumn(name = "training_id") })
        private List<UserProfile> userProfiles = new ArrayList<>();
    
        @Column(name = "training_subject", length = 200)
        private String trainingSubject;
    
    
    @Entity
    @Table
    public class UserProfile implements Serializable {
    
        @Id
        @GeneratedValue
        private Long profileId;
    
        @Column(name = "profile_description")
        private String profileDescription;
    
        @ManyToMany(mappedBy = "userProfiles")
        private List<Training> trainings = new ArrayList<>();
    
    
    public interface TrainingRepository extends JpaRepository<Training, Long> {
    }
    
    public interface UserProfileRepository extends JpaRepository<UserProfile, Long> {
    }
    

    使用上面的JSON这将起作用,我测试了它。您不会直接在curl-POST的响应中看到正确的结果。要查看添加的关系,您必须遵循userProfiles-link,如GEThttp://localhost:8080/transactions/