如何在抽象JPA标准查询中使用JSF ListDataModel对象



我正在使用JPA 2 EclipseLink开发JSF应用程序。我需要使用列表的ListDataModel实现,而不是普通的列表实现。我想把这个方法放在一个抽象的facade类中,这样它就可以在整个应用程序中使用。对于普通的List实现,抽象类

public List<T> findAll() {
    javax.persistence.criteria.CriteriaQuery cq = getEntityManager().getCriteriaBuilder().createQuery();
    cq.select(cq.from(entityClass));
    return getEntityManager().createQuery(cq).getResultList();
}

抽象类的实现是:

@Stateless
public class ExportFacade extends AbstractFacade<Export> {
    @PersistenceContext(unitName = "GazpromModulePU")
    private EntityManager em;
    @Override
    protected EntityManager getEntityManager() {
        return em;
    }
    public ExportFacade() {
        super(Export.class);
    }

上述方法的结果被正确显示,一切工作正常。现在我想做完全相同的事情,但在ListDataModel中返回结果。我试着:

public ListDataModel<T> findAllListDataModel() {
    javax.persistence.criteria.CriteriaQuery cq = getEntityManager().getCriteriaBuilder().createQuery();
    cq.select(cq.from(entityClass));
    return new ListDataModel<T>(getEntityManager().createQuery(cq).getResultList());
}

使用相同的实现(以及上面的抽象方法),不显示列表,错误控制台为空白。我可以使用如下方法手动硬编码ListDataModel:

public ListDataModel<Export> hardCodedMethod() {
    if(someList == null) {
         someList = makeModel();
    }
    return someList;
}
public ListDataModel<Export> makeModel() {
    List<Export> elist = myFacade.findAll();
    ListDataModel<Export> model = new ListDataMOdel<Export>(eList);
    return model;
}
我想在一个抽象类中实现上面的代码,而不是在整个应用程序中硬编码。我希望得到任何指导。提前感谢!

首先,您不应该在服务类中有任何JSF构件。这使您的业务层与当前的web层紧密结合。换句话说,您的业务层不能跨不同的web层重用,例如RESTful、Websockets、普通JSP/Servlet等。

不要改变你的服务类。继续返回List。确保您在任何服务等级中没有任何import javax.faces.***线。而是在JSF端解决您的问题。例如,创建一个抽象的支持bean。

public abstract class ListDataModelBacking<T> {
    private transient ListDataModel<T> model;
    public abstract List<T> getListFromService();
    public ListDataModel<T> getModel() {
        if (model == null) {
            model = new ListDataModel<>(getListFromService());
        }
        return model;
    }
}

注意DataModel的实现应该是不可序列化的。

那么你可以像下面这样在一个常规的后台bean中使用它:

@Named
@ViewScoped
public class FooBacking extends ListDataModelBacking<Foo> implements Serializable {
    @Inject
    private FooService fooService;
    @Override
    public List<Foo> getListFromService() {
        return fooService.listAll();
    }
}
<h:dataTable value="#{fooBacking.model}" ...>

或者,敲击ListDataModel并寻找一个更简单的解决方案来解决您试图在bean中使用ListDataModel属性来解决的具体功能需求。也许是EL 2.2传递方法参数的能力?参见a.o.我如何将选定的行传递给dataTable中的commandLink ?

相关内容

  • 没有找到相关文章

最新更新