[hibernate-commits] Hibernate SVN: r11714 - in trunk/HibernateExt/search/src: java/org/hibernate/search/jpa/impl and 2 other directories.

hibernate-commits at lists.jboss.org hibernate-commits at lists.jboss.org
Sun Jun 24 14:00:46 EDT 2007


Author: epbernard
Date: 2007-06-24 14:00:46 -0400 (Sun, 24 Jun 2007)
New Revision: 11714

Added:
   trunk/HibernateExt/search/src/java/org/hibernate/search/jpa/Search.java
   trunk/HibernateExt/search/src/java/org/hibernate/search/jpa/impl/FullTextQueryImpl.java
   trunk/HibernateExt/search/src/test/org/hibernate/search/test/jpa/
   trunk/HibernateExt/search/src/test/org/hibernate/search/test/jpa/Bretzel.java
   trunk/HibernateExt/search/src/test/org/hibernate/search/test/jpa/EntityManagerTest.java
   trunk/HibernateExt/search/src/test/org/hibernate/search/test/jpa/JPATestCase.java
Log:
HSEARCH-89 JPA wrappers implementation

Added: trunk/HibernateExt/search/src/java/org/hibernate/search/jpa/Search.java
===================================================================
--- trunk/HibernateExt/search/src/java/org/hibernate/search/jpa/Search.java	                        (rev 0)
+++ trunk/HibernateExt/search/src/java/org/hibernate/search/jpa/Search.java	2007-06-24 18:00:46 UTC (rev 11714)
@@ -0,0 +1,24 @@
+//$Id$
+package org.hibernate.search.jpa;
+
+import javax.persistence.EntityManager;
+
+import org.hibernate.search.jpa.impl.FullTextEntityManagerImpl;
+
+/**
+ * Helper class that should be used when building a FullTextEntityManager
+ *
+ * @author Emmanuel Bernard
+ */
+public final class Search {
+	private Search() {
+	}
+
+	/**
+	 * Build a full text capable EntityManager
+	 * The underlying EM implementation has to be Hibernate EntityManager
+	 */
+	public static FullTextEntityManager createFullTextEntityManager(EntityManager em) {
+		return new FullTextEntityManagerImpl(em);
+	}
+}
\ No newline at end of file

