【问题标题】:Hibernate/Spring: Illegal attempt to associate a collection with two open sessions in unit testHibernate/Spring:非法尝试将集合与单元测试中的两个打开会话相关联
【发布时间】:2012-04-15 16:13:19
【问题描述】:

我在单元测试中看到上述错误,不知道如何纠正它。

我的单元测试类扩展了 AbstractTransactionalDataSourceSpringContextTests 并执行以下操作:

// Retrieve a RuleGroup
RuleGroup ruleGroupToUpdate = ruleGroupDao.findRuleGroup(a, b, c, d);
// Update an encapsulated Attribute
// Save the RuleGroup
ruleGroupDao.updateRuleGroup(ruleGroupToUpdate);

以下是我的 RuleGroup 映射文件的 sn-p。可以看到,一个 RuleGroup 封装了 Rule 和 Attribute 集合,默认都是惰性加载的:

<class name="a.b.c.d.RuleGroup" table="RULE_GROUP">
    <id name="ruleGroupID" column="RULE_GRP_ID">
        <generator class="increment"/>
    </id>
    <set name="rules" lazy="true" cascade="save-update" table=RULES">
        <key column="RULE_GRP_ID" not-null="false"/>
        <many-to-many unique="true" column="RULE_ID" class="a.b.c.d.Rule"/>
    </set>
    <set name="attributes" lazy="true" cascade="save-update" table="ATTRIBUTES">
        <key property-ref="xrefID" column="XREF_ID" not-null="true"/>
        <many-to-many unique="true" column="CONFIG_ATTR_ID" class="a.b.c.d.Attribute"/>             
    </set>
</class>

我的 DAO 类扩展了 HibernateDaoSupport:

  • findRuleGroup 方法使用 getSession().createCriteria() 来执行查询。使用“join”提取来检索规则和属性
  • updateRuleGroup 方法使用 getHibernateTemplate().update() 来执行更新

    通过调试我的测试,在 findRuleGroup 方法中创建了一个新 Session,然后在 updateRuleGroup 方法中再次创建。因此,当执行更新时,Hibernate 会看到我的 Attribute 集合已经与 findRuleGroup 会话相关联并抛出异常。

    我该如何解决这个问题?据推测,更新不应打开新会话。如果我指定 HibernateTemplate 不应该创建新会话,那么我会得到一个不同的异常,说没有与线程关联的会话。我在这里不知所措!

  • 【问题讨论】:

      标签: spring hibernate


      【解决方案1】:

      我认为您根本没有交易。 getHibernateTemplate() 可以打开一个新会话。在此处查看源代码:bit.ly/HsgDrR。一种常见的做法是使用 spring 的 @Transactional 注释将方法包装在事务中的 dao 中。如果你不这样做,调用 getSession() 以外的任何东西都可能导致在你的事务之外打开新会话并泄漏。

      希望对您有所帮助。

      【讨论】:

      • 感谢您的回复。如果我不想在 DAO 级别指定 @Transactional 我还有哪些其他选项?如果我在没有 HibernteTemplate 的情况下使用 Hibernate,这会避免创建新会话吗?
      • 只是为了指定我的修复。我删除了 AbstractTransactionalDataSourceSpringContextTests 并改用 Spring 3 单元测试支持,我在每个单元测试中指定了 @Transactional 注释。因此,这在我的单元测试中提供了事务支持,并且不再发生错误。谢谢!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-09-18
      • 1970-01-01
      • 2011-03-06
      • 2015-03-23
      • 1970-01-01
      • 2011-05-14
      相关资源
      最近更新 更多