【问题标题】:Unable to save data to composite Table Via Spring Data rest json post无法通过 Spring Data rest json post 将数据保存到复合表
【发布时间】:2017-08-24 00:20:37
【问题描述】:

我在 db 中有 3 个表
培训
- training_id (pk)

user_profile
- profile_id (pk)

-training_profile(复合表)
- training_id
- profile_id

我已经在 user_profile 表中记录了 profile_id=44 并想为培训表创建新记录,并将这个新培训与已经存在的 id 为 44 的 user_profile 记录相关联,但在将发布数据保存到培训表之后但它没有插入到查找表 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;
    }
}
  • 用户资料

    @实体 @Table(name = "user_profile", schema = "public")
    公共类 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;
    }
    

    }

我通过邮递员发布的 json 帖子

我得到回应

响应显示新的训练记录插入到 training_id 为 67 的表中 未找到此新保存的培训的关联

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

【问题讨论】:

  • 您可以编辑您的问题并进行一些更正,然后重试吗?将@Id @GeneratedValue 放在id 字段前面的正确位置。在TrainingUserProfile 中。
  • GET http://localhost:8080/api/userProfiles/44 确实返回了什么?
  • localhost:8080/api/userProfiles/44,请检查我是否添加了有问题的屏幕截图

标签: spring spring-boot spring-data-jpa spring-data-rest


【解决方案1】:

您可以使用相对 url 分配:

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

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

已编辑

如果您将 ManyToMany 关系的拥有站点移动到 Training,它将与上述 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<>();

Training 拥有userProfiles 内的关系。

我认为就您而言,这是目前最好的选择。另一种选择是,当将所有者站点保持在 transactions 上的 UserProfile 时,更新那里的关系,例如:

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

但是这样你就需要多次休息调用(1.发布新的训练并获取新的 ID 2.获取当前的训练列表 3.PATCH 训练列表和新添加的训练)

最后一个选择是自行添加 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,例如 GET http://localhost:8080/transactions/&lt;newId&gt;/userProfiles

【讨论】:

  • 这必须工作,也许与stackoverflow.com/questions/42929828/…检查
  • 我已相应更新 curl -i -X POST -H "Content-Type:application/json" -d "{ \"trainingSubject\" : \Oracle\", \"userProfile\" : "localhost:8080/api/userProfiles/44" }" localhost:8080/api/trainings 但它抛出 com.fasterxml.jackson.core.JsonParseException 异常:意外字符('\\'(代码 92)):预期有效值(数字,字符串
  • 好的,我输入了转义序列并重新发布了 json,但它再次给了我与屏幕截图中相同的响应。
  • 啊好吧.. 用上层 JSON 发布后(来自答案)GET http://localhost:8080/api/training/67/userProfiles 下有什么东西吗?请求父级时,标准行为中的关系子级属性不会被传递。然后客户必须点击链接。
  • 卷曲应该是这样的:curl -i -X POST -H "Content-Type:application/json" -d "{ \"trainingSubject\" : \Oracle\", \"userProfiles\":[\"/userProfiles/44\"] }" http://localhost:8080/api/training
猜你喜欢
  • 2018-02-02
  • 2016-08-19
  • 2017-07-10
  • 2015-07-22
  • 2016-06-07
  • 2021-10-04
  • 2014-04-04
  • 2014-05-05
  • 2022-08-20
相关资源
最近更新 更多