Added: trunk/HibernateExt/search/src/java/org/hibernate/search/jpa/impl/FullTextQueryImpl.java
===================================================================
--- trunk/HibernateExt/search/src/java/org/hibernate/search/jpa/impl/FullTextQueryImpl.java	                        (rev 0)
+++ trunk/HibernateExt/search/src/java/org/hibernate/search/jpa/impl/FullTextQueryImpl.java	2007-06-24 18:00:46 UTC (rev 11714)
@@ -0,0 +1,247 @@
+//$Id$
+package org.hibernate.search.jpa.impl;
+
+import java.util.List;
+import java.util.Date;
+import java.util.Calendar;
+import java.util.Set;
+import java.util.HashSet;
+import java.io.Serializable;
+import javax.persistence.Query;
+import javax.persistence.TemporalType;
+import javax.persistence.FlushModeType;
+import javax.persistence.NoResultException;
+import javax.persistence.NonUniqueResultException;
+import javax.persistence.PersistenceException;
+import javax.persistence.EntityExistsException;
+import javax.persistence.EntityNotFoundException;
+import javax.persistence.OptimisticLockException;
+
+import org.hibernate.search.jpa.FullTextQuery;
+import org.hibernate.search.SearchException;
+import org.hibernate.Criteria;
+import org.hibernate.TypeMismatchException;
+import org.hibernate.HibernateException;
+import org.hibernate.StaleStateException;
+import org.hibernate.ObjectNotFoundException;
+import org.hibernate.UnresolvableObjectException;
+import org.hibernate.QueryException;
+import org.hibernate.TransientObjectException;
+import org.hibernate.StaleObjectStateException;
+import org.hibernate.Session;
+import org.hibernate.FlushMode;
+import org.hibernate.exception.ConstraintViolationException;
+import org.hibernate.hql.QueryExecutionRequestException;
+import org.apache.lucene.search.Sort;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class FullTextQueryImpl implements FullTextQuery {
+	private final org.hibernate.search.FullTextQuery query;
+	private Session session;
+
+	public FullTextQueryImpl(org.hibernate.search.FullTextQuery query, Session session) {
+		this.query = query;
+		this.session = session;
+	}
+
+	public FullTextQuery setSort(Sort sort) {
+		query.setSort( sort );
+		return this;
+	}
+
+	public int getResultSize() {
+		return query.getResultSize();
+	}
+
+	public FullTextQuery setCriteriaQuery(Criteria criteria) {
+		query.setCriteriaQuery( criteria );
+		return this;
+	}
+
+	public FullTextQuery setIndexProjection(String... fields) {
+		query.setIndexProjection( fields );
+		return this;
+	}
+
+	public List getResultList() {
+		try {
+			return query.list();
+		}
+		catch (QueryExecutionRequestException he) {
+			//TODO when an illegal state exceptio should be raised?
+			throw new IllegalStateException(he);
+		}
+		catch( TypeMismatchException e ) {
+			//TODO when an illegal arg exceptio should be raised?
+			throw new IllegalArgumentException(e);
+		}
+		catch (SearchException he) {
+			throwPersistenceException( he );
+			throw he;
+		}
+	}
+
+	//TODO mutualize this code with the EM this will fix the rollback issues
+	private void throwPersistenceException(Exception e) {
+		if ( e instanceof StaleStateException ) {
+			PersistenceException pe = wrapStaleStateException( (StaleStateException) e );
+			throwPersistenceException( pe );
+		}
+		else if ( e instanceof ConstraintViolationException ) {
+			//FIXME this is bad cause ConstraintViolationException happens in other circumstances
+			throwPersistenceException( new EntityExistsException( e ) );
+		}
+		else if ( e instanceof ObjectNotFoundException ) {
+			throwPersistenceException( new EntityNotFoundException( e.getMessage() ) );
+		}
+		else if ( e instanceof org.hibernate.NonUniqueResultException ) {
+			throwPersistenceException( new NonUniqueResultException( e.getMessage() ) );
+		}
+		else if ( e instanceof UnresolvableObjectException ) {
+			throwPersistenceException( new EntityNotFoundException( e.getMessage() ) );
+		}
+		else if ( e instanceof QueryException ) {
+			throw new IllegalArgumentException( e );
+		}
+		else if ( e instanceof TransientObjectException ) {
+			//FIXME rollback
+			throw new IllegalStateException( e ); //Spec 3.2.3 Synchronization rules
+		}
+		else {
+			throwPersistenceException( new PersistenceException( e ) );
+		}
+	}
+
+	public void throwPersistenceException(PersistenceException e) {
+		if ( ! ( e instanceof NoResultException || e instanceof NonUniqueResultException ) ) {
+			//FIXME rollback
+		}
+		throw e;
+	}
+
+	public PersistenceException wrapStaleStateException(StaleStateException e) {
+		PersistenceException pe;
+		if ( e instanceof StaleObjectStateException ) {
+			StaleObjectStateException sose = (StaleObjectStateException) e;
+			Serializable identifier = sose.getIdentifier();
+			if (identifier != null) {
+				Object entity = session.load( sose.getEntityName(), identifier );
+				if ( entity instanceof Serializable ) {
+					//avoid some user errors regarding boundary crossing
+					pe = new OptimisticLockException( null, e, entity );
+				}
+				else {
+					pe = new OptimisticLockException( e );
+				}
+			}
+			else {
+				pe = new OptimisticLockException( e );
+			}
+		}
+		else {
+			pe = new OptimisticLockException( e );
+		}
+		return pe;
+	}
+
+	public Object getSingleResult() {
+		try {
+			List result = query.list();
+			if ( result.size() == 0 ) {
+				throwPersistenceException( new NoResultException( "No entity found for query" ) );
+			}
+			else if ( result.size() > 1 ) {
+				Set uniqueResult = new HashSet(result);
+				if ( uniqueResult.size() > 1 ) {
+					throwPersistenceException( new NonUniqueResultException( "result returns " + uniqueResult.size() + " elements") );
+				}
+				else {
+					return uniqueResult.iterator().next();
+				}
+
+			}
+			else {
+				return result.get(0);
+			}
+			return null; //should never happen
+		}
+		catch (QueryExecutionRequestException he) {
+			throw new IllegalStateException(he);
+		}
+		catch( TypeMismatchException e ) {
+			throw new IllegalArgumentException(e);
+		}
+		catch (HibernateException he) {
+			throwPersistenceException( he );
+			return null;
+		}
+	}
+
+	public Query setMaxResults(int maxResult) {
+		if ( maxResult < 0 ) {
+			throw new IllegalArgumentException(
+					"Negative ("
+							+ maxResult
+							+ ") parameter passed in to setMaxResults"
+			);
+		}
+		query.setMaxResults( maxResult );
+		return this;
+	}
+
+	public Query setFirstResult(int firstResult) {
+		if ( firstResult < 0 ) {
+			throw new IllegalArgumentException(
+					"Negative ("
+							+ firstResult
+							+ ") parameter passed in to setFirstResult"
+			);
+		}
+		query.setFirstResult( firstResult );
+		return this;
+	}
+
+	public int executeUpdate() {
+		throw new IllegalStateException( "Update not allowed in FullTextQueries" );
+	}
+
+	public Query setHint(String hintName, Object value) {
+		return this;
+	}
+
+	public Query setParameter(String name, Object value) {
+		throw new UnsupportedOperationException( "parameters not supported in fullText queries");
+	}
+
+	public Query setParameter(String name, Date value, TemporalType temporalType) {
+		throw new UnsupportedOperationException( "parameters not supported in fullText queries");
+	}
+
+	public Query setParameter(String name, Calendar value, TemporalType temporalType) {
+		throw new UnsupportedOperationException( "parameters not supported in fullText queries");
+	}
+
+	public Query setParameter(int position, Object value) {
+		throw new UnsupportedOperationException( "parameters not supported in fullText queries");
+	}
+
+	public Query setParameter(int position, Date value, TemporalType temporalType) {
+		throw new UnsupportedOperationException( "parameters not supported in fullText queries");
+	}
+
+	public Query setParameter(int position, Calendar value, TemporalType temporalType) {
+		throw new UnsupportedOperationException( "parameters not supported in fullText queries");
+	}
+
+	public Query setFlushMode(FlushModeType flushMode) {
+		if ( flushMode == FlushModeType.AUTO ) {
+			query.setFlushMode( FlushMode.AUTO );
+		}
+		else if ( flushMode == FlushModeType.COMMIT ) {
+			query.setFlushMode( FlushMode.COMMIT );
+		}
+		return this;
+	}
+}

