我正在使用JPA 2 EclipseLink开发JSF应用程序。我需要使用我的列表的ListDataModel实现而不是正常的List实现。我想将此方法放在一个抽象的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;
}
我想在抽象类中实现上面的代码,而不是在整个应用程序中对其进行硬编码。非常感谢任何指导。提前谢谢!
答案 0 :(得分:1)
首先,您不应该在服务类中拥有任何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. How can I pass selected row to commandLink inside dataTable?