使用带JPA的线程保存实体(同步)

时间:2015-02-13 10:29:06

标签: java multithreading jpa

我在JAVA中使用线程在同一个实体上执行一些操作。我执行persist方法时出现问题。我的方式是下一个:

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

其中nameObject是要保留的对象的名称。 给我看的错误是:

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)

我尝试对没有结果的对象进行锁定优化。

1 个答案:

答案 0 :(得分:1)

您将方法标记为Transactional,同时您在保存前开始事务处理,这导致两个会话打开将代码更改为,

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

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