JPA延迟加载JSF视图中的集合 - 比使用过滤器更好的方法?

Jas*_*onI 1 java-ee-6 jsf-2 jpa-2.0

目前我正在使用事务视图模式在视图中对集合进行延迟加载.

我在web.xml中有以下内容

<filter>
  <filter-name>view</filter-name>
  <filter-class>com.jasoni.ViewFilter</filter-class>
</filter>
<filter-mapping>
  <filter-name>view</filter-name>
  <url-pattern>*.xhtml</url-pattern>
</filter-mapping>
Run Code Online (Sandbox Code Playgroud)

Filter类有以下内容......

public class ViewFilter implements Filter {
  @Resource UserTransaction tx;

  public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
    try {
      tx.begin();
      chain.doFilter(request, response);
    }
    //catch here
    finally {
      //another try-catch
      tx.commit();
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

假设我有以下(相当做作的)支持bean

@ManagedBean
@RequestScoped
public class DepartmentEmployees {
  @EJB
  private DepartmentServiceBean deptService;
  @ManagedProperty(value="#{param.deptId}")
  private Integer deptId;
  private Department dept;

  @PostConstruct
  public String init() {
    dept = deptService.findById(deptId);
  }
}
Run Code Online (Sandbox Code Playgroud)

我可以在我的视图中执行类似的操作(.xhtml文件)

<ul>
<c:forEach var="emp" items="#{departmentEmployees.dept.employees}">
  <li>#{emp.firstName} #{emp.lastName}</li>
</c:forEach>
</ul>
Run Code Online (Sandbox Code Playgroud)

只是想知道是否有人知道在不使用过滤器(或servlet)的情况下完成同样的事情的不同方法.

jan*_*oth 5

这种方法("视野开放会议")有几个主要缺点.除了是一种hacky(当然不是用于控制业务会话的servlet过滤器的设计理念),你没有很多选项来适当地处理渲染JSF页面时发生的任何"真实"异常.

您没有写太多关于您的基础架构/技术堆栈,但我认为您在Java EE 6服务器上.

我通常使用EntityManger扩展模式,并使用我只通过注释我的业务外观的某些方法来显式控制的事务来刷新它.看一下这个例子(取自Adam Bien - 真实世界Java EE模式,重新思考最佳实践):

@Stateful
@TransactionAttribute(TransactionAttributeType.NEVER)
public class BookFacadeBean implements BookFacade {
    @PersistenceContext(type=PersistenceContextType.EXTENDED)
    private EntityManager em;
    private Book currentBook;

    public Book find(long id){
        this.currentBook = this.em.find(Book.class, id);
        return this.currentBook;
    }
    public void create(Book book){
        this.em.persist(book);
        this.currentBook = book;
    }
    public Book getCurrentBook() {
        return currentBook;
    }
    @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
    public void save(){
        //nothing to do here
    }
}
Run Code Online (Sandbox Code Playgroud)

此方法的下一个级别是将EntityManager绑定到CDI会话范围.看看(a)Weld(b)Seam 3坚持进一步讨论该主题.

这是一个替代的粗略草图,而不是详细的操作方法.我希望这个级别的信息是您所要求的 - 随意提出进一步的问题.:-)