Added: trunk/HibernateExt/search/src/test/org/hibernate/search/test/jpa/Bretzel.java
===================================================================
--- trunk/HibernateExt/search/src/test/org/hibernate/search/test/jpa/Bretzel.java	                        (rev 0)
+++ trunk/HibernateExt/search/src/test/org/hibernate/search/test/jpa/Bretzel.java	2007-06-24 18:00:46 UTC (rev 11714)
@@ -0,0 +1,63 @@
+//$Id$
+package org.hibernate.search.test.jpa;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.GeneratedValue;
+
+import org.hibernate.search.annotations.Indexed;
+import org.hibernate.search.annotations.DocumentId;
+import org.hibernate.search.annotations.Field;
+import org.hibernate.search.annotations.Index;
+
+/**
+ * @author Emmanuel Bernard
+ */
+ at Entity
+ at Indexed
+public class Bretzel {
+	@Id
+	@GeneratedValue
+	@DocumentId
+	private Integer id;
+
+	@Field(index = Index.UN_TOKENIZED)
+	private float saltQty;
+
+	@Field(index = Index.UN_TOKENIZED)
+	private float weight;
+
+
+	public Bretzel() {
+	}
+
+	public Bretzel(float saltQty, float weight) {
+		this.saltQty = saltQty;
+		this.weight = weight;
+	}
+
+
+	public Integer getId() {
+		return id;
+	}
+
+	public void setId(Integer id) {
+		this.id = id;
+	}
+
+	public float getSaltQty() {
+		return saltQty;
+	}
+
+	public void setSaltQty(float saltQty) {
+		this.saltQty = saltQty;
+	}
+
+	public float getWeight() {
+		return weight;
+	}
+
+	public void setWeight(float weight) {
+		this.weight = weight;
+	}
+}

