在我的应用程序(Primefaces + Hibernate + Oracle DB)中,我试图将具有整数数组列表(manageesIds)的实体持久化到两个表(arraylist将进入“详细信息”表)。
尝试使用Web应用程序保存实体时会抛出ClassCastException。但是,当我从主方法而不是从Web应用程序调用“updateJobDescription”方法时,它工作正常。
实体:
@SuppressWarnings("serial")
@Entity
@Table(name = "EMP_JOB_DESCRIPTION")
public class EmployeeInfo
{
public EmployeeInfo()
{
manageesIds.add(new Integer(1));
manageesIds.add(new Integer(1));
manageesIds.add(new Integer(1));
manageesIds.add(new Integer(1));
manageesIds.add(new Integer(1));
manageesIds.add(new Integer(1));
manageesIds.add(new Integer(1));
}
@Id
@Column(name = "emp_no")
private Integer empNo;
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
public String getEmail()
{
return email;
}
public void setEmail(String email)
{
this.email = email;
}
public String getOfficialPosition()
{
return officialPosition;
}
public void setOfficialPosition(String officialPosition)
{
this.officialPosition = officialPosition;
}
@Column(name = "emp_national_id_no")
private String nationalIdNo;
@Column(name = "emp_jawal_phone")
private String mobile;
@Column(name = "emp_phone_ext")
private String extension;
@Column(name = "emp_onreal_job_type")
private Integer actualPositionId;
@Column(name = "emp_st_old_dest")
private Integer workDestination;
@Column(name = "emp_city")
private Integer cityId;
@Column(name = "emp_specialty_desc")
private String specialtyDesc;
@Column(name = "emp_duties_desc")
private String dutiesDesc;
@Column(name = "emp_mng_job_desc")
private Integer managerPositionId;
@Column(name = "emp_qualification")
private Integer qualificationId;
@Column(name = "emp_last_qualification")
private Integer lastQualificationId;
@Column(name = "emp_experience")
private String experience;
@Column(name = "emp_training")
private String training;
@Transient
private String name;
@Transient
private String email;
@Transient
private String officialPosition;
@ElementCollection
@CollectionTable(name = "emp_job_description_detail", joinColumns = @JoinColumn(name = "EMP_NO"))
@Column(name = "EMP_MNG_CHAIRED_JOB_DESC")
private List<Integer> manageesIds = new ArrayList<Integer>();
保存方法:
public static synchronized void updateJobDescription(EmployeeInfo jobDesc)
{
Session session = getNewSession(true);
session.saveOrUpdate(jobDesc);
closeSession(session, true);
}
例外:
14:42:26,586 SEVERE [javax.faces.event] (http-localhost-127.0.0.1-8888-3) java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer
at org.hibernate.type.descriptor.java.IntegerTypeDescriptor.unwrap(IntegerTypeDescriptor.java:36)
at org.hibernate.type.descriptor.sql.IntegerTypeDescriptor$1.doBind(IntegerTypeDescriptor.java:57)
at org.hibernate.type.descriptor.sql.BasicBinder.bind(BasicBinder.java:92)
at org.hibernate.type.AbstractStandardBasicType.nullSafeSet(AbstractStandardBasicType.java:305)
at org.hibernate.type.AbstractStandardBasicType.nullSafeSet(AbstractStandardBasicType.java:300)
at org.hibernate.type.AbstractSingleColumnStandardBasicType.nullSafeSet(AbstractSingleColumnStandardBasicType.java:57)
at org.hibernate.persister.collection.AbstractCollectionPersister.writeElement(AbstractCollectionPersister.java:811)
at org.hibernate.persister.collection.AbstractCollectionPersister.recreate(AbstractCollectionPersister.java:1201)
at org.hibernate.action.internal.CollectionRecreateAction.execute(CollectionRecreateAction.java:58)
at org.hibernate.engine.spi.ActionQueue.execute(ActionQueue.java:362)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:354)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:279)
at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:326)
at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:52)
at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1181)
at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:379)
at org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.beforeTransactionCommit(JdbcTransaction.java:101)
at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.commit(AbstractTransactionImpl.java:175)
at com.kku.jd.persistence.PersistenceManager.closeSession(PersistenceManager.java:53)
at com.kku.jd.persistence.PersistenceManager.updateJobDescription(PersistenceManager.java:137)
at com.kku.jd.managedbeans.UpdateBean.updateJobDescription(UpdateBean.java:123)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.apache.el.parser.AstValue.invoke(AstValue.java:262)
at org.apache.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:278)
at javax.faces.event.MethodExpressionActionListener.processAction(MethodExpressionActionListener.java:153)
at javax.faces.event.ActionEvent.processListener(ActionEvent.java:88)
at javax.faces.component.UIComponentBase.broadcast(UIComponentBase.java:769)
at javax.faces.component.UICommand.broadcast(UICommand.java:300)
at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:794)
at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1259)
at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:81)
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.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:329)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:248)
at org.primefaces.webapp.filter.FileUploadFilter.doFilter(FileUploadFilter.java:77)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:280)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:248)
at org.apache.shiro.web.servlet.AbstractShiroFilter.executeChain(AbstractShiroFilter.java:449)
at org.apache.shiro.web.servlet.AbstractShiroFilter$1.call(AbstractShiroFilter.java:365)
at org.apache.shiro.subject.support.SubjectCallable.doCall(SubjectCallable.java:90)
at org.apache.shiro.subject.support.SubjectCallable.call(SubjectCallable.java:83)
at org.apache.shiro.subject.support.DelegatingSubject.execute(DelegatingSubject.java:383)
at org.apache.shiro.web.servlet.AbstractShiroFilter.doFilterInternal(AbstractShiroFilter.java:362)
at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:125)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:280)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:248)
at com.kku.jd.filter.InitializeSessionFilter.doFilter(InitializeSessionFilter.java:46)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:280)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:248)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:275)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:161)
at org.jboss.as.web.security.SecurityContextAssociationValve.invoke(SecurityContextAssociationValve.java:153)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:155)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:368)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:877)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:671)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:930)
at java.lang.Thread.run(Unknown Source)
更新
以下是我从Main方法中调用它的方法:
public static void main(String[] args)
{
EmployeeInfo empInfo = new EmployeeInfo();
empInfo.setEmail("sary@gmail.com");
empInfo.setEmpNo(7);
empInfo.setMobile("5698535");
empInfo.setName("Sary");
empInfo.setOfficialPosition("Dev Manager");
empInfo.setNationalIdNo("123456789");
List<Integer> ids = new ArrayList<Integer>();
ids.add(1);
empInfo.setManageesIds(ids);
updateJobDescription(empInfo);
}
对于Web应用程序,命令按钮调用托管bean的方法。
xhtml文件中的Commnad按钮:
<p:commandButton value="#{msg.fourth_save}" ajax="false" actionListener="#{updateBean.updateJobDescription}" />
管理bean:
public void updateJobDescription()
{
// save all entered info
PersistenceManager.updateJobDescription(empInfo);
// return navigation to first page
wizard.setStep(FIRST_STEP);
}
答案 0 :(得分:1)
如果您将manageesIds
绑定到基于UISelectMany
的组件(如<h:selectManyCheckbox>
或<h:selectManyListbox>
)而未明确指定转换提交的String
值的转换器,则会发生这种情况到Integer
。你有一个List<Integer>
属性,并且在运行时(EL运行的那一刻)不存在泛型类型,因此所有EL看到的都是简单的List
。只要您没有明确指定转换器,EL就会假设它只是List<String>
。
有两种解决方案:
明确指定转换器。您可以使用JSF内置IntegerConverter
:
<h:selectManyCheckbox ... converter="javax.faces.Integer">
使用类型化数组而不是通用列表作为属性。这样,JSF / EL将能够确定具体类型并应用自动强制/转换。
private Integer[] manageesIds;