在Hibernate中保留一个Integers数组列表会引发异常

时间:2013-07-23 11:47:27

标签: hibernate jsf-2 primefaces

在我的应用程序(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);

}

1 个答案:

答案 0 :(得分:1)

如果您将manageesIds绑定到基于UISelectMany的组件(如<h:selectManyCheckbox><h:selectManyListbox>)而未明确指定转换提交的String值的转换器,则会发生这种情况到Integer。你有一个List<Integer>属性,并且在运行时(EL运行的那一刻)不存在泛型类型,因此所有EL看到的都是简单的List。只要您没有明确指定转换器,EL就会假设它只是List<String>

有两种解决方案:

  1. 明确指定转换器。您可以使用JSF内置IntegerConverter

    <h:selectManyCheckbox ... converter="javax.faces.Integer">
    
  2. 使用类型化数组而不是通用列表作为属性。这样,JSF / EL将能够确定具体类型并应用自动强制/转换。

    private Integer[] manageesIds;