javaboygo
javaboygo

Reputation: 244

Save entity using threads with JPA (synchronized)

I am using threads in JAVA to do a few of operations over the same entity. The problem appears when I do the persist method. The way that I do is the next:

@Transactional
    private void persist(){
        synchronized(this){
            JPA.em().getTransaction().begin();
            <nameObject>.save();
            JPA.em().getTransaction().commit();
        }
    }

where nameObject is the name of the object to persist. The error that show me is:

Exception in thread "Thread-38" javax.persistence.PersistenceException: org.hibernate.HibernateException: Illegal attempt to associate a collection with two open sessions
    at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1389)
    at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1317)
    at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1323)
    at org.hibernate.ejb.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:845)
    at play.db.jpa.JPABase._save(JPABase.java:31)
    at play.db.jpa.GenericModel.save(GenericModel.java:204)
    at models.invoicing.PreInvoiceThread.persist(PreInvoiceThread.java:290)
    at models.invoicing.PreInvoiceThread.run(PreInvoiceThread.java:273)
    at java.lang.Thread.run(Thread.java:745)

I have try make a lockoptimistic over the Object without results.

Upvotes: 1

Views: 2480

Answers (1)

Adisesha
Adisesha

Reputation: 5258

You marked the method as Transactional and at the same time you are beginning transaction before save, which is causing two sessions to open Change the code to,

@Transactional
private void persist(){
    synchronized(this){
        <nameObject>.save();
    }
}

or

private void persist(){
    synchronized(this){
        JPA.em().getTransaction().begin();
        <nameObject>.save();
        JPA.em().getTransaction().commit();
    }
}

Upvotes: 1

Related Questions