Очень и очень странная ошибка ClassCastException. Метод setInt в PreparedStatement - PullRequest
1 голос
/ 11 июля 2010

Может кто-нибудь сказать мне, почему этот метод не работает?

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

, где currentSubscriptions:

List<Integer> currentSubscriptions;

Я получаю эту ошибку, хотя это список целых чисел: -

SEVERE: java.lang.ClassCastException: java.lang.String не может быть приведен к java.lang.Integer

Предположим, что объект подключения уже существует. И я очень уверен, что currentSubscriptions не равно нулю, иначе я бы не получил эту ошибку. Если вместо использования List я жёстко кодирую вот так:

objPreparedStatement.setInt(2,1);

Это работает. Я даже напечатал значения List с помощью System.out.println, и это совершенно нормально. Они только целые числа. Не знаю, почему он рассматривает их как строки. Я даже пытался Integer.parseInt на элемент списка. Тем не менее это дает мне ту же ошибку. Это одна из самых смешных ошибок, с которыми я когда-либо сталкивался.

Заранее спасибо:)

РЕДАКТИРОВАТЬ: -

По крайней мере, это должно работать. Но даже это не работает: -

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

            objPreparedStatement.setInt(2, intSubscriptionId );

РЕДАКТИРОВАТЬ 2:

Размещение всего кода: -

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

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

Пожалуйста, посмотрите на h: selectManyCheckbox из JSF. JSF внутренне передает все отмеченные мной флажки в мой список. Я думаю, что JSF преобразует мой список целых чисел в строку.

Ответы [ 2 ]

6 голосов
/ 11 июля 2010

Вам необходимо указать h:selectManyCheckbox преобразовать значения в Integer, указав javax.faces.Integer в качестве преобразователя. Общие типы в EL неизвестны, и параметры по умолчанию рассматриваются как String.

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

Нет необходимости использовать List<String> вместо этого, что приведет только к более слабому беспорядку в бине.

3 голосов
/ 11 июля 2010

Строки можно поместить в List<Integer>, если вы используете небезопасные операции:

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

intList и list содержат ссылки на тот же список, который теперь содержит строку.Как вы видели, вы получаете ClassCastException при попытке извлечь элемент из intList.

Обобщения Java работают с использованием скрытого приведения, и вы можете отменить проверку типов.Чтобы проверить это, присвойте List, а затем напечатайте класс каждого элемента:

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

EDIT : я не знаком с JSF, но думаю, что ваше предположениеправильный.Одно из решений - сделать currentSubscriptions a List<String> повсюду (что, похоже, ожидает JSF).Затем get(0) вернет String, который вы можете разобрать в Integer.Может быть более чистый метод, но это должно сработать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...