java - Spring -> org.hibernate.HibernateException : Illegal attempt to associate a collection with two open sessions

标签 java spring hibernate spring-mvc

在我当前的 spring 项目中,当我的应用程序尝试执行此方法时:

  public void setPedido(Cliente current) {
    Pedido novo = new Pedido();
    novo.setData(new Date());
    novo.setListaDeProdutos(current.getCestaDeCompras());
    pedido.insert(novo);

    if(current.getListaDePedidos() == null)
      current.setListaDePedidos(new ArrayList<Pedido>());

    current.getListaDePedidos().add(novo);
    current.getCestaDeCompras().clear();
    cliente.update(current);
  }

我收到此错误:

Caused by: org.hibernate.HibernateException: Illegal attempt to associate a collection with two open sessions
        at org.hibernate.collection.internal.AbstractPersistentCollection.setCurrentSession(AbstractPersistentCollection.java:633)
        at org.hibernate.event.internal.WrapVisitor.processCollection(WrapVisitor.java:66)
        at org.hibernate.event.internal.AbstractVisitor.processValue(AbstractVisitor.java:121)
        at org.hibernate.event.internal.WrapVisitor.processValue(WrapVisitor.java:125)
        at org.hibernate.event.internal.AbstractVisitor.processEntityPropertyValues(AbstractVisitor.java:76)
        at org.hibernate.event.internal.AbstractSaveEventListener.visitCollectionsBeforeSave(AbstractSaveEventListener.java:372)
        at org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:273)
        at org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:194)
        at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:125)
        at org.hibernate.jpa.event.internal.core.JpaPersistEventListener.saveWithGeneratedId(JpaPersistEventListener.java:84)
        at org.hibernate.event.internal.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:206)
        at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:149)
        at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:75)
        at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:811)
        at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:784)
        at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:789)
        at org.hibernate.jpa.spi.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:1181)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:606)
        at org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerInvocationHandler.invoke(ExtendedEntityManagerCreator.java:344)
        at com.sun.proxy.$Proxy79.persist(Unknown Source)
        at org.store.generic.persistence.Dao.insert(Dao.java:29)
        at org.store.generic.persistence.Dao$$FastClassBySpringCGLIB$$ac46d9f5.invoke(<generated>)
        at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
        at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:717)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
        at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136)

我的 Dao 类(放置方法插入的地方)是这样的:

public class Dao<E> {

    @Autowired
    private EntityManagerFactory factory;

    protected Class<? extends Model> clazz;

    public Dao(Class<? extends Model> clazz) {
        this.clazz = clazz;
    }

    public EntityManager getEntityManager() {
        return factory.createEntityManager();
    }

    public void insert(E object) {
        EntityManager entityManager = getEntityManager();
        entityManager.getTransaction().begin();
        entityManager.persist(object);
        entityManager.getTransaction().commit();
    }

    ...
}

我也尝试在Dao类的insert、update、delete方法中,以及在service类中使用它们的方法中添加注释@Transaction,但出现了同样的问题。

任何人都可以看到我在这里做错了什么?

ps.:我试图保存的实体类是:

@Entity
public class Pedido extends Model {
  @Id
  @GeneratedValue(strategy=GenerationType.IDENTITY)
  @Order(value = 1)
  private Integer id;

  @Order(value = 2)
  private Date data;

  @ManyToMany
  @JoinTable(name="listaDeProdutos", joinColumns={@JoinColumn(name="fk_pedido")}, inverseJoinColumns={@JoinColumn(name="fk_produto")})
  @LazyCollection(LazyCollectionOption.FALSE)
  @Order(value = 3)
  private List<Produto> listaDeProdutos;
}

最佳答案

好吧,事实上,产生此错误的问题是由于 Dao 类的方法中缺少 close() 指令。我将代码修改为:

public void insert(E object) {
    EntityManager entityManager = getEntityManager();
    entityManager.getTransaction().begin();
    entityManager.persist(object);
    entityManager.getTransaction().commit();
    entityManager.close();
}

现在一切正常。

关于java - Spring -> org.hibernate.HibernateException : Illegal attempt to associate a collection with two open sessions,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27589111/

相关文章:

java - MyBatis 中选择时处理空值

java - 返回的接口(interface)对象如何声明其方法

java - 有没有办法标准化进入 Spring 应用程序的所有请求有效负载中的所有字符串?

spring - 使用 Spring @Procedure 调用 StoredProcedure 而不绑定(bind)到表

java - 以编程方式加载 Spring 3.1 中的属性

java - Hibernate 和 MySQL 的创建时间戳和上次更新时间戳

java - 内部类中的非最终变量

java - 根据主体tomcat重定向请求

java - 如何安全地强制提交 Spring - hibernate 事务

java - 使用复合备用键映射多对一关系