SeamFramework.orgCommunity Documentation
Motori di ricerca full text come Apache Lucene™ sono una potentissima tecnologia che fornisce alle applicazioni efficienti query full text. Hibernate Search, che utilizza Apache Lucene al suo interno, indicizza il modello di dominio con l'aggiunta di alcune annotazioni, si prende cura del database, della sincronizzazione degli indici e restituisce oggetti regolari gestiti che corrispondono alle query full text. Tuttavia si tenga presente che ci sono delle irregolarità quando si ha a che fare con un modello di dominio a oggetti sopra ad un indice di testo (mantenere l'indice aggiornato, irregolarità tra la struttura dell'indice ed il modello di dominio, e irregolarità di query). Ma i benefici di velocità ed efficienza superano di gran lunga queste limitazioni.
Hibernate Search è stato progettato per integrarsi nel modo più naturale possibile con JPA ed Hibernate. Essendo una naturale estensione, JBoss Seam fornisce l'integrazione con Hibernate Search.
Si prega di riferirsi alla documentazione Hibernate Search per informazioni sul progetto Hibernate Search.
Hibernate Search è configurato in uno dei file META-INF/persistence.xml
o hibernate.cfg.xml
.
La configurazione di Hibernate Search ha dei valori di default impostati per la maggior parte dei parametri di configurazione. Ecco qua una configurazione minimale di persistence unit per poter iniziare.
<persistence-unit name="sample">
<jta-data-source
>java:/DefaultDS</jta-data-source>
<properties>
[...]
<!-- utilizza un file system basato su indice -->
<property name="hibernate.search.default.directory_provider"
value="org.hibernate.search.store.FSDirectoryProvider"/>
<!-- directory dove gli indici verranno memorizzati -->
<property name="hibernate.search.default.indexBase"
value="/Users/prod/apps/dvdstore/dvdindexes"/>
</properties>
</persistence-unit
>
Se si pensa di usare Hibernate Annotation o EntityManager 3.2.x (incorporato in JBoss AS 4.2.x e successivi), occorre configurare anche gli opportuni event listener.
<persistence-unit name="sample">
<jta-data-source
>java:/DefaultDS</jta-data-source>
<properties>
[...]
<!-- utilizza un file system basato su indice -->
<property name="hibernate.search.default.directory_provider"
value="org.hibernate.search.store.FSDirectoryProvider"/>
<!-- directory dove gli indici verranno memorizzati -->
<property name="hibernate.search.default.indexBase"
value="/Users/prod/apps/dvdstore/dvdindexes"/>
<property name="hibernate.ejb.event.post-insert"
value="org.hibernate.search.event.FullTextIndexEventListener"/>
<property name="hibernate.ejb.event.post-update"
value="org.hibernate.search.event.FullTextIndexEventListener"/>
<property name="hibernate.ejb.event.post-delete"
value="org.hibernate.search.event.FullTextIndexEventListener"/>
</properties>
</persistence-unit
>
Questo passo non è più necessario se vengono utilizzati Hibernate Annotation o EntityManager 3.3.x.
In aggiunta al file di configurazione, devono essere deployati i seguenti jar:
hibernate-search.jar
hibernate-commons-annotations.jar
lucene-core.jar
Se vengono messi in un EAR, non si dimentichi di aggiornare application.xml
Hibernate Search impiega annotazioni per mappare le entità ad un indice di Lucene, per maggiori informazioni si guardi alla documentazione di riferimento.
Hibernate Search è pienamente integrato con la API e la semantica di JPA/Hibernate. Passare da una query basata su HQL o Criteria richiede solo poche linee di codice. La principale API con cui l'applicazione interagisce è l'API FullTextSession
(sottoclasse della Session
di Hibernate).
Quando Hibernate Search è presente, JBoss Seam inietta una FullTextSession
.
@Stateful
@Name("search")
public class FullTextSearchAction implements FullTextSearch, Serializable {
@In FullTextSession session;
public void search(String searchString) {
org.apache.lucene.search.Query luceneQuery = getLuceneQuery();
org.hibernate.Query query session.createFullTextQuery(luceneQuery, Product.class);
searchResults = query
.setMaxResults(pageSize + 1)
.setFirstResult(pageSize * currentPage)
.list();
}
[...]
}
FullTextSession
estende org.hibernate.Session
così che può essere usata come una regolare Hibernate Session.
Se viene usata la Java Persistence API, è proposta un'integrazione più lieve.
@Stateful
@Name("search")
public class FullTextSearchAction implements FullTextSearch, Serializable {
@In FullTextEntityManager em;
public void search(String searchString) {
org.apache.lucene.search.Query luceneQuery = getLuceneQuery();
javax.persistence.Query query = em.createFullTextQuery(luceneQuery, Product.class);
searchResults = query
.setMaxResults(pageSize + 1)
.setFirstResult(pageSize * currentPage)
.getResultList();
}
[...]
}
Quando Hibernate Search è presente, viene iniettato un FulltextEntityManager
. FullTextEntityManager
estende EntityManager
con metodi specifici di ricerca, allo stesso modo FullTextSession
estende Session
.
Quando viene impiegata l'iniezione di un session bean EJB3.0 o message driven (cioè tramite l'annotazione @PersistenceContext), non è possibile rimpiazzare l'interfaccia EntityManager
con l'interfaccia FullTextEntityManager
nella dichiarazione. Comunque l'implementazione iniettata sarà FullTextEntityManager
: è quindi possibile il downcasting.
@Stateful
@Name("search")
public class FullTextSearchAction implements FullTextSearch, Serializable {
@PersistenceContext EntityManager em;
public void search(String searchString) {
org.apache.lucene.search.Query luceneQuery = getLuceneQuery();
FullTextEntityManager ftEm = (FullTextEntityManager) em;
javax.persistence.Query query = ftEm.createFullTextQuery(luceneQuery, Product.class);
searchResults = query
.setMaxResults(pageSize + 1)
.setFirstResult(pageSize * currentPage)
.getResultList();
}
[...]
}
Per persone abituate a Hibernate Seam fuori da Seam, notare che l'uso di Search.createFullTextSession
non è necessario.
Controlla gli esempi DVDStore o Blog della distribuzione di JBoss Seam per un uso pratico di Hibernate Search.