detached entity passed to persist
Asked Answered
P

1

7

used: hibernate 3.6.10, maven 2, postgres 9. I have code that must work but it doesn't. before I used hibernate 3.6.2 and got really frustrated error: java.lang.ClassCastException: org.hibernate.action.DelayedPostInsertIdentifier cannot be cast to java.lang.Long

But after updating to 3.6.10 error became more sensible: javax.persistence.PersistenceException: org.hibernate.PersistentObjectException: detached entity passed to persist

Code is a standart domain model:

Entity:

@Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL)
@Entity
@Table(schema = "simulators", name = "mySimulator_card")
public class MySimulatorCard {

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

    @Column(name = "account_number", unique = true, nullable = false)
    private String accountNumber;

etc...

DAO:

public abstract class AbstractDao<E, PK extends Serializable> implements Dao<E, PK> {

    private EntityManager entityManager;

    public EntityManager getEntityManager() {
        return entityManager;
    }

    @PersistenceContext(unitName = "MySimulator")
    public void setEntityManager(EntityManager entityManager) {
        this.entityManager = entityManager;
    }

    public abstract Class<E> getEntityClass();

    @Override
    public void persist(E e) {
        getEntityManager().persist(e);//<-- some thing wroooong
    }

etc...

And according table:

CREATE TABLE simulators.mySimulator_card
(
  id bigserial NOT NULL,
  account_number character varying(255) NOT NULL,

etc...

  CONSTRAINT mySimulator_card_pk PRIMARY KEY (id),
  CONSTRAINT mySimulator_card_account_fk FOREIGN KEY (account_id)
      REFERENCES simulators.mySimulator_account (id) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE NO ACTION,
  CONSTRAINT mySimulator_card_currency_fk FOREIGN KEY (currency_id)
      REFERENCES simulators.mySimulator_currency ("name") MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE NO ACTION,
  CONSTRAINT mySimulator_card_product_fk FOREIGN KEY (product_id)
      REFERENCES simulators.mySimulator_product (id) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE NO ACTION,
  CONSTRAINT mySimulator_account_account_number_uq UNIQUE (account_number),
  CONSTRAINT mySimulator_card_san_uq UNIQUE (san)
)
WITH (
  OIDS=FALSE
);
ALTER TABLE simulators.mySimulator_card OWNER TO functional;

I suppose something wrong with context in functional tests because production is work fine. Also when I tried to use this trick to get session from entityManager:

    EntityManager em = getEntityManager();
    HibernateEntityManager hem = em.unwrap(HibernateEntityManager.class);
    Session session = hem.getSession();
    session.persist(e);

I've got the error:

java.lang.IllegalStateException: No transactional EntityManager available

Now sure that it is a good idea to post all test config because there are a lot of workaround stuff. Any idea?

Proliferous answered 16/4, 2012 at 4:1 Comment(7)
You will normally only get that error if you are attempting to update detached objects. If your persist method needs to handle both creation and update then you will need to use the entity manager's merge function.Backbone
Can you clarify: are you saying that this code works correctly in production (deployed to a server) but fails when running integration tests (ie JUnit)?Floreneflorentia
yes it works on prodaction server (I was told so) but it doesn't work with functional tests (JUnit and testsng).Proliferous
I understand that my object is deatached, I tried to call merge first, but the error the same.Proliferous
I tried to get session manually and it was closed when I tried to call session.persist. Then I found such solution: org.hibernate.Session hSession = (Session) em.getDelegate(); org.hibernate.classic.Session session = hSession.getSessionFactory().openSession(); session.setFlushMode(FlushMode.MANUAL); ManagedSessionContext.bind(session); session.beginTransaction(); session.persist(e); session.getTransaction().commit(); session.close(); but the error again: detached entity passed to persistProliferous
I've changed <tx:annotation-driven mode="aspectj" proxy-target-class="true" transaction-manager="denariiTransactionManager"/> to <tx:annotation-driven transaction-manager="denariiTransactionManager"/> and now entities are saved in DB but only in table without data. For some reason hibernate forgets id and starts from 1.Proliferous
also I add such code if (getEntityManager().isOpen()) { System.out.println("ITSOPEN_PERSIST"); } else { System.out.println("SUCK_NOTOPEN_PERSIST"); } if (getEntityManager().contains(e)) { System.out.println("ITSCONTAINSENTITYIN_PERSIST"); } else { System.out.println("SUCK_NOTCONTAIN_PERSIST"); } and my EntityManager is always opened but always doesn't contatin entity. Maybe it will helpProliferous
A
21

This error is raised among others when you try to persist a value in a column that is autogenerated.

Check if you're passing a value to persist for the column id, which you've marked as:

@GeneratedValue(strategy = GenerationType.IDENTITY)

Regards.

Abominate answered 19/3, 2014 at 14:25 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.