Java Enterprise Tutorial – Named query parametriche

Nel seguente tutorial non porremo troppa attenzione sugli aspetti riguardandi l’IDE o la creazione di file e classi ma solo sugli aspetti più dettagliati del codice, di conseguenza si presume che il lettore dovrebbe già avere una conoscenza di base del contesto Enterprise.
Se volete un’infarinatura potete seguire il tutorial base sul mio blog.
Vi ricordo, inoltre, che il progetto di esempio e tutti i riferimenti all’ambiente di sviluppo sono da riverirsi a l’IDE Netbeans 6.5.

Dopo l’introduzione alle named query, vediamo più nel dettaglio il loro funzionamento.
Nel caso volessimo una classica query di selezione, discriminando in base ad uno o più valori, possiamo preparare una named query personalizzata che accetti i parametri necessari.
Facendo sempre riferimento al progetto oggetto del tutorial di introduzione alle named query modifichiamo l’entity bean “Users” aggiungendo una named query per eseguire una LIKE sul campo name.
Sriviamo la query in questo modo aggiungendola alla lista delle altre named query ricordandoci che il separatore tra le named query è la virgola.

@NamedQuery(name = "Users.like", query = "SELECT u FROM Users u WHERE u.name LIKE :name")

Come si può notare la stringa :name verrà sostituita dal parametro che andremo a settare prima dell’esecuzione della query, utilizzando l’etichetta “name” potremo infatti assegnare un valore arbitrario.
Volendo avremmo anche potuto mettere al posto della stringa :name la stringa :1 utilizzando la notazione posizionale e quindi passare i parametri in ordine invece che in base ad un etichetta.

Una volta aggiunta la nostra named query prepariamo un metodo per richiamarla in un session bean, utilizziamo sempre lo stesso bean chiamato “UserServeBean” e creiamo un metodo UsersLike così scritto.

public List UsersLike(String value){
EntityManager em=emf.createEntityManager();
Query q=em.createNamedQuery("Users.like");
q.setParameter("name", value);
List l=q.getResultList();
return l;
}

Poniamo la nostra attenzione sulla riga q.setParameter(“name”, value); in questo modo andiamo a settare all’etichetta “name” il valore passato al metodo identificato dalla variabile value.
Per verificare il corretto funzionamento della query creiamo una servlet che invocherà il metodo, chiamiamola UsersLike, essa rivecerà un parametro in POST e lo passerà al metodo restituendo la lista dei risultati.

package servlet;
import entity.Users;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;
import java.util.ListIterator;
import javax.ejb.EJB;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import session.UserServeRemote;
/**
*
* @author Mauro the King
*/
public class UsersLike extends HttpServlet {
@EJB
private UserServeRemote userServeBean;
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
String value = request.getParameter("value");
try {
List<Users> list = userServeBean.UsersLike(value+"%");
ListIterator<Users> it = list.listIterator();
out.println("<html>");
out.println("<head>");
out.println("<title>Servlet UserList</title>");
out.println("</head>");
out.println("<body>");
if (list.size() == 0) {
out.println("Nessun risultato");
} else {
while (it.hasNext()) {
Users temp = it.next();
out.println("<br>-Nome: " + temp.getName() + "<br>-Cognome: " + temp.getSurname() + "<br>-Email: " + temp.getEmail());
out.println("<br>----------------------------<br>");
}
}
out.println("</body>");
out.println("</html>");
} finally {
out.close();
}
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}
@Override
public String getServletInfo() {
return "Short description";
}// </editor-fold>
}

Non ci resta che creare una pagina JSP con una bella form che invii in POST una variabile value alla servlet.
Per creare una pagina JSP è sufficiente fare click destro nel WAR project sulla cartella Web Pages e poi ->Nuovo->JSP.
Chiamiamo la pagina searchUser e inseriamo un form con un campo di testo e un pulsante, in questo modo.

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>JSP Page</title>
</head>
<body>
<form action="UsersLike" method="POST">
<input type="text" name="value" size="20"><br>
<input type="submit" value="CERCA">
</form>
</body>
</html>

Ora non ci resta che provare, buildiamo e deployamo il tutto e proviamo a fare una ricerca spostandoci sulla pagina searchUser.jsp, inserite una stringa qualsiasi ricordando che la servlet aggiungerà alla stringa inserita il valore ‘%’ in modo da ottenere come risultato tutti gli utenti che hanno il nome che inizia per la chiave inserita.
Ricordate di scaricare il dump del database usato per questo tutorial ,se non lo avete già fatto, e di inserire qualche record all’interno del db :-) prima di effettuare il test.
Potete, come sempre, scaricare il progetto di esempio completo dei contenuti del seguente tutorial.

  • mauro

    complimeti per ituoi tutorial.
    Hai anche qualcosa su struts??????? sempre su netbeans?

    ho provato questa sezione sulle query parametriche , ma la risèposta è una pagina che non trova nulla. puoi aiutarmi?
    grazie mauro

  • Mauro Rocco

    Ancora non ho preparato niente su struts volevo affrontare prima argomenti come le transazioni e client CORBA stand alone per poi passare ai framework come struts, quindi penso che ci vorrà ancora un pò per vedere sul mio sito tutorial su struts.
    Per quanto riguarda l’errore dovresi darmi qualche dettaglio in più come ad esempio lo stack trace di glassfish.
    Ti da lo stesso errore se utilizzi il progetto completo a fine articolo?
    Ciao e grazie per i complimenti :-)

  • mauro

    devo dire che per evitare di modificare la classe dentity ho creato il db in mysql.
    se vuoi ti invio il mio progetto e il file dump di mysql –
    Sarebbe molto interessante vedere pubblicato qualcosa su corba , anche per capire come fare a richiamare un Ejb da un altro Ejb situato su in seerver diverso.

    La risorsa JNDI in prativica viene creata nal server che ospita l’ejb che vogliamo richiamare???
    ma poi come faccio a sapere dove si trova l’ejb se lo richiamo in una applicazione o Ejb che si trpva su un altro server?

    HO notato su glassfish che in configurazione ORB: iiop vi è un pannello dove sono inserite i numeri di porte relkative ai listeners …. inoltre dice di inserire dei numeri di network adress che sono segnate per ora come 0.0.0.0 Come funziona la cosa? Se puoi rispondimi anche in privato .grazie mille .
    Inoltre in una applicaz web si possono inserire delle refernze a ejb nel file descriptor.. (vi è un tools visulae dove aggiungerele ma senza un esempio +è dura)..
    Ciao E ancora grazie mauro

  • Mauro Rocco

    Si, la risorsa JNDI viene fornita dal server che osbita l’ejb, quando la chiamata deve avvenire da un altro server o client stand alone bisogna settare anche proprietà come url, porta di ascolto e eventuali credenziali di autenticazione per l’invio della richiesta CORBA.
    Solitamente glassfish resta in ascolto delle richieste CORBA sulla porta 3700, il listener di default è attivato quindi il tuo server può già ricevere richieste remote.
    Per quando riguarda l’applicazione web, con netbeans creando una chiamata ad un’entity, come nel mio tutorial, il riferimento all’ejb viene già inserito nel descriptor xml come puoi notare leggendo il codice xml sorgente.
    Il tuo progetto puoi inviarmelo all’indirizzo info@rmhomepages.com
    In merito a CORBA e richieste remote devi pazientare solo un paio di giorni e avrai on line un bel tutorial :-)
    Ciao

  • Alberto

    Ciao Mauro…scusa se ti disturbo ancora, continuando a sviluppare l’applicazione seguendo i tuoi tutorial mi sono trovato di fronte ad un altro errore e non riesco a capire cosa sia…leggendo qua e là su internet si dice sia qualke bug di NetBeans 6 e glassfish nel load dei session bean dicendo che nel deploy non riesce a sostituire i vecchi con i nuovi session bean ma nn so quanto possa essere vero…una parte dell’errore è la seguente:

    CORE5021: Application NOT loaded: [EnterpriseApplication]
    ADM1075:Error on listening event:[Error while loading application [EnterpriseApplication]. Please refer to the server log for more details. ]
    deployed with moduleid = EnterpriseApplication
    naming.bind
    EJB5090: Exception in creating EJB container [javax.naming.NameAlreadyBoundException: Use rebind to override]
    appId=EnterpriseApplication moduleName=EnterpriseApplication-ejb_jar ejbName=UserServeBean
    LDR5012: Jndi name conflict found in [EnterpriseApplication]. Jndi name [session.UserServeRemote] for bean [UserServeBean] is already in use.
    LDR5013: Naming exception while creating EJB container:
    javax.naming.NameAlreadyBoundException: Use rebind to override

  • Mauro Rocco

    Potrebbe anche essere che hai caricato in precedenza lo stesso bean (stesso JNDI name) ma in un package ejb di diverso nome, in questo caso risultano due progetti differenti ma stesso nome del bean .
    Puoi risolvere aprendo l’interfaccia di amministrazione web di Glassfish!
    Spostati sul Tab Services e poi in basso espandi il nodo Server, tasto destro su Glassfish V2->start (se non è già avviato) e poi sempre tasto destro su GlassfishV2-> View admin console
    A questo punto dovrebbe aprirti nel browser l’interfaccia di admin che solitamente si trova a un’indirizzo simile a questo http://localhost:13030/login.jsf (la porta può variare a secondo dell’OS o per altri parametri).
    Per entrare, se non hai cambiato le configurazioni di default, la user è admin e la pass adminadmin.
    Ora puoi fare l’undeploy dei progetti spostandoti sul nodo relativo ai progetti nel menù a sinistra vedrai un elenco dei vari progetti con un bel pulsante undeploy.
    Una volta fatto dovresti poter deployare da netbeans senza problemi.
    Spero che così tu riesca a risolvere il problema.
    Ciao :-)

  • Alberto

    Ho risolto, grazie mille… 😉

  • Vincenzo

    Ciao, volevo ringraziarti e possibilmente farti una statua (virtuale s’intende!) per l’enorme aiuto che mi hai dato con questo tutorial per altro fatto davvero egregiamente!

    Mi hai risolto un problema che mi teneva bloccato da mesi perchè il caro prof non sapeva nemmeno come funziona la persistenza negli ejb, fugurarsi le query!!!!

    Ora che l’ho trovato verrò spesso a farti visita in questo blog! 😛

    Grazie ancora e buon natale!!! :)

  • Mauro Rocco

    Grazie mille Vincenzo, buon natale a te e a tutti gli internauti, mi dispiace solamente di non trovare molto tempo per scrivere ancora ma spero che nel 2010 possa pubblicare qualche altro articolo interessante e qualche tricks su J2EE.
    Grazie ancora