Java 如何在spring jpa中基于实体将数据从父表保存到子表
我有一个主表用户、主题表和注释表 其中,对于单个主题,可以有多个注释 用户表将已填充。 我将收到一个post请求,用如下结构保存主题Java 如何在spring jpa中基于实体将数据从父表保存到子表,java,spring,hibernate,spring-boot,jpa,Java,Spring,Hibernate,Spring Boot,Jpa,我有一个主表用户、主题表和注释表 其中,对于单个主题,可以有多个注释 用户表将已填充。 我将收到一个post请求,用如下结构保存主题 { "topicId":"T001", "title":"stackoverflow", "commentBeans":[ { "comment":"developer platform" }, { "comment":"developer communtiy" } ] }
{
"topicId":"T001",
"title":"stackoverflow",
"commentBeans":[
{
"comment":"developer platform"
},
{
"comment":"developer communtiy"
}
]
}
使用的框架:
弹簧靴
JPA
DB:postgresql
我能够以传统方式保存数据(即首先获取请求并保存主题bean。从保存的实体获取primarykey并循环commentbean列表,在该列表中,另一个get服务将动态设置用户num并保存它们)
我想知道是否有任何方法可以使用单个保存查询保存数据
@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;
}
@实体
@表(name=“user”)
公共类用户实现可序列化{
@身份证
@列(name=“user\u num”)
@GeneratedValue(策略=GenerationType.AUTO)
私有长用户数;
@列(name=“user\u id”)
私有字符串用户标识;
@列(name=“username”)
私有字符串用户名;
}
@实体
@表(name=“topics”)
公共类TopicBean实现了可序列化{
@身份证
@列(name=“topic\u num”)
@GeneratedValue(策略=GenerationType.AUTO)
私人长主题;
@列(name=“topicId”)
私有字符串topicId;
@列(name=“title”)
私有字符串标题;
@OneToMany(mappedBy=“topicBean”)
私有列表;
}
@实体
@表(name=“comments”)
公共类CommentBean实现了可序列化{
@嵌入ID
私钥;
@列(name=“comment”)
私有字符串注释;
@许多酮
@JoinColumn(name=“topic\u num”)
私有TopicBean TopicBean;
@许多酮
@JoinColumn(name=“user\u num”)
私有TopicBean TopicBean;
}
@可嵌入
公共类CommentBeanKey实现了可序列化{
私有静态最终长serialVersionUID=5889249943605061539L;
@列(name=“topic\u num”)
私人长主题;
@列(name=“user\u num”)
私有长用户数;
}
我看到了下面的链接,如果我做得不对,我也不太担心。感谢您的帮助
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>();
}
@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;
}
//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"
}
}*/
}
Controller.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>();
}
@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;
}
//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"
}
}*/
}
您需要的是级联操作@OneToMany(mappedBy=“topicBean”,cascade=CascadeType.ALL)。查看不同的类型以优化它。我正在尝试在注释表中插入主题表的主键,由于主键在插入时为null,因此我得到了约束冲突异常。cascadeType.ALL应该为您解决该问题。你试过了吗?我试过了,并且得到了约束冲突异常,因为主题表的主键在comments tableHello@Vignesh_A中变为null,我已经为你创建了一个示例,请根据它更改代码,如果有任何问题,请告诉我Patel,需要一些澄清。1) 在插入父表期间,是否可以将子表中父表自动生成的主键保存为外键。实际上,我试着按照你说的方式插入数据,但我在异常中得到的parentId为null。是的,这是可能的。对于上述控制器,这是第一种情况。请确保为每个子项设置父项(此处为循环),并将其后的子项设置为parent.setChild(..)。请与Json InputHello共享执行保存操作的相关代码,@Vignesh_A请接受并向上投票答案,如果答案有帮助Hi Patel,我仍然无法解决此问题。我的子对象具有复合主键,我假设您的解决方案仅适用于单个主键?如果我错了,请纠正我。顺便说一句,我们将在未来几天内共享github链接。