简体   繁体   中英

Method threw 'org.hibernate.PersistentObjectException' exception. detached entity passed to persist

I have two tables ( ie, Entities in Hibernate) which are related as:

@Entity
@Table(name = "table_one")
public class TableOne  {

    private int id;
    private String code;
    private String value;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id", unique = true, nullable = false)
    public Integer getId() {
        return this.id;
    }

    @Column(name= "code")
    public String getCode() {
        return this.code;
    }

    @Column(name= "value")
    public String getValue() {
        return this.value;
    }
    // setters ignored here
}

----------------------------------------------
@Entity
@Table(name = "table_two")
public class TableTwo {

    private Integer id;
    private TableOne tableOne;
    private String request;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id", unique = true, nullable = false)
    public Integer getId() {
        return id;
    }

    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "table_one_id", nullable = false)
    public TableOne getTableOne() {
        return tableOne;
    }

    @Column(name= "request")
    public String getRequest() {
        return this.request;
    }
    // setters ignored here
}

Now, from a method (or a class) which does not have @Transactional annotation, I call a Service class method to persist TableTwo object. This service method is annotated @Transactional .

// from a normal method with no annotations
service.insert(tableTwo);
----------------------------
public class MyService {

    @Autowired
    private MyDao dao;

    @Transactional
    public void insert(TableTwo tableTwo){
        dao.insert(tableTwo);
    }
}
------------------------------
public class MyDao {
    public void insert(TableTwo tableTwo){
      sessionFactory.getCurrentSession().persist(tableTwo.getTableOne());
      sessionFactory.getCurrentSession().persist(tabletwo);
    }
}

This gives me the following exception in debugging:

Method threw 'org.hibernate.PersistentObjectException' exception.
detached entity passed to persist: org.project.TableOne

What is wrong here ? I am converting the transient object of TableOne inside TableTwo to persisted state, and then persisting TableTwo object. How can I correct this ? Is it possible to do so through annotation, if possible ?

I don't want to be persisting TableOne object every time I persist TableTwo object. If possible, I just want to do :

tableTwo.setTableOne(new TableOne(id));
dao.persist(tableTwo);

Try to call saveOrUpdate instead of persist .
persist operation is intended for brand new transient objects and it fails if id is already assigned.

I see that you are getting the tableOne object from service class ie, TableOne tableOne = service.getTableOneById(id); .

So, I believe that tableOne record already exists in the database and subsequently there is no need to persist it again in your dao insert(...) method.

You can remove sessionFactory.getCurrentSession().persist(tableTwo.getTableOne()); as you are not making any changes to the tableOne object.

Or in case you have made any changes to the tableOne object that needs to be persisted, then consider using merge method ie, sessionFactory.getCurrentSession().merge(tableTwo.getTableOne()); instead.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM