2010-07-11 9 views
1

이 메소드가 작동하지 않는 이유는 누구에게 말해 줄 수 있습니까? currentSubscriptions아주 이상한 오류 ClassCastException. PreparedStatement의 setInt 메소드

String strQuery = "Insert Into cust_subs (CustomerId,SubscriptionId) Values (?,?)"; 
PreparedStatement objPreparedStatement = Utils.getPreparedStatement(objConnection, strQuery); 
objPreparedStatement.setInt(2, currentSubscriptions.get(0)); 

입니다 :이 오류가

List<Integer> currentSubscriptions; 

는 정수 목록에도 불구하고 -

SEVERE : java.lang.ClassCastException가 : java.lang.String의 수 없어 java.lang.Integer에 캐스트된다.

접속 오브젝트 이미 존재 함. 그리고 나는이 currentSubscriptions이 null이 아니라는 것을 확신합니다. 그렇지 않으면이 오류가 발생하지 않았을 것입니다. 대신 List를 사용하는 나는 다음과 같이 하드 코딩 경우

objPreparedStatement.setInt(2,1); 

을 그것은 작동합니다. 나는 심지어 System.out.println을 사용하여 List의 값을 인쇄했으며 완벽하게 괜찮습니다. 그것들은 정수입니다. 왜 그것들을 문자열로 취급하는지 모르겠다. 심지어 목록의 항목에 Integer.parseInt을 사용해 봤습니다. 아직도 그것은 나에게 같은 오류를 준다. 이것은 내가 직면 한 가장 재미있는 오류 중 하나입니다.

편집 : 사전에

감사합니다 : -이어야이 작동합니다

. 그러나 심지어이 작동하지 않습니다 : -

int intSubscriptionId = Integer.parseInt(currentSubscriptions.get(0).toString()); 

      objPreparedStatement.setInt(2, intSubscriptionId); 

편집 2 :

는 전체 코드를 게시 : - :

<?xml version='1.0' encoding='UTF-8' ?> 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml" 
     xmlns:h="http://java.sun.com/jsf/html" 
     xmlns:f="http://java.sun.com/jsf/core" 
     xmlns:msc="http://mscit/jsf"> 
    <h:head> 
     <title>Facelet Title</title> 
    </h:head> 
    <h:body> 
     <center> 
      <h:form> 
      <h1>Add Subscription</h1> 

      <b> Customer Name :</b> <h:outputText value="#{addSubscriptionBean.customer.firstName} #{addSubscriptionBean.customer.lastName}"/> 

      <h:selectManyCheckbox value="#{addSubscriptionBean.currentSubscriptions}"> 

       <f:selectItems value="#{addSubscriptionBean.subscriptionList}" var="row" itemLabel="#{row.title}" itemValue="#{row.subscriptionId}" /> 

      </h:selectManyCheckbox> 

      <h:commandButton value="Save" actionListener="#{addSubscriptionBean.save}"/> 
      </h:form> 
     </center> 
    </h:body> 
</html> 

-

package beans; 

import entities.Customer; 
import entities.Subscription; 
import java.io.IOException; 
import java.io.Serializable; 
import java.sql.Connection; 
import java.sql.PreparedStatement; 
import java.sql.ResultSet; 
import java.sql.SQLException; 
import java.sql.Savepoint; 
import java.util.ArrayList; 
import java.util.List; 
import javax.faces.bean.ManagedBean; 
import javax.faces.bean.ViewScoped; 
import javax.faces.context.FacesContext; 
import javax.servlet.http.HttpServletRequest; 
import misc.Utils; 

@ManagedBean 
@ViewScoped 
public class AddSubscriptionBean implements Serializable { 

    private Customer customer; 
    private List<Integer> currentSubscriptions; 
    private List<Subscription> subscriptionList; 

    public List<Subscription> getSubscriptionList() { 
     return subscriptionList; 
    } 

    public void setSubscriptionList(List<Subscription> subscriptionList) { 
     this.subscriptionList = subscriptionList; 
    } 

    public List<Integer> getCurrentSubscriptions() { 
     return currentSubscriptions; 
    } 

    public void setCurrentSubscriptions(List<Integer> currentSubscriptions) { 
     this.currentSubscriptions = currentSubscriptions; 
    } 

    public Customer getCustomer() { 
     return customer; 
    } 

    public void setCustomer(Customer customer) { 
     this.customer = customer; 
    } 