Added: trunk/HibernateExt/search/src/test/org/hibernate/search/test/jpa/EntityManagerTest.java
===================================================================
--- trunk/HibernateExt/search/src/test/org/hibernate/search/test/jpa/EntityManagerTest.java	                        (rev 0)
+++ trunk/HibernateExt/search/src/test/org/hibernate/search/test/jpa/EntityManagerTest.java	2007-06-24 18:00:46 UTC (rev 11714)
@@ -0,0 +1,70 @@
+//$Id$
+package org.hibernate.search.test.jpa;
+
+import javax.persistence.EntityManager;
+
+import org.hibernate.search.jpa.Search;
+import org.hibernate.search.jpa.FullTextEntityManager;
+import org.apache.lucene.search.Query;
+import org.apache.lucene.search.TermQuery;
+import org.apache.lucene.queryParser.QueryParser;
+import org.apache.lucene.analysis.StopAnalyzer;
+import org.apache.lucene.index.Term;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class EntityManagerTest extends JPATestCase {
+
+	public void testQuery() throws Exception {
+		FullTextEntityManager em = Search.createFullTextEntityManager( factory.createEntityManager() );
+		em.getTransaction().begin();
+		Bretzel bretzel = new Bretzel( 23, 34 );
+		em.persist( bretzel );
+		em.getTransaction().commit();
+		em.clear();
+		em.getTransaction().begin();
+		QueryParser parser = new QueryParser( "title", new StopAnalyzer() );
+		Query query = parser.parse( "saltQty:noword" );
+		assertEquals( 0, em.createFullTextQuery( query ).getResultList().size() );
+		query = new TermQuery( new Term("saltQty", "23.0") );
+		assertEquals( "getResultList", 1, em.createFullTextQuery( query ).getResultList().size() );
+		assertEquals( "getSingleResult and object retrieval", 23f,
+				( (Bretzel)  em.createFullTextQuery( query ).getSingleResult() ).getSaltQty() );
+		assertEquals( 1, em.createFullTextQuery( query ).getResultSize() );
+		em.getTransaction().commit();
+
+		em.clear();
+
+		em.getTransaction().begin();
+		em.remove( em.find( Bretzel.class, bretzel.getId() ) );
+		em.getTransaction().commit();
+		em.close();
+	}
+
+	public void testIndex() throws Exception {
+		FullTextEntityManager em = Search.createFullTextEntityManager( factory.createEntityManager() );
+		em.getTransaction().begin();
+		Bretzel bretzel = new Bretzel( 23, 34 );
+		em.persist( bretzel );
+		em.getTransaction().commit();
+		em.clear();
+
+		//Not really a unit test but a test that shows the method call wiouth failing
+		//FIXME port the index test
+		em.getTransaction().begin();
+		em.index( em.find( Bretzel.class, bretzel.getId() ) );
+		em.getTransaction().commit();
+
+		em.getTransaction().begin();
+		em.remove( em.find( Bretzel.class, bretzel.getId() ) );
+		em.getTransaction().commit();
+		em.close();
+	}
+
+	public Class[] getAnnotatedClasses() {
+		return new Class[] {
+				Bretzel.class
+		};
+	}
+}

