java.lang.ClassCastException: com.soleil.proxy.$Proxy0 ne peut pas être lancé pour org.andrea.myexample.myDeclarativeTransactionSpring.StudentJDBCTemplate

Je suis en train de mettre en œuvre ce tutoriel sur Déclarative des Transactions dans le Cadre du Printemps de l'application mais ne fonctionne pas car lorsque j'essaie d'exécuter le MainApp classe pour tester le comportement de l'application-je obtenir une erreur:

http://www.tutorialspoint.com/spring/declarative_management.htm

J'ai donc le StudentDAO interface dans laquelle j'ai seulement définir le CRUD méthode que je veux:

package org.andrea.myexample.myDeclarativeTransactionSpring;

import java.util.List;

import javax.sql.DataSource;

/** Interfaccia che definisce i metodi che implementano le operazioni di CRUD
 *  che vogliamo implementare nel nostro DAO:
 */
public interface StudentDAO {

    /**
     * Questo metodo viene usato per inizializzare le risorse del database cioè
     * la connessione al database:
     */
    public void setDataSource(DataSource ds);

    /**
     * Questo metodo serve a creare un record nella tabella Student e nella
     * tabella Marks:
     */
    public void create(String name, Integer age, Integer marks, Integer year);

    /**
     * Questo metodo serve ad elencare tutti i record all'interno della tabella
     * Studend e della tabella Marks
     */
    public List<StudentMarks> listStudents();
}

Puis j'ai StudentMark classe qui rappresent mon entité à persister sur le tableau 2 sur la base de données:

package org.andrea.myexample.myDeclarativeTransactionSpring;

//Rappresenta l'entity:
public class StudentMarks {

    //Proprietà:
    private Integer age;
    private String name;
    private Integer id;
    private Integer marks;
    private Integer year;
    private Integer sid;

    //Metodi Getter & Setter:
    public void setAge(Integer age) {
        this.age = age;
    }

    public Integer getAge() {
        return age;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public Integer getId() {
        return id;
    }

    public void setMarks(Integer marks) {
        this.marks = marks;
    }

    public Integer getMarks() {
        return marks;
    }

    public void setYear(Integer year) {
        this.year = year;
    }

    public Integer getYear() {
        return year;
    }

    public void setSid(Integer sid) {
        this.sid = sid;
    }

    public Integer getSid() {
        return sid;
    }
}

Puis j'ai la classe StudentMarksMapper que de mettre en œuvre RowMapper interface:

package org.andrea.myexample.myDeclarativeTransactionSpring;

import java.sql.ResultSet;
import java.sql.SQLException;
import org.springframework.jdbc.core.RowMapper;


/** Classe che implementa l'interfaccia RowMapper. Si tratta di un'interfaccia
 *  usata da JdbcTemplate per mappare le righe di un ResultSet (oggetto che 
 *  contiene l'insieme delle righe restituite da una query SQL) riga per riga.
 *  Le implementazioni di questa interfaccia mappano ogni riga su di un oggetto
 *  risultante senza doversi preoccupare della gestione delle eccezioni poichè
 *  le SQLException saranno catturate e gestite dalla chiamata a JdbcTemplate.
 */
public class StudentMarksMapper implements RowMapper<StudentMarks> {

