将实体及其所有相关实体保存在spring boot中的单个保存中

时间:2017-05-30 13:07:25

标签: java spring jpa spring-boot one-to-many

我使用Spring Boot,REST和JPA来构建我的应用程序。在应用程序中,有2个实体具有一对多的关系。

实体1:

@Entity
@Table( name = "report")
@JsonIgnoreProperties(ignoreUnknown = true)
public class CustomReport {

@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "REPORT_SEQ")
@SequenceGenerator(sequenceName = "REPORT_SEQ", allocationSize = 1, name = "REPORT_SEQ")
private Long id;

private String name;
private Long createdBy;
private Timestamp lastModifiedTimestamp;


@OneToMany(mappedBy = "customReport", cascade = CascadeType.ALL)
private Set<CustomReportActivity> customReportActivitySet;



public Set<CustomReportActivity> getCustomReportActivitySet() {
    return customReportActivitySet;
}

public void setCustomReportActivitySet(Set<CustomReportActivity> customReportActivitySet) {
    this.customReportActivitySet = customReportActivitySet;
}



public Long getId() {
    return id;
}

public void setId(Long id) {
    this.id = id;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

public Long getCreatedBy() {
    return createdBy;
}

public void setCreatedBy(Long createdBy) {
    this.createdBy = createdBy;
}

public Timestamp getLastModifiedTimestamp() {
    return lastModifiedTimestamp;
}

public void setLastModifiedTimestamp(Timestamp lastModifiedTimestamp) {
    this.lastModifiedTimestamp = lastModifiedTimestamp;
}

}

实体2:

@Entity
@Table( name = "report_activity")
public class CustomReportActivity {

@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "REPORT_ACTIVITY_SEQ")
@SequenceGenerator(sequenceName = "REPORT_ACTIVITY_SEQ", allocationSize = 1, name = "REPORT_ACTIVITY_SEQ")
private Long id;

String activityName;

@ManyToOne
@JoinColumn( name="report_id" )
@JsonBackReference
private CustomReport customReport;

public Long getId() {
    return id;
}

public void setId(Long id) {
    this.id = id;
}

public String getActivityName() {
    return activityName;
}

public void setActivityName(String activityName) {
    this.activityName = activityName;
}

public CustomReport getCustomReport() {
    return customReport;
}

public void setCustomReport(CustomReport customReport) {
    this.customReport = customReport;
}

}

我的请求JSON如下:

{
   "name": "test report",
   "createdBy" : 129,
   "customReportActivitySet": [
        {"activityName":"a"},
        {"activityName":"b"},
        {"activityName":"c"},
        {"activityName":"d"},
        {"activityName":"e"}
    ]  
}

我想一次保存两个实体。我已通过以下方式实现了保存功能:

@RequestMapping(value="/save", method = RequestMethod.POST)
public ResponseEntity<?> addReport(@RequestBody CustomReport customReport) {
    return new ResponseEntity<>(customReportService.createCustomReport(customReport), HttpStatus.CREATED);

}

CustomReportService方法:

 public CustomReport createCustomReport(CustomReport customReport) {
    return customReportRepository.save(customReport);
}

CustomRepository:

public interface CustomReportRepository extends CrudRepository<CustomReport, Long> {

}

但是我得到了约束违规异常:

  

java.sql.SQLIntegrityConstraintViolationException:ORA-01400:不能   将NULL插入(&#34; REPORT_ACTIVITY&#34;。&#34; REPORT_ID&#34;)

是否可以在一次保存操作中保存两个实体?

请帮忙!

2 个答案:

答案 0 :(得分:2)

您必须添加一小段代码,这些代码将填充CustomReportActivity实例中的每个CustomReport。只有这样,持久性提供才能成功执行级联保存操作:

public CustomReport createCustomReport(CustomReport customReport) {
   customReport.getCustomReportActivitySet.forEach((activity) -> {
      activity.setCustomReport(customReport);
   });

   return customReportRepository.save(customReport);
}

底线是必须在关系的两边设置依赖关系。

答案 1 :(得分:1)

尝试此示例,在我的情况下,该示例按预期工作,通过创建与父实体的关系,子实体在一个保存操作中自动保存:

@Entity
public class CustomReport {
    @Id
    private Long id;

    @JoinColumn(name = "reportId")
    @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
    private Set<CustomReportActivity> activities;
}

@Entity
public class CustomReportActivity {
    @Id
    private Long id;
    private Long reportId;
}