Spring Data REST - 如何同时保存包含子项的父实体

时间:2015-11-24 20:11:19

标签: spring rest transactions spring-data spring-data-rest

我正在使用Spring Data REST来公开我的实体,我希望能够同时保存(创建和更新)父实体及其子实体。

以下是我的实体:

@Entity
@Table(name = "scenario")
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
public class Scenario extends AbstractAuditableEntity {

    @Id
    // Sequence name must be preceded by schema name.
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "scenarioIdSeq")
    @SequenceGenerator(name = "scenarioIdSeq", sequenceName = "scenario_id_seq", allocationSize = 1)
    @Column(unique = true, nullable = false, columnDefinition = "SERIAL")
    private Long id;

    @Version
    // Used by JPA for optimistic locking
    protected int version;

    @OneToMany(mappedBy = "scenario")
    @LazyCollection(LazyCollectionOption.TRUE)
    private Set<Action> actions = new HashSet<Action>();
}

@Entity
@Table(name = "action")
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
public class Action extends AbstractAuditableEntity {

    @Id
    // Sequence name must be preceded by schema name.
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "actionIdSeq")
    @SequenceGenerator(name = "actionIdSeq", sequenceName = "action_id_seq", allocationSize = 1)
    @Column(unique = true, nullable = false, columnDefinition = "SERIAL")
    private Long id;

    @Version
    // Used by JPA for optimistic locking
    protected int version;

    @RestResource(rel = "action_scenario")
    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "scenario_id", columnDefinition = "BIGINT", nullable = false)
    private Scenario scenario;

    @JsonIgnore
    @OneToMany(mappedBy = "action")
    @LazyCollection(LazyCollectionOption.TRUE)
    private Set<ActionParameter> parameters = new HashSet<ActionParameter>();
}

@Entity
@Table(name = "action_parameter")
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
public class ActionParameter extends AbstractAuditableEntity {

    @Id
    // Sequence name must be preceded by schema name.
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "actionParamIdSeq")
    @SequenceGenerator(name = "actionParamIdSeq", sequenceName = "action_parameter_id_seq", allocationSize = 1)
    @Column(unique = true, nullable = false, columnDefinition = "SERIAL")
    private Long id;

    @Version
    // Used by JPA for optimistic locking
    protected int version;

    @RestResource(rel = "parameter_action")
    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "action_id", columnDefinition = "BIGINT", nullable = false)
    private Action action;
}

所以我希望能够同时(在同一个交易中)保存(创建和更新)整个场景及其动作和动作参数。

使用Spring Data REST实现这一目标的最佳方法是什么?

更新1:

我已经尝试按照建议使用cascade属性,但现在我收到了这个错误:

  

无法写入内容:检测到多条关联链接   关系类型!消除关联歧义   @ org.springframework.data.rest.core.annotation.RestResource(路径=,   出口= TRUE,   description=@org.springframework.data.rest.core.annotation.Description(值=),   相对= action_scenario)

每个关系都已使用@RestResource(rel =“xxx”)注释,所以我不明白为什么我会收到此错误?!

我错过了什么吗?

1 个答案:

答案 0 :(得分:0)

您必须在cascade注释中使用@OneToMany属性:

I.e。:

@OneToMany(mappedBy = "scenario", cascade = CascadeType.MERGE)     
@LazyCollection(LazyCollectionOption.TRUE)
@JsonManagedReference
private Set<Action> actions = new HashSet<Action>();
}

这样,您可以将Action个实例添加到预定义的Set,并使用Scenario

保存它们
Scenario scenario = new Scenario():
scenario.getActions.add(new Action);
scenarioRepository.save(scenario);