我正在使用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 ?