6

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?

BenMorel
  • 34,448
  • 50
  • 182
  • 322
Dmitrii Borovoi
  • 2,814
  • 9
  • 32
  • 50
  • 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. – Perception Apr 16 '12 at 04:26
  • 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)? – gutch Apr 16 '12 at 04:39
  • yes it works on prodaction server (I was told so) but it doesn't work with functional tests (JUnit and testsng). – Dmitrii Borovoi Apr 16 '12 at 05:28
  • I understand that my object is deatached, I tried to call merge first, but the error the same. – Dmitrii Borovoi Apr 16 '12 at 05:29
  • 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 persist – Dmitrii Borovoi Apr 16 '12 at 05:33
  • I've changed to and now entities are saved in DB but only in table without data. For some reason hibernate forgets id and starts from 1. – Dmitrii Borovoi Apr 17 '12 at 06:45
  • 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 help – Dmitrii Borovoi Apr 17 '12 at 06:47

1 Answers1

20

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.

periket2000
  • 543
  • 7
  • 13