2013-02-28 7 views
5

मैं स्प्रिंग फ्रेमवर्क आवेदन में घोषणात्मक लेन-देन के बारे में इस ट्यूटोरियल लागू करने के लिए कोशिश कर रहा हूँ org.andrea.myexample.myDeclarativeTransactionSpring.StudentJDBCTemplate में ढाला नहीं जा सकता है, लेकिन क्योंकि काम नहीं करते मैं एक त्रुटि प्राप्त जब मैं MainApp वर्ग आवेदन व्यवहार का परीक्षण करने पर अमल करने का प्रयास करें:

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

तो मैं StudentDAO इंटरफ़ेस जिसमें मैं केवल CRUD विधि को परिभाषित है कि मैं चाहता हूँ:

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

तब मैं StudentMark वर्ग है कि मेरे इकाई rappresent डेटाबेस पर 2 मेज पर दृढ़ रहना करने के लिए है:

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

तब मैं कक्षा StudentMarksMapper कि लागू RowMapper इंटरफेस है:

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

इसके आगे थाई

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

फिर इस MainApp आवेदन का परीक्षण करने के वर्ग है: रों StudentJDBCTemplate वर्ग कि StudentDAO इंटरफेस है

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 यह मेरा Beans.xml विन्यास फाइल है:

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

प्रकोप कहते हैं कि

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) 

यह त्रुटि संदेश में है कि समस्या MainApp वर्ग ... 22 लाइन पर है कि बस जब है: एलईएम जब मैं अपने MainApp वर्ग मैं निम्न त्रुटि messate प्राप्त चलाने का प्रयास है कि है मैं बीन युक्त आईडी प्राप्त करने की कोशिश करता हूं = "studentJDBCTemplate:

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

समस्या कहां है? मैं कैसे हल कर सकता हूं?

Tnx

एंड्रिया

+3

मैं वसंत प्रॉक्सी पर बहुत ताजा नहीं हूं, लेकिन मुझे लगता है कि प्रॉक्सी 'StudentJDBCTemplate' को बढ़ाने के बजाय इंटरफ़ेस' StudentDAO' को कार्यान्वित करेगी। तो जब आप 'एप्लासिटी कॉन्टेक्स्ट' से उस बीन के लिए पूछते हैं, तो आप शायद इसे 'StudentDAO'' पर डालना चाहते हैं। –

+0

@ निकोलस.hauschild - धन्यवाद, यह काम किया। मुझे आश्चर्य है कि यह किस तरह से काम करता है? टिप के लिए +1 और मुझे लगता है कि यह एक जवाब होना चाहिए –

उत्तर

10

विकल्प 1, अपने विन्यास बदल इंटरफेस स्तर पर लेन-देन सुई:

<aop:config> 
    <aop:pointcut id="createOperation" 
     expression="execution(* org.andrea.myexample.myDeclarativeTransactionSpring.StudentDAO.create(..))" /> 
    <aop:advisor advice-ref="txAdvice" pointcut-ref="createOperation" /> 
</aop:config> 

और है कि इंटरफ़ेस का एक उदाहरण के रूप में सेम प्राप्त:

StudentDAO studentDao = (StudentDAO) context.getBean("studentJDBCTemplate"); 

विकल्प 2, इंगित करता है कि प्रॉक्सी को लक्ष्य क्लास का विस्तार करना चाहिए

<aop:config proxy-target-class="true"> 
    ... 
</aop:config> 

पहला विकल्प क्लीनर है, लेकिन स्पष्ट रूप से मैं वसंत सेम XML में मौजूद बजाय @Transactional एनोटेशन AOP घोषणाओं का उपयोग करना पसंद करते हैं: proxy-target-class विशेषता का उपयोग है। बाद में सही होने के लिए कभी-कभी भिन्न होता है और यदि आपके पास अपने घटकों पर विशिष्ट लेनदेन परीक्षण नहीं हैं, तो आप पर ध्यान दें कि चीजें गलत हैं

+0

ठीक है, अब यह काम करता है ... – AndreaNobili

2

आप aop pointcut अभिव्यक्ति में इंटरफ़ेस प्रकार निम्न पंक्ति में अर्थात् का उपयोग करना चाहिए: -

expression="execution(* org.andrea.myexample.myDeclarativeTransactionSpring.StudentJDBCTemplate.create(..))" /> 

नीचे कोड का उपयोग करें: -

expression="execution(* org.andrea.myexample.myDeclarativeTransactionSpring.StudentDAO.create(..))" /> 

स्प्रिंग प्रॉक्सी दो प्रकार का है जो के माध्यम से AOP का समर्थन करता है इंटरफ़ेस आधारित (प्रॉक्सी लक्ष्य वर्ग द्वारा लागू सभी इंटरफेस लागू करता है) और कक्षा आधारित (लक्ष्य वर्ग को उप-वर्गीकृत करके प्राप्त)।

2

मैं छात्रदाओ इंटरफ़ेस से बीन उदाहरण प्राप्त करके <aop:config> को बदले बिना निष्पादित करने में सक्षम था।

<aop:config> 
     <aop:pointcut id="createOperation" 
     expression="execution(* com.tutorialspoint.StudentJDBCTemplate.create(..))"/> 
     <aop:advisor advice-ref="txAdvice" pointcut-ref="createOperation"/> 
</aop:config> 

StudentDAO studentJDBCTemplate = (StudentDAO)context.getBean("studentJDBCTemplate"); 
संबंधित मुद्दे