PersistentObjectException: detached entity passed to persist thrown by JPA and Hibernate

前端 未结 18 2348
醉酒成梦
醉酒成梦 2020-11-22 05:10

I have a JPA-persisted object model that contains a many-to-one relationship: an Account has many Transactions. A Transaction has one

相关标签:
18条回答
  • 2020-11-22 05:47

    Resolved by saving dependent object before the next.

    This was happened to me because I was not setting Id (which was not auto generated). and trying to save with relation @ManytoOne

    0 讨论(0)
  • 2020-11-22 05:48

    If nothing helps and you are still getting this exception, review your equals() methods - and don't include child collection in it. Especially if you have deep structure of embedded collections (e.g. A contains Bs, B contains Cs, etc.).

    In example of Account -> Transactions:

      public class Account {
    
        private Long id;
        private String accountName;
        private Set<Transaction> transactions;
    
        @Override
        public boolean equals(Object obj) {
          if (this == obj)
            return true;
          if (obj == null)
            return false;
          if (!(obj instanceof Account))
            return false;
          Account other = (Account) obj;
          return Objects.equals(this.id, other.id)
              && Objects.equals(this.accountName, other.accountName)
              && Objects.equals(this.transactions, other.transactions); // <--- REMOVE THIS!
        }
      }
    

    In above example remove transactions from equals() checks. This is because hibernate will imply that you are not trying to update old object, but you pass a new object to persist, whenever you change element on the child collection.
    Of course this solutions will not fit all applications and you should carefully design what you want to include in the equals and hashCode methods.

    0 讨论(0)
  • 2020-11-22 05:49

    If above solutions not work just one time comment the getter and setter methods of entity class and do not set the value of id.(Primary key) Then this will work.

    0 讨论(0)
  • 2020-11-22 05:50

    This is a typical bidirectional consistency problem. It is well discussed in this link as well as this link.

    As per the articles in the previous 2 links you need to fix your setters in both sides of the bidirectional relationship. An example setter for the One side is in this link.

    An example setter for the Many side is in this link.

    After you correct your setters you want to declare the Entity access type to be "Property". Best practice to declare "Property" access type is to move ALL the annotations from the member properties to the corresponding getters. A big word of caution is not to mix "Field" and "Property" access types within the entity class otherwise the behavior is undefined by the JSR-317 specifications.

    0 讨论(0)
  • 2020-11-22 05:50

    Probably in this case you obtained your account object using the merge logic, and persist is used to persist new objects and it will complain if the hierarchy is having an already persisted object. You should use saveOrUpdate in such cases, instead of persist.

    0 讨论(0)
  • My Spring Data JPA-based answer: I simply added a @Transactional annotation to my outer method.

    Why it works

    The child entity was immediately becoming detached because there was no active Hibernate Session context. Providing a Spring (Data JPA) transaction ensures a Hibernate Session is present.

    Reference:

    https://vladmihalcea.com/a-beginners-guide-to-jpa-hibernate-entity-state-transitions/

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