域表出现错误“对象引用了未保存的瞬态实例-在刷新之前保存瞬态实例”

时间:2019-06-17 19:25:07

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

当我开始使用JPA时,我已经看到错误“ org.hibernate.TransientPropertyValueException:对象引用了一个未保存的临时实例-在刷新之前保存该临时实例”。我知道一般可以通过添加cascade = CascadeType.ALL来解决此错误,但是在这种情况下,此错误已出现在域表中,这意味着在这种情况下,将CascadeType放置没有任何意义,因为该实体已经具有数据库中的ID。

我的代码的相关部分是(还有其他字段,getter,setter等):

Rac类:

@Entity
@Table(name = "RAC", schema = "SchRAC")
public class Rac {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "RacCod")
private Long idRac;

//anoter fields (...)

@OneToMany(fetch = FetchType.LAZY, mappedBy = "rac", cascade = {CascadeType.ALL})
@JsonManagedReference 
private List<RacProvidencia> racProvidencias;

RacProvidencia类:

@Entity
@Table(name = "RACPRO", schema = "SchRAC")
public class RacProvidencia implements Serializable {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    @Column(name = "RacProCod")
    private Long idRacProvidencia;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "RacCod")
    @JsonBackReference //coloquei para evitar a recursao infinita de JSON
    private Rac rac;

    @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.REFRESH)
    @JoinColumn(name = "ProCod")
    private Providencia providencia;

    @NotNull
    @Column(name = "RacProNum", length = 100)
    private String numero;

    @Column(name = "RacProDat")
    private Date dataProvidencia;

Providencecia类(域表):

@Entity
@Table(name = "PRO", schema = "SchRAC")
public class Providencia {

    @Id
    @Column(name = "ProCod")
    private Integer idProvidencia;

    @Column(name = "ProDes", length = 50)
    private String descricao;

服务:

public RacProvidencia adicionarProvidenciaRac(Long codigo, @Valid RacProvidencia racProvidencia) {
    Rac rac = this.racRepository.findById(codigo).get();
    racProvidencia.setRac(rac);
    return racProvidenciaRepository.save(racProvidencia);
}

如您所见,对象“ Rac”已经保存,然后用户添加“ Providencias”(如果愿意)。然后,我收到对象“ Providencia”,按ID搜索对象Rac,设置对象并保存。

此错误最奇怪的部分是因为5分钟后,系统不再显示此错误。可能会发生什么?将来如何避免这个问题?

1 个答案:

答案 0 :(得分:1)

您具有双向关系,但只设置了关系的一侧。

public RacProvidencia adicionarProvidenciaRac(Long codigo, @Valid RacProvidencia racProvidencia) {
    Rac rac = this.racRepository.findById(codigo).get();
    racProvidencia.setRac(rac);

    rac.getRacProvidencias().add(racProvidencia);  // <-- This

    return racProvidenciaRepository.save(racProvidencia);
}

您的持久性提供者双方都需要。