Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 12

Discussione: Problemi con JPQL

  1. #1

    Problemi con JPQL

    Sto costruendo un progetto Java con Spring, utilizzando Hibernate/JPA. La entity è molto semplice, utilizzo un tabella con 3 campi:
    (vedi codice). passando alla costruzione dei servizi, tutto bene finchè utilizzo JPQL semplice(caso 1), ma appena cerco di creare query più complesse, mi da errore anche solo esplodendo i campi (caso 2).
    L'errore che restituisce è [Ljava.lang.Object; cannot be cast to it.miaapp.entity.Book
    Qualcuno sa darmi una mano? Grazie

    Codice PHP:
      @Entity
      
    @Table(name "BOOKS")
      public class 
    Book implements Serializable {
            
      @
    Id    
      
    @Column(name "ISBN")
      
    String isbn;

      @
    Column(name "AUTHOR")
      
    String author;
        
      @
    Column(name "TITLE")
      
    String title;

      
    get e set...

      
    // caso 1
      
    @Override
      
    public List<BookgetBook() {
          
    Query q em.createQuery("SELECT u FROM Book u");
          return 
    q.getResultList();
            
      }

      
    // caso 2
      
    @Override
      
    public Book getBook1(String modBook) {
          
    Query q em.createQuery("SELECT u.isbn, u.author, u.title FROM Book u where isbn='" modBook "'");
          return (
    Bookq.getSingleResult();
            
      } 
    Valli di Chioggia
    Blog di Excel VBA Microsoft Excel e Visual basic
    Bacheca Padova Annunci gratuiti
    AAA Padova Annunci a Padova

  2. #2
    premetto che di hibernate nn ne so praticamente nulla. Però mi pare di capire che nella select tu vai a tirare fuori solo alcuni campi. quindi nn hai l'oggetto Book ma una serie di campi. Secondo me se provi ad usare una query del genere "SELECT u FROM Book u where isbn=..." dovresti risolvere il problema. Poi nel metodo che richiama questo vai a selezionarti solo i campi che ti interessano

  3. #3
    Utente di HTML.it
    Registrato dal
    Feb 2007
    Messaggi
    4,157
    scusa quando hai problemi di cast cerchiamo di capire i tipi ritornati. A quanto pare tu hai una collection di object, non un solo oggetto (come pensi).

    Per quanto mi riguarda, se ti aspetti un solo result, prova

    Codice PHP:
     @Override 
      
    public List<BookgetBook() { 
          
    Query q em.createQuery("SELECT u FROM Book u where ...."); 
          return 
    q.getResultList().get(0); 
             
      } 
    anche se non è ottimizzato
    RTFM Read That F*** Manual!!!

  4. #4
    Innanzitutto grazie delle risposte.
    Il punto non è questo, quello che sto cercando di scoprire è se con JPA riesco a gestire query complesse che non siano Select semplici.
    Ad esempio query che estraggano solo alcuni campi a cui applicare funzioni di aggregazione come: COUNT, MAX, MIN o meglio ancora JOIN fra tabelle.
    La cosa che non riesco a capire è come farmi restituire da una query in JPA qualcosa che non sia strettamente una entity. Ho provato a creare una query SQL e ad associarla ad una classe che non sia una entità associata ad una tabella con questa codifica:
    Codice PHP:
    Query q em.createNativeQuery("SELECT isbn, author, title FROM Book"it.miaapp.entity.Bookx.class); 
    dove bookx è una semplice classe di appoggio, ma non riesce a castarla!
    Ho trovato nel web una struttura di questo tipo da inserire nella classe:
    Codice PHP:
    @SqlResultSetMapping(name="Bookx",  entities =@EntityResult
    (entityClass=it.miaapp.entity.Bookx.class , fields= {
        @
    FieldResult(name="isbn"column="isbn"),
        @
    FieldResult(name="author"column="author"),
        @
    FieldResult(name="title"column="title")                
    }) 
    ma niente da fare.... una entity deve obbligatoriamente essere riferito ad una tabella nel DB!!!?????
    Valli di Chioggia
    Blog di Excel VBA Microsoft Excel e Visual basic
    Bacheca Padova Annunci gratuiti
    AAA Padova Annunci a Padova

  5. #5
    Utente di HTML.it
    Registrato dal
    Feb 2007
    Messaggi
    4,157
    non sono sicurissima (non ho mai visto realmente quella parte), ma a naso direi di si (visti anche i principi su cui si basa).
    ovviamente di query complesse è possibile farne, bisogna vedere bene la documentazione.
    Senza sapere nè leggere nè scrivere questo link lo trovo interessante
    RTFM Read That F*** Manual!!!

  6. #6
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,326
    Sì, è possibile gestire query che estraggano solo un sottoinsieme di campi, ma non è proprio così "semplice". Le cose si dividono in due tipologie:

    1) Se devi estrarre un solo campo, lo puoi fare in quanto otterrai come risultato un List<Tipo> dove Tipo sarà uno dei tipi "base": Integer, Long, String, ecc... chiaramente, il tipo corrispondente del campo che devi estrarre.

    2) Se devi estrarre una tupla qualunque (che può essere un sottoinsieme dei campi di una entità, oppure l'unione di più campi provenienti da più entità), dovrai prevedere la creazione di una classe apposita (non una Entity) in grado di modellare il record che verrà estratto.

    Vediamo un esempio.
    Posso avere le seguendi due Entity:

    codice:
    @Entity
    public class Prodotto {
       @Id private String codiceProdotto;
       private String descrizioneProdotto;
       private String codiceClassificazione;
       ...
    }
    
    @Entity
    public class Classificazione {
       @Id private String codiceClassificazione;
       private String descrizioneClassificazione;
       ...
    }
    Suppongo di voler estrarre ciascun prodotto con la descrizione della sua classificazione. Creo una classe (non una entity!) che modelli il record che voglio estrarre:

    codice:
    package pippo;
    
    public class ProdClass {
       private String codiceProdotto;
       private String descrizioneProdotto;
       private String descrizioneClassificazione;
    
       public ProdClass(String codiceProdotto, String descrizioneProdotto, String descrizioneClassificazione) {
          ...
       }
    }
    E posso scrivere la seguente istruzione JPQL:

    codice:
    SELECT NEW pippo.ProdClass(p.codiceProdotto, p.descrizioneProdotto, c.descrizioneClassificazione)
    FROM Prodotto p, Classificazione c
    WHERE (p.codiceClassificazione = c.codiceClassificazione)
    Ciao.
    "Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
    Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza

  7. #7
    Grazie della Risposta LeleTF, porta pazienza ma non riesco a capire come posso usare le informazioni indicate nel punto 2 alla struttura su cui sto lavorando.
    Premetto che il progetto si basa su una struttura abbastanza ostica basata su Spring+JPA+Hibernate.
    Nel pacchetto entità sono definite tutte le entità che rappresentano il collegamento con le tabelle del DB.
    All’interno del pacchetto Service vengono definiti i servizi per eseguire le query e restituire i dati nelle entità ed utilizzano EntityManager Esempio:
    codice:
      
    Su BookService.java
    public interface BookService {
    
    	public List<Book> getBook();
    }
    Su BookServiceImpl.java
    @Transactional(value = "bookTransactionManager")
    public class BookServiceImpl implements BookService{
    
    
    	private EntityManager em;
    	// private Book u = new Book();
    
    	@Override
    	public List<Book> getBook() {
    		Query q = em.createQuery("SELECT u FROM Book u");
    		return q.getResultList();
    		
    	}
    }
    I vari servizi vengono poi chiamati secondo le necessità dalle ActionBean. Tutti i parametri di connessione e la definizione dei servizi sono mappati su un documento: applicationcontext.xml
    Detto questo come si pone la classe “ProdClass” che mi hai indicato? Inoltre riesco a definire quel codice JPQL che mi proponi di esempio utilizzando EntityManager? ESEMPIO:
    codice:
    	public List< ProdClass> getBook() {
    		Query q = em.createQuery("SELECT NEW pippo.ProdClass(p.codiceProdotto, p.descrizioneProdotto,c.descrizioneClassificazione)
    FROM Prodotto p, Classificazione c WHERE (p.codiceClassificazione = c.codiceClassificazione)");
    		return q.getResultList();
    		
    	}
    Procedendo così temo che mi risponda che non riesce a castare la classe...
    Grazie della pazienza
    Valli di Chioggia
    Blog di Excel VBA Microsoft Excel e Visual basic
    Bacheca Padova Annunci gratuiti
    AAA Padova Annunci a Padova

  8. #8
    Ok grazie al link di Valia forse ci ho capito qualcosa sull'esempio di LeleTF. Traduco e posto:

    JPA supporta i risultati delle query JPQL con le istanze delle classi risultato personalizzate. Ciò è utile per le interrogazioni con più espressioni SELECT, dove gli oggetti personalizzati risultato possono fornire un'alternativa object oriented a rappresentare i risultati come Object [] elementi.
    Il nome completo della classe risultato è specificato in una nuova espressione, come segue:

    codice:
    SELECT NEW example.CountryAndCapital(c.name, c.capital.name)
    La classe risultato deve avere un costruttore compatibile che corrisponda alle espressioni di risultato SELECT, come segue:
    codice:
    package example;
     
    public class CountryAndCapital {
        public String countryName;
        public String capitalName;
     
        public CountryAndCapital(String countryName, String capitalName) {
            this.countryName = countryName;
            this.capitalName = capitalName;
        }
    }
    Il codice seguente mostra l'esecuzione di questa query:

    codice:
      String queryStr =
          "SELECT NEW example.CountryAndCapital(c.name, c.capital.name) " +
          "FROM Country AS c";
      TypedQuery<CountryAndCaiptal> query =
          em.createQuery(queryStr, CountryAndCaiptal.class);
      List<CountryAndCaiptal> results = query.getResultList();
    Valli di Chioggia
    Blog di Excel VBA Microsoft Excel e Visual basic
    Bacheca Padova Annunci gratuiti
    AAA Padova Annunci a Padova

  9. #9
    Come da indicazioni ho creato la classe di appoggio che mette in relazione la tabella Book ed Autore

    codice:
    public class BookAndAutore {
    	   private String title;
    	   private String author;
    	   private int eta;
    
    	   public BookAndAutore(String title, String author, int eta) {
    	        this.title = title;
    	        this.author = author;
    	        this.eta = eta;
    	        
    	   }
    	}
    Nel creare il service però trovo già un inghippo. Il metodo createQuery non accetta la classe e mi restituisce errore in compilazione:
    The method createQuery(String) in the type EntityManager is not applicable for the arguments
    Ecco il metodo:

    codice:
    	public List<BookAndAutore>  getBookAutore() {
    		String queryStr = "select it.miaapp.entity.BookAndAutore(p.title, p.author, c.eta) from books p, autore c where (p.author = c.author)";
    
    		TypedQuery<BookAndAutore> query =  em.createQuery(queryStr, BookAndAutore.class);
    		List<BookAndAutore> results = query.getResultList();
    
    	}
    Qualcuno ha qualche idea?
    Grazie
    Valli di Chioggia
    Blog di Excel VBA Microsoft Excel e Visual basic
    Bacheca Padova Annunci gratuiti
    AAA Padova Annunci a Padova

  10. #10
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,326
    Sì, ci sono fondamentalmente due errori:

    1) La query va sistemata (manca il NEW):
    codice:
    String queryStr = "select new it.miaapp.entity.BookAndAutore(p.title, p.author, c.eta) from books p, autore c where (p.author = c.author)";
    2) Non puoi usare una TypedQuery. TypedQuery funziona solo con le Entity, ma tu non stai restituendo un'Entity. Usa una query semplice:

    codice:
    Query q = em.createQuery( queryStr );
    List<BookAndAutore> results = query.getResultList();
    Potresti ricevere un warning in compilazione in quanto stai effettuando un cast non sicuro.


    Ciao.
    "Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
    Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.