java - 访问 JPA 实体中的父实体

标签 java jpa struts2

我使用 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

最佳答案

删除 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,它们提供了轻松处理实体管理器的解决方案。为每个查询打开一个新的实体管理器的方法并不是最佳的 - 理想情况下,每个事务或整个请求应该有一个实体管理器。阅读有关延迟初始化异常、OpenSessionInViewFilter 等的信息。

关于java - 访问 JPA 实体中的父实体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12361609/

相关文章:

java - 强制基类使用自己的方法而不是重写方法

java - 马文 3 : Is it possible to build a JDBC-3 driver with Java 6?

Java - JPA @Basic 和 @Embedded 注释

java - 将表单提交到 Struts 操作后,在 DisplayTag 上将页面设置为 1

java - 跟踪实例属性更改

java - Hibernate 两父一子映射

java - 使用 Spring 框架获取 'Named query not found'

java - 没有 setter getter 的 struts 2 Action

java - 我应该在哪里为 Struts2 中的参数提供 getter 和 setter?

Java双倍缩放