    /** Creates a new instance of AddSubscriptionBean */ 
    public AddSubscriptionBean() throws IOException, SQLException { 

     Connection objConnection = null; 
     try { 
      HttpServletRequest objHttpServletRequest = (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest(); 
      int intCustomerId = Integer.parseInt(objHttpServletRequest.getParameter("cid")); 
      String strQuery = "Select * from customer Where CustomerID = " + intCustomerId; 

      ResultSet objResultSet = Utils.executeResultSet(objConnection, strQuery); 
      if (objResultSet.next()) { 
       String strFirstName = objResultSet.getString("FirstName"); 
       String strLastName = objResultSet.getString("LastName"); 
       customer = new Customer(intCustomerId, strFirstName, strLastName); 
      } 

      currentSubscriptions = new ArrayList<Integer>(); 

      for (Subscription objSubscription : customer.getSubscriptionList()) { 
       currentSubscriptions.add(objSubscription.getSubscriptionId()); 
      } 


      subscriptionList = new ArrayList<Subscription>(); 
      strQuery = "Select * from subscription"; 
      objResultSet = Utils.executeResultSet(objConnection, strQuery); 
      while (objResultSet.next()) { 
       int intSubscriptionId = objResultSet.getInt("SubscriptionId"); 
       String strSubsriptionTitle = objResultSet.getString("Title"); 
       String strSubsriptionType = objResultSet.getString("Type"); 
       Subscription objSubscription = new Subscription(intSubscriptionId, strSubsriptionTitle, strSubsriptionType); 
       subscriptionList.add(objSubscription); 
      } 


     } catch (Exception ex) { 
      ex.printStackTrace(); 
      FacesContext.getCurrentInstance().getExternalContext().redirect("index.jsf"); 
     } finally { 
      if (objConnection != null) { 
       objConnection.close(); 
      } 
     } 
    } 

    public void save() throws SQLException { 

     Connection objConnection = null; 
     Savepoint objSavepoint = null; 
     try { 
      objConnection = Utils.getConnection(); 
      objConnection.setAutoCommit(false); 
      objSavepoint = objConnection.setSavepoint(); 
      String strQuery = "Delete From cust_subs Where CustomerId = " + customer.getCustomerId(); 

      if (!Utils.executeQuery(objConnection, strQuery)) { 
       throw new Exception(); 
      } 

      strQuery = "Insert Into cust_subs (CustomerId,SubscriptionId) Values (?,?)"; 


      int intCustomerId = customer.getCustomerId(); 
      PreparedStatement objPreparedStatement = Utils.getPreparedStatement(objConnection, strQuery); 
      for (int intIndex = 0; intIndex < currentSubscriptions.size(); intIndex++) { 
       objPreparedStatement.setInt(1, intCustomerId); 
       int intSubscriptionId = Integer.parseInt(currentSubscriptions.get(0).toString()); 

       objPreparedStatement.setInt(2, intSubscriptionId); 
       objPreparedStatement.addBatch(); 
      } 

      objPreparedStatement.executeBatch(); 

      objConnection.commit(); 
     } catch (Exception ex) { 
      ex.printStackTrace(); 
      if (objConnection != null) { 
       objConnection.rollback(objSavepoint); 
      } 
     } finally { 
      if (objConnection != null) { 
       objConnection.close(); 
      } 
     } 
    } 
} 

이 내 JSF 페이지입니다 JSF의 h : selectManyCheckbox를보십시오. JSF는 내 목록에 체크 한 모든 체크 박스를 내부적으로 전달합니다. JSF가 정수 목록을 문자열로 변환하고 있다고 생각합니다. 지금 문자열을 포함하는 동일한 목록에

List<Integer> intList = new ArrayList<Integer>(); 
List list = intList; 
list.add("1"); 

intListlist 보류 참조 :

+0

실제로 'setInt'는 오류가 발생한 위치입니까? 'PreparedStatement.setInt'는 두 개의 정수 인자를 취하는 단 하나의 과부하를 가지고 있습니다; 귀하의'List.get' autounbox해야하고 잘 작동합니다. 하지만'Utils.getPreparedStatement'는 어떨까요? 그게 커스텀 메소드인가요? 커스텀 라이브러리입니까? Google에서 해당 정적 메소드를 검색하면이 페이지 만 반환됩니다. –

+0

'currentSubscriptions.get (0) .getClass(). getName()'은 무엇을 반환합니까? –

+0

@Paul,'currentSubscriptions.get (0)'은'ClassCastException'을 발생시킬 것입니다. 그는 내가 대답 한 것처럼'List'에 배정해야합니다. –

답변

6

변환기로 javax.faces.Integer을 지정하여 값을 Integer으로 변환하려면 h:selectManyCheckbox에 지시해야합니다. 일반 유형은 EL에서 알 수 없으므로 기본적으로 매개 변수를 String으로 취급합니다.

<h:selectManyCheckbox converter="javax.faces.Integer"> 

단지 빈에서 더 weaktype의 혼란으로 이어질 것이다 대신 List<String>를 사용할 필요가 없습니다.

+0

고마워요. 내가 뭘 찾고 있었는지 고마워! – TCM

3

그것은 당신이 안전하지 않은 작업을 사용하는 경우 List<Integer>에 문자열을 넣어 가능합니다. 지금까지 본 것처럼 intList에서 요소를 추출하려고하면 ClassCastException이 표시됩니다.

자바 제네릭은 숨겨진 캐스트를 사용하여 작동하므로 유형 검사를 무효화 할 수 있습니다. 내가 JSF에 익숙하지 않은,하지만 난 당신의 추측이 정확하다고 생각 :

List currentSubscriptionsUnsafe = currentSubscriptions; 
for(Object o : currentSubscriptionsUnsafe) 
{ 
    System.out.println(o.getClass()); 
} 

편집이를 테스트하려면 다음 각 요소의 클래스를 인쇄하는 List에 할당합니다. 한 가지 해결책은 currentSubscriptionsList<String>으로 만드는 것입니다 (JSF가 예상 한 것 같습니다).그런 다음 get(0)String을 반환하며이를 Integer으로 파싱 할 수 있습니다. 더 깨끗한 방법이있을 수 있지만이 방법이 효과적입니다.

+0

하지만 그런 일은하지 않습니다. 이걸 어떻게 없앨까요? 목록 대신 어떤 변경을해야합니까? – TCM

+0

@Nitesh, 해당 코드를 사용하는 모든 요소의 클래스를 인쇄하십시오. 이것이 문제인지를 알려줄 것입니다. –

+0

안녕 매튜, 네, 정말로이게 문제입니다. 나는 이것을 얻는다 : -'INFO : class java.lang.String'. 어떻게 해결할 수 있을까요? 왜 그것이 오버 머드인가? 정수를 전달하더라도? – TCM