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

后端 未结 2 1791
心在旅途
心在旅途 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<Genre> 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<Genre> 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

    0 讨论(0)
  • 2021-01-07 04:14

    For me the issue was using Cascade.ALL instead of Cascade.MERGE.

    0 讨论(0)
提交回复
热议问题