Added: trunk/HibernateExt/search/src/test/org/hibernate/search/test/jpa/JPATestCase.java
===================================================================
--- trunk/HibernateExt/search/src/test/org/hibernate/search/test/jpa/JPATestCase.java	                        (rev 0)
+++ trunk/HibernateExt/search/src/test/org/hibernate/search/test/jpa/JPATestCase.java	2007-06-24 18:00:46 UTC (rev 11714)
@@ -0,0 +1,111 @@
+//$Id$
+package org.hibernate.search.test.jpa;
+
+import java.util.Map;
+import java.util.HashMap;
+import java.util.Properties;
+import java.util.ArrayList;
+import java.io.InputStream;
+import java.io.IOException;
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.Persistence;
+
+import org.hibernate.cfg.Environment;
+import org.hibernate.ejb.HibernatePersistence;
+import org.hibernate.search.store.RAMDirectoryProvider;
+import org.apache.lucene.analysis.StopAnalyzer;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public abstract class JPATestCase extends junit.framework.TestCase {
+	protected EntityManagerFactory factory;
+
+	public JPATestCase() {
+		super();
+	}
+
+	public JPATestCase(String name) {
+		super( name );
+	}
+
+	public void setUp() {
+		factory = new HibernatePersistence().createEntityManagerFactory( getConfig() );
+	}
+
+	public void tearDown() {
+		factory.close();
+	}
+
+	public abstract Class[] getAnnotatedClasses();
+
+	public String[] getEjb3DD() {
+		return new String[]{};
+	}
+
+	public Map<Class, String> getCachedClasses() {
+		return new HashMap<Class, String>();
+	}
+
+	public Map<String, String> getCachedCollections() {
+		return new HashMap<String, String>();
+	}
+
+	public static Properties loadProperties() {
+		Properties props = new Properties();
+		InputStream stream = Persistence.class.getResourceAsStream( "/hibernate.properties" );
+		if ( stream != null ) {
+			try {
+				props.load( stream );
+			}
+			catch (Exception e) {
+				throw new RuntimeException( "could not load hibernate.properties" );
+			}
+			finally {
+				try {
+					stream.close();
+				}
+				catch (IOException ioe) {
+				}
+			}
+		}
+		props.setProperty( Environment.HBM2DDL_AUTO, "create-drop" );
+		return props;
+	}
+
+	public Map getConfig() {
+		Map config = loadProperties();
+		ArrayList<Class> classes = new ArrayList<Class>();
+
+		for ( Class clazz : getAnnotatedClasses() ) {
+			classes.add( clazz );
+		}
+		config.put( HibernatePersistence.LOADED_CLASSES, classes );
+		for ( Map.Entry<Class, String> entry : getCachedClasses().entrySet() ) {
+			config.put(
+					HibernatePersistence.CLASS_CACHE_PREFIX + "." + entry.getKey().getName(),
+					entry.getValue()
+			);
+		}
+		for ( Map.Entry<String, String> entry : getCachedCollections().entrySet() ) {
+			config.put(
+					HibernatePersistence.COLLECTION_CACHE_PREFIX + "." + entry.getKey(),
+					entry.getValue()
+			);
+		}
+		if ( getEjb3DD().length > 0 ) {
+			ArrayList<String> dds = new ArrayList<String>();
+			for ( String dd : getEjb3DD() ) {
+				dds.add( dd );
+			}
+			config.put( HibernatePersistence.XML_FILE_NAMES, dds );
+		}
+
+		//Search config
+		config.put( "hibernate.search.default.directory_provider", RAMDirectoryProvider.class.getName() );
+		config.put( org.hibernate.search.Environment.ANALYZER_CLASS, StopAnalyzer.class.getName() );
+
+		return config;
+	}
+}
+




More information about the hibernate-commits mailing list