我正在使用 Netbeans 使用 JPA 开发 JSF 应用程序。我创建实体类,然后通过 Netbeans 从实体类生成 JSF 页面。它创建一个 AbstractFacade、为每个实体扩展抽象外观的外观、每个实体的控制器 bean 和一个 JSF 页面。然后我改变并使用这些生成的代码来创建我的逻辑。
当我在单个 JSF 页面中使用两个控制器 bean 时,会间歇性地出现 ClassCastException 。但是当我重新启动 GLassFish 服务器时,异常消失了一段时间并再次出现,我无法找出是什么引发了更改。例如,考虑有一个名为 Atm 的实体的情况。它有一个属性 MedicineGroup,它也是另一个实体。当要通过 JSF 页面保存来自 Atm 实体的对象时,我让所有 MedicineGroups 调用 MedicineGroupController 并将其分配给 Atm 对象的选定 GenericName 属性。在发生 ClassCastException 之前,此逻辑运行良好。
(大多数JSF页面都使用上述相同的方法。Atm实体具有Vtm的属性。Ampp具有Atm atm,MeasurmentUnitstrengthUnit,Doublestrength,Double rol等peoperties。)
我也可以通过更改逻辑来完成相同的事情,这样每个 JSF 页面只有一个控制器,但是如果可以在同一个 JSF 页面中引用多个控制器 bean,那就很容易了。
这里有什么问题?
我在下面列出了一些重要的代码。
JSF 页面的相关部分。
<h:selectOneListbox id="txtGroup" value="#{vtmController.current.medicineGroup}" size="5" >
<f:selectItems value="#{medicineGroupController.items}" var="gp" itemValue="#{gp}" itemLabel="#{gp.name}"/>
</h:selectOneListbox>
实体类的示例
@Entity
@Inheritance
public class Vtm extends PharmaceuticalItem implements Serializable {
@ManyToOne
MedicineGroup medicineGroup;
public MedicineGroup getMedicineGroup() {
return medicineGroup;
}
public void setMedicineGroup(MedicineGroup medicineGroup) {
this.medicineGroup = medicineGroup;
}
}
控制器类示例,其中包括一个自动生成的转换器。
@ManagedBean
@SessionScoped
public final class VtmController {
@EJB
private VtmFacade ejbFacade;
SessionController sessionController = new SessionController();
List<Vtm> lstItems;
private Vtm current;
private DataModel<Vtm> items = null;
private int selectedItemIndex;
boolean selectControlDisable = false;
boolean modifyControlDisable = true;
String selectText = "";
public VtmController() {
}
public List<Vtm> getLstItems() {
return getFacade().findBySQL("Select d From Vtm d");
}
public void setLstItems(List<Vtm> lstItems) {
this.lstItems = lstItems;
}
public int getSelectedItemIndex() {
return selectedItemIndex;
}
public void setSelectedItemIndex(int selectedItemIndex) {
this.selectedItemIndex = selectedItemIndex;
}
public Vtm getCurrent() {
if (current == null) {
current = new Vtm();
}
return current;
}
public void setCurrent(Vtm current) {
this.current = current;
}
private VtmFacade getFacade() {
return ejbFacade;
}
public DataModel<Vtm> getItems() {
items = new ListDataModel(getFacade().findAll("name", true));
return items;
}
public static int intValue(long value) {
int valueInt = (int) value;
if (valueInt != value) {
throw new IllegalArgumentException(
"The long value " + value + " is not within range of the int type");
}
return valueInt;
}
public DataModel searchItems() {
recreateModel();
if (items == null) {
if (selectText.equals("")) {
items = new ListDataModel(getFacade().findAll("name", true));
} else {
items = new ListDataModel(getFacade().findAll("name", "%" + selectText + "%",
true));
if (items.getRowCount() > 0) {
items.setRowIndex(0);
current = (Vtm) items.getRowData();
Long temLong = current.getId();
selectedItemIndex = intValue(temLong);
} else {
current = null;
selectedItemIndex = -1;
}
}
}
return items;
}
public Vtm searchItem(String itemName, boolean createNewIfNotPresent) {
Vtm searchedItem = null;
items = new ListDataModel(getFacade().findAll("name", itemName, true));
if (items.getRowCount() > 0) {
items.setRowIndex(0);
searchedItem = (Vtm) items.getRowData();
} else if (createNewIfNotPresent) {
searchedItem = new Vtm();
searchedItem.setName(itemName);
searchedItem.setCreatedAt(Calendar.getInstance().getTime());
searchedItem.setCreater(sessionController.loggedUser);
getFacade().create(searchedItem);
}
return searchedItem;
}
private void recreateModel() {
items = null;
}
public void prepareSelect() {
this.prepareModifyControlDisable();
}
public void prepareEdit() {
if (current != null) {
selectedItemIndex = intValue(current.getId());
this.prepareSelectControlDisable();
} else {
JsfUtil.addErrorMessage(new MessageProvider().getValue("nothingToEdit"));
}
}
public void prepareAdd() {
selectedItemIndex = -1;
current = new Vtm();
this.prepareSelectControlDisable();
}
public void saveSelected() {
if (selectedItemIndex > 0) {
getFacade().edit(current);
JsfUtil.addSuccessMessage(new MessageProvider().getValue("savedOldSuccessfully"));
} else {
current.setCreatedAt(Calendar.getInstance().getTime());
current.setCreater(sessionController.loggedUser);
getFacade().create(current);
JsfUtil.addSuccessMessage(new MessageProvider().getValue("savedNewSuccessfully"));
}
this.prepareSelect();
recreateModel();
getItems();
selectText = "";
selectedItemIndex = intValue(current.getId());
}
public void addDirectly() {
JsfUtil.addSuccessMessage("1");
try {
current.setCreatedAt(Calendar.getInstance().getTime());
current.setCreater(sessionController.loggedUser);
getFacade().create(current);
JsfUtil.addSuccessMessage(new MessageProvider().getValue("savedNewSuccessfully"));
current = new Vtm();
} catch (Exception e) {
JsfUtil.addErrorMessage(e, "Error");
}
}
public void cancelSelect() {
this.prepareSelect();
}
public void delete() {
if (current != null) {
current.setRetired(true);
current.setRetiredAt(Calendar.getInstance().getTime());
current.setRetirer(sessionController.loggedUser);
getFacade().edit(current);
JsfUtil.addSuccessMessage(new MessageProvider().getValue("deleteSuccessful"));
} else {
JsfUtil.addErrorMessage(new MessageProvider().getValue("nothingToDelete"));
}
recreateModel();
getItems();
selectText = "";
selectedItemIndex = -1;
current = null;
this.prepareSelect();
}
public boolean isModifyControlDisable() {
return modifyControlDisable;
}
public void setModifyControlDisable(boolean modifyControlDisable) {
this.modifyControlDisable = modifyControlDisable;
}
public boolean isSelectControlDisable() {
return selectControlDisable;
}
public void setSelectControlDisable(boolean selectControlDisable) {
this.selectControlDisable = selectControlDisable;
}
public String getSelectText() {
return selectText;
}
public void setSelectText(String selectText) {
this.selectText = selectText;
searchItems();
}
public void prepareSelectControlDisable() {
selectControlDisable = true;
modifyControlDisable = false;
}
public void prepareModifyControlDisable() {
selectControlDisable = false;
modifyControlDisable = true;
}
@FacesConverter(forClass = Vtm.class)
public static class VtmControllerConverter implements Converter {
public Object getAsObject(FacesContext facesContext, UIComponent component, String value) {
if (value == null || value.length() == 0) {
return null;
}
VtmController controller = (VtmController) facesContext.getApplication().getELResolver().
getValue(facesContext.getELContext(), null, "vtmController");
return controller.ejbFacade.find(getKey(value));
}
java.lang.Long getKey(String value) {
java.lang.Long key;
key = Long.valueOf(value);
return key;
}
String getStringKey(java.lang.Long value) {
StringBuffer sb = new StringBuffer();
sb.append(value);
return sb.toString();
}
public String getAsString(FacesContext facesContext, UIComponent component, Object object) {
if (object == null) {
return null;
}
if (object instanceof Vtm) {
Vtm o = (Vtm) object;
return getStringKey(o.getId());
} else {
throw new IllegalArgumentException("object " + object + " is of type "
+ object.getClass().getName() + "; expected type: " + VtmController.class.getName());
}
}
}
}
立面示例
@Stateless
public class VtmFacade extends AbstractFacade<Vtm> {
@PersistenceContext(unitName = "HOPU")
private EntityManager em;
@Override
protected EntityManager getEntityManager() {
return em;
}
public VtmFacade() {
super(Vtm.class);
}
}
生成的抽象外观和我所做的更改。
public abstract class AbstractFacade<T> {
protected Class<T> entityClass;
public AbstractFacade(Class<T> entityClass) {
this.entityClass = entityClass;
}
protected abstract EntityManager getEntityManager();
public void create(T entity) {
getEntityManager().persist(entity);
}
public void edit(T entity) {
getEntityManager().merge(entity);
}
public void remove(T entity) {
getEntityManager().remove(getEntityManager().merge(entity));
}
public T find(Object id) {
return getEntityManager().find(entityClass, id);
}
public List<T> findAll(boolean withoutRetired) {
return findAll(null, null, withoutRetired);
}
public List<T> findAll() {
javax.persistence.criteria.CriteriaBuilder cb = getEntityManager().getCriteriaBuilder();
javax.persistence.criteria.CriteriaQuery<T> cq = cb.createQuery(entityClass);
javax.persistence.criteria.Root<T> rt = cq.from(entityClass);
return getEntityManager().createQuery(cq).getResultList();
}
public List<T> findAll(String fieldName) {
return findAll(fieldName, "", false);
}
public List<T> findAll(String fieldName, boolean withoutRetired) {
return findAll(fieldName, "", withoutRetired);
}
public List<T> findAll(String fieldName, String fieldValue) {
return findAll(fieldName, fieldValue, false);
}
public List<T> findBySQL(String temSQL) {
TypedQuery<T> qry = getEntityManager().createQuery(temSQL, entityClass);
return qry.getResultList();
}
public List<T> findBySQL(String temSQL, Map<String, Date> parameters) {
TypedQuery<T> qry = getEntityManager().createQuery(temSQL, entityClass);
Set s=parameters.entrySet();
Iterator it=s.iterator();
while (it.hasNext()){
Map.Entry m=(Map.Entry)it.next();
Date pVal = (Date) m.getValue();
String pPara=(String) m.getKey();
qry.setParameter(pPara, pVal, TemporalType.DATE);
System.out.println("Parameter " + pPara + "\tVal" + pVal);
}
return qry.getResultList();
}
private void test(Class myClass, Object ob) {
}
public List<T> findAll(String fieldName, String fieldValue, boolean withoutRetired) {
javax.persistence.criteria.CriteriaBuilder cb = getEntityManager().getCriteriaBuilder();
javax.persistence.criteria.CriteriaQuery<T> cq = cb.createQuery(entityClass);
javax.persistence.criteria.Root<T> rt = cq.from(entityClass);
ParameterExpression<String> p = cb.parameter(String.class);
Predicate predicateField = cb.like(rt.<String>get(fieldName), fieldValue);
Predicate predicateRetired = cb.equal(rt.<Boolean>get("retired"), false);
Predicate predicateFieldRetired = cb.and(predicateField, predicateRetired);
if (withoutRetired && !fieldValue.equals("")) {
cq.where(predicateFieldRetired);
} else if (withoutRetired) {
cq.where(predicateRetired);
} else if (!fieldValue.equals("")) {
cq.where(predicateField);
}
if (!fieldName.equals("")) {
cq.orderBy(cb.asc(rt.get(fieldName)));
}
return getEntityManager().createQuery(cq).getResultList();
}
public List<T> findExact(String fieldName, String fieldValue, boolean withoutRetired) {
javax.persistence.criteria.CriteriaBuilder cb = getEntityManager().getCriteriaBuilder();
javax.persistence.criteria.CriteriaQuery<T> cq = cb.createQuery(entityClass);
javax.persistence.criteria.Root<T> rt = cq.from(entityClass);
ParameterExpression<String> p = cb.parameter(String.class);
Predicate predicateField = cb.equal(cb.upper(rt.<String>get(fieldName)), fieldValue.toLowerCase());
Predicate predicateRetired = cb.equal(rt.<Boolean>get("retired"), false);
Predicate predicateFieldRetired = cb.and(predicateField, predicateRetired);
if (withoutRetired && !fieldValue.equals("")) {
cq.where(predicateFieldRetired);
} else if (withoutRetired) {
cq.where(predicateRetired);
} else if (!fieldValue.equals("")) {
cq.where(predicateField);
}
if (!fieldName.equals("")) {
cq.orderBy(cb.asc(rt.get(fieldName)));
}
return getEntityManager().createQuery(cq).getResultList();
}
public T findByField(String fieldName, String fieldValue, boolean withoutRetired) {
List<T> lstAll = findExact(fieldName, fieldValue, true);
if (lstAll.isEmpty()) {
return null;
} else {
return lstAll.get(0);
}
}
public T findFirstBySQL(String temSQL) {
TypedQuery<T> qry = getEntityManager().createQuery(temSQL, entityClass);
try {
return qry.getResultList().get(0);
} catch (Exception e) {
System.out.println(e.getMessage());
return null;
}
}
public <U> List<T> testMethod(U[] a, Collection<U> all) {
List<T> myList = new ArrayList<T>();
return myList;
}
public <U> List<T> findAll(String fieldName, int searchID, boolean withoutRetired) {
javax.persistence.criteria.CriteriaBuilder cb = getEntityManager().getCriteriaBuilder();
javax.persistence.criteria.CriteriaQuery<T> cq = cb.createQuery(entityClass);
javax.persistence.criteria.Root<T> rt = cq.from(entityClass);
if (withoutRetired) {
cq.where(cb.and(cb.equal(rt.get("retired"), false)),
(cb.equal(rt.get(fieldName).get("id"), searchID)));
} else {
cq.where(cb.equal(rt.get("retired"), false));
}
return getEntityManager().createQuery(cq).getResultList();
}
public int count() {
javax.persistence.criteria.CriteriaQuery cq = getEntityManager().getCriteriaBuilder().createQuery();
javax.persistence.criteria.Root<T> rt = cq.from(entityClass);
cq.select(getEntityManager().getCriteriaBuilder().count(rt));
javax.persistence.Query q = getEntityManager().createQuery(cq);
return ((Long) q.getSingleResult()).intValue();
}
public Double findAggregateDbl(String strJQL){
Query q= getEntityManager().createQuery(strJQL);
try{
return (Double) q.getSingleResult();
}catch (Exception e){
System.out.println(e.getMessage());
return 0.0;
}
}
}
这是异常引用的代码。
AtmController controller = (AtmController) facesContext.getApplication().getELResolver().
getValue(facesContext.getELContext(), null, "atmController");
在不同的实例中,这个对应的地方相同,但控制器不同。当错误发生一次时,尽管 JSF 页面访问后缀,相同的控制器给出错误,但在服务器重新启动后,控制器会根据错误开始发生的页面而有所不同。
这是完整的堆栈跟踪。(控制器类的名称会根据我用来访问的 JSF 页面而有所不同。)
INFO: java.lang.ClassCastException: gov.sp.health.bean.VtmController cannot be cast to gov.sp.health.bean.AtmController
java.lang.ClassCastException: gov.sp.health.bean.VtmController cannot be cast to gov.sp.health.bean.AtmController
at gov.sp.health.bean.AtmController$VtmControllerConverter.getAsObject(AtmController.java:252)
at com.sun.faces.renderkit.html_basic.HtmlBasicInputRenderer.getConvertedValue(HtmlBasicInputRenderer.java:171)
at com.sun.faces.renderkit.html_basic.MenuRenderer.convertSelectOneValue(MenuRenderer.java:202)
at com.sun.faces.renderkit.html_basic.MenuRenderer.getConvertedValue(MenuRenderer.java:319)
at javax.faces.component.UIInput.getConvertedValue(UIInput.java:1030)
at javax.faces.component.UIInput.validate(UIInput.java:960)
at javax.faces.component.UIInput.executeValidate(UIInput.java:1233)
at javax.faces.component.UIInput.processValidators(UIInput.java:698)
at com.sun.faces.context.PartialViewContextImpl$PhaseAwareVisitCallback.visit(PartialViewContextImpl.java:508)
at com.sun.faces.component.visit.PartialVisitContext.invokeVisitCallback(PartialVisitContext.java:183)
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1590)
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601)
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601)
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601)
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601)
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601)
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601)
at javax.faces.component.UIForm.visitTree(UIForm.java:344)
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601)
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601)
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601)
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601)
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601)
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601)
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601)
at com.sun.faces.context.PartialViewContextImpl.processComponents(PartialViewContextImpl.java:376)
at com.sun.faces.context.PartialViewContextImpl.processPartial(PartialViewContextImpl.java:252)
at javax.faces.context.PartialViewContextWrapper.processPartial(PartialViewContextWrapper.java:183)
at javax.faces.component.UIViewRoot.processValidators(UIViewRoot.java:1170)
at com.sun.faces.lifecycle.ProcessValidationsPhase.execute(ProcessValidationsPhase.java:76)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:593)
at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1542)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:343)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:217)
at org.primefaces.webapp.filter.FileUploadFilter.doFilter(FileUploadFilter.java:79)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:256)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:217)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:279)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:655)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:595)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:161)
at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:331)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:231)
at com.sun.enterprise.v3.services.impl.ContainerMapper$AdapterCallable.call(ContainerMapper.java:317)
at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:195)
at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:849)
at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:746)
at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1045)
at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:228)
at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137)
at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104)
at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90)
at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79)
at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54)
at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59)
at com.sun.grizzly.ContextTask.run(ContextTask.java:71)
at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532)
at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513)
at java.lang.Thread.run(Thread.java:722)
AtmController 内的转换器
@FacesConverter(forClass = Atm.class)
public static class AtmControllerConverter implements Converter {
public Object getAsObject(FacesContext facesContext, UIComponent component, String value) {
if (value == null || value.length() == 0) {
return null;
}
AtmController controller = (AtmController) facesContext.getApplication().getELResolver().
getValue(facesContext.getELContext(), null, "atmController");
return controller.ejbFacade.find(getKey(value));
}
java.lang.Long getKey(String value) {
java.lang.Long key;
key = Long.valueOf(value);
return key;
}
String getStringKey(java.lang.Long value) {
StringBuffer sb = new StringBuffer();
sb.append(value);
return sb.toString();
}
public String getAsString(FacesContext facesContext, UIComponent component, Object object) {
if (object == null) {
return null;
}
if (object instanceof Atm) {
Atm o = (Atm) object;
return getStringKey(o.getId());
} else {
throw new IllegalArgumentException("object " + object + " is of type "
+ object.getClass().getName() + "; expected type: " + AtmController.class.getName());
}
}
}
VtmController 内的转换器
@FacesConverter(forClass = Vtm.class)
public static class VtmControllerConverter implements Converter {
public Object getAsObject(FacesContext facesContext, UIComponent component, String value) {
if (value == null || value.length() == 0) {
return null;
}
VtmController controller = (VtmController) facesContext.getApplication().getELResolver().
getValue(facesContext.getELContext(), null, "vtmController");
return controller.ejbFacade.find(getKey(value));
}
java.lang.Long getKey(String value) {
java.lang.Long key;
key = Long.valueOf(value);
return key;
}
String getStringKey(java.lang.Long value) {
StringBuffer sb = new StringBuffer();
sb.append(value);
return sb.toString();
}
public String getAsString(FacesContext facesContext, UIComponent component, Object object) {
if (object == null) {
return null;
}
if (object instanceof Vtm) {
Vtm o = (Vtm) object;
return getStringKey(o.getId());
} else {
throw new IllegalArgumentException("object " + object + " is of type "
+ object.getClass().getName() + "; expected type: " + VtmController.class.getName());
}
}
}
MedicineGroupController 内的转换器
@FacesConverter(forClass = MedicineGroup.class)
public static class MedicineGroupControllerConverter implements Converter {
public Object getAsObject(FacesContext facesContext, UIComponent component, String value) {
if (value == null || value.length() == 0) {
return null;
}
MedicineGroupController controller = (MedicineGroupController) facesContext.getApplication().getELResolver().
getValue(facesContext.getELContext(), null, "medicineGroupController");
return controller.ejbFacade.find(getKey(value));
}
java.lang.Long getKey(String value) {
java.lang.Long key;
key = Long.valueOf(value);
return key;
}
String getStringKey(java.lang.Long value) {
StringBuffer sb = new StringBuffer();
sb.append(value);
return sb.toString();
}
public String getAsString(FacesContext facesContext, UIComponent component, Object object) {
if (object == null) {
return null;
}
if (object instanceof MedicineGroup) {
MedicineGroup o = (MedicineGroup) object;
return getStringKey(o.getId());
} else {
throw new IllegalArgumentException("object " + object + " is of type "
+ object.getClass().getName() + "; expected type: " + MedicineGroupController.class.getName());
}
}
}