2010-07-11 4 views
1

Quelqu'un peut-il me dire pourquoi cette méthode ne fonctionne pas?Une erreur très très étrange ClassCastException. La méthode setInt de PreparedStatement

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

currentSubscriptions est:

List<Integer> currentSubscriptions; 

Je reçois cette erreur même si elle est la liste entière: -

GRAVES: java.lang.ClassCastException: java.lang.String ne peut pas être converti en java.lang.Integer

Supposons que cet objet de connexion existe déjà. Et je suis très sûr que currentSubscriptions n'est pas nulle sinon je n'aurais pas eu cette erreur. Si au lieu d'utiliser List i hardcode comme ceci:

objPreparedStatement.setInt(2,1); 

Il fonctionne. J'ai même imprimé les valeurs de List en utilisant System.out.println et c'est parfaitement bien. Ce sont des entiers seulement. Je ne sais pas pourquoi il les traite comme des cordes. J'ai même essayé Integer.parseInt sur l'article de la liste. Pourtant, cela me donne la même erreur. C'est l'une des erreurs les plus drôles que j'ai jamais rencontrées.

Merci à l'avance :)

EDIT: -

Atleast cela devrait fonctionner. Mais même cela ne fonctionne pas: -

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

      objPreparedStatement.setInt(2, intSubscriptionId); 

EDIT 2:

affichage code complet: -

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(); 
      } 
     } 
    } 
} 

C'est ma page JSF: -

<?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> 

S'il vous plaît regardez le h: selectManyCheckbox de JSF. JSF passe en interne toutes les cases que j'ai cochées dans ma liste. Je pense que JSF convertit ma liste d'entiers en chaîne.

+0

Est-ce que 'setInt' est réellement où votre erreur se produit? 'PreparedStatement.setInt' a seulement une surcharge, prenant deux arguments entiers; votre 'List.get' devrait être autounbox et cela devrait fonctionner correctement. Mais qu'en est-il de 'Utils.getPreparedStatement'? Est-ce une méthode personnalisée ou dans une bibliothèque personnalisée? La recherche de cette méthode statique spécifique sur Google ne renvoie que cette page. –

+0

Qu'est-ce que 'currentSubscriptions.get (0) .getClass(). GetName()' renvoie? –

+0

@Paul, 'currentSubscriptions.get (0)' provoquera une exception ClassCastException'. Il doit assigner à une liste, comme je l'ai montré dans ma réponse. –

Répondre

6

Vous devez indiquer à h:selectManyCheckbox de convertir les valeurs en Integer en spécifiant javax.faces.Integer comme convertisseur. Les types génériques sont inconnus dans EL et les paramètres par défaut sont String.

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

Pas besoin d'utiliser List<String> à la place qui ne conduirait à plus de fouillis weaktype dans la fève.

+0

Merci exactement ce que je cherchais! – TCM

3

Il est possible de mettre des chaînes dans une List<Integer> si vous utilisez des opérations dangereuses:

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

intList et list contenir des références à la même liste, qui contient désormais une chaîne. Comme vous l'avez vu, vous obtenez un ClassCastException en essayant d'extraire l'élément de intList. Les génériques Java fonctionnent en utilisant le moulage caché, et vous pouvez annuler le contrôle de type. Pour tester cela, attribuez à un List, puis imprimez la classe de chaque élément:

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

EDIT: Je ne suis pas familier avec JSF, mais je pense que votre estimation est correcte. Une solution consiste à faire currentSubscriptions un List<String> partout (ce que JSF semble attendre).Ensuite, get(0) renverra un String, que vous pouvez analyser en Integer. Il peut y avoir une méthode plus propre, mais cela devrait fonctionner.

+0

Mais je ne fais pas une telle chose. Comment puis-je me débarrasser de cela? Quels changements dois-je faire au lieu de la liste? – TCM

+0

@Nitesh, imprime la classe de chaque élément en utilisant ce code. Cela vous dira si c'est le problème. –

+0

Salut Matthew, Oui en effet c'est le problème. Je reçois ceci: - 'INFO: class java.lang.String'. Comment puis-je resoudre ceci? Pourquoi est-ce que c'est trop mal? même si je passe des entiers dedans? – TCM

Questions connexes