1

我正在使用:Hibernate 3.6.8 和 mySQL、Tomcat 6、JDBC 连接池

我遇到了 Hibernate 打开大量连接的问题,这最终导致我的 Web 应用程序无法获得新连接。起初我以为问题是我在没有连接池的情况下运行,所以我连接了 Tomcat JDBC 池。

这使问题变得更糟。它没有在几次查询后失败,而是立即失败。原来这是因为 Hibernate 试图打开比我的池大小(30)更多的连接。我检查了一下,在我创建 EntityManager 的任何地方,如果有尝试,我都会在 finally 子句中调用 close(),所以我不确定它们为什么保持打开状态。

查看 close() 的源代码,我发现如果有一个事务打开,它实际上并没有关闭,所以我尝试在实体管理器上调用 getTransaction().commit(),即使它只是一个选择语句。这没有效果。然后我发现了这个配置标志,并将其打开:
<property name="hibernate.ejb.discard_pc_on_close" value="true" />

这有所不同,当我尝试渲染对象以进行输出时出现异常:未能延迟初始化角色集合:XXX.Comment.attachments,没有会话或会话已关闭

问题似乎是我进行了许多查询来创建评论集合,并且所有这些查询都保持连接打开。Comment 类包含以下内容:

@OneToMany
@JoinTable(name = "Object", joinColumns = { @JoinColumn(name = "parentId") }, inverseJoinColumns = { @JoinColumn(name = "id") })
public List<Attachment> getAttachments()
{
    if (attachments == null)
    {
        attachments = new ArrayList<Attachment>();
    }
    return attachments;
}

我会提到这里有一些继承。
Attachment是KObject(db中的表名Object)的子类,KObject包含了用来映射回Comment的parentId(也是KObject的子类)。

为澄清起见,这是我给实体经理的电话:

public <T> T findById(Class<T> objClass, String id)
{
    EntityManager em = theEMF.createEntityManager();
    em.getTransaction().begin();
    try {
        T obj = em.find(objClass, id);
        return obj;
    } catch(NoResultException e) {
        return null;
    } finally {
        em.getTransaction().commit();
        em.clear();
        em.close();
    }   
}

theEMF 是一个在首次使用时初始化的静态成员变量。

我认为解决方案是@OneToMany(fetch=FetchType.EAGER),但这没有效果。我究竟做错了什么?

4

0 回答 0