防止级联插入JPA

时间:2018-12-03 19:31:47

标签: java hibernate spring-boot jpa spring-data-jpa

我有两节课:

public class Order{

  @Id
  @GeneratedValue(strategy = GenerationType.AUTO)
  Long id;

  @ManyToOne(fetch = FetchType.LAZY)
  Status status;

}

public class Status{

  @Id
  @GeneratedValue(strategy = GenerationType.AUTO)
  Long id;

  String description;

}

当我调用Spring的JPARepository来保存Order时,jpa尝试保存保存一个新的Status行,但是实际上我只想保存Order和Status之间的关系。 我的状态表永远都不会改变。 如何防止在“状态”表中第二次插入?

例外:

"org.hibernate.TransientPropertyValueException: object references an unsaved transient instance - save the transient instance before flushing

“订单”表具有ID(PK),StatusId(FK) “状态”表具有ID(PK),说明

3 个答案:

答案 0 :(得分:2)

您可以指定要在级联注释中级联的操作,请参见cascade(),例如

@ManyToOne(fetch=..., cascade={CascadeType.DETACH,CascadeType.REFRESH})

请注意,我们指定哪些操作要级联,这意味着将其他操作级联。

答案 1 :(得分:0)

如果状态可以有多个订单,则应将关联控件移至状态类,并在其中具有带oneToMany批注的订单列表。另外,最好使用双向关联而不是单向。总结一下,适当的映射如下所示:

public class Order{

  @Id
  @GeneratedValue(strategy = GenerationType.AUTO)
  Long id;

  @ManyToOne(fetch = FetchType.LAZY)
  Status status;
}


public class Status{

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    Long id;

    String description;

    @OneToMany(fetch=FetchType.LAZY, cascade = CascadeType.ALL, mappedBy="status")
    List<Order> orders;
}

答案 2 :(得分:-2)

这是一个非常基本的概念。由于您使用@GeneratedValue,因此每次保存并创建新行时,它将生成新的ID。