与额外列Jpa

时间:2017-03-30 09:55:26

标签: hibernate spring-boot spring-data-jpa lombok postgresql-9.6

我处于这种情况。我有三个实体:Form,FormComponent和FormComponentJoin。 它是额外列的多对多关系。 我想保存一个表单实体和他的所有孩子只需要一次调用FormRepository save()方法,但它不起作用。 这是错误消息: 错误由以下原因引起:org.hibernate.TransientPropertyValueException:对象引用未保存的瞬态实例 - 在刷新之前保存瞬态实例 这些是我的实体:

@Data
@Entity
@Table(name = "form")
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode
public class Form implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(generator = "system-uuid")
    @GenericGenerator(name = "system-uuid", strategy = "uuid")
    private String id;

    private String name;

    @OneToMany(mappedBy = "form", cascade = { CascadeType.PERSIST, CascadeType.MERGE }, orphanRemoval = true)
    @NotFound(action = NotFoundAction.IGNORE)
    @Singular
    private List<FormComponentJoin> formComponentJoin = new ArrayList<>();

}

@Data
@EqualsAndHashCode
@Entity
@Table(name = "form_component")
@AllArgsConstructor(suppressConstructorProperties = true)
@NoArgsConstructor
public class FormComponent implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(generator = "system-uuid")
    @GenericGenerator(name = "system-uuid", strategy = "uuid")
    private String id;

    @JsonIgnore
    @OneToMany(mappedBy = "formComponent", cascade = CascadeType.ALL, orphanRemoval = true)
    @NotFound(action = NotFoundAction.IGNORE)
    private List<FormComponentJoin> formComponentJoin = new ArrayList<>();

    @ManyToOne
    @JsonIgnore
    private FormComponent parent;

    @OneToMany(mappedBy = "parent", cascade = CascadeType.ALL)
    @Singular
    private List<FormComponent> children;

    private String value;
}

@Entity
@Table(name = "form_component_join")
@Data
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode
public class FormComponentJoin implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(generator = "system-uuid")
    @GenericGenerator(name = "system-uuid", strategy = "uuid")
    private String id;

    @ManyToOne
    @JoinColumn(name = "form_id", referencedColumnName = "id")
    @NotFound(action = NotFoundAction.IGNORE)
    @JsonIgnore
    private Form form;

    @ManyToOne
    @JoinColumn(name = "form_component_id", referencedColumnName = "id")
    @NotFound(action = NotFoundAction.IGNORE)
    private FormComponent formComponent;

    @Column(name = "position")
    private int pos;

}

@Repository
@Transactional(readOnly = true)
public interface FormRepository extends PagingAndSortingRepository<Form, String> {

}

为了进行测试,我使用CommandLineRunner:

@Bean
public CommandLineRunner initDatabase(FormRepository formRepository) {
    return (args) -> {

    FormComponent formComponent1 = FormComponent.builder().value("test").build();
    formComponent1.setChildren(null);
    formComponent1.setParent(null);

    FormComponentJoin formComponentJoin1 = FormComponentJoin.builder().pos(1).formComponent(formComponent1).build();

    Form form = Form.builder().name("test").build()).child(formComponentJoin1).build();
    formComponentJoin1.setForm(form);       

    form = formRepository.save(form);   

}

这是完整的堆栈跟踪:

引起:org.hibernate.TransientPropertyValueException:对象引用未保存的瞬态实例 - 在刷新之前保存瞬态实例:org.fao.backend.entity.FormComponentJoin.formComponent - &gt; org.fao.backend.entity.FormComponent         at org.hibernate.engine.spi.CascadingActions $ 8.noCascade(CascadingActions.java:398)         在org.hibernate.engine.internal.Cascade.cascade(Cascade.java:129)         at org.hibernate.event.internal.AbstractSaveEventListener.cascadeBeforeSave(AbstractSaveEventListener.java:442)         在org.hibernate.event.internal.DefaultPersistEventListener.justCascade(DefaultPersistEventListener.java:188)         在org.hibernate.event.internal.DefaultPersistEventListener.entityIsPersistent(DefaultPersistEventListener.java:181)         在org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:145)         在org.hibernate.internal.SessionImpl.firePersistOnFlush(SessionImpl.java:838)         在org.hibernate.internal.SessionImpl.persistOnFlush(SessionImpl.java:831)         在org.hibernate.engine.spi.CascadingActions $ 8.cascade(CascadingActions.java:357)         在org.hibernate.engine.internal.Cascade.cascadeToOne(Cascade.java:350)         在org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:293)         在org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:161)         在org.hibernate.engine.internal.Cascade.cascadeCollectionElements(Cascade.java:379)         在org.hibernate.engine.internal.Cascade.cascadeCollection(Cascade.java:319)         在org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:296)         在org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:161)         在org.hibernate.engine.internal.Cascade.cascade(Cascade.java:118)         在org.hibernate.event.internal.AbstractFlushingEventListener.cascadeOnFlush(AbstractFlushingEventListener.java:167)         在org.hibernate.event.internal.AbstractFlushingEventListener.prepareEntityFlushes(AbstractFlushingEventListener.java:158)         at org.hibernate.event.internal.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:91)         在org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:55)         在org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1258)         在org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:425)         at org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.beforeTransactionCommit(JdbcTransaction.java:101)         at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.commit(AbstractTransactionImpl.java:177)         在org.hibernate.jpa.internal.TransactionImpl.commit(TransactionImpl.java:77)         ...省略了58个常见帧

1 个答案:

答案 0 :(得分:0)

最终我理解错误是FormComponentJoin实体中的映射。

这是新的映射:

@ManyToOne(cascade = { CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REMOVE })
@JoinColumn(name = "form_id") // , referencedColumnName = "id"
@NotFound(action = NotFoundAction.IGNORE)
@JsonIgnore
private Form form;

@ManyToOne(cascade = { CascadeType.PERSIST, CascadeType.MERGE })
@JoinColumn(name = "form_component_id") // , referencedColumnName = "id"
@NotFound(action = NotFoundAction.IGNORE)
private FormComponent formComponent;