    /** Implementazione del metodo dell'interfaccia RowMapper che mappa una 
     *  specifica riga della tabella su di un oggetto Student
     * 
     *  @param Un oggetto ResultSet contenente l'insieme di tutte le righe
     *         restituite dalla query
     * 
     *  @param L'indice che indentifica una specifica riga
     * 
     *  @return Un nuovo oggetto Student rappresentante la riga selezionata
     *          all'interno dell'oggetto ResultSet
     * 
     *  @see org.springframework.jdbc.core.RowMapper#mapRow(java.sql.ResultSet, int)
     */
    public StudentMarks mapRow(ResultSet rs, int rowNum) throws SQLException {

        StudentMarks studentMarks = new StudentMarks();

        studentMarks.setId(rs.getInt("id"));
        studentMarks.setName(rs.getString("name"));
        studentMarks.setAge(rs.getInt("age"));
        studentMarks.setSid(rs.getInt("sid"));
        studentMarks.setMarks(rs.getInt("marks"));
        studentMarks.setYear(rs.getInt("year"));

        return studentMarks;
    }
}

À côté d'elle c'est StudentJDBCTemplate classe qui StudentDAO interface:

package org.andrea.myexample.myDeclarativeTransactionSpring;
import java.util.List;
import javax.sql.DataSource;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
/**
* Classe che fornisce l'implementazione per il nostro DAO le cui funzionalità
* di CRUD sono state definite tramite l'interfaccia StudentDAO
*/
public class StudentJDBCTemplate implements StudentDAO {
//Utility per l'accesso alla sorgente dati
private JdbcTemplate jdbcTemplateObject;
/**
* Metodo Setter per l'Injection della dipendenza relativa alla sorgente
* dati. Tale metodo inoltre costruisce anche l'oggetto istanza di
* JdbcTemplate usato per interagire con i dati nel database.
* 
* @param la sorgente dati
*/
public void setDataSource(DataSource dataSource) {
this.jdbcTemplateObject = new JdbcTemplate(dataSource);
}
/**
* Metodo relativo all'operazione di CREATE che inserisce un nuovo record
* all'interno della tabella Student ed un correlato nuovo record nella
* tabella Marks.
*/
public void create(String name, Integer age, Integer marks, Integer year) {
try {
//Query che inserisce nome ed età nella tabella Student:
String SQL1 = "insert into Student (name, age) values (?, ?)";
//Esegue la query passandogli anche i valori effettivi da inserire:
jdbcTemplateObject.update(SQL1, name, age);
//Seleziona l'ultimo studente inserito nella tabella Marks:
String SQL2 = "select max(id) from Student";
//Esegue la query e mette il risultato (l'ID) in sid:
int sid = jdbcTemplateObject.queryForInt(SQL2);
/**
* Query che inserisce un nuovo record nella tabella Marks. Il
* record rappresenta il voto per l'ultimo studente inserito nella
* tabella Student:
*/
String SQL3 = "insert into Marks(sid, marks, year) "
+ "values (?, ?, ?)";
//Esegue la query passandogli anche i valori effettivi da inserire:
jdbcTemplateObject.update(SQL3, sid, marks, year);
System.out.println("Created Name = " + name + ", Age = " + age);
//SIMULA UNA RuntimeExceptio:
throw new RuntimeException("Simulazione di una condizione d'errore");
} catch (DataAccessException e) {       //GESTIONE DELL'ECCEZIONE
System.out.println("Errore nella creazione dei record, esegue rollback");
throw e;
}
}
/**
* Metodo relativo all'operazione di READ che recupera la lista degli
* studenti e dei relativi voti
* 
* @return La lista di oggetti che rappresentano uno studente ed i suoi voti
*         correlati
*/
public List<StudentMarks> listStudents() {
/**
* Query che estrae la lista di tutti i record nella tabella Student e
* che per ogni record in tale tabella estrae i relativi record
* correlati nella tabella Marks
*/
String SQL = "select * from Student, Marks where Student.id=Marks.sid";
/**
* Ottengo la lista degli oggetti StudentMarks, corrispondenti ognuno ad
* un record della tabella Student con i correlati vori rappresentati
* dai record della tabella Marks, invocando il metodo query 
* sull'oggetto JdbcTemplate passandogli i seguenti parametri.
* 
* @param La query per creare il preparated statement
* @param Un oggetto che implementa RowMapper che viene usato per
*        mappare una singola riga della tabella su di un oggetto Java
*/
List<StudentMarks> studentMarks = jdbcTemplateObject.query(SQL,
new StudentMarksMapper());
return studentMarks;
}
}

Alors c'est le MainApp classe pour tester l'application:

package org.andrea.myexample.myDeclarativeTransactionSpring;
import java.util.List;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
//Classe principale:
public class MainApp {
public static void main(String[] args) {
/**
* Crea il contesto in base alle impostazioni dell'applicazione definite
* nel file Beans.xml
*/
ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");
/**
* Recupera un bean avente id="studentJDBCTemplate" nel file di
* configurazione Beans.xml
*/
StudentJDBCTemplate studentJDBCTemplate = (StudentJDBCTemplate) context.getBean("studentJDBCTemplate");
System.out.println("------Creazione dei record--------");
//Creo i record nelle tabelle Studend e Marks:
studentJDBCTemplate.create("Zara", 11, 99, 2010);
studentJDBCTemplate.create("Nuha", 20, 97, 2010);
studentJDBCTemplate.create("Ayan", 25, 100, 2011);
System.out.println("------Elenca tutti i record--------");
//Recupera la lista degli studenti con i voti ad essi associati:
List<StudentMarks> studentMarks = studentJDBCTemplate.listStudents();
for (StudentMarks record : studentMarks) {      //e li stampa
System.out.print("ID : " + record.getId());
System.out.print(", Name : " + record.getName());
System.out.print(", Marks : " + record.getMarks());
System.out.print(", Year : " + record.getYear());
System.out.println(", Age : " + record.getAge());
}
}
}

Finnally c'est mon Beans.xml fichier de configuration:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
<!-- Initializazione della sorgente dati: -->
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/SpringTestDb" />
<property name="username" value="root" />
<property name="password" value="aprile12" />
</bean>
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="create" />
</tx:attributes>
</tx:advice>
<aop:config>
<aop:pointcut id="createOperation"
expression="execution(* org.andrea.myexample.myDeclarativeTransactionSpring.StudentJDBCTemplate.create(..))" />
<aop:advisor advice-ref="txAdvice" pointcut-ref="createOperation" />
</aop:config>
<!-- Inizializzazione del Transaction Manager: -->
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<!-- Definizione del bean che rappresenta il DAO studentJDBCTemplate: -->
<bean id="studentJDBCTemplate" class="org.andrea.myexample.myDeclarativeTransactionSpring.StudentJDBCTemplate">
<property name="dataSource" ref="dataSource" />
</bean>
</beans>

la prroblem est que lorsque je tente de lancer mon MainApp classe-je obtenir l'erreur suivante messate:

INFO: Loaded JDBC driver: com.mysql.jdbc.Driver
Exception in thread "main" java.lang.ClassCastException: com.sun.proxy.$Proxy0 cannot be cast to org.andrea.myexample.myDeclarativeTransactionSpring.StudentJDBCTemplate
at org.andrea.myexample.myDeclarativeTransactionSpring.MainApp.main(MainApp.java:22)

Dans ce message d'erreur dit que le problème est à la ligne 22 de la classe MainApp...c'est tout simplement lorsque j'essaie d'obtenir le haricot ayant pour ID="studentJDBCTemplate:

StudentJDBCTemplate studentJDBCTemplate = (StudentJDBCTemplate) context.getBean("studentJDBCTemplate");

Où est le problème? Comment puis-je le résoudre?

Tnx

Andrea

  • Je ne suis pas très frais sur le Printemps des proxys, mais je pense que le proxy va implémenter l'interface StudentDAO plutôt que de prolonger la StudentJDBCTemplate. Ainsi, lorsque vous demandez ce que c'haricot, de la ApplciationContext, vous voulez probablement pour le jeter aux StudentDAO à la place.
  • Merci, ça a fonctionné. Je me demande pourquoi il fonctionne de la manière qu'il le fait ? +1 pour l'astuce et je pense que cela devrait être une réponse
InformationsquelleAutor AndreaNobili | 2013-02-28