Hibernate SVN: r12906 - trunk/HibernateExt/annotations/src/java/org/hibernate/annotations.
by hibernate-commits@lists.jboss.org
Author: epbernard
Date: 2007-08-08 09:47:16 -0400 (Wed, 08 Aug 2007)
New Revision: 12906
Modified:
trunk/HibernateExt/annotations/src/java/org/hibernate/annotations/Where.java
trunk/HibernateExt/annotations/src/java/org/hibernate/annotations/WhereJoinTable.java
Log:
ANN-647 javaDoc
Modified: trunk/HibernateExt/annotations/src/java/org/hibernate/annotations/Where.java
===================================================================
--- trunk/HibernateExt/annotations/src/java/org/hibernate/annotations/Where.java 2007-08-07 17:39:26 UTC (rev 12905)
+++ trunk/HibernateExt/annotations/src/java/org/hibernate/annotations/Where.java 2007-08-08 13:47:16 UTC (rev 12906)
@@ -7,6 +7,7 @@
/**
* Where clause to add to the element Entity or target entity of a collection
+ * The clause is written in SQL
*
* @author Emmanuel Bernard
*/
Modified: trunk/HibernateExt/annotations/src/java/org/hibernate/annotations/WhereJoinTable.java
===================================================================
--- trunk/HibernateExt/annotations/src/java/org/hibernate/annotations/WhereJoinTable.java 2007-08-07 17:39:26 UTC (rev 12905)
+++ trunk/HibernateExt/annotations/src/java/org/hibernate/annotations/WhereJoinTable.java 2007-08-08 13:47:16 UTC (rev 12906)
@@ -8,6 +8,7 @@
/**
* Where clause to add to the colleciton join table
+ * The clause is written in SQL
*
* @author Emmanuel Bernard
*/
17 years, 4 months
Hibernate SVN: r12905 - trunk/HibernateExt/search/doc/reference/en/modules.
by hibernate-commits@lists.jboss.org
Author: epbernard
Date: 2007-08-07 13:39:26 -0400 (Tue, 07 Aug 2007)
New Revision: 12905
Modified:
trunk/HibernateExt/search/doc/reference/en/modules/batchindex.xml
Log:
HSEARCH-79
Modified: trunk/HibernateExt/search/doc/reference/en/modules/batchindex.xml
===================================================================
--- trunk/HibernateExt/search/doc/reference/en/modules/batchindex.xml 2007-08-07 16:51:42 UTC (rev 12904)
+++ trunk/HibernateExt/search/doc/reference/en/modules/batchindex.xml 2007-08-07 17:39:26 UTC (rev 12905)
@@ -60,7 +60,7 @@
- <programlisting>fullTextSession.setFlushMode(FlushMode.APPLICATION);
+ <programlisting>fullTextSession.setFlushMode(FlushMode.MANUAL);
transaction = fullTextSession.beginTransaction();
//Scrollable results will avoid loading too many objects in memory
ScrollableResults results = fullTextSession.createCriteria( Email.class ).scroll( ScrollMode.FORWARD_ONLY );
17 years, 4 months
Hibernate SVN: r12904 - trunk/HibernateExt/search/doc/reference/en/modules.
by hibernate-commits@lists.jboss.org
Author: hardy.ferentschik
Date: 2007-08-07 12:51:42 -0400 (Tue, 07 Aug 2007)
New Revision: 12904
Modified:
trunk/HibernateExt/search/doc/reference/en/modules/architecture.xml
trunk/HibernateExt/search/doc/reference/en/modules/configuration.xml
trunk/HibernateExt/search/doc/reference/en/modules/getting-started.xml
trunk/HibernateExt/search/doc/reference/en/modules/mapping.xml
Log:
HSEARCH-98 Updated the dependencies list
Modified: trunk/HibernateExt/search/doc/reference/en/modules/architecture.xml
===================================================================
--- trunk/HibernateExt/search/doc/reference/en/modules/architecture.xml 2007-08-06 16:47:30 UTC (rev 12903)
+++ trunk/HibernateExt/search/doc/reference/en/modules/architecture.xml 2007-08-07 16:51:42 UTC (rev 12904)
@@ -26,7 +26,7 @@
fact, the Search Session is built on top of the Hibernate Session. The
application code use the unified <classname>org.hibernate.Query</classname>
or <classname>javax.persistence.Query</classname> APIs exactly the way a
- HQL, JPA-QL or native queries would be done.</para>
+ HQL, JPA-QL or native queries would do.</para>
<section>
<title>Batching Scope</title>
Modified: trunk/HibernateExt/search/doc/reference/en/modules/configuration.xml
===================================================================
--- trunk/HibernateExt/search/doc/reference/en/modules/configuration.xml 2007-08-06 16:47:30 UTC (rev 12903)
+++ trunk/HibernateExt/search/doc/reference/en/modules/configuration.xml 2007-08-07 16:51:42 UTC (rev 12904)
@@ -327,7 +327,7 @@
</section>
<section id="jms-backend">
- <title>JMS Back end</title>
+ <title>JMS Master/Slave configuration</title>
<para>This chapter describes in greater detail how to configure the
Master / Slaves Hibernate Search architecture.</para>
Modified: trunk/HibernateExt/search/doc/reference/en/modules/getting-started.xml
===================================================================
--- trunk/HibernateExt/search/doc/reference/en/modules/getting-started.xml 2007-08-06 16:47:30 UTC (rev 12903)
+++ trunk/HibernateExt/search/doc/reference/en/modules/getting-started.xml 2007-08-07 16:51:42 UTC (rev 12904)
@@ -28,47 +28,24 @@
<row>
<entry>Hibernate Search</entry>
<entry>
- Version 3.0.0.Beta4.
+ Version 3.0.0.Beta4 with all its dependencies - hibernate-search.jar, lucene-core-2.2.0.jar, jms.jar, ejb3-persistence.jar and
+ hibernate-commons-annotations.jar
</entry>
- </row>
- <row>
- <entry>Lucene</entry>
- <entry>
- Version 2.2.0. This library is contained in the Hibernate Search zip file.
- </entry>
- </row>
- <row>
- <entry>EJB3 Persistence</entry>
- <entry>
- Contained in the Hibernate Search zip file.
- </entry>
- </row>
- <row>
- <entry>JMS</entry>
- <entry>
- Contained in the Hibernate Search zip file. Needed for JMS configuration
- via <classname>org.hibernate.search.store.FSMasterDirectoryProvider</classname>
- resp. <classname>org.hibernate.search.store.FSSlaveDirectoryProvider</classname>.
- See <xref linkend="jms-backend"/>.
- </entry>
- </row>
+ </row>
<row>
<entry>Hibernate Core</entry>
<entry>
- Version >= 3.2.2 with all its dependencies.
+ Version >= 3.2.2 with all its dependencies - hibernate3.jar, ehcache-1.2.3.jar,
+ swarmcache-1.0rc2.jar, jboss-cache.jar, jgroups-2.2.8.jar, jta.jar, commons-logging-1.0.4.jar,
+ c3p0-0.9.1.jar, asm-attrs.jar, dom4j-1.6.1.jar, ant-antlr-1.6.5.jar, cglib-2.1.3.jar,
+ oscache-2.1.jar, asm.jar, commons-collections-2.1.1.jar, ant-1.6.5.jar and proxool-0.8.3.jar.
</entry>
</row>
<row>
<entry>Hibernate Annotations</entry>
<entry>
- Version 3.3x with all its dependencies
+ Version 3.3.x with all its dependencies - hibernate-annotations.jar, ejb3-persistence.jar and jta.jar.
</entry>
- </row>
- <row>
- <entry>Hibernate Commons Annotations</entry>
- <entry>
- Contained in the Hibernate Search zip file.
- </entry>
</row>
</tbody>
</tgroup>
@@ -82,7 +59,7 @@
</section>
<section>
- <title>Hibernate Configuration</title>
+ <title>Configuration</title>
<para>
Once you have downloaded and added all required dependencies to your application you have
to add a few properties to your hibernate configuration file. The good
@@ -184,7 +161,7 @@
</section>
<section>
- <title>Indexing</title>
+ <title>Inital Indexing</title>
<para>
Once you have added the above properties and annotations it is time to trigger an
initial batch index of your books. You can achieve this by adding the following lines
@@ -228,4 +205,15 @@
session.close();
</programlisting>
</section>
+
+ <section>
+ <title>What's next</title>
+ <para>
+ The above paragraphs hopefully helped you to get started with Hibernate Search. You
+ should have a simple file system based index and be able to search and retrieve a list of
+ your indexed objects via Hibernate Search. The next step is to get more familiar with the
+ overall architecture and explore more advanced topics like <xref linkend="jms-backend"/> and
+ <xref linkend="search-configuration-directory-sharding"/>.
+ </para>
+ </section>
</chapter>
\ No newline at end of file
Modified: trunk/HibernateExt/search/doc/reference/en/modules/mapping.xml
===================================================================
--- trunk/HibernateExt/search/doc/reference/en/modules/mapping.xml 2007-08-06 16:47:30 UTC (rev 12903)
+++ trunk/HibernateExt/search/doc/reference/en/modules/mapping.xml 2007-08-07 16:51:42 UTC (rev 12904)
@@ -123,7 +123,7 @@
</section>
<section>
- <title>mapping a property multiple times</title>
+ <title>Mapping properties multiple times</title>
<para>It is sometimes needed to map a proeprty multiple times per index,
with slightly different indexing strategies. Especially, sorting a query
17 years, 4 months
Hibernate SVN: r12903 - trunk/HibernateExt/search/doc/reference/en/modules.
by hibernate-commits@lists.jboss.org
Author: hardy.ferentschik
Date: 2007-08-06 12:47:30 -0400 (Mon, 06 Aug 2007)
New Revision: 12903
Modified:
trunk/HibernateExt/search/doc/reference/en/modules/query.xml
Log:
HSEARCH-98 Added a new section id for cross referencing.
Modified: trunk/HibernateExt/search/doc/reference/en/modules/query.xml
===================================================================
--- trunk/HibernateExt/search/doc/reference/en/modules/query.xml 2007-08-06 16:47:04 UTC (rev 12902)
+++ trunk/HibernateExt/search/doc/reference/en/modules/query.xml 2007-08-06 16:47:30 UTC (rev 12903)
@@ -168,7 +168,7 @@
than one entity type is expected to be returned.</para>
</section>
- <section>
+ <section id="projections">
<title>Projection</title>
<para>For some use cases, returning the domain object (graph) is
17 years, 4 months
Hibernate SVN: r12902 - trunk/HibernateExt/search/doc/reference/en/modules.
by hibernate-commits@lists.jboss.org
Author: hardy.ferentschik
Date: 2007-08-06 12:47:04 -0400 (Mon, 06 Aug 2007)
New Revision: 12902
Modified:
trunk/HibernateExt/search/doc/reference/en/modules/getting-started.xml
Log:
HSEARCH-98 More getting strarted ...
Modified: trunk/HibernateExt/search/doc/reference/en/modules/getting-started.xml
===================================================================
--- trunk/HibernateExt/search/doc/reference/en/modules/getting-started.xml 2007-08-06 16:46:42 UTC (rev 12901)
+++ trunk/HibernateExt/search/doc/reference/en/modules/getting-started.xml 2007-08-06 16:47:04 UTC (rev 12902)
@@ -3,8 +3,6 @@
<chapter id="getting-started">
<title>Getting started</title>
- <important>Under construction</important>
-
<para>
The following chapter will guide you through the minimal steps
required to integrate Hibernate Search into an existing
@@ -28,37 +26,86 @@
</entry>
</row>
<row>
+ <entry>Hibernate Search</entry>
+ <entry>
+ Version 3.0.0.Beta4.
+ </entry>
+ </row>
+ <row>
+ <entry>Lucene</entry>
+ <entry>
+ Version 2.2.0. This library is contained in the Hibernate Search zip file.
+ </entry>
+ </row>
+ <row>
+ <entry>EJB3 Persistence</entry>
+ <entry>
+ Contained in the Hibernate Search zip file.
+ </entry>
+ </row>
+ <row>
+ <entry>JMS</entry>
+ <entry>
+ Contained in the Hibernate Search zip file. Needed for JMS configuration
+ via <classname>org.hibernate.search.store.FSMasterDirectoryProvider</classname>
+ resp. <classname>org.hibernate.search.store.FSSlaveDirectoryProvider</classname>.
+ See <xref linkend="jms-backend"/>.
+ </entry>
+ </row>
+ <row>
<entry>Hibernate Core</entry>
<entry>
- Version >= 3.2.2
+ Version >= 3.2.2 with all its dependencies.
</entry>
</row>
<row>
<entry>Hibernate Annotations</entry>
<entry>
- Version 3.3x
+ Version 3.3x with all its dependencies
</entry>
- </row>
+ </row>
+ <row>
+ <entry>Hibernate Commons Annotations</entry>
+ <entry>
+ Contained in the Hibernate Search zip file.
+ </entry>
+ </row>
</tbody>
</tgroup>
</table>
<para>
- You can download the dependencies from the Hibernate
- <ulink url="http://www.hibernate.org/6.html">download site</ulink>. The required dependency versions
- can also be found in the <ulink url="http://www.hibernate.org/6.html#A3">Compatibility Matrix</ulink>.
+ You can download these dependencies from the Hibernate
+ <ulink url="http://www.hibernate.org/6.html">download site</ulink>. You can also verify the
+ dependency versions against the <ulink url="http://www.hibernate.org/6.html#A3">
+ Hibernate Compatibility Matrix</ulink>.
</para>
</section>
<section>
<title>Hibernate Configuration</title>
- Lets assume that your application contains a class <classname>Book</classname> which
- is managed by Hibernate. You now want to add free text search abilities to your application
- in order to search within the books body and summary.
+ <para>
+ Once you have downloaded and added all required dependencies to your application you have
+ to add a few properties to your hibernate configuration file. The good
+ news is that for initial experiments most properties offer a sensible default and can
+ be kept untouched.
+ We recommend to start with a <classname>FSDirectoryProvider</classname>.
+ This has the advantage that you can physically inspect (eg via
+ <ulink url="http://www.getopt.org/luke/">Luke</ulink>) the Lucene indeces created by
+ Hibernate Search. Once you have a working configuration you can start experimenting with
+ other <xref linkend="search-configuration-directory"/>s.
+ </para>
+ <para>
+ Lets assume that your application contains the Hibernate managed class <classname>example.Book</classname>.
+ You now want to add free text search capabilities to your application
+ in order to search the bodies and summaries of the books contained in your database.
+ </para>
<programlisting>
+package exmaple.Book
...
@Entity
public class Book {
+ @Id
private Integer id;
private String body;
private String summary;
@@ -72,37 +119,76 @@
// standard getters/setters follow here
...
</programlisting>
- <para>
- Once you have downloaded and added all required dependencies to your application you have
- to add some basic Hibernate Search properties to your hibernate configuration file.
- We recommend to start your first experiments with a <classname>FSDirectoryProvider</classname>.
- This has the advantage that you can physically inspect (eg with
- <ulink url="http://www.getopt.org/luke/">Luke</ulink>) the Lucene indeces created by
- Hibnerate Search. Once you have a working configuration you can start experimenting with
- other <xref linkend="search-configuration-directory"/>s.
- </para>
<para>
+ First you have to tell Hibernate Search which <classname>DirectoryProvider</classname> to use.
+ This can be achieved by setting the <literal>hibernate.search.default.directory_provider</literal>.
+ You also want to specify the default root directory for all indexes via <literal>hibernate.search.default.indexBase</literal>.
</para>
<programlisting>
...
-# the default base directory for the indecies
-hibernate.search.default.indexBase = /var/lucene/indices
-
# the default directory provider
hibernate.search.default.directory_provider = org.hibernate.search.store.FSDirectoryProvider
+
+# the default base directory for the indecies
+hibernate.search.default.indexBase = /var/lucene/indexes
...
</programlisting>
+ <para>
+ Next you have to add three annotations to the <classname>Book</classname> class. The
+ first annotation <literal>@Indexed</literal> marks <classname>Book</classname>
+ as indexable. By design Hibernate Search needs to store an untokenized id in the index to ensure
+ index unicity for a given entity. <literal>@DocumentId</literal> marks the property to use
+ as id.
+ Last but not least you have to index the fields you want to make searchable. In our example
+ these fields are <literal>body</literal> and <literal>summary</literal>. Both properties get
+ annotated with <literal>@Field</literal>. The property <literal>index=Index.TOKENIZED</literal> will
+ ensure that the text will be tokenized using the default Lucene analyzer whereas
+ <literal>store=Store.NO</literal> ensures that the actual data will not be stored in the index.
+ </para>
+ <para>
+ These settings are sufficient for an initial test. For more details on entity mapping refer
+ to <xref linkend="search-mapping-entity"/>. In case you want to store and retrieve
+ the indexed data refer to projections in <xref linkend="projections" />
+ </para>
+
+ <programlisting>
+package exmaple.Book
+...
+@Entity
+<emphasis role="bold">@Indexed</emphasis>
+public class Book {
+
+ @Id
+ <emphasis role="bold">@DocumentId</emphasis>
+ private Integer id;
+
+ <emphasis role="bold">@Field(index=Index.TOKENIZED, store=Store.NO)</emphasis>
+ private String body;
+
+ <emphasis role="bold">@Field(index=Index.TOKENIZED, store=Store.NO)</emphasis>
+ private String summary;
+ private Set<Author> authors = new HashSet<Author>();
+ private Author mainAuthor;
+ private Date publicationDate;
+
+ public Book() {
+ }
+
+ // standard getters/setters follow here
+...
+ </programlisting>
+
</section>
<section>
<title>Indexing</title>
<para>
- Once you have added these properties to your configuration you will have to trigger an
+ Once you have added the above properties and annotations it is time to trigger an
initial batch index of your books. You can achieve this by adding the following lines
- to your code:
+ to your code (see also <xref linkend="search-batchindex"/>):
</para>
<programlisting>
FullTextSession fullTextSession = Search.createFullTextSession(session);
@@ -113,12 +199,33 @@
tx.commit(); //index are written at commit time
</programlisting>
<para>
- For more information see <xref linkend="search-batchindex"/>.
+ After executing the above code there should be a Lucene index under
+ <literal>/var/lucene/indexes/example.Book</literal>. Go ahead an inspect this index. It will
+ help you to understand how Hibernate Search works.
</para>
</section>
<section>
<title>First search</title>
+ <para>
+ Now it is time to execute a first search. The following code will prepare a query against
+ the fields <literal>summary</literal> and <literal>body</literal> , execute it and return
+ a list of <classname>Book</classname>s:
+ </para>
+
+ <programlisting>
+// get hold of the hibernate session. There are multiple ways of doing this depending on the type of application
+Session session = HibernateUtil.getCurrentSession();
+FullTextSession s = Search.createFullTextSession();
+Transaction tx = s.beginTransaction();
+
+MultiFieldQueryParser parser = new MultiFieldQueryParser( new String[]{"summary", "body"}, new StandardAnalyzer());
+Query query = parser.parse( "Java" );
+org.hibernate.Query hibQuery = s.createFullTextQuery( query, Book.class );
+List result = hibQuery.list();
+
+tx.commit();
+session.close();
+ </programlisting>
</section>
-
</chapter>
\ No newline at end of file
17 years, 4 months
Hibernate SVN: r12901 - trunk/HibernateExt/search/doc/reference/en.
by hibernate-commits@lists.jboss.org
Author: hardy.ferentschik
Date: 2007-08-06 12:46:42 -0400 (Mon, 06 Aug 2007)
New Revision: 12901
Modified:
trunk/HibernateExt/search/doc/reference/en/master.xml
Log:
HSEARCH-98 Now getting started is enabled.
Modified: trunk/HibernateExt/search/doc/reference/en/master.xml
===================================================================
--- trunk/HibernateExt/search/doc/reference/en/master.xml 2007-08-06 16:46:15 UTC (rev 12900)
+++ trunk/HibernateExt/search/doc/reference/en/master.xml 2007-08-06 16:46:42 UTC (rev 12901)
@@ -50,7 +50,7 @@
versions.</important>
</preface>
- <!-- &getting-started; -->
+ &getting-started;
&architecture;
17 years, 4 months
Hibernate SVN: r12900 - trunk/HibernateExt/search/doc/reference/en/modules.
by hibernate-commits@lists.jboss.org
Author: hardy.ferentschik
Date: 2007-08-06 12:46:15 -0400 (Mon, 06 Aug 2007)
New Revision: 12900
Modified:
trunk/HibernateExt/search/doc/reference/en/modules/architecture.xml
Log:
HSEARCH-98 Minor text changes and a few cross references.
Modified: trunk/HibernateExt/search/doc/reference/en/modules/architecture.xml
===================================================================
--- trunk/HibernateExt/search/doc/reference/en/modules/architecture.xml 2007-08-06 16:45:40 UTC (rev 12899)
+++ trunk/HibernateExt/search/doc/reference/en/modules/architecture.xml 2007-08-06 16:46:15 UTC (rev 12900)
@@ -3,23 +3,26 @@
<chapter id="search-architecture">
<title>Architecture</title>
- <para>Hibernate Search is made of an indexing engine and an index search
+ <para>Hibernate Search is consists of an indexing engine and an index search
engine. Both are backed by Apache Lucene.</para>
<para>When an entity is inserted, updated or removed to/from the database,
Hibernate Search keeps track of this event (through the Hibernate event
system) and schedule an index update. All the index updates are handled for
- you without you having to use the Apache Lucene APIs.</para>
+ you without you having to use the Apache Lucene APIs
+ (see <xref linkend="search-configuration-event"/>).
+ </para>
<para>To interact with Apache Lucene indexes, Hibernate Search has the
- notion of <classname>DirectoryProvider</classname> . A directory provider
+ notion of <classname>DirectoryProvider</classname>s. A directory provider
will manage a given Lucene <classname>Directory</classname> type. You can
- configure directory providers to adjust the directory target.</para>
+ configure directory providers to adjust the directory target
+ (see <xref linkend="search-configuration-directory"/>).</para>
<para>Hibernate Search can also use a Lucene index to search an entity and
- return a (list of) managed entity saving you from the tedious Object /
- Lucene Document mapping and low level Lucene APIs. The same persistence
- context is shared between Hibernate and Hibernate Search ; as a matter of
+ return a list of managed entities saving you the tedious object to
+ Lucene document mapping. The same persistence
+ context is shared between Hibernate and Hibernate Search; as a matter of
fact, the Search Session is built on top of the Hibernate Session. The
application code use the unified <classname>org.hibernate.Query</classname>
or <classname>javax.persistence.Query</classname> APIs exactly the way a
17 years, 4 months
Hibernate SVN: r12899 - trunk/HibernateExt/search/doc/reference/en/modules.
by hibernate-commits@lists.jboss.org
Author: hardy.ferentschik
Date: 2007-08-06 12:45:40 -0400 (Mon, 06 Aug 2007)
New Revision: 12899
Modified:
trunk/HibernateExt/search/doc/reference/en/modules/configuration.xml
Log:
HSEARCH-98 Added new section id for cross referencing
Modified: trunk/HibernateExt/search/doc/reference/en/modules/configuration.xml
===================================================================
--- trunk/HibernateExt/search/doc/reference/en/modules/configuration.xml 2007-08-03 18:17:21 UTC (rev 12898)
+++ trunk/HibernateExt/search/doc/reference/en/modules/configuration.xml 2007-08-06 16:45:40 UTC (rev 12899)
@@ -326,7 +326,7 @@
</table>
</section>
- <section>
+ <section id="jms-backend">
<title>JMS Back end</title>
<para>This chapter describes in greater detail how to configure the
17 years, 4 months
Hibernate SVN: r12898 - in trunk/HibernateExt/search/src: java/org/hibernate/search/query and 1 other directories.
by hibernate-commits@lists.jboss.org
Author: epbernard
Date: 2007-08-03 14:17:21 -0400 (Fri, 03 Aug 2007)
New Revision: 12898
Modified:
trunk/HibernateExt/search/src/java/org/hibernate/search/FullTextQuery.java
trunk/HibernateExt/search/src/java/org/hibernate/search/query/FullTextQueryImpl.java
trunk/HibernateExt/search/src/java/org/hibernate/search/query/ScrollableResultsImpl.java
trunk/HibernateExt/search/src/test/org/hibernate/search/test/query/LuceneQueryTest.java
Log:
HSEARCH-14 fetchSize for scrollable result sets (John Griffin)
Modified: trunk/HibernateExt/search/src/java/org/hibernate/search/FullTextQuery.java
===================================================================
--- trunk/HibernateExt/search/src/java/org/hibernate/search/FullTextQuery.java 2007-08-03 17:42:55 UTC (rev 12897)
+++ trunk/HibernateExt/search/src/java/org/hibernate/search/FullTextQuery.java 2007-08-03 18:17:21 UTC (rev 12898)
@@ -25,7 +25,7 @@
* @return this for method chaining
*/
FullTextQuery setSort(Sort sort);
-
+
/**
* Allows to use lucene filters.
* Semi-deprecated? a preferred way is to use the @FullTextFilterDef approach
@@ -37,7 +37,7 @@
/**
* Returns the number of hits for this search
- *
+ * <p/>
* Caution:
* The number of results might be slightly different from
* <code>list().size()</code> because list() if the index is
@@ -48,10 +48,9 @@
/**
* Defines the Database Query used to load the Lucene results.
* Useful to load a given object graph by refining the fetch modes
- *
+ * <p/>
* No projection (criteria.setProjection() ) allowed, the root entity must be the only returned type
* No where restriction can be defined either.
- *
*/
FullTextQuery setCriteriaQuery(Criteria criteria);
@@ -59,19 +58,17 @@
* Defines the Lucene field names projected and returned in a query result
* Each field is converted back to it's object representation, an Object[] being returned for each "row"
* (similar to an HQL or a Criteria API projection).
- *
+ * <p/>
* A projectable field must be stored in the Lucene index and use a {@link org.hibernate.search.bridge.TwoWayFieldBridge}
* Unless notified in their JavaDoc, all built-in bridges are two-way. All @DocumentId fields are projectable by design.
- *
+ * <p/>
* If the projected field is not a projectable field, null is returned in the object[]
- *
*/
FullTextQuery setProjection(String... fields);
/**
* Will be removed in the near future
* @deprecated Use #setProjection
- *
*/
FullTextQuery setIndexProjection(String... fields);
@@ -95,4 +92,9 @@
*/
FullTextQuery setMaxResults(int maxResults);
+ /**
+ * Defines scrollable result fetch size as well as the JDBC fetch size
+ */
+ FullTextQuery setFetchSize(int i);
+
}
Modified: trunk/HibernateExt/search/src/java/org/hibernate/search/query/FullTextQueryImpl.java
===================================================================
--- trunk/HibernateExt/search/src/java/org/hibernate/search/query/FullTextQueryImpl.java 2007-08-03 17:42:55 UTC (rev 12897)
+++ trunk/HibernateExt/search/src/java/org/hibernate/search/query/FullTextQueryImpl.java 2007-08-03 18:17:21 UTC (rev 12898)
@@ -73,6 +73,7 @@
private String[] indexProjection;
private SearchFactoryImplementor searchFactoryImplementor;
private Map<String, FullTextFilterImpl> filterDefinitions;
+ private int fetchSize = 1;
/**
* classes must be immutable
@@ -202,7 +203,7 @@
int max = max( first, hits );
DocumentExtractor extractor = new DocumentExtractor( searchFactory, indexProjection );
Loader loader = getLoader( (Session) this.session, searchFactory );
- return new ScrollableResultsImpl( searcher, hits, first, max, extractor, loader, searchFactory );
+ return new ScrollableResultsImpl( searcher, hits, first, max, fetchSize, extractor, loader, searchFactory );
}
catch (IOException e) {
//close only in case of exception
@@ -524,6 +525,15 @@
return this;
}
+ public FullTextQuery setFetchSize(int fetchSize) {
+ super.setFetchSize( fetchSize );
+ if ( fetchSize <= 0 ) {
+ throw new IllegalArgumentException( "'fetch size' parameter less than or equals to 0" );
+ }
+ this.fetchSize = fetchSize;
+ return this;
+ }
+
public int executeUpdate() throws HibernateException {
throw new HibernateException( "Not supported operation" );
}
Modified: trunk/HibernateExt/search/src/java/org/hibernate/search/query/ScrollableResultsImpl.java
===================================================================
--- trunk/HibernateExt/search/src/java/org/hibernate/search/query/ScrollableResultsImpl.java 2007-08-03 17:42:55 UTC (rev 12897)
+++ trunk/HibernateExt/search/src/java/org/hibernate/search/query/ScrollableResultsImpl.java 2007-08-03 18:17:21 UTC (rev 12898)
@@ -12,6 +12,8 @@
import java.util.Locale;
import java.util.Map;
import java.util.TimeZone;
+import java.util.List;
+import java.util.ArrayList;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -33,6 +35,7 @@
* exposed to returned null objects (if the index is out of date).
*
* @author Emmanuel Bernard
+ * @author John Griffin
*/
public class ScrollableResultsImpl implements ScrollableResults {
private static Log log = LogFactory.getLog( ScrollableResultsImpl.class );
@@ -41,6 +44,7 @@
private final Hits hits;
private final int first;
private final int max;
+ private final int fetchSize;
private int current;
private EntityInfo[] entityInfos;
private Loader loader;
@@ -48,7 +52,7 @@
private Map<EntityInfo, Object[]> resultContext;
public ScrollableResultsImpl(
- IndexSearcher searcher, Hits hits, int first, int max, DocumentExtractor extractor,
+ IndexSearcher searcher, Hits hits, int first, int max, int fetchSize, DocumentExtractor extractor,
Loader loader, SearchFactory searchFactory
) {
this.searcher = searcher;
@@ -62,8 +66,55 @@
int size = max - first + 1 > 0 ? max - first + 1 : 0;
this.entityInfos = new EntityInfo[size];
this.resultContext = new HashMap<EntityInfo, Object[]>( size );
+ this.fetchSize = fetchSize;
}
+ // The 'cache' is a sliding window that moves back and
+ // forth over entityInfos loading values of size fetchSize
+ // as necessary.
+ private EntityInfo loadCache(int windowStart) {
+ int windowStop;
+
+ EntityInfo info = entityInfos[windowStart - first];
+ if ( info != null ) {
+ //data has already been loaded
+ return info;
+ }
+
+ if ( windowStart + fetchSize > max) {
+ windowStop = max;
+ }
+ else {
+ windowStop = windowStart + fetchSize - 1;
+ }
+
+ List<EntityInfo> entityInfosLoaded = new ArrayList<EntityInfo>(windowStop - windowStart + 1);
+ for (int x = windowStart; x <= windowStop; x++) {
+ try {
+ if (entityInfos[x - first] == null) {
+ //FIXME should check that clazz match classes but this complicates a lot the firstResult/maxResult
+ entityInfos[x - first] = documentExtractor.extract( hits, x );
+ entityInfosLoaded.add( entityInfos[x - first] );
+ }
+ }
+ catch (IOException e) {
+ throw new HibernateException( "Unable to read Lucene hits[" + x + "]", e );
+ }
+
+ }
+ //preload effitciently first
+ loader.load( entityInfosLoaded.toArray( new EntityInfo[entityInfosLoaded.size()] ) );
+ //load one by one to inject null results if needed
+ for ( EntityInfo slidingInfo : entityInfosLoaded ) {
+ if ( !resultContext.containsKey( slidingInfo ) ) {
+ Object loaded = loader.load( slidingInfo );
+ if ( !loaded.getClass().isArray() ) loaded = new Object[] { loaded };
+ resultContext.put( slidingInfo, (Object[]) loaded );
+ }
+ }
+ return entityInfos[windowStart - first];
+ }
+
public boolean next() throws HibernateException {
return ++current <= max;
}
@@ -120,23 +171,8 @@
// do that since we have to make up for
// an Object[]. J.G
if ( current < first || current > max ) return null;
- EntityInfo info = entityInfos[current - first];
- if ( info == null ) {
- try {
- info = documentExtractor.extract( hits, current );
- }
- catch (IOException e) {
- throw new HibernateException( "Unable to read Lucene hits[" + current + "]", e );
- }
- //FIXME should check that clazz match classes but this complicates a lot the firstResult/maxResult
- entityInfos[current - first] = info;
- }
- if ( !resultContext.containsKey( info ) ) {
- Object loaded = loader.load( info );
- if ( !loaded.getClass().isArray() ) loaded = new Object[] { loaded };
- resultContext.put( info, (Object[]) loaded );
- }
- return resultContext.get( info );
+ loadCache( current );
+ return resultContext.get( entityInfos[current - first] );
}
public Object get(int i) throws HibernateException {
Modified: trunk/HibernateExt/search/src/test/org/hibernate/search/test/query/LuceneQueryTest.java
===================================================================
--- trunk/HibernateExt/search/src/test/org/hibernate/search/test/query/LuceneQueryTest.java 2007-08-03 17:42:55 UTC (rev 12897)
+++ trunk/HibernateExt/search/src/test/org/hibernate/search/test/query/LuceneQueryTest.java 2007-08-03 18:17:21 UTC (rev 12898)
@@ -21,6 +21,7 @@
/**
* @author Emmanuel Bernard
+ * @author John Griffin
*/
public class LuceneQueryTest extends SearchTestCase {
@@ -250,6 +251,165 @@
s.close();
}
+ // Technically this is checked by other tests but let's do it anyway. J.G.
+ public void testDefaultFetchSize() throws Exception {
+ FullTextSession s = Search.createFullTextSession( openSession() );
+ prepEmployeeIndex( s );
+
+ s.clear();
+ Transaction tx = s.beginTransaction();
+ QueryParser parser = new QueryParser( "dept", new StandardAnalyzer() );
+
+ Query query = parser.parse( "dept:ITech" );
+ org.hibernate.search.FullTextQuery hibQuery = s.createFullTextQuery( query, Employee.class );
+ hibQuery.setProjection( "id", "lastname", "dept" );
+
+ ScrollableResults projections = hibQuery.scroll();
+ projections.beforeFirst();
+ Object[] projection = projections.get();
+ assertNull( projection );
+
+ projections.next();
+ assertTrue( projections.isFirst() );
+
+ //cleanup
+ for (Object element : s.createQuery( "from " + Employee.class.getName() ).list()) s.delete( element );
+ tx.commit();
+ s.close();
+ }
+
+ public void testFetchSizeLargerThanHits() throws Exception {
+ FullTextSession s = Search.createFullTextSession( openSession() );
+ prepEmployeeIndex( s );
+
+ s.clear();
+ Transaction tx = s.beginTransaction();
+ QueryParser parser = new QueryParser( "dept", new StandardAnalyzer() );
+
+ Query query = parser.parse( "dept:ITech" );
+ org.hibernate.search.FullTextQuery hibQuery = s.createFullTextQuery( query, Employee.class );
+ hibQuery.setProjection( "id", "lastname", "dept" );
+ hibQuery.setFetchSize( 6 );
+
+ ScrollableResults results = hibQuery.scroll();
+ results.beforeFirst();
+ results.next();
+ Object[] result = results.get();
+ assertEquals( "incorrect entityInfo returned", 1000, result[0] );
+
+ //cleanup
+ for (Object element : s.createQuery( "from " + Employee.class.getName() ).list()) s.delete( element );
+ tx.commit();
+ s.close();
+ }
+
+ public void testFetchSizeDefaultFirstAndMax() throws Exception {
+ FullTextSession s = Search.createFullTextSession( openSession() );
+ prepEmployeeIndex( s );
+
+ s.clear();
+ Transaction tx = s.beginTransaction();
+ QueryParser parser = new QueryParser( "dept", new StandardAnalyzer() );
+
+ Query query = parser.parse( "dept:ITech" );
+ org.hibernate.search.FullTextQuery hibQuery = s.createFullTextQuery( query, Employee.class );
+ hibQuery.setProjection( "id", "lastname", "dept" );
+ hibQuery.setFetchSize( 3 );
+
+ ScrollableResults results = hibQuery.scroll();
+ results.beforeFirst();
+ results.next();
+ Object[] result = results.get();
+ assertEquals( "incorrect entityInfo returned", 1000, result[0] );
+ results.scroll( 2 );
+ result = results.get();
+ assertEquals( "incorrect entityInfo returned", 1003, result[0] );
+ // check cache addition
+ results.next();
+ result = results.get();
+ assertEquals( "incorrect entityInfo returned", 1004, result[0] );
+
+ results.scroll( -2 );
+ result = results.get();
+ assertEquals( "incorrect entityInfo returned", 1002, result[0] );
+
+ //cleanup
+ for (Object element : s.createQuery( "from " + Employee.class.getName() ).list()) s.delete( element );
+ tx.commit();
+ s.close();
+ }
+
+ public void testFetchSizeNonDefaultFirstAndMax() throws Exception {
+ FullTextSession s = Search.createFullTextSession( openSession() );
+ prepEmployeeIndex( s );
+
+ s.clear();
+ Transaction tx = s.beginTransaction();
+ QueryParser parser = new QueryParser( "dept", new StandardAnalyzer() );
+
+ Query query = parser.parse( "dept:ITech" );
+ org.hibernate.search.FullTextQuery hibQuery = s.createFullTextQuery( query, Employee.class );
+ hibQuery.setProjection( "id", "lastname", "dept" );
+ hibQuery.setFetchSize( 3 );
+ hibQuery.setFirstResult( 1 );
+ hibQuery.setMaxResults( 3 );
+
+ ScrollableResults results = hibQuery.scroll();
+ results.beforeFirst();
+ results.next();
+ Object[] result = results.get();
+ assertEquals( "incorrect entityInfo returned", 1002, result[0] );
+
+ results.scroll( 2 );
+ result = results.get();
+ assertEquals( "incorrect entityInfo returned", 1004, result[0] );
+
+ results.next();
+ result = results.get();
+ assertNull( result );
+
+ // Let's see if a bad reverse scroll screws things up
+ /**
+ * These instructions uncover problems with calculations
+ * of 'current'. It should be limited by first and max.
+ */
+ results.scroll( -6 );
+ result = results.get();
+ assertNull( result );
+
+ //cleanup
+ for (Object element : s.createQuery( "from " + Employee.class.getName() ).list()) s.delete( element );
+ tx.commit();
+ s.close();
+ }
+
+ public void testFetchSizeNonDefaultFirstAndMaxNoHits() throws Exception {
+ FullTextSession s = Search.createFullTextSession( openSession() );
+ prepEmployeeIndex( s );
+
+ s.clear();
+ Transaction tx = s.beginTransaction();
+ QueryParser parser = new QueryParser( "dept", new StandardAnalyzer() );
+
+ Query query = parser.parse( "dept:XXX" );
+ org.hibernate.search.FullTextQuery hibQuery = s.createFullTextQuery( query, Employee.class );
+ hibQuery.setProjection( "id", "lastname", "dept" );
+ hibQuery.setFetchSize( 3 );
+ hibQuery.setFirstResult( 1 );
+ hibQuery.setMaxResults( 3 );
+
+ ScrollableResults results = hibQuery.scroll();
+ results.beforeFirst();
+ Object[] result = results.get();
+ assertNull( "non-null entity infos returned", result );
+
+ //cleanup
+ for (Object element : s.createQuery( "from " + Employee.class.getName() ).list()) s.delete( element );
+ tx.commit();
+ s.close();
+ }
+
+
public void testMultipleEntityPerIndex() throws Exception {
FullTextSession s = Search.createFullTextSession( openSession() );
Transaction tx = s.beginTransaction();
17 years, 5 months
Hibernate SVN: r12897 - core/trunk/connection-proxool/src/main/java/org/hibernate/connection.
by hibernate-commits@lists.jboss.org
Author: steve.ebersole(a)jboss.com
Date: 2007-08-03 13:42:55 -0400 (Fri, 03 Aug 2007)
New Revision: 12897
Modified:
core/trunk/connection-proxool/src/main/java/org/hibernate/connection/ProxoolConnectionProvider.java
Log:
HHH-2696 : migrate to slf4j
Modified: core/trunk/connection-proxool/src/main/java/org/hibernate/connection/ProxoolConnectionProvider.java
===================================================================
--- core/trunk/connection-proxool/src/main/java/org/hibernate/connection/ProxoolConnectionProvider.java 2007-08-03 17:39:19 UTC (rev 12896)
+++ core/trunk/connection-proxool/src/main/java/org/hibernate/connection/ProxoolConnectionProvider.java 2007-08-03 17:42:55 UTC (rev 12897)
@@ -90,10 +90,10 @@
if ( "true".equals(externalConfig) ) {
// Validate that an alias name was provided to determine which pool to use
- if ( !StringHelper.isNotEmpty(proxoolAlias) ) {
+ if ( !StringHelper.isNotEmpty( proxoolAlias ) ) {
String msg = "Cannot configure Proxool Provider to use an existing in memory pool without the " + Environment.PROXOOL_POOL_ALIAS + " property set.";
- log.fatal(msg);
- throw new HibernateException(msg);
+ log.error( msg );
+ throw new HibernateException( msg );
}
// Append the stem to the proxool pool alias
proxoolAlias = PROXOOL_JDBC_STEM + proxoolAlias;
@@ -101,28 +101,28 @@
// Set the existing pool flag to true
existingPool = true;
- log.info("Configuring Proxool Provider using existing pool in memory: " + proxoolAlias);
+ log.info( "Configuring Proxool Provider using existing pool in memory: " + proxoolAlias );
// Configured using the JAXP Configurator
}
- else if ( StringHelper.isNotEmpty(jaxpFile) ) {
+ else if ( StringHelper.isNotEmpty( jaxpFile ) ) {
- log.info("Configuring Proxool Provider using JAXPConfigurator: " + jaxpFile);
+ log.info( "Configuring Proxool Provider using JAXPConfigurator: " + jaxpFile );
// Validate that an alias name was provided to determine which pool to use
- if ( !StringHelper.isNotEmpty(proxoolAlias) ) {
+ if ( !StringHelper.isNotEmpty( proxoolAlias ) ) {
String msg = "Cannot configure Proxool Provider to use JAXP without the " + Environment.PROXOOL_POOL_ALIAS + " property set.";
- log.fatal(msg);
- throw new HibernateException(msg);
+ log.error( msg );
+ throw new HibernateException( msg );
}
try {
- JAXPConfigurator.configure( ConfigHelper.getConfigStreamReader(jaxpFile), false );
+ JAXPConfigurator.configure( ConfigHelper.getConfigStreamReader( jaxpFile ), false );
}
- catch (ProxoolException e) {
+ catch ( ProxoolException e ) {
String msg = "Proxool Provider unable to load JAXP configurator file: " + jaxpFile;
- log.fatal(msg, e);
- throw new HibernateException(msg, e);
+ log.error( msg, e );
+ throw new HibernateException( msg, e );
}
// Append the stem to the proxool pool alias
@@ -131,24 +131,24 @@
// Configured using the Properties File Configurator
}
- else if ( StringHelper.isNotEmpty(propFile) ) {
+ else if ( StringHelper.isNotEmpty( propFile ) ) {
- log.info("Configuring Proxool Provider using Properties File: " + propFile);
+ log.info( "Configuring Proxool Provider using Properties File: " + propFile );
// Validate that an alias name was provided to determine which pool to use
- if ( !StringHelper.isNotEmpty(proxoolAlias) ) {
+ if ( !StringHelper.isNotEmpty( proxoolAlias ) ) {
String msg = "Cannot configure Proxool Provider to use Properties File without the " + Environment.PROXOOL_POOL_ALIAS + " property set.";
- log.fatal(msg);
- throw new HibernateException(msg);
+ log.error( msg );
+ throw new HibernateException( msg );
}
try {
- PropertyConfigurator.configure( ConfigHelper.getConfigProperties(propFile) );
+ PropertyConfigurator.configure( ConfigHelper.getConfigProperties( propFile ) );
}
- catch (ProxoolException e) {
+ catch ( ProxoolException e ) {
String msg = "Proxool Provider unable to load load Property configurator file: " + propFile;
- log.fatal(msg, e);
- throw new HibernateException(msg, e);
+ log.error( msg, e );
+ throw new HibernateException( msg, e );
}
// Append the stem to the proxool pool alias
17 years, 5 months