Se volete "persistere" qualcosa dovete avere una implementazione di JPA
Eclipse esce con una implementazione che non conosco, Eclipselink o qualcosa di simile.
Voglio provare a usare hibernate visto che già lo conosco.
Seguiamo questo link (è per ganymede) : http://edemmorny.wordpress.com/2009/04/28/using-eclipse-dali-with-hibernate-as-persistence-provider/
Eclipse Galileo è già installato
Andando su https://www.hibernate.org/ scarico :
hibernate entitymanager, hibernate annotations (due zip per oltre 16MB ed uno sgrugnafalco di files)
Decomprimo in due comode cartelle
Cosa fare ora è un tantino oscuro ...
Proviamo la strada della libreria :
Copiamo i files ch pare servano in una cartella nel workspace :
* slf4j-api.jar
* dom4j.jar
* ejb3-persistence.jar
* hibernate-annotations.jar
* hibernate-commons-annotations.jar
* hibernate-core.jar
* javassist.jar
* jta.jar
N.B. stanno tutte nello scompattato di entitymanager, cartella lib, quindi annotations non serve a nulla !
Ora libreria, menu windows tanto per cambiare !!!
Window>>Preferences>>Java>>Build Path>>User Libraries
New Library, nome HIBERNATEJPA, add jars ed aggiungiamo tutti i jar di cui sopra, fatta la libreria.
Ora, proprietà del progettino ejbTest per aggiungerla
Project Facets
mettiamo il check in Java Persistence
Nella parte bassa della finestra viene fuori un link : Further configuration available
Clikkiamo li, ci si apre una finestrella popup
Lasciamo Platform -> Generic
Scegliamo in Jpa Implementation Type -> User Library
Andiamo a mettere la spunta sulla nostra HIBERNATEJPA
Per precauzione, visto che il progetto al momento è deployato sotto a JBoss che ha hibernate di suo
Tolgo la spunta da (non ricordo il testo esatto cmq qualcosa tipo) Deploy ste library with il project
Ora siamo a mezza strada, abbiamo il supporto JPA ma ci manca un connector ed un database e qualche
class ed Entity per verificare se va ... ma sono le 22:30 e sinceramente mi pare troppo da affrontare ora.
Abbloggo il blog con Ejb e continuo nel weekend.
Prove e provettine di Database
Il necessario :
- Mysql server (e chi non ha un server mysql installato al giorno d'oggi)
- Tutto il minestrone d'eclipse e progetto ejb/jsf/jpa/etc visto nei precedenti post
- Pazienza e speranza
Per prima cosa, creiamoci il nostro database di prova
Andate su mysql, con qualunque client vogliate, e digitiamo le seguenti query :
create database ejbTest; grant all on ejbTest.* to 'prova'@'%' identified by 'prova'; use ejbTest; create table usertest ( id bigint(20) NOT NULL auto_increment, user varchar(50) NOT NULL, pass varchar(50) NOT NULL, firstName varchar(50) NOT NULL, lastName varchar(50) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB;
A questo punto avete il vostro database, il nostro scopo ora è di collegare questo database al lato ejb della nostra applicazione di prova e cercare di leggere/scrivere un record.
(N.B. di seguito assumo di usare la configurazione default per jboss .. se avete configurato jboss diversamente dovreste essere in grado di saper variare queste istruzioni di conseguenza !!! :D)
Ci serve un datasource per Jboss, che ha sta pretesa di vedere i database solo se gli si passa qualche datasource
Ergo :
a] Per collegare java a mysql ci serve un connector jdbc :
- google search per mysql connector
- download del connector (formato zip o gz)
- scompattare
- copiare dalla cartella scompattata mysql-connector-java-un_po_di_numeri_.jar dentro a : CARTELLA_DI_JBOSS/server/default/lib
b] dire a jboss che datasource vogliamo utilizzare (ovvero che database e su che server visto che le connessioni le creerà jboss) :
- Creare un bel file ejbTest-ds.xml
[contenuto file ejbTest-ds.xml]
<datasources> <local-tx-datasource> <jndi-name>ejbTestDS</jndi-name> <connection-url>jdbc:mysql://localhost:3306/ejbTest</connection-url> <driver-class>com.mysql.jdbc.Driver</driver-class> <user-name>prova</user-name> <password>prova</password> </local-tx-datasource> </datasources>
- copiare il file in CARTELLA_DI_JBOSS/server/default/deploy
(ora dovremmo aver fatto tutto ciò che serve esternamente al progetto, torniamo ad eclipse de Sol)
Aggiunto jpa di hibernate al progetto dovremmo avere la voce JPA Content con sotto persistence.xml
Apriamolo in modifica (tab source di sotto !!!) e scriviamo :
<jta-data-source>java:/ejbTestDS</jta-data-source>
<properties>
<property name="hibernate.dialect"
value="org.hibernate.dialect.MySQLDialect"/>
</properties>
Sembra poco (anche a me sembrava pochissimo, e difatti credevo che non andasse nulla), ma basta.
Cominciamo a disegnare la nostra applicazionciella
La classe che rappresenterà i record della nostra tabella : Usertest
N.B.
@Entity significa che mappa una entità (tabella)
@Id indica che il campo è la chiave univoca dei record
@GeneratedValue indica che i valori del campo id viene generato dal database
Classe Usertest.java
package org.tutorial.jpa.impl;
import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
@Entity (name="usertest")
public class Usertest implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
public Usertest() {
}
/**
* @param id the id to set
*/
public void setId(Long id) {
this.id = id;
}
/**
* @return the id
*/
@Id
@GeneratedValue
public Long getId() {
return id;
}
/**
* @param user the user to set
*/
public void setUser(String user) {
this.user = user;
}
/**
* @return the user
*/
public String getUser() {
return user;
}
/**
* @param pass the pass to set
*/
public void setPass(String pass) {
this.pass = pass;
}
/**
* @return the pass
*/
public String getPass() {
return pass;
}
/**
* @param firstName the firstName to set
*/
public void setFirstName(String firstName) {
this.firstName = firstName;
}
/**
* @return the firstName
*/
public String getFirstName() {
return firstName;
}
/**
* @param lastName the lastName to set
*/
public void setLastName(String lastName) {
this.lastName = lastName;
}
/**
* @return the lastName
*/
public String getLastName() {
return lastName;
}
private Long id;
private String user;
private String pass;
private String firstName;
private String lastName;
}
Una bella interfaccia per una classe Stateless da richiamare dalla parte web per leggere o salvare degli Usertest
Interfaccia UsertestFacade.java
package org.tutorial.jpa;
import javax.ejb.Remote;
import org.tutorial.jpa.impl.Usertest;
@Remote
public interface UsertestFacade {
public abstract Usertest getPerson(String user);
public abstract Usertest save(Usertest usertest);
}
Una classe che implementi UsertestFacade per farci i ragionamenti che servono :
Classe UsertestFacadeBean.java
package org.tutorial.jpa.impl;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import org.tutorial.jpa.UsertestFacade;
@Stateless (mappedName="UsertestFacade")
public class UsertestFacadeBean implements UsertestFacade {
@PersistenceContext(unitName="EjbTestPU") EntityManager em;
/* (non-Javadoc)
* @see org.tutorial.jpa.impl.UsertestFacade#getPerson(java.lang.String)
*/
public Usertest getPerson(String user) {
Usertest entity = null;
try {
Query query = em.createQuery("SELECT u FROM usertest u WHERE u.user = ?1");
query.setParameter(1, user);
entity = (Usertest) query.getSingleResult();
}
catch (NoResultException noneFound) {
// if not found, just return null
}
return entity;
}
/* (non-Javadoc)
* @see org.tutorial.jpa.impl.UsertestFacade#save(org.tutorial.jpa.impl.Usertest)
*/
public Usertest save(Usertest usertest) {
em.persist(usertest);
return usertest;
}
}
Se mentre scrivete queste classi vi capita come a me che il Eclipse segnala vari e fantasiosi errori, fate un clean ogni tanto oppure togliete l'autocompile che sembra che faccia un po' di casotto.
Fatto questo, ricreiamo i packages anche nel progetto web e copiamoci dentro Usertest.java e UsertestFacade.java (le implementazioni non servono)
Apriamo il nostro solito login.jsp ed aggiungiamo :
<%@page import="org.tutorial.jpa.*, org.tutorial.jpa.impl.* "%>
<%
Usertest ut = new Usertest();
ut.setUser("prova");
ut.setPass("prova");
ut.setFirstName("Jingle");
ut.setLastName("Bells");
UsertestFacade utf = (UsertestFacade)context.lookup("UsertestFacade");
// Salvo il nuovo Usertest
utf.save(ut);
// rileggo lo Usertest appena salvato
Usertest ut1 = utf.getPerson("prova");
%>
<%=ut1.getUser()%>
E dovremmo vedere scritto in giro il nostro user appena salvato :)
Problemi Aperti :
Q] Dipendenze, la mia applicazione web dipende dalle classi e dalle interfacce definite nel modulo ejb, come faccio a fargliele vedere senza dover sempre copiare/incollare le classi dall'ejb al progetto web ?
A] Mettere dipendenza da un progetto all'altro, ovvero nelle properties del progetto web, scegliete build paths ed andate a dirgli che dipende dal progetto ejb. In questo modo potete evitare di copiare sempre le classi interfacce ed altro dal progetto ejb a quello web.
Q] Il mio eclipse non riconosce che jboss è partito, rimane sempre in starting Jboss anche dopo la fine dell'avvio. Posso lavorare ma allo scadere del wait timeout configurato su eclipse, il buon ide mi secca l'istanza di jboss !
A] Lo fa pure a me e non ho ancora trovato soluzione tranne dargli qualche ora di tempo per lo start.
Nessun commento:
Posta un commento