【问题标题】:How to save data-from-parent-to-child-tables-based-on-entities-in-spring-jpa如何在spring-jpa中保存从父表到子表的数据
【发布时间】:2019-12-05 13:06:18
【问题描述】:

我有一个表主表用户、主题表和 cmets 表 其中一个主题可以有多个 cmets

用户表将已被填充。 我将收到一个帖子请求以保存具有如下结构的主题

{  
   "topicId":"T001",
   "title":"stackoverflow",
   "commentBeans":[  
      {  
"comment":"developer platform"
      },

      {  
"comment":"developer communtiy"
      }
   ]
}

使用的框架: 弹簧靴 JPA 数据库:postgressql

我能够以传统方式保存数据(即首先获取请求并保存主题bean。从保存的实体中获取主键并循环commentbean列表,其中用户编号将由另一个获取服务动态设置并保存它们)

我想知道是否可以通过单个保存查询来保存数据。

@Entity
@Table(name ="user")
public class User implements Serializable {

    @Id
    @Column(name = "user_num")
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long userNum;

    @Column(name = "user_id")
    private String userId;

    @Column(name = "username")
    private String userName;

}

@Entity
@Table(name = "topics")
public class TopicBean implements Serializable {

    @Id
    @Column(name = "topic_num")
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long topicNum;

    @Column(name = "topicId")
    private String topicId;
    @Column(name = "title")
    private String title;

    @OneToMany(mappedBy="topicBean")
    private List<CommentBean> commentBeans;
}

@Entity
@Table(name = "comments")
public class CommentBean implements Serializable {

    @EmbeddedId
    private CommentBeanKey key;


    @Column(name = "comment")
    private string comment;

    @ManyToOne
    @JoinColumn(name="topic_num")
    private TopicBean topicBean;

    @ManyToOne
    @JoinColumn(name="user_num")
    private TopicBean topicBean;

}

@Embeddable
public class CommentBeanKey implements Serializable{

    private static final long serialVersionUID = 5889249943605061539L;

    @Column(name ="topic_num")
    private Long topicNum;

    @Column(name ="user_num")
    private Long userNum;


}

我看到了下面的链接,如果我做错了,我有点担心。任何帮助表示赞赏。

https://thoughts-on-java.org/hibernate-tips-how-to-map-an-entity-to-multiple-tables/

【问题讨论】:

  • 您需要的是级联操作...@OneToMany(mappedBy="topicBean", cascade = CascadeType.ALL)。看看不同的类型来完善它。
  • 我试图在评论表中插入主题表的主键,由于插入时主键为空,因此出现约束冲突异常。
  • cascadeType.ALL 应该为您解决这个问题。你试过吗?
  • 由于主题表的主键在 cmets 表中变为空,因此我尝试并收到约束违规异常
  • 您好@Vignesh_A,我为您创建了一个示例,请根据它更改代码,如果有任何问题,请告诉我

标签: java spring hibernate spring-boot jpa


【解决方案1】:

Parent.java

@Entity
@Table(name = "parent")
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class Parent {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int parentId;
    private String name;

    @OneToMany(mappedBy="parent",fetch=FetchType.LAZY,cascade = CascadeType.PERSIST)
    private List<Child> child = new ArrayList<Child>();
}

Child.java

@Entity
@Table(name = "child")
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class Child {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int childId;
    private String account;

    @ManyToOne(fetch = FetchType.LAZY, targetEntity = Parent.class)
    @JoinColumn(name="parentId", referencedColumnName = "parentId", nullable = false)
    private Parent parent;

}

Controller.java

//save Child with Parent at same 
    @PostMapping(value = "/onetomany")
    public String OneToMany(@RequestBody Parent parent)
    {
        System.out.println("Parent: "+parent.toString());
        for (Child child : parent.getChild()) {
            child.setParent(parent);
        }

        parent.setChild(parent.getChild());
        parentRepository.save(parent);
        return "saved";

         /*{
            "name":"Romil",
            "child":[
               {"account":"1"},
               {"account":"2"}
             ]
         }*/
    }

        //save Child with Parent's ID
        @PostMapping(value = "/onetomanyPID")
        public String OneToMany(@RequestBody Child child)
        {
            child.setParent(child.getParent());
            childRepository.save(child);
            return "saved";

            /*{
            "account":"3",
             "parent":{
                 "parentId":"1",
                  "name":"Romil"
              }
            }*/
        }

【讨论】:

  • 帕特尔,需要澄清一下。 1)是否可以在插入父表时将父表中自动生成的主键保存为外键。实际上,我尝试按照您所说的方式插入数据,但在异常中我将 parentId 设置为 null。
  • 是的,有可能。对于上述控制器,这是第一种情况。确保为每个孩子设置父级(此处为 for 循环),然后将子级设置为 parent.setChild(..)。
  • 请分享您使用Json Input进行保存操作的相关代码
  • 您好,@Vignesh_A 如果有帮助,请接受并投票赞成
  • 嗨 Patel,我仍然无法解决问题。我的子对象具有复合主键,我假设您的解决方案仅适用于单个主键?如果我错了,请纠正我。 btw 将在接下来的几天内分享 github 链接。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-12-02
  • 2022-01-20
  • 1970-01-01
  • 2019-03-16
  • 1970-01-01
  • 1970-01-01
  • 2019-05-08
相关资源
最近更新 更多