Unable to save data to composite Table Via Spring Data rest json post

吃可爱长大的小学妹 提交于 2019-12-04 05:29:30

问题


I have 3 Tables in db
training
- training_id (pk)

user_profile
- profile_id (pk)

-training_profile (composite table)
- training_id
- profile_id

I have already record in user_profile table having profile_id=44 and want to create new record for training table ,and also to associate this new training with already existing user_profile record which has id 44,but after post data is saved to training table but it is not inserted into lookup table user_training.
My Object Classes Are - Training Class

@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;
    }
}
  • UserProfile

    @Entity @Table(name = "user_profile", schema = "public")
    public class UserProfile implements 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;
    }
    

    }

My json post via postman

And Response I get

Response show that new training record inserted in table having training_id as 67 No association found for this new saved training

again it created new record for training and does not associate with existing user profile , I post curl -i -X POST -H "Content-Type:application/json" -d "{ \"trainingSubject\" : \"Oracle\", \"userProfiles\":[\"/userProfiles/44\"] }" http://localhost:8080/api/trainings


回答1:


You could use the relative url assignment:

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

Maybe also try with the full url: http://localhost:8080/api/userProfiles/44

EDITED

If you move the owning site of the ManyToMany relation to Training it will work with the above JSON. So currently the owner is allowed to set the realtions. If you do it like that:

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

plus

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

Training owns the relation within userProfiles.

I think in your case it's the best option for now. Another option would be, when keeping the owner site at UserProfile on transactions, to update the relation there like:

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

But with this you would need multible rest calls (1. POST new training and get the new Id 2. GET current training list 3. PATCH trainings list with newly added training)

Last option would be to add the REST-controller on your own.

Complete files for the first approach:

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

With the upper JSON this will work, I tested it. You will not see the correct result directly in the response of curl-POST. To see the added relation you must follow the userProfiles-link like GET http://localhost:8080/transactions/<newId>/userProfiles



来源:https://stackoverflow.com/questions/43111692/unable-to-save-data-to-composite-table-via-spring-data-rest-json-post

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