JPA: detached entity passed to persist: nested exception is org.hibernate.PersistentObjectException

后端 未结 2 1790
心在旅途
心在旅途 2021-01-07 03:38

JPA: many-to-many connection.

Scenerio:

Multiple product can be saved under multiple categories. Like: Mango can be used as Frui

2条回答
  •  走了就别回头了
    2021-01-07 04:04

    At last, I got my solution for Many-to-Many connection in JPA.

    Root Cause Analysis:

    In a JPA many-to-many relationship, if cascade type has been set at CascadeType.PERSIST (or CascadeType.ALL, which includes CascadeType.PERSIST), then while saving the parent and updating it with references of the child, it will try to save the child again.

    Following Issues can appear:

    Child is already in persistence store (A detached instance has been passed) -in this case it will throw an exception “org.hibernate.PersistentObjectException: detached entity passed to persist”

    Solution:

    Use this:

    @ManyToMany(fetch = FetchType.EAGER,
            cascade = {
                    CascadeType.MERGE,
                    CascadeType.REFRESH
                })
    @JoinTable(name = "commodity_genre", joinColumns = {
            @JoinColumn(name = "commodity_id", referencedColumnName = "id") }, inverseJoinColumns = {
                    @JoinColumn(name = "genre_id", referencedColumnName = "id") })
    @JsonManagedReference
    private List genres;
    

    Instead of:

    @ManyToMany(fetch = FetchType.LAZY,
            cascade = {
                    CascadeType.MERGE,
                    CascadeType.PERSIST
                })
    @JoinTable(name = "commodity_genre", joinColumns = {
            @JoinColumn(name = "commodity_id", referencedColumnName = "id") }, inverseJoinColumns = {
                    @JoinColumn(name = "genre_id", referencedColumnName = "id") })
    @JsonManagedReference
    private List genres;
    

    For JPA, the best option would be to query for entity on the server side before trying to save it.

    • If its sure that only new child will be added, and not a detached instance from DB, CascadeType.PERSIST will take care of it.
    • On the other hand, if the requirement is never to add a new child if it's not already in DB then CascadeType.PERSIST should be removed and cascade={CascadeType.MERGE,CascadeType.REFRESH} should be used

    Resource Link:

    Persisting a detached entity in JPA

提交回复
热议问题