2

我正在使用 JPA 1、Struts2.3.1、Google-App-Enging 1.7.0

在我的漫画中,我有以下带有 getter 和 setter 的属性:

@ManyToOne(fetch=FetchType.LAZY, targetEntity=User.class)
private User user = null;

我的 JPA 查询方法:

public Comics readComics(int random, String url){
    EntityManager em = EMF.get().createEntityManager();
    Comics comics = null;

    try{
        Query q = em.createNamedQuery("Comics.getComics");
        q.setParameter("random", random);
        q.setParameter("url", url);
        comics = (Comics) q.getSingleResult();

    } catch(NoResultException ex){
        System.out.println("ERROR CATCHED: " + ex.getMessage());
        comics = null;
    } finally{
        em.close();
    }

    return comics;
}

在我看来,我有:

<s:property value="comics.user.userName"/>

userName在这种情况下无法访问,但是当实体管理器未关闭时userName会显示。

什么是正确的?可以去掉em.close()吗?

========================

使用BeanUtils.copyProperties 我还尝试了以下代码:

Comics emComics = (Comics) q.getSingleResult();
BeanUtils.copyProperties(comics, emComics);
BeanUtils.copyProperties(comics.getUser(), emComics.getUser());

是正确的使用方法copyProperties吗?删除BeanUtils.copyProperties(comics.getUser(), emComics.getUser());将再次不显示user

4

1 回答 1

2

删除 em.close() 是不行的 - 如果你这样做,你最终会出现连接泄漏。池中的所有连接都用完后,应用程序将停止工作。

简单的修复是确保在调用 em.close() 之前初始化 jsp 所需的一切。

如果您使用 hibernate 作为提供程序,那么您可以使用 Hibernate.initialize()

public Comics readComics(int random, String url){
    EntityManager em = EMF.get().createEntityManager();
    Comics comics = null;
   try{
        Query q = em.createNamedQuery("Comics.getComics");
        q.setParameter("random", random);
        q.setParameter("url", url);
        comics = (Comics) q.getSingleResult();

        Hibernate.initialize(comics.getUser());

    } catch(NoResultException ex){
        System.out.println("ERROR CATCHED: " + ex.getMessage());
        comics = null;
    } finally{
        em.close();
    }

    return comics;
}

如果您使用的是其他提供程序,您可以寻找等效方法或编写自己的函数,该函数仅获取对象的一个​​属性以触发代理的初始化。

另一种选择是在获取漫画时使用连接获取来修改查询以获取用户关联。

正确的解决方案是使用 Spring 或 EJB,它们提供了轻松处理实体管理器的解决方案。您为每个查询打开一个新 entityManager 的方法不是最佳的 - 理想情况下,它应该是每个事务或整个请求的一个 entityManager。阅读有关延迟初始化异常、OpenSessionInViewFilter 等的信息。

于 2012-09-11T02:11:59.590 回答