Hibernate SVN: r14691 - core/trunk/core/src/main/java/org/hibernate/context.
by hibernate-commits@lists.jboss.org
Author: steve.ebersole(a)jboss.com
Date: 2008-05-27 10:48:51 -0400 (Tue, 27 May 2008)
New Revision: 14691
Modified:
core/trunk/core/src/main/java/org/hibernate/context/JTASessionContext.java
Log:
HHH-1786 : current session cleanup synch hack for WebSphere.
Modified: core/trunk/core/src/main/java/org/hibernate/context/JTASessionContext.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/context/JTASessionContext.java 2008-05-26 23:04:52 UTC (rev 14690)
+++ core/trunk/core/src/main/java/org/hibernate/context/JTASessionContext.java 2008-05-27 14:48:51 UTC (rev 14691)
@@ -118,7 +118,10 @@
throw new HibernateException( "Unable to register cleanup Synchronization with TransactionManager" );
}
- currentSessionMap.put( txn, currentSession );
+ Object txnIdentifier = factory.getSettings().getTransactionManagerLookup() == null
+ ? txn
+ : factory.getSettings().getTransactionManagerLookup().getTransactionIdentifier( txn );
+ currentSessionMap.put( txnIdentifier, currentSession );
}
return currentSession;
16 years, 6 months
Hibernate SVN: r14690 - in search/trunk: src/java/org/hibernate/search/backend and 3 other directories.
by hibernate-commits@lists.jboss.org
Author: sannegrinovero
Date: 2008-05-26 19:04:52 -0400 (Mon, 26 May 2008)
New Revision: 14690
Added:
search/trunk/src/java/org/hibernate/search/backend/configuration/MaskedProperty.java
search/trunk/src/test/org/hibernate/search/test/configuration/MaskedPropertiesTest.java
Modified:
search/trunk/doc/reference/en/modules/batchindex.xml
search/trunk/doc/reference/en/modules/configuration.xml
search/trunk/doc/reference/en/modules/optimize.xml
search/trunk/src/java/org/hibernate/search/backend/LuceneIndexingParameters.java
search/trunk/src/java/org/hibernate/search/backend/configuration/IndexWriterSetting.java
search/trunk/src/java/org/hibernate/search/store/DirectoryProviderFactory.java
search/trunk/src/test/org/hibernate/search/test/configuration/ConfigurationReadTestCase.java
search/trunk/src/test/org/hibernate/search/test/configuration/LuceneIndexingParametersTest.java
search/trunk/src/test/org/hibernate/search/test/configuration/ShardsConfigurationTest.java
Log:
HSEARCH-200: more IndexWriter settings available, some changes about configuration parsing;
Also includes related Documentation changes, and some unrelated documentation typos.
Modified: search/trunk/doc/reference/en/modules/batchindex.xml
===================================================================
--- search/trunk/doc/reference/en/modules/batchindex.xml 2008-05-23 21:42:40 UTC (rev 14689)
+++ search/trunk/doc/reference/en/modules/batchindex.xml 2008-05-26 23:04:52 UTC (rev 14690)
@@ -42,13 +42,17 @@
<para>Other parameters which also can affect indexing time and memory
consumption are
- <literal>hibernate.search.[default|<indexname>].batch.merge_factor</literal>
+ <literal>hibernate.search.[default|<indexname>].indexwriter.batch.max_buffered_docs</literal>
,
- <literal>hibernate.search.[default|<indexname>].batch.max_merge_docs</literal>
+ <literal>hibernate.search.[default|<indexname>].indexwriter.batch.max_field_length</literal>
,
- <literal>hibernate.search.[default|<indexname>].batch.max_buffered_docs</literal>
+ <literal>hibernate.search.[default|<indexname>].indexwriter.batch.max_merge_docs</literal>
+ ,
+ <literal>hibernate.search.[default|<indexname>].indexwriter.batch.merge_factor</literal>
+ ,
+ <literal>hibernate.search.[default|<indexname>].indexwriter.batch.ram_buffer_size</literal>
and
- <literal>hibernate.search.[default|<indexname>].batch.ram_buffer_size</literal>
+ <literal>hibernate.search.[default|<indexname>].indexwriter.batch.term_index_interval</literal>
. These parameters are Lucene specific and Hibernate Search is just
passing these paramters through - see <xref
linkend="lucene-indexing-performance" /> for more details.</para>
@@ -108,7 +112,7 @@
<note>
<para>Methods <methodname>index</methodname>,
<methodname>purge</methodname> and <methodname>purgeAll</methodname> are
- available on <classname>FullTextEntityManager</classname> as well</para>
+ available on <classname>FullTextEntityManager</classname> as well.</para>
</note>
</section>
</chapter>
Modified: search/trunk/doc/reference/en/modules/configuration.xml
===================================================================
--- search/trunk/doc/reference/en/modules/configuration.xml 2008-05-23 21:42:40 UTC (rev 14689)
+++ search/trunk/doc/reference/en/modules/configuration.xml 2008-05-26 23:04:52 UTC (rev 14690)
@@ -400,7 +400,7 @@
<programlisting>@MessageDriven(activationConfig = {
@ActivationConfigProperty(propertyName="destinationType", propertyValue="javax.jms.Queue"),
- @ActivationConfigProperty(propertyName="destination", propertyValue="queue/hiebrnatesearch"),
+ @ActivationConfigProperty(propertyName="destination", propertyValue="queue/hibernatesearch"),
@ActivationConfigProperty(propertyName="DLQMaxResent", propertyValue="1")
} )
public class MDBSearchController extends AbstractJMSHibernateSearchController implements MessageListener {
@@ -556,7 +556,7 @@
</section>
</section>
- <section id="lucene-indexing-performance" revision="2">
+ <section id="lucene-indexing-performance" revision="3">
<title>Tuning Lucene indexing performance</title>
<para>Hibernate Search allows you to tune the Lucene indexing performance
@@ -564,54 +564,41 @@
Lucene <literal>IndexWriter</literal> such as
<literal>mergeFactor</literal>, <literal>maxMergeDocs</literal> and
<literal>maxBufferedDocs</literal>. You can specify these parameters
- either as default values applying for all indexes or on a per index
- basis.</para>
+ either as default values applying for all indexes, on a per index
+ basis, or even per shard.</para>
<para>There are two sets of parameters allowing for different performance
settings depending on the use case. During indexing operations triggered
- by database modifications, the following ones are used: <itemizedlist>
- <listitem>
- <para><literal>hibernate.search.[default|<indexname>].transaction.merge_factor</literal></para>
- </listitem>
+ by database modifications, the parameters are grouped by the
+ <literal>transaction</literal> keyword:
+ <programlisting>hibernate.search.[default|<indexname>].indexwriter.transaction.<parameter_name></programlisting>
+ When indexing occurs via <literal>FullTextSession.index()</literal> (see <xref
+ linkend="search-batchindex" />), the used properties are those grouped under the <literal>batch</literal> keyword:
+ <programlisting>hibernate.search.[default|<indexname>].indexwriter.batch.<parameter_name></programlisting>
+ </para>
- <listitem>
- <para><literal>hibernate.search.[default|<indexname>].transaction.max_merge_docs</literal></para>
- </listitem>
-
- <listitem>
- <para><literal>hibernate.search.[default|<indexname>].transaction.max_buffered_docs</literal></para>
- </listitem>
-
- <listitem>
- <para><literal>hibernate.search.[default|<indexname>].transaction.ram_buffer_size</literal></para>
- </listitem>
- </itemizedlist>When indexing occurs via
- <literal>FullTextSession.index()</literal> (see <xref
- linkend="search-batchindex" />), the following properties are used:
- <itemizedlist>
- <listitem>
- <para><literal>hibernate.search.[default|<indexname>].batch.merge_factor</literal></para>
- </listitem>
-
- <listitem>
- <para><literal>hibernate.search.[default|<indexname>].batch.max_merge_docs</literal></para>
- </listitem>
-
- <listitem>
- <para><literal>hibernate.search.[default|<indexname>].batch.max_buffered_docs</literal></para>
- </listitem>
-
- <listitem>
- <para><literal>hibernate.search.[default|<indexname>].batch.ram_buffer_size</literal></para>
- </listitem>
- </itemizedlist></para>
-
<para>Unless the corresponding <literal>.batch</literal> property is
explicitly set, the value will default to the
- <literal>.transaction</literal> property.</para>
+ <literal>.transaction</literal> property.
+ If no value is set for a <literal>.batch</literal> value in a specific shard configuration,
+ Hibernate Search will look at the index section, then at the default section and after that
+ it will look for a <literal>.transaction</literal> in the same order:
+ <programlisting>
+ hibernate.search.Animals.2.indexwriter.transaction.max_merge_docs 10
+ hibernate.search.Animals.2.indexwriter.transaction.merge_factor 20
+ hibernate.search.default.indexwriter.batch.max_merge_docs 100</programlisting>
+ This configuration will result in these settings applied to the second shard of Animals index:
+ <itemizedlist>
+ <listitem><literal>transaction.max_merge_docs</literal> = 10</listitem>
+ <listitem><literal>batch.max_merge_docs</literal> = 100</listitem>
+ <listitem><literal>transaction.merge_factor</literal> = 20</listitem>
+ <listitem><literal>batch.merge_factor</literal> = 20</listitem>
+ </itemizedlist>
+ All other values will use the defaults defined in Lucene.
+ </para>
<para>
- The default for all values is to leave them at Lucene's own default,
+ The default for all values is to leave them at Lucene's own default,
so the listed values in the following table actually depend on the
version of Lucene you are using;
values shown are relative to version <literal>2.3</literal>.
@@ -633,62 +620,60 @@
</thead>
<tbody>
+
<row>
- <entry><literal>hibernate.search.[default|<indexname>].transaction.merge_factor</literal></entry>
+ <entry><literal>hibernate.search.[default|<indexname>].indexwriter.[transaction|batch].max_buffered_delete_terms</literal></entry>
- <entry><para>Controls segment merge frequency and size. </para>
- <para>Determines how often segment indices are merged when
- insertion occurs. With smaller values, less RAM is used while
- indexing, and searches on unoptimized indices are faster, but
- indexing speed is slower. With larger values, more RAM is used
- during indexing, and while searches on unoptimized indices are
- slower, indexing is faster. Thus larger values (> 10) are best
- for batch index creation, and smaller values (< 10) for indices
- that are interactively maintained. The value must no be lower than
- 2.</para> <para>Used by Hibernate Search during index update
- operations as part of database modifications.</para></entry>
+ <entry><para>Determines the minimal number of delete terms required before the buffered
+ in-memory delete terms are applied and flushed. If there are documents
+ buffered in memory at the time, they are merged and a new segment is
+ created.</para></entry>
- <entry>10</entry>
+ <entry>Disabled (flushes by RAM usage)</entry>
</row>
<row>
- <entry><literal>hibernate.search.[default|<indexname>].transaction.max_merge_docs</literal></entry>
+ <entry><literal>hibernate.search.[default|<indexname>].indexwriter.[transaction|batch].max_buffered_docs</literal></entry>
- <entry><para>Defines the largest number of documents allowed in a
- segment.</para> <para>Used by Hibernate Search during index update
- operations as part of database modifications.</para></entry>
+ <entry><para>Controls the amount of documents buffered in memory
+ during indexing. The bigger the more RAM is consumed.</para>
+ </entry>
- <entry>Unlimited (Integer.MAX_VALUE)</entry>
+ <entry>Disabled (flushes by RAM usage)</entry>
</row>
<row>
- <entry><literal>hibernate.search.[default|<indexname>].transaction.max_buffered_docs</literal></entry>
+ <entry><literal>hibernate.search.[default|<indexname>].indexwriter.[transaction|batch].max_field_length</literal></entry>
- <entry><para>Controls the amount of documents buffered in memory
- during indexing. The bigger the more RAM is consumed.</para>
- <para>Used by Hibernate Search during index update operations as
- part of database modifications.</para></entry>
+ <entry><para>The maximum number of terms that will be indexed for a single field.
+ This limits the amount of memory required for indexing so that very large data will not crash the indexing process by
+ running out of memory. This setting refers to the number of running terms,
+ not to the number of different terms.</para>
+ <para>This silently truncates large documents, excluding from the index all terms that occur further in the document.
+ If you know your source documents are large, be sure to set this value high enough to accomodate the expected size.
+ If you set it to Integer.MAX_VALUE, then the only limit is your memory, but you should anticipate an OutOfMemoryError.
+ </para>
+ <para>If setting this value in <literal>batch</literal> differently than in <literal>transaction</literal>
+ you may get different data (and results) in your index depending on the indexing mode.</para>
+ </entry>
- <entry>Disabled (not set)</entry>
+ <entry>10000</entry>
</row>
<row>
- <entry><literal>hibernate.search.[default|<indexname>].transaction.ram_buffer_size</literal></entry>
+ <entry><literal>hibernate.search.[default|<indexname>].indexwriter.[transaction|batch].max_merge_docs</literal></entry>
- <entry><para>Controls the amount of RAM in MB dedicated to document buffers.
- When used together max_buffered_docs a flush occurs for whichever event happens first.</para>
- <para>Generally for faster indexing performance it's best to flush by RAM usage instead of document
- count and use as large a RAM buffer as you can.</para>
- <para>Used by Hibernate Search during index update operations as
- part of database modifications.</para></entry>
+ <entry><para>Defines the largest number of documents allowed in a segment.
+ Larger values are best for batched indexing and speedier searches.
+ Small values are best for transaction indexing.</para></entry>
- <entry>16 MB</entry>
+ <entry>Unlimited (Integer.MAX_VALUE)</entry>
</row>
<row>
- <entry><literal>hibernate.search.[default|<indexname>].batch.merge_factor</literal></entry>
+ <entry><literal>hibernate.search.[default|<indexname>].indexwriter.[transaction|batch].merge_factor</literal></entry>
- <entry><para>Controls segment merge frequency and size.</para>
+ <entry><para>Controls segment merge frequency and size. </para>
<para>Determines how often segment indices are merged when
insertion occurs. With smaller values, less RAM is used while
indexing, and searches on unoptimized indices are faster, but
@@ -697,45 +682,34 @@
slower, indexing is faster. Thus larger values (> 10) are best
for batch index creation, and smaller values (< 10) for indices
that are interactively maintained. The value must no be lower than
- 2.</para> <para>Used during indexing via
- <literal>FullTextSession.index()</literal></para></entry>
+ 2.</para></entry>
<entry>10</entry>
</row>
<row>
- <entry><literal>hibernate.search.[default|<indexname>].batch.max_merge_docs</literal></entry>
+ <entry><literal>hibernate.search.[default|<indexname>].indexwriter.[transaction|batch].ram_buffer_size</literal></entry>
- <entry><para>Defines the largest number of documents allowed in a
- segment.</para> <para>Used during indexing via
- <literal>FullTextSession.index()</literal></para></entry>
-
- <entry>Unlimited (Integer.MAX_VALUE)</entry>
- </row>
-
- <row>
- <entry><literal>hibernate.search.[default|<indexname>].batch.max_buffered_docs</literal></entry>
-
- <entry><para>Controls the amount of documents buffered in memory
- during indexing. The bigger the more RAM is consumed.</para>
- <para>Used during indexing via
- <literal>FullTextSession.index()</literal></para></entry>
-
- <entry>Disabled (not set)</entry>
- </row>
-
- <row>
- <entry><literal>hibernate.search.[default|<indexname>].batch.ram_buffer_size</literal></entry>
-
<entry><para>Controls the amount of RAM in MB dedicated to document buffers.
When used together max_buffered_docs a flush occurs for whichever event happens first.</para>
<para>Generally for faster indexing performance it's best to flush by RAM usage instead of document
count and use as large a RAM buffer as you can.</para>
- <para>Used during indexing via
- <literal>FullTextSession.index()</literal></para></entry>
+ </entry>
<entry>16 MB</entry>
</row>
+ <row>
+ <entry><literal>hibernate.search.[default|<indexname>].indexwriter.[transaction|batch].term_index_interval</literal></entry>
+
+ <entry><para>Expert: Set the interval between indexed terms.</para>
+ <para>Large values cause less memory to be used by IndexReader, but slow random-access to terms.
+ Small values cause more memory to be used by an IndexReader, and speed
+ random-access to terms. See Lucene documentation for more details.</para>
+ </entry>
+
+ <entry>128</entry>
+ </row>
+
</tbody>
</tgroup>
</table>
Modified: search/trunk/doc/reference/en/modules/optimize.xml
===================================================================
--- search/trunk/doc/reference/en/modules/optimize.xml 2008-05-23 21:42:40 UTC (rev 14689)
+++ search/trunk/doc/reference/en/modules/optimize.xml 2008-05-26 23:04:52 UTC (rev 14690)
@@ -4,8 +4,8 @@
<title>Index Optimization</title>
<para>From time to time, the Lucene index needs to be optimized. The process
- is essentially a defragmentation: until the optimization occurs, deleted
- documents are just marked as such, no physical deletion is applied, the
+ is essentially a defragmentation: until the optimization occurs deleted
+ documents are just marked as such, no physical deletion is applied; the
optimization can also adjust the number of files in the Lucene
Directory.</para>
@@ -46,7 +46,6 @@
<programlisting>hibernate.search.default.optimizer.operation_limit.max = 1000
hibernate.search.default.optimizer.transaction_limit.max = 100
-
hibernate.search.Animal.optimizer.transaction_limit.max = 50</programlisting>
<para>An optimization will be triggered to the <literal>Animal</literal>
@@ -65,7 +64,7 @@
</listitem>
</itemizedlist>
- <para>If none of these parameters are defined, not optimization is
+ <para>If none of these parameters are defined, no optimization is
processed automatically.</para>
</section>
@@ -73,14 +72,14 @@
<title>Manual optimization</title>
<para>You can programmatically optimize (defragment) a Lucene index from
- Hibernate Search through the <classname>SearchFactory</classname></para>
+ Hibernate Search through the <classname>SearchFactory</classname>:</para>
- <programlisting>searchFactory.optimize(Order.class);
+ <programlisting>searchFactory.optimize(Order.class);</programlisting>
-searchFactory.optimize();</programlisting>
+ <programlisting>searchFactory.optimize();</programlisting>
- <para>The first example reindex the Lucene index holding
- <classname>Order</classname>s, the second, optimize all indexes.</para>
+ <para>The first example optimizes the Lucene index holding
+ <classname>Order</classname>s; the second, optimizes all indexes.</para>
<para>The <classname>SearchFactory</classname> can be accessed from a
<classname>FullTextSession</classname>:</para>
@@ -97,15 +96,17 @@
<title>Adjusting optimization</title>
<para>Apache Lucene has a few parameters to influence how optimization is
- performed. Hibernate Search expose those parameters.</para>
+ performed. Hibernate Search exposes those parameters.</para>
- <para>Further index optimisation parameters include
- <literal>hibernate.search.[default|<indexname>].[batch|transaction].merge_factor</literal>,
- <literal>hibernate.search.[default|<indexname>].[batch|transaction].max_merge_docs</literal>,
- <literal>hibernate.search.[default|<indexname>].[batch|transaction].max_buffered_docs</literal>
- and
- <literal>hibernate.search.[default|<indexname>].[batch|transaction].ram_buffer_size</literal>
- - see <xref linkend="lucene-indexing-performance" /> for more
- details.</para>
+ <para>Further index optimisation parameters include:
+ <itemizedlist>
+ <listitem><literal>hibernate.search.[default|<indexname>].indexwriter.[batch|transaction].max_buffered_docs</literal></listitem>
+ <listitem><literal>hibernate.search.[default|<indexname>].indexwriter.[batch|transaction].max_field_length</literal></listitem>
+ <listitem><literal>hibernate.search.[default|<indexname>].indexwriter.[batch|transaction].max_merge_docs</literal></listitem>
+ <listitem><literal>hibernate.search.[default|<indexname>].indexwriter.[batch|transaction].merge_factor</literal></listitem>
+ <listitem><literal>hibernate.search.[default|<indexname>].indexwriter.[batch|transaction].ram_buffer_size</literal></listitem>
+ <listitem><literal>hibernate.search.[default|<indexname>].indexwriter.[batch|transaction].term_index_interval</literal></listitem>
+ </itemizedlist>
+ See <xref linkend="lucene-indexing-performance" /> for more details.</para>
</section>
</chapter>
Modified: search/trunk/src/java/org/hibernate/search/backend/LuceneIndexingParameters.java
===================================================================
--- search/trunk/src/java/org/hibernate/search/backend/LuceneIndexingParameters.java 2008-05-23 21:42:40 UTC (rev 14689)
+++ search/trunk/src/java/org/hibernate/search/backend/LuceneIndexingParameters.java 2008-05-26 23:04:52 UTC (rev 14690)
@@ -1,107 +1,131 @@
-//$Id$
-package org.hibernate.search.backend;
-
-import java.io.Serializable;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Properties;
-
-import org.apache.lucene.index.IndexWriter;
-import org.hibernate.search.SearchException;
-import org.hibernate.search.backend.configuration.IndexWriterSetting;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Wrapper class around the Lucene indexing parameters <i>mergeFactor</i>, <i>maxMergeDocs</i>,
- * <i>maxBufferedDocs</i>, <i>termIndexInterval</i>, <i>RAMBufferSizeMB</i>.
- * <p>
- * There are two sets of these parameters. One is for regular indexing the other is for batch indexing
- * triggered by <code>FullTextSessoin.index(Object entity)</code>
- *
- * @author Hardy Ferentschik
- * @author Sanne Grinovero
- */
-public class LuceneIndexingParameters implements Serializable {
-
- // value keyword
- public static final String EXPLICIT_DEFAULT_VALUE = "default";
- // property path keywords
- public static final String BATCH = "batch";
- public static final String TRANSACTION = "transaction";
-
- private final ParameterSet transactionIndexParameters;
- private final ParameterSet batchIndexParameters;
-
- public LuceneIndexingParameters( Properties sourceProps ) {
- Properties transactionProps = new Properties();
- Properties batchProps = new Properties( transactionProps ); // transaction settings is the default for batch
- //don't iterate on property entries we know all the keys:
- for ( IndexWriterSetting t : IndexWriterSetting.values() ) {
- String key = t.getKey();
- String trxValue = sourceProps.getProperty( TRANSACTION + "." + key );
- if (trxValue != null) {
- transactionProps.setProperty( key, trxValue );
- }
- String batchValue = sourceProps.getProperty( BATCH + "." + key );
- if (batchValue != null) {
- batchProps.setProperty( key, batchValue );
- }
- }
- transactionIndexParameters = new ParameterSet(transactionProps);
- batchIndexParameters = new ParameterSet(batchProps);
- }
-
- public ParameterSet getTransactionIndexParameters() {
- return transactionIndexParameters;
- }
-
- public ParameterSet getBatchIndexParameters() {
- return batchIndexParameters;
- }
-
- public class ParameterSet implements Serializable {
-
- final Map<IndexWriterSetting, Integer> parameters = new HashMap<IndexWriterSetting, Integer>();
-
- public ParameterSet(Properties prop) {
- for ( IndexWriterSetting t : IndexWriterSetting.values() ) {
- String value = prop.getProperty( t.getKey() );
- if ( ! (value==null || EXPLICIT_DEFAULT_VALUE.equals(value) ) ) {
- parameters.put( t, t.parseVal(value) );
- }
- }
- }
-
- /**
- * Applies the parameters represented by this to a writer.
- * Undefined parameters are not set, leaving the lucene default.
- * @param writer the IndexWriter whereto the parameters will be applied.
- */
- public void applyToWriter(IndexWriter writer) {
- for ( Map.Entry<IndexWriterSetting,Integer> entry : parameters.entrySet() ) {
- try {
- entry.getKey().applySetting( writer, entry.getValue() );
- } catch ( IllegalArgumentException e ) {
- //TODO if DirectoryProvider had getDirectoryName() exceptions could tell better
- throw new SearchException( "Illegal IndexWriter setting "
- + entry.getKey().getKey() + " "+ e.getMessage(), e );
- }
- }
- }
-
- public Integer getCurrentValueFor(IndexWriterSetting ws){
- return parameters.get(ws);
- }
-
- public void setCurrentValueFor(IndexWriterSetting ws, Integer newValue){
- if (newValue==null){
- parameters.remove(ws);
- } else {
- parameters.put(ws, newValue);
- }
- }
-
- }
-
-}
+//$Id$
+package org.hibernate.search.backend;
+
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+
+import org.apache.lucene.index.IndexWriter;
+import org.hibernate.search.SearchException;
+import org.hibernate.search.backend.configuration.IndexWriterSetting;
+import org.hibernate.search.backend.configuration.MaskedProperty;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import static org.hibernate.search.backend.configuration.IndexWriterSetting.MAX_FIELD_LENGTH;
+
+/**
+ * Wrapper class around the Lucene indexing parameters defined in IndexWriterSetting.
+ * <p>
+ * There are two sets of these parameters. One is for regular indexing the other is for batch indexing
+ * triggered by <code>FullTextSessoin.index(Object entity)</code>
+ *
+ * @author Hardy Ferentschik
+ * @author Sanne Grinovero
+ */
+public class LuceneIndexingParameters implements Serializable {
+
+ private static final long serialVersionUID = 5424606407623591663L;
+ private static Logger log = LoggerFactory.getLogger( LuceneIndexingParameters.class );
+
+ // value keyword
+ public static final String EXPLICIT_DEFAULT_VALUE = "default";
+ // property path keywords
+ public static final String BATCH = "batch";
+ public static final String TRANSACTION = "transaction";
+ public static final String PROP_GROUP = "indexwriter";
+
+ private final ParameterSet transactionIndexParameters;
+ private final ParameterSet batchIndexParameters;
+
+ public LuceneIndexingParameters( Properties sourceProps ) {
+ //prefer keys under "indexwriter" but fallback for backwards compatibility:
+ Properties indexingParameters = new MaskedProperty( sourceProps, PROP_GROUP, sourceProps );
+ //get keys for "transaction"
+ Properties transactionProps = new MaskedProperty( indexingParameters, TRANSACTION );
+ //get keys for "batch" (defaulting to transaction)
+ Properties batchProps = new MaskedProperty( indexingParameters, BATCH, transactionProps ); //TODO to close HSEARCH-201 just remove 3° parameter
+ transactionIndexParameters = new ParameterSet( transactionProps, TRANSACTION );
+ batchIndexParameters = new ParameterSet( batchProps, BATCH );
+ doSanityChecks( transactionIndexParameters, batchIndexParameters );
+ }
+
+ private void doSanityChecks(ParameterSet transParams, ParameterSet batchParams) {
+ if ( log.isWarnEnabled() ) {
+ Integer maxFieldLengthTransaction = transParams.parameters.get( MAX_FIELD_LENGTH );
+ Integer maxFieldLengthBatch = transParams.parameters.get( MAX_FIELD_LENGTH );
+ if ( notEquals( maxFieldLengthTransaction, maxFieldLengthBatch ) ){
+ log.warn( "The max_field_length value configured for transaction is different than the value configured for batch." );
+ }
+ }
+ }
+
+ private boolean notEquals(Integer a, Integer b) {
+ if ( a==null && b==null ) return false;
+ if ( a==null && b!=null ) return true;
+ if ( a!=null && b==null ) return true;
+ return a.intValue() != b.intValue();
+ }
+
+ public ParameterSet getTransactionIndexParameters() {
+ return transactionIndexParameters;
+ }
+
+ public ParameterSet getBatchIndexParameters() {
+ return batchIndexParameters;
+ }
+
+ public class ParameterSet implements Serializable {
+
+ private static final long serialVersionUID = -6121723702279869524L;
+
+ final Map<IndexWriterSetting, Integer> parameters = new HashMap<IndexWriterSetting, Integer>();
+
+ public ParameterSet(Properties prop, String paramName) {
+ //don't iterate on property entries as we know all the keys:
+ for ( IndexWriterSetting t : IndexWriterSetting.values() ) {
+ String key = t.getKey();
+ String value = prop.getProperty( key );
+ if ( ! ( value==null || EXPLICIT_DEFAULT_VALUE.equalsIgnoreCase( value ) ) ) {
+ if ( log.isDebugEnabled() ) {
+ //TODO add DirectoryProvider name when available to log message
+ log.debug( "Set indexwriter parameter " + paramName +"." + key + " to value : "+ value );
+ }
+ parameters.put( t, t.parseVal( value ) );
+ }
+ }
+ }
+
+ /**
+ * Applies the parameters represented by this to a writer.
+ * Undefined parameters are not set, leaving the lucene default.
+ * @param writer the IndexWriter whereto the parameters will be applied.
+ */
+ public void applyToWriter(IndexWriter writer) {
+ for ( Map.Entry<IndexWriterSetting,Integer> entry : parameters.entrySet() ) {
+ try {
+ entry.getKey().applySetting( writer, entry.getValue() );
+ } catch ( IllegalArgumentException e ) {
+ //TODO if DirectoryProvider had getDirectoryName() exceptions could tell better
+ throw new SearchException( "Illegal IndexWriter setting "
+ + entry.getKey().getKey() + " "+ e.getMessage(), e );
+ }
+ }
+ }
+
+ public Integer getCurrentValueFor(IndexWriterSetting ws){
+ return parameters.get(ws);
+ }
+
+ public void setCurrentValueFor(IndexWriterSetting ws, Integer newValue){
+ if (newValue==null){
+ parameters.remove(ws);
+ } else {
+ parameters.put(ws, newValue);
+ }
+ }
+
+ }
+
+}
Modified: search/trunk/src/java/org/hibernate/search/backend/configuration/IndexWriterSetting.java
===================================================================
--- search/trunk/src/java/org/hibernate/search/backend/configuration/IndexWriterSetting.java 2008-05-23 21:42:40 UTC (rev 14689)
+++ search/trunk/src/java/org/hibernate/search/backend/configuration/IndexWriterSetting.java 2008-05-26 23:04:52 UTC (rev 14690)
@@ -5,32 +5,73 @@
import org.apache.lucene.index.IndexWriter;
import org.hibernate.search.SearchException;
+/**
+ * Represents possible options to be applied to an
+ * <code>org.apache.lucene.index.IndexWriter</code>
+ *
+ * @author Sanne Grinovero
+ */
public enum IndexWriterSetting implements Serializable {
-
- MERGE_FACTOR( "merge_factor" ) {
+ /**
+ * @see org.apache.lucene.index.IndexWriter.setMaxBufferedDeleteTerms(int)
+ */
+ MAX_BUFFERED_DELETE_TERMS( "max_buffered_delete_terms" ) {
public void applySetting(IndexWriter writer, int value) {
- writer.setMergeFactor( value );
+ writer.setMaxBufferedDeleteTerms( value );
}
} ,
+ /**
+ * @see org.apache.lucene.index.IndexWriter.setMaxBufferedDocs(int)
+ */
+ MAX_BUFFERED_DOCS( "max_buffered_docs" ) {
+ public void applySetting(IndexWriter writer, int value) {
+ writer.setMaxBufferedDocs( value );
+ }
+ } ,
+ /**
+ * @see org.apache.lucene.index.IndexWriter.setMaxFieldLength(int)
+ */
+ MAX_FIELD_LENGTH( "max_field_length" ) {
+ public void applySetting(IndexWriter writer, int value) {
+ writer.setMaxFieldLength( value );
+ }
+ } ,
+ /**
+ * @see org.apache.lucene.index.IndexWriter.setMaxMergeDocs(int)
+ */
MAX_MERGE_DOCS( "max_merge_docs" ) {
public void applySetting(IndexWriter writer, int value) {
writer.setMaxMergeDocs( value );
}
} ,
- MAX_BUFFERED_DOCS( "max_buffered_docs" ) {
+ /**
+ * @see org.apache.lucene.index.IndexWriter.setMergeFactor(int)
+ */
+ MERGE_FACTOR( "merge_factor" ) {
public void applySetting(IndexWriter writer, int value) {
- writer.setMaxBufferedDocs( value );
+ writer.setMergeFactor( value );
}
} ,
+ /**
+ * @see org.apache.lucene.index.IndexWriter.setRAMBufferSizeMB(int)
+ */
RAM_BUFFER_SIZE( "ram_buffer_size" ) {
public void applySetting(IndexWriter writer, int value) {
writer.setRAMBufferSizeMB( value );
}
+ },
+ /**
+ * @see org.apache.lucene.index.IndexWriter.setTermIndexInterval(int)
+ */
+ TERM_INDEX_INTERVAL( "term_index_interval" ) {
+ public void applySetting(IndexWriter writer, int value) {
+ writer.setTermIndexInterval( value );
+ }
};
private final String cfgKey;
- IndexWriterSetting(String configurationKey){
+ IndexWriterSetting(String configurationKey) {
this.cfgKey = configurationKey;
}
@@ -39,6 +80,9 @@
*/
public abstract void applySetting(IndexWriter writer, int value);
+ /**
+ * @return The key used in configuration files to select an option.
+ */
public String getKey() {
return cfgKey;
}
Added: search/trunk/src/java/org/hibernate/search/backend/configuration/MaskedProperty.java
===================================================================
--- search/trunk/src/java/org/hibernate/search/backend/configuration/MaskedProperty.java (rev 0)
+++ search/trunk/src/java/org/hibernate/search/backend/configuration/MaskedProperty.java 2008-05-26 23:04:52 UTC (rev 14690)
@@ -0,0 +1,345 @@
+package org.hibernate.search.backend.configuration;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.io.PrintWriter;
+import java.io.Serializable;
+import java.util.Collection;
+import java.util.Enumeration;
+import java.util.InvalidPropertiesFormatException;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * A wrapper to Properties, to restrict the availability of
+ * values to only those which have a key beginning with some
+ * masking String.
+ * Methods to list available keys or values or otherwise
+ * enumerate available properties are not available.
+ *
+ * @author Sanne Grinovero
+ */
+public class MaskedProperty extends Properties implements Serializable {
+
+ private static final long serialVersionUID = -593307257383085113L;
+ private static Logger log = LoggerFactory.getLogger( MaskedProperty.class );
+
+ private final Properties masked;
+ private final Properties fallBack;
+ private final String radix;
+
+ /**
+ * Provides a view to the provided Properties hiding
+ * all keys not starting with some [mask.].
+ * @param propsToMask the Properties containing the values.
+ * @param mask
+ */
+ public MaskedProperty(Properties propsToMask, String mask) {
+ this( propsToMask, mask, null );
+ }
+
+ /**
+ * Provides a view to the provided Properties hiding
+ * all keys not starting with some [mask.].
+ * If no value is found then a value is returned from propsFallBack,
+ * without masking.
+ * @param propsToMask
+ * @param mask
+ * @param propsFallBack
+ */
+ public MaskedProperty(Properties propsToMask, String mask, Properties propsFallBack) {
+ if ( propsToMask==null || mask==null ) {
+ throw new java.lang.IllegalArgumentException();
+ }
+ this.masked = propsToMask;
+ this.radix = mask + ".";
+ this.fallBack = propsFallBack;
+ }
+
+ @Override
+ public String getProperty(String key) {
+ String compositeKey = radix + key;
+ String value = masked.getProperty( compositeKey );
+ if ( value != null) {
+ log.trace( "found a match for key: [{}] value: {}", compositeKey, value );
+ return value;
+ }
+ else if ( fallBack != null ) {
+ return fallBack.getProperty( key );
+ }
+ else {
+ return null;
+ }
+ }
+
+ /**
+ * @throws IllegalArgumentException if the key is not a String instance
+ */
+ @Override
+ public boolean containsKey(Object key) {
+ if ( ! ( key instanceof String ) ) {
+ throw new IllegalArgumentException( "key must be a String" );
+ }
+ return getProperty( key.toString() ) != null;
+ }
+
+ @Override
+ public String getProperty(String key, String defaultValue) {
+ String val = getProperty( key );
+ return ( val == null ) ? defaultValue : val;
+ }
+
+ /**
+ * @throws UnsupportedOperationException
+ */
+ @Override
+ public void list(PrintStream out) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * @throws UnsupportedOperationException
+ */
+ @Override
+ public void list(PrintWriter out) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * @throws UnsupportedOperationException
+ */
+ @Override
+ public synchronized void load(InputStream inStream) throws IOException {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * @throws UnsupportedOperationException
+ */
+ @Override
+ public synchronized void loadFromXML(InputStream in) throws IOException,
+ InvalidPropertiesFormatException {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * @throws UnsupportedOperationException
+ */
+ @Override
+ public Enumeration<?> propertyNames() {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * @throws UnsupportedOperationException
+ */
+ @Override
+ public synchronized void save(OutputStream out, String comments) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * @throws UnsupportedOperationException
+ */
+ @Override
+ public synchronized Object setProperty(String key, String value) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * @throws UnsupportedOperationException
+ */
+ @Override
+ public synchronized void store(OutputStream out, String comments)
+ throws IOException {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * @throws UnsupportedOperationException
+ */
+ @Override
+ public synchronized void storeToXML(OutputStream os, String comment,
+ String encoding) throws IOException {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * @throws UnsupportedOperationException
+ */
+ @Override
+ public synchronized void storeToXML(OutputStream os, String comment)
+ throws IOException {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * @throws UnsupportedOperationException
+ */
+ @Override
+ public synchronized void clear() {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * @throws UnsupportedOperationException
+ */
+ @Override
+ public synchronized Object clone() {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * @throws UnsupportedOperationException
+ */
+ @Override
+ public synchronized boolean contains(Object value) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * @throws UnsupportedOperationException
+ */
+ @Override
+ public boolean containsValue(Object value) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * @throws UnsupportedOperationException
+ */
+ @Override
+ public synchronized Enumeration<Object> elements() {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * @throws UnsupportedOperationException
+ */
+ @Override
+ public Set<java.util.Map.Entry<Object, Object>> entrySet() {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * @throws UnsupportedOperationException
+ */
+ @Override
+ public synchronized Object get(Object key) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public synchronized boolean isEmpty() {
+ if ( fallBack==null ) {
+ return masked.isEmpty();
+ }
+ else {
+ return masked.isEmpty() && fallBack.isEmpty();
+ }
+ }
+
+ /**
+ * @throws UnsupportedOperationException
+ */
+ @Override
+ public synchronized Enumeration<Object> keys() {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * @throws UnsupportedOperationException
+ */
+ @Override
+ public Set<Object> keySet() {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * @throws UnsupportedOperationException
+ */
+ @Override
+ public synchronized Object put(Object key, Object value) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * @throws UnsupportedOperationException
+ */
+ @Override
+ public synchronized void putAll(Map<? extends Object, ? extends Object> t) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * @throws UnsupportedOperationException
+ */
+ @Override
+ protected void rehash() {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * @throws UnsupportedOperationException
+ */
+ @Override
+ public synchronized Object remove(Object key) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * @throws UnsupportedOperationException
+ */
+ @Override
+ public synchronized int size() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public synchronized String toString() {
+ return masked.toString();
+ }
+
+ /**
+ * @throws UnsupportedOperationException
+ */
+ @Override
+ public Collection<Object> values() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = ( ( fallBack == null ) ? 0 : fallBack.hashCode() );
+ result = prime * result + masked.hashCode();
+ result = prime * result + radix.hashCode();
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if ( this == obj )
+ return true;
+ if ( getClass() != obj.getClass() )
+ return false;
+ final MaskedProperty other = (MaskedProperty) obj;
+ if ( fallBack == null ) {
+ if ( other.fallBack != null )
+ return false;
+ } else if ( ! fallBack.equals( other.fallBack ) )
+ return false;
+ if ( ! masked.equals( other.masked ) )
+ return false;
+ if ( ! radix.equals( other.radix ) )
+ return false;
+ return true;
+ }
+
+}
Modified: search/trunk/src/java/org/hibernate/search/store/DirectoryProviderFactory.java
===================================================================
--- search/trunk/src/java/org/hibernate/search/store/DirectoryProviderFactory.java 2008-05-23 21:42:40 UTC (rev 14689)
+++ search/trunk/src/java/org/hibernate/search/store/DirectoryProviderFactory.java 2008-05-26 23:04:52 UTC (rev 14690)
@@ -1,331 +1,272 @@
-//$Id$
-package org.hibernate.search.store;
-
-import java.util.ArrayList;
-import java.util.Enumeration;
-import java.util.List;
-import java.util.Map;
-import java.util.Properties;
-import java.util.concurrent.locks.ReentrantLock;
-import java.util.regex.Pattern;
-
-import org.hibernate.HibernateException;
-import org.hibernate.annotations.common.reflection.ReflectionManager;
-import org.hibernate.annotations.common.reflection.XClass;
-import org.hibernate.cfg.Configuration;
-import org.hibernate.mapping.PersistentClass;
-import org.hibernate.search.SearchException;
-import org.hibernate.search.annotations.Indexed;
-import org.hibernate.search.backend.LuceneIndexingParameters;
-import org.hibernate.search.engine.SearchFactoryImplementor;
-import org.hibernate.search.impl.SearchFactoryImpl;
-import org.hibernate.search.store.optimization.IncrementalOptimizerStrategy;
-import org.hibernate.search.store.optimization.NoOpOptimizerStrategy;
-import org.hibernate.search.store.optimization.OptimizerStrategy;
-import org.hibernate.util.ReflectHelper;
-import org.hibernate.util.StringHelper;
-
-/**
- * Create a Lucene directory provider
- * <p/>
- * Lucene directory providers are configured through properties
- * <ul>
- * <li>hibernate.search.default.* and</li>
- * <li>hibernate.search.<indexname>.*</li>
- * </ul>
- * <p/>
- * <indexname> properties have precedence over default
- * <p/>
- * The implementation is described by
- * hibernate.search.[default|indexname].directory_provider
- * <p/>
- * If none is defined the default value is FSDirectory
- *
- * @author Emmanuel Bernard
- * @author Sylvain Vieujot
- * @author Hardy Ferentschik
- */
-public class DirectoryProviderFactory {
- private List<DirectoryProvider<?>> providers = new ArrayList<DirectoryProvider<?>>();
- private static String LUCENE_PREFIX = "hibernate.search.";
- private static String LUCENE_DEFAULT = LUCENE_PREFIX + "default.";
- private static String DEFAULT_DIRECTORY_PROVIDER = FSDirectoryProvider.class.getName();
-
- private static final String SHARDING_STRATEGY = "sharding_strategy";
- private static final String NBR_OF_SHARDS = SHARDING_STRATEGY + ".nbr_of_shards";
- private static Pattern dotPattern = Pattern.compile( "\\." );
-
-
- public DirectoryProviders createDirectoryProviders(XClass entity, Configuration cfg, SearchFactoryImplementor searchFactoryImplementor) {
- //get properties
- String directoryProviderName = getDirectoryProviderName( entity, cfg );
- Properties[] indexProps = getDirectoryProperties( cfg, directoryProviderName );
-
- //set up the directories
- int nbrOfProviders = indexProps.length;
- DirectoryProvider[] providers = new DirectoryProvider[nbrOfProviders];
- for (int index = 0 ; index < nbrOfProviders ; index++) {
- String providerName = nbrOfProviders > 1 ?
- directoryProviderName + "." + index :
- directoryProviderName;
- providers[index] = createDirectoryProvider( providerName,indexProps[index], searchFactoryImplementor);
- }
-
- //define sharding strategy
- IndexShardingStrategy shardingStrategy;
- Properties shardingProperties = new Properties();
- //we use an enumeration to get the keys from defaultProperties as well
- Enumeration<String> allProps = (Enumeration<String>) indexProps[0].propertyNames();
- while ( allProps.hasMoreElements() ){
- String key = allProps.nextElement();
- if ( key.startsWith( SHARDING_STRATEGY ) ) {
- shardingProperties.put( key, indexProps[0].getProperty( key ) );
- }
- }
-
- String shardingStrategyName = shardingProperties.getProperty( SHARDING_STRATEGY );
- if ( shardingStrategyName == null) {
- if ( indexProps.length == 1 ) {
- shardingStrategy = new NotShardedStrategy();
- }
- else {
- shardingStrategy = new IdHashShardingStrategy();
- }
- }
- else {
- try {
- Class shardigStrategyClass = ReflectHelper.classForName( shardingStrategyName, this.getClass() );
- shardingStrategy = (IndexShardingStrategy) shardigStrategyClass.newInstance();
- }
- catch (ClassNotFoundException e) {
- throw new SearchException("Unable to find ShardingStrategy class " + shardingStrategyName + " for " + directoryProviderName, e);
- }
- catch (IllegalAccessException e) {
- throw new SearchException("Unable to create instance of ShardingStrategy class " + shardingStrategyName
- + " Be sure to have a no-arg constructor", e);
- }
- catch (InstantiationException e) {
- throw new SearchException("Unable to create instance of ShardingStrategy class " + shardingStrategyName
- + " Be sure to have a no-arg constructor", e);
- }
- catch (ClassCastException e) {
- throw new SearchException("ShardingStrategy class does not implements DirecotryProviderShardingStrategy: "
- + shardingStrategyName, e);
- }
- }
- shardingStrategy.initialize( shardingProperties, providers );
-
- return new DirectoryProviders( shardingStrategy, providers );
- }
-
- public void startDirectoryProviders() {
- for ( DirectoryProvider provider : providers ) {
- provider.start();
- }
- }
-
- private DirectoryProvider<?> createDirectoryProvider(String directoryProviderName, Properties indexProps, SearchFactoryImplementor searchFactoryImplementor) {
- String className = indexProps.getProperty( "directory_provider" );
- if ( StringHelper.isEmpty( className ) ) {
- className = DEFAULT_DIRECTORY_PROVIDER;
- }
- DirectoryProvider<?> provider;
- try {
- @SuppressWarnings( "unchecked" )
- Class<DirectoryProvider> directoryClass = ReflectHelper.classForName(
- className, DirectoryProviderFactory.class
- );
- provider = directoryClass.newInstance();
- }
- catch (Exception e) {
- throw new HibernateException( "Unable to instanciate directory provider: " + className, e );
- }
- try {
- provider.initialize( directoryProviderName, indexProps, searchFactoryImplementor );
- }
- catch (Exception e) {
- throw new HibernateException( "Unable to initialize: " + directoryProviderName, e);
- }
- int index = providers.indexOf( provider );
- if ( index != -1 ) {
- //share the same Directory provider for the same underlying store
- return providers.get( index );
- }
- else {
- configureOptimizerStrategy(searchFactoryImplementor, indexProps, provider);
- configureIndexingParameters(searchFactoryImplementor, indexProps, provider);
- providers.add( provider );
- if ( !searchFactoryImplementor.getLockableDirectoryProviders().containsKey( provider ) ) {
- searchFactoryImplementor.getLockableDirectoryProviders().put( provider, new ReentrantLock() );
- }
- return provider;
- }
- }
-
- private void configureOptimizerStrategy(SearchFactoryImplementor searchFactoryImplementor, Properties indexProps, DirectoryProvider<?> provider) {
- boolean incremental = indexProps.containsKey( "optimizer.operation_limit.max" )
- || indexProps.containsKey( "optimizer.transaction_limit.max" );
- OptimizerStrategy optimizerStrategy;
- if (incremental) {
- optimizerStrategy = new IncrementalOptimizerStrategy();
- optimizerStrategy.initialize( provider, indexProps, searchFactoryImplementor);
- }
- else {
- optimizerStrategy = new NoOpOptimizerStrategy();
- }
- searchFactoryImplementor.addOptimizerStrategy(provider, optimizerStrategy);
- }
-
- /**
- * Creates a new <code>LuceneIndexingParameters</code> instance for the specified provider.
- * If there are no matching properties in the configuration default values will be applied.
- * <p>
- * NOTE:</br>
- * If a non batch value is set in the configuration apply it also to the
- * batch mode. This covers the case where users only specify
- * parameters for the non batch mode. In this case the same parameters apply for
- * batch indexing.
- * </p>
- *
- * @param searchFactoryImplementor the search factory.
- * @param indexProps The properties extracted from the configuration.
- * @param provider The directory provider for which to configure the indexing parameters.
- */
- private void configureIndexingParameters(SearchFactoryImplementor searchFactoryImplementor, Properties indexProps, DirectoryProvider<?> provider) {
- LuceneIndexingParameters indexingParams = new LuceneIndexingParameters( indexProps );
- searchFactoryImplementor.addIndexingParmeters( provider, indexingParams );
- }
-
- /**
- * Returns an array of directory properties
- * Properties are defaulted. For a given property name,
- * hibernate.search.indexname.n has priority over hibernate.search.indexname which has priority over hibernate.search
- * If the Index is not sharded, a single Properties is returned
- * If the index is sharded, the Properties index matches the shard index
- */
- private static Properties[] getDirectoryProperties(Configuration cfg, String directoryProviderName) {
-
- Properties cfgAndImplicitProperties = new Properties();
- // cfg has no defaults, so we may use keySet iteration
- //FIXME not so sure about that cfg.setProperties()?
- for ( Map.Entry entry : cfg.getProperties().entrySet() ) {
- String key = entry.getKey().toString();// casting to String
- if ( key.startsWith( LUCENE_PREFIX ) ) {
- //put regular properties and add an explicit batch property when a transaction property is set
- cfgAndImplicitProperties.put( key, entry.getValue() );
- //be careful to replace only the intended ".transaction." with ".batch.":
- String[] splitKey = dotPattern.split( key );
- //TODO this code is vulnerable to properties with dot in the name. This is not a problem today though
- if ( splitKey.length > 2 && splitKey[ splitKey.length - 2 ]
- .equals( LuceneIndexingParameters.TRANSACTION ) ) {
- splitKey[ splitKey.length - 2 ] = LuceneIndexingParameters.BATCH;
- StringBuilder missingKeyBuilder = new StringBuilder( splitKey[0] );
- for (int i = 1; i < splitKey.length; i++) {
- missingKeyBuilder.append( "." );
- missingKeyBuilder.append( splitKey[i] );
- }
- String additionalKey = missingKeyBuilder.toString();
- if ( cfg.getProperty(additionalKey) == null ){
- cfgAndImplicitProperties.put(additionalKey, cfg.getProperty(key) );
- }
- }
- }
- }
- Properties globalProperties = new Properties();
- Properties directoryLocalProperties = new Properties( globalProperties );
- String directoryLocalPrefix = LUCENE_PREFIX + directoryProviderName + ".";
- for ( Map.Entry entry : cfgAndImplicitProperties.entrySet() ) {
- String key = entry.getKey().toString();// casting to String
- if ( key.startsWith( LUCENE_DEFAULT ) ) {
- globalProperties.put( key.substring( LUCENE_DEFAULT.length() ), entry.getValue() );
- }
- else if ( key.startsWith( directoryLocalPrefix ) ) {
- directoryLocalProperties.put( key.substring( directoryLocalPrefix.length() ),entry.getValue() );
- }
- }
- final String shardsCountValue = directoryLocalProperties.getProperty(NBR_OF_SHARDS);
- if (shardsCountValue == null) {
- // no shards: finished.
- return new Properties[] { directoryLocalProperties };
- } else {
- // count shards
- int shardsCount = -1;
- {
- try {
- shardsCount = Integer.parseInt( shardsCountValue );
- } catch (NumberFormatException e) {
- if ( cfgAndImplicitProperties.getProperty(directoryLocalPrefix + NBR_OF_SHARDS ) != null)
- throw new SearchException( shardsCountValue + " is not a number", e);
- }
- }
- // create shard-specific Props
- Properties[] shardLocalProperties = new Properties[shardsCount];
- for ( int i = 0; i < shardsCount; i++ ) {
- String currentShardPrefix = i + ".";
- Properties currentProp = new Properties( directoryLocalProperties );
- //Enumerations are ugly but otherwise we can't get the property defaults:
- Enumeration<String> localProps = (Enumeration<String>) directoryLocalProperties.propertyNames();
- while ( localProps.hasMoreElements() ){
- String key = localProps.nextElement();
- if ( key.startsWith( currentShardPrefix ) ) {
- currentProp.setProperty( key.substring( currentShardPrefix.length() ), directoryLocalProperties.getProperty( key ) );
- }
- }
- shardLocalProperties[i] = currentProp;
- }
- return shardLocalProperties;
- }
- }
-
- private static String getDirectoryProviderName(XClass clazz, Configuration cfg) {
- //yuk
- ReflectionManager reflectionManager = SearchFactoryImpl.getReflectionManager(cfg);
- //get the most specialized (ie subclass > superclass) non default index name
- //if none extract the name from the most generic (superclass > subclass) @Indexed class in the hierarchy
- //FIXME I'm inclined to get rid of the default value
- PersistentClass pc = cfg.getClassMapping( clazz.getName() );
- XClass rootIndex = null;
- do {
- XClass currentClazz = reflectionManager.toXClass( pc.getMappedClass() );
- Indexed indexAnn = currentClazz.getAnnotation( Indexed.class );
- if ( indexAnn != null ) {
- if ( indexAnn.index().length() != 0 ) {
- return indexAnn.index();
- }
- else {
- rootIndex = currentClazz;
- }
- }
- pc = pc.getSuperclass();
- }
- while ( pc != null );
- //there is nobody out there with a non default @Indexed.index
- if ( rootIndex != null ) {
- return rootIndex.getName();
- }
- else {
- throw new HibernateException(
- "Trying to extract the index name from a non @Indexed class: " + clazz.getName() );
- }
- }
-
- public class DirectoryProviders {
- private IndexShardingStrategy shardingStrategy;
- private DirectoryProvider[] providers;
-
-
- public DirectoryProviders(IndexShardingStrategy shardingStrategy, DirectoryProvider[] providers) {
- this.shardingStrategy = shardingStrategy;
- this.providers = providers;
- }
-
-
- public IndexShardingStrategy getSelectionStrategy() {
- return shardingStrategy;
- }
-
- public DirectoryProvider[] getProviders() {
- return providers;
- }
- }
-}
+//$Id$
+package org.hibernate.search.store;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Properties;
+import java.util.concurrent.locks.ReentrantLock;
+
+import org.hibernate.annotations.common.reflection.ReflectionManager;
+import org.hibernate.annotations.common.reflection.XClass;
+import org.hibernate.cfg.Configuration;
+import org.hibernate.mapping.PersistentClass;
+import org.hibernate.search.SearchException;
+import org.hibernate.search.annotations.Indexed;
+import org.hibernate.search.backend.LuceneIndexingParameters;
+import org.hibernate.search.backend.configuration.MaskedProperty;
+import org.hibernate.search.engine.SearchFactoryImplementor;
+import org.hibernate.search.impl.SearchFactoryImpl;
+import org.hibernate.search.store.optimization.IncrementalOptimizerStrategy;
+import org.hibernate.search.store.optimization.NoOpOptimizerStrategy;
+import org.hibernate.search.store.optimization.OptimizerStrategy;
+import org.hibernate.util.ReflectHelper;
+import org.hibernate.util.StringHelper;
+
+/**
+ * Create a Lucene directory provider
+ * <p/>
+ * Lucene directory providers are configured through properties
+ * <ul>
+ * <li>hibernate.search.default.* and</li>
+ * <li>hibernate.search.<indexname>.*</li>
+ * </ul>
+ * <p/>
+ * <indexname> properties have precedence over default
+ * <p/>
+ * The implementation is described by
+ * hibernate.search.[default|indexname].directory_provider
+ * <p/>
+ * If none is defined the default value is FSDirectory
+ *
+ * @author Emmanuel Bernard
+ * @author Sylvain Vieujot
+ * @author Hardy Ferentschik
+ * @author Sanne Grinovero
+ */
+public class DirectoryProviderFactory {
+
+ private List<DirectoryProvider<?>> providers = new ArrayList<DirectoryProvider<?>>();
+ private static String DEFAULT_DIRECTORY_PROVIDER = FSDirectoryProvider.class.getName();
+
+ private static final String SHARDING_STRATEGY = "sharding_strategy";
+ private static final String NBR_OF_SHARDS = SHARDING_STRATEGY + ".nbr_of_shards";
+
+ public DirectoryProviders createDirectoryProviders(XClass entity, Configuration cfg, SearchFactoryImplementor searchFactoryImplementor) {
+ //get properties
+ String directoryProviderName = getDirectoryProviderName( entity, cfg );
+ Properties[] indexProps = getDirectoryProperties( cfg, directoryProviderName );
+
+ //set up the directories
+ int nbrOfProviders = indexProps.length;
+ DirectoryProvider[] providers = new DirectoryProvider[nbrOfProviders];
+ for ( int index = 0 ; index < nbrOfProviders ; index++ ) {
+ String providerName = nbrOfProviders > 1 ?
+ directoryProviderName + "." + index :
+ directoryProviderName;
+ providers[index] = createDirectoryProvider( providerName, indexProps[index], searchFactoryImplementor );
+ }
+
+ //define sharding strategy
+ IndexShardingStrategy shardingStrategy;
+ //any indexProperty will do, the indexProps[0] surely exists.
+ String shardingStrategyName = indexProps[0].getProperty( SHARDING_STRATEGY );
+ if ( shardingStrategyName == null) {
+ if ( indexProps.length == 1 ) {
+ shardingStrategy = new NotShardedStrategy();
+ }
+ else {
+ shardingStrategy = new IdHashShardingStrategy();
+ }
+ }
+ else {
+ try {
+ Class shardigStrategyClass = ReflectHelper.classForName( shardingStrategyName, this.getClass() );
+ shardingStrategy = (IndexShardingStrategy) shardigStrategyClass.newInstance();
+ }
+ catch (ClassNotFoundException e) {
+ throw new SearchException("Unable to find ShardingStrategy class " + shardingStrategyName + " for " + directoryProviderName, e);
+ }
+ catch (IllegalAccessException e) {
+ throw new SearchException("Unable to create instance of ShardingStrategy class " + shardingStrategyName
+ + " Be sure to have a no-arg constructor", e);
+ }
+ catch (InstantiationException e) {
+ throw new SearchException("Unable to create instance of ShardingStrategy class " + shardingStrategyName
+ + " Be sure to have a no-arg constructor", e);
+ }
+ catch (ClassCastException e) {
+ throw new SearchException("ShardingStrategy class does not implements DirecotryProviderShardingStrategy: "
+ + shardingStrategyName, e);
+ }
+ }
+ shardingStrategy.initialize(
+ new MaskedProperty( indexProps[0], SHARDING_STRATEGY ), providers );
+ return new DirectoryProviders( shardingStrategy, providers );
+ }
+
+ public void startDirectoryProviders() {
+ for ( DirectoryProvider provider : providers ) {
+ provider.start();
+ }
+ }
+
+ private DirectoryProvider<?> createDirectoryProvider(String directoryProviderName, Properties indexProps, SearchFactoryImplementor searchFactoryImplementor) {
+ String className = indexProps.getProperty( "directory_provider" );
+ if ( StringHelper.isEmpty( className ) ) {
+ className = DEFAULT_DIRECTORY_PROVIDER;
+ }
+ DirectoryProvider<?> provider;
+ try {
+ @SuppressWarnings( "unchecked" )
+ Class<DirectoryProvider> directoryClass = ReflectHelper.classForName(
+ className, DirectoryProviderFactory.class
+ );
+ provider = directoryClass.newInstance();
+ }
+ catch (Exception e) {
+ throw new SearchException( "Unable to instantiate directory provider: " + className, e );
+ }
+ try {
+ provider.initialize( directoryProviderName, indexProps, searchFactoryImplementor );
+ }
+ catch (Exception e) {
+ throw new SearchException( "Unable to initialize: " + directoryProviderName, e );
+ }
+ int index = providers.indexOf( provider );
+ if ( index != -1 ) {
+ //share the same Directory provider for the same underlying store
+ return providers.get( index );
+ }
+ else {
+ configureOptimizerStrategy( searchFactoryImplementor, indexProps, provider );
+ configureIndexingParameters( searchFactoryImplementor, indexProps, provider );
+ providers.add( provider );
+ if ( !searchFactoryImplementor.getLockableDirectoryProviders().containsKey( provider ) ) {
+ searchFactoryImplementor.getLockableDirectoryProviders().put( provider, new ReentrantLock() );
+ }
+ return provider;
+ }
+ }
+
+ private void configureOptimizerStrategy(SearchFactoryImplementor searchFactoryImplementor, Properties indexProps, DirectoryProvider<?> provider) {
+ boolean incremental = indexProps.containsKey( "optimizer.operation_limit.max" )
+ || indexProps.containsKey( "optimizer.transaction_limit.max" );
+ OptimizerStrategy optimizerStrategy;
+ if (incremental) {
+ optimizerStrategy = new IncrementalOptimizerStrategy();
+ optimizerStrategy.initialize( provider, indexProps, searchFactoryImplementor );
+ }
+ else {
+ optimizerStrategy = new NoOpOptimizerStrategy();
+ }
+ searchFactoryImplementor.addOptimizerStrategy( provider, optimizerStrategy );
+ }
+
+ /**
+ * Creates a new <code>LuceneIndexingParameters</code> instance for the specified provider.
+ * If there are no matching properties in the configuration default values will be applied.
+ * <p>
+ * NOTE:</br>
+ * If a non batch value is set in the configuration apply it also to the
+ * batch mode. This covers the case where users only specify
+ * parameters for the non batch mode. In this case the same parameters apply for
+ * batch indexing. Parameters are found "depth-first": if a batch parameter is set
+ * in a global scope it will take priority on local transaction parameters.
+ * </p>
+ *
+ * @param searchFactoryImplementor the search factory.
+ * @param directoryProperties The properties extracted from the configuration.
+ * @param provider The directory provider for which to configure the indexing parameters.
+ */
+ private void configureIndexingParameters(SearchFactoryImplementor searchFactoryImplementor,
+ Properties directoryProperties, DirectoryProvider<?> provider) {
+ LuceneIndexingParameters indexingParams = new LuceneIndexingParameters( directoryProperties );
+ searchFactoryImplementor.addIndexingParmeters( provider, indexingParams );
+ }
+
+ /**
+ * Returns an array of directory properties
+ * Properties are defaulted. For a given property name,
+ * hibernate.search.indexname.n has priority over hibernate.search.indexname which has priority over hibernate.search.default
+ * If the Index is not sharded, a single Properties is returned
+ * If the index is sharded, the Properties index matches the shard index
+ */
+ private static Properties[] getDirectoryProperties(Configuration cfg, String directoryProviderName) {
+ Properties rootCfg = new MaskedProperty( cfg.getProperties(), "hibernate.search" );
+ Properties globalProperties = new MaskedProperty( rootCfg, "default" );
+ Properties directoryLocalProperties = new MaskedProperty( rootCfg, directoryProviderName, globalProperties );
+ final String shardsCountValue = directoryLocalProperties.getProperty( NBR_OF_SHARDS );
+ if ( shardsCountValue == null ) {
+ // no shards: finished.
+ return new Properties[] { directoryLocalProperties };
+ } else {
+ // count shards
+ int shardsCount;
+ {
+ try {
+ shardsCount = Integer.parseInt( shardsCountValue );
+ } catch (NumberFormatException e) {
+ throw new SearchException( shardsCountValue + " is not a number", e);
+ }
+ }
+ // create shard-specific Props
+ Properties[] shardLocalProperties = new Properties[shardsCount];
+ for ( int i = 0; i < shardsCount; i++ ) {
+ shardLocalProperties[i] = new MaskedProperty(
+ directoryLocalProperties, Integer.toString(i), directoryLocalProperties );
+ }
+ return shardLocalProperties;
+ }
+ }
+
+ private static String getDirectoryProviderName(XClass clazz, Configuration cfg) {
+ //yuk
+ ReflectionManager reflectionManager = SearchFactoryImpl.getReflectionManager(cfg);
+ //get the most specialized (ie subclass > superclass) non default index name
+ //if none extract the name from the most generic (superclass > subclass) @Indexed class in the hierarchy
+ //FIXME I'm inclined to get rid of the default value
+ PersistentClass pc = cfg.getClassMapping( clazz.getName() );
+ XClass rootIndex = null;
+ do {
+ XClass currentClazz = reflectionManager.toXClass( pc.getMappedClass() );
+ Indexed indexAnn = currentClazz.getAnnotation( Indexed.class );
+ if ( indexAnn != null ) {
+ if ( indexAnn.index().length() != 0 ) {
+ return indexAnn.index();
+ }
+ else {
+ rootIndex = currentClazz;
+ }
+ }
+ pc = pc.getSuperclass();
+ }
+ while ( pc != null );
+ //there is nobody out there with a non default @Indexed.index
+ if ( rootIndex != null ) {
+ return rootIndex.getName();
+ }
+ else {
+ throw new SearchException(
+ "Trying to extract the index name from a non @Indexed class: " + clazz.getName() );
+ }
+ }
+
+ public class DirectoryProviders {
+ private IndexShardingStrategy shardingStrategy;
+ private DirectoryProvider[] providers;
+
+ public DirectoryProviders(IndexShardingStrategy shardingStrategy, DirectoryProvider[] providers) {
+ this.shardingStrategy = shardingStrategy;
+ this.providers = providers;
+ }
+
+ public IndexShardingStrategy getSelectionStrategy() {
+ return shardingStrategy;
+ }
+
+ public DirectoryProvider[] getProviders() {
+ return providers;
+ }
+ }
+
+}
Modified: search/trunk/src/test/org/hibernate/search/test/configuration/ConfigurationReadTestCase.java
===================================================================
--- search/trunk/src/test/org/hibernate/search/test/configuration/ConfigurationReadTestCase.java 2008-05-23 21:42:40 UTC (rev 14689)
+++ search/trunk/src/test/org/hibernate/search/test/configuration/ConfigurationReadTestCase.java 2008-05-26 23:04:52 UTC (rev 14690)
@@ -8,6 +8,7 @@
import org.hibernate.search.engine.SearchFactoryImplementor;
import org.hibernate.search.impl.SearchFactoryImpl;
import org.hibernate.search.test.SearchTestCase;
+import org.hibernate.search.util.FileHelper;
/**
* Contains some utility methods to simplify coding of
@@ -17,7 +18,7 @@
*/
public abstract class ConfigurationReadTestCase extends SearchTestCase {
- private static final File INDEX_DIR = new File( new File("."), "indextemp" );
+ private static final File INDEX_DIR = new File( new File( "." ), "indextemp" );
private SearchFactoryImplementor searchFactory;
@@ -31,7 +32,7 @@
FullTextSession fullTextSession = Search.createFullTextSession( openSession() );
searchFactory = (SearchFactoryImpl) fullTextSession.getSearchFactory();
fullTextSession.close();
- remove(INDEX_DIR);
+ FileHelper.delete( INDEX_DIR );
INDEX_DIR.mkdirs();
}
@@ -83,19 +84,7 @@
protected void tearDown() throws Exception {
super.tearDown();
- remove(INDEX_DIR);
+ FileHelper.delete( INDEX_DIR );
}
-
- private void remove(File indexDir) {
- if (indexDir.exists()) {
- File[] containing = indexDir.listFiles();
- if ( containing != null ) { //is a directory
- for (int i=0; i<containing.length; i++ ){
- remove(containing[i]);
- }
- }
- indexDir.delete();
- }
- }
}
Modified: search/trunk/src/test/org/hibernate/search/test/configuration/LuceneIndexingParametersTest.java
===================================================================
--- search/trunk/src/test/org/hibernate/search/test/configuration/LuceneIndexingParametersTest.java 2008-05-23 21:42:40 UTC (rev 14689)
+++ search/trunk/src/test/org/hibernate/search/test/configuration/LuceneIndexingParametersTest.java 2008-05-26 23:04:52 UTC (rev 14690)
@@ -28,9 +28,10 @@
cfg.setProperty( "hibernate.search.Book.batch.max_merge_docs", "12" );
cfg.setProperty( "hibernate.search.Book.batch.merge_factor", "13" );
- cfg.setProperty( "hibernate.search.Book.batch.max_buffered_docs", "14" );
+ // new keyword "indexwriter" is also supported to group parameters:
+ cfg.setProperty( "hibernate.search.Book.indexwriter.batch.max_buffered_docs", "14" );
- cfg.setProperty( "hibernate.search.Book.transaction.ram_buffer_size", "4" );
+ cfg.setProperty( "hibernate.search.Book.indexwriter.transaction.ram_buffer_size", "4" );
cfg.setProperty( "hibernate.search.Book.transaction.max_merge_docs", "15" );
cfg.setProperty( "hibernate.search.Book.transaction.merge_factor", "16" );
cfg.setProperty( "hibernate.search.Book.transaction.max_buffered_docs", "17" );
@@ -59,7 +60,7 @@
public void testUnsetBatchValueTakesTransaction() throws Exception {
assertValueIsSet( Document.class, BATCH, MERGE_FACTOR, 6 );
- assertValueIsSet( Document.class, BATCH, MAX_BUFFERED_DOCS, 7 );
+ assertValueIsSet( Document.class, BATCH, MAX_BUFFERED_DOCS, 1000 );
}
public void testExplicitBatchParameters() throws Exception {
@@ -69,7 +70,7 @@
}
public void testInheritedBatchParametersFromTranscation() throws Exception {
- assertValueIsSet( Book.class, BATCH, RAM_BUFFER_SIZE, 4 );
+ assertValueIsSet( Book.class, BATCH, RAM_BUFFER_SIZE, 1 );
}
public void testTransactionParameters() throws Exception {
Added: search/trunk/src/test/org/hibernate/search/test/configuration/MaskedPropertiesTest.java
===================================================================
--- search/trunk/src/test/org/hibernate/search/test/configuration/MaskedPropertiesTest.java (rev 0)
+++ search/trunk/src/test/org/hibernate/search/test/configuration/MaskedPropertiesTest.java 2008-05-26 23:04:52 UTC (rev 14690)
@@ -0,0 +1,40 @@
+package org.hibernate.search.test.configuration;
+
+import java.util.Properties;
+
+import org.hibernate.search.backend.configuration.MaskedProperty;
+
+/**
+ * @author Sanne Grinovero
+ */
+public class MaskedPropertiesTest extends junit.framework.TestCase {
+
+ public void testConfigurationParsingPrecedence() {
+ Properties cfg = new Properties();
+ cfg.put( "hibernate.search.Animals.transaction.indexwriter.max_merge_docs", "1" );
+ cfg.put( "hibernate.search.Animals.2.transaction.indexwriter.max_merge_docs", "2" );
+ cfg.put( "hibernate.search.Animals.2.transaction.max_merge_docs", "3" );
+ cfg.put( "hibernate.search.Animals.transaction.max_merge_docs", "5" );
+ cfg.put( "hibernate.search.default.transaction.max_merge_docs", "6" );
+ cfg.put( "hibernate.search.default.transaction.indexwriter.max_field_length", "7" );
+
+ //this is more a "concept demo" than a test:
+ Properties root = new MaskedProperty( cfg, "hibernate.search" );
+ //only keys starting as "hibernate.search.default" are exposed:
+ Properties common = new MaskedProperty( root, "default" );
+ //now as "hibernate.search.Animals" or "hibernate.search.default" if first fails:
+ Properties dirProvider = new MaskedProperty( root, "Animals", common );
+ //this narrows visibility to "hibernate.search.<providername|default>.transaction":
+ Properties transaction = new MaskedProperty( dirProvider, "transaction" );
+ Properties shard2 = new MaskedProperty( dirProvider, "2", dirProvider );
+ Properties transactionInShard2 = new MaskedProperty( shard2, "transaction", transaction );
+ Properties newStyleTransaction = new MaskedProperty( transaction, "indexwriter", transaction );
+ Properties newStyleTransactionInShard2 = new MaskedProperty(
+ transactionInShard2, "indexwriter", transactionInShard2 );
+
+ assertEquals( "7" , newStyleTransaction.getProperty( "max_field_length" ) );
+ assertEquals( "7" , newStyleTransactionInShard2.getProperty( "max_field_length" ) );
+ assertEquals( "5" , transaction.getProperty( "max_merge_docs" ) );
+ }
+
+}
Modified: search/trunk/src/test/org/hibernate/search/test/configuration/ShardsConfigurationTest.java
===================================================================
--- search/trunk/src/test/org/hibernate/search/test/configuration/ShardsConfigurationTest.java 2008-05-23 21:42:40 UTC (rev 14689)
+++ search/trunk/src/test/org/hibernate/search/test/configuration/ShardsConfigurationTest.java 2008-05-26 23:04:52 UTC (rev 14690)
@@ -4,6 +4,7 @@
import static org.hibernate.search.backend.configuration.IndexWriterSetting.MAX_MERGE_DOCS;
import static org.hibernate.search.backend.configuration.IndexWriterSetting.MERGE_FACTOR;
import static org.hibernate.search.backend.configuration.IndexWriterSetting.RAM_BUFFER_SIZE;
+import static org.hibernate.search.backend.configuration.IndexWriterSetting.TERM_INDEX_INTERVAL;
import static org.hibernate.search.test.configuration.ConfigurationReadTestCase.TransactionType.TRANSACTION;
import static org.hibernate.search.test.configuration.ConfigurationReadTestCase.TransactionType.BATCH;
import org.hibernate.search.store.DirectoryProvider;
@@ -37,32 +38,36 @@
cfg.setProperty( "hibernate.search.Documents.0.transaction.max_buffered_docs", "58" );
cfg.setProperty( "hibernate.search.Documents.1.batch.max_merge_docs", "11" );
cfg.setProperty( "hibernate.search.Documents.1.transaction.max_buffered_docs", "12" );
+ cfg.setProperty( "hibernate.search.Documents.1.transaction.term_index_interval", "12" );
}
public void testCorrectNumberOfShardsDetected() throws Exception {
- DirectoryProvider[] docDirProviders = getSearchFactory().getDirectoryProviders(Document.class);
- assertNotNull(docDirProviders);
- assertEquals(4, docDirProviders.length);
- DirectoryProvider[] bookDirProviders = getSearchFactory().getDirectoryProviders(Book.class);
- assertNotNull(bookDirProviders);
- assertEquals(2, bookDirProviders.length);
+ DirectoryProvider[] docDirProviders = getSearchFactory()
+ .getDirectoryProviders( Document.class );
+ assertNotNull( docDirProviders);
+ assertEquals( 4, docDirProviders.length );
+ DirectoryProvider[] bookDirProviders = getSearchFactory()
+ .getDirectoryProviders( Book.class );
+ assertNotNull( bookDirProviders );
+ assertEquals( 2, bookDirProviders.length );
}
public void testSelectionOfShardingStrategy() throws Exception {
- IndexShardingStrategy shardingStrategy = getSearchFactory().getDocumentBuilders().get(Document.class).getDirectoryProviderSelectionStrategy();
+ IndexShardingStrategy shardingStrategy = getSearchFactory().getDocumentBuilders()
+ .get( Document.class ).getDirectoryProviderSelectionStrategy();
assertNotNull( shardingStrategy );
assertEquals( shardingStrategy.getClass(), UselessShardingStrategy.class );
}
public void testShardingSettingsInherited() throws Exception {
- DirectoryProvider[] docDirProviders = getSearchFactory().getDirectoryProviders(Document.class);
+ DirectoryProvider[] docDirProviders = getSearchFactory().getDirectoryProviders( Document.class );
assertTrue( docDirProviders[0] instanceof RAMDirectoryProvider );
assertTrue( docDirProviders[1] instanceof FSDirectoryProvider );
assertTrue( docDirProviders[2] instanceof RAMDirectoryProvider );
}
public void testShardN2UsesDefaults() throws Exception {
- assertValueIsSet( Document.class, 2, TRANSACTION, MAX_BUFFERED_DOCS, 6);
+ assertValueIsSet( Document.class, 2, TRANSACTION, MAX_BUFFERED_DOCS, 6 );
assertValueIsDefault( Document.class, 2, TRANSACTION, MAX_MERGE_DOCS );
assertValueIsSet( Document.class, 2, TRANSACTION, MERGE_FACTOR, 100 );
assertValueIsDefault( Document.class, 2, TRANSACTION, RAM_BUFFER_SIZE );
@@ -78,8 +83,8 @@
}
public void testShard_BatchInheritedFromTransaction() throws Exception {
- assertValueIsSet( Document.class, 1, BATCH, MAX_BUFFERED_DOCS, 12 );
- assertValueIsSet( Document.class, 0, BATCH, MAX_BUFFERED_DOCS, 58 );
+ assertValueIsSet( Document.class, 1, BATCH, TERM_INDEX_INTERVAL, 12 );
+ assertValueIsSet( Document.class, 0, BATCH, MAX_BUFFERED_DOCS, 4 );
}
protected Class[] getMappings() {
16 years, 6 months
Hibernate SVN: r14689 - search/trunk/src/java/org/hibernate/search/engine.
by hibernate-commits@lists.jboss.org
Author: sannegrinovero
Date: 2008-05-23 17:42:40 -0400 (Fri, 23 May 2008)
New Revision: 14689
Modified:
search/trunk/src/java/org/hibernate/search/engine/SearchFactoryImplementor.java
Log:
typo
Modified: search/trunk/src/java/org/hibernate/search/engine/SearchFactoryImplementor.java
===================================================================
--- search/trunk/src/java/org/hibernate/search/engine/SearchFactoryImplementor.java 2008-05-23 21:30:38 UTC (rev 14688)
+++ search/trunk/src/java/org/hibernate/search/engine/SearchFactoryImplementor.java 2008-05-23 21:42:40 UTC (rev 14689)
@@ -39,6 +39,7 @@
public LuceneIndexingParameters getIndexingParameters(DirectoryProvider<?> provider);
+ //FIXME spelling error in method name:
void addIndexingParmeters(DirectoryProvider<?> provider, LuceneIndexingParameters indexingParams);
public String getIndexingStrategy();
16 years, 6 months
Hibernate SVN: r14687 - in search/trunk/src: java/org/hibernate/search/backend/impl and 7 other directories.
by hibernate-commits@lists.jboss.org
Author: epbernard
Date: 2008-05-22 14:21:01 -0400 (Thu, 22 May 2008)
New Revision: 14687
Modified:
search/trunk/src/java/org/hibernate/search/backend/QueueingProcessor.java
search/trunk/src/java/org/hibernate/search/backend/Worker.java
search/trunk/src/java/org/hibernate/search/backend/impl/BatchedQueueingProcessor.java
search/trunk/src/java/org/hibernate/search/backend/impl/TransactionalWorker.java
search/trunk/src/java/org/hibernate/search/engine/SearchFactoryImplementor.java
search/trunk/src/java/org/hibernate/search/event/FullTextIndexEventListener.java
search/trunk/src/java/org/hibernate/search/impl/SearchFactoryImpl.java
search/trunk/src/java/org/hibernate/search/store/DirectoryProvider.java
search/trunk/src/java/org/hibernate/search/store/FSDirectoryProvider.java
search/trunk/src/java/org/hibernate/search/store/FSMasterDirectoryProvider.java
search/trunk/src/java/org/hibernate/search/store/FSSlaveDirectoryProvider.java
search/trunk/src/java/org/hibernate/search/store/RAMDirectoryProvider.java
search/trunk/src/test/org/hibernate/search/test/FSDirectoryTest.java
search/trunk/src/test/org/hibernate/search/test/HANTestCase.java
search/trunk/src/test/org/hibernate/search/test/directoryProvider/FSSlaveAndMasterDPTest.java
search/trunk/src/test/org/hibernate/search/test/worker/WorkerTestCase.java
Log:
HSEARCH-199 close resources on SF.close() had to change the DirectoryProvider API and the worker / QueueingProcess APIs
Modified: search/trunk/src/java/org/hibernate/search/backend/QueueingProcessor.java
===================================================================
--- search/trunk/src/java/org/hibernate/search/backend/QueueingProcessor.java 2008-05-22 15:43:24 UTC (rev 14686)
+++ search/trunk/src/java/org/hibernate/search/backend/QueueingProcessor.java 2008-05-22 18:21:01 UTC (rev 14687)
@@ -36,4 +36,10 @@
* Rollback works
*/
void cancelWorks(WorkQueue workQueue);
+
+ /**
+ * clean resources
+ * This method should log errors rather than raise an exception
+ */
+ void close();
}
Modified: search/trunk/src/java/org/hibernate/search/backend/Worker.java
===================================================================
--- search/trunk/src/java/org/hibernate/search/backend/Worker.java 2008-05-22 15:43:24 UTC (rev 14686)
+++ search/trunk/src/java/org/hibernate/search/backend/Worker.java 2008-05-22 18:21:01 UTC (rev 14687)
@@ -16,4 +16,10 @@
void performWork(Work work, EventSource session);
void initialize(Properties props, SearchFactoryImplementor searchFactoryImplementor);
+
+ /**
+ * clean resources
+ * This method can return exceptions
+ */
+ void close();
}
Modified: search/trunk/src/java/org/hibernate/search/backend/impl/BatchedQueueingProcessor.java
===================================================================
--- search/trunk/src/java/org/hibernate/search/backend/impl/BatchedQueueingProcessor.java 2008-05-22 15:43:24 UTC (rev 14686)
+++ search/trunk/src/java/org/hibernate/search/backend/impl/BatchedQueueingProcessor.java 2008-05-22 18:21:01 UTC (rev 14687)
@@ -25,6 +25,8 @@
import org.hibernate.search.backend.impl.lucene.LuceneBackendQueueProcessorFactory;
import org.hibernate.search.engine.DocumentBuilder;
import org.hibernate.search.engine.SearchFactoryImplementor;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
* Batch work until #performWorks is called.
@@ -33,6 +35,9 @@
* @author Emmanuel Bernard
*/
public class BatchedQueueingProcessor implements QueueingProcessor {
+
+ private static final Logger log = LoggerFactory.getLogger( BatchedQueueingProcessor.class );
+
private boolean sync;
private int batchSize;
private ExecutorService executorService;
@@ -157,14 +162,16 @@
workQueue.clear();
}
- @Override
- public void finalize() throws Throwable {
- super.finalize();
+ public void close() {
//gracefully stop
- //TODO move to the SF close lifecycle
if ( executorService != null && !executorService.isShutdown() ) {
executorService.shutdown();
- executorService.awaitTermination(Long.MAX_VALUE, TimeUnit.SECONDS );
+ try {
+ executorService.awaitTermination(Long.MAX_VALUE, TimeUnit.SECONDS );
+ }
+ catch (InterruptedException e) {
+ log.error("Unable to property shut down asynchronous indexing work", e);
+ }
}
}
Modified: search/trunk/src/java/org/hibernate/search/backend/impl/TransactionalWorker.java
===================================================================
--- search/trunk/src/java/org/hibernate/search/backend/impl/TransactionalWorker.java 2008-05-22 15:43:24 UTC (rev 14686)
+++ search/trunk/src/java/org/hibernate/search/backend/impl/TransactionalWorker.java 2008-05-22 18:21:01 UTC (rev 14687)
@@ -49,4 +49,9 @@
public void initialize(Properties props, SearchFactoryImplementor searchFactory) {
this.queueingProcessor = new BatchedQueueingProcessor( searchFactory, props );
}
+
+ public void close() {
+ queueingProcessor.close();
+ }
+
}
Modified: search/trunk/src/java/org/hibernate/search/engine/SearchFactoryImplementor.java
===================================================================
--- search/trunk/src/java/org/hibernate/search/engine/SearchFactoryImplementor.java 2008-05-22 15:43:24 UTC (rev 14686)
+++ search/trunk/src/java/org/hibernate/search/engine/SearchFactoryImplementor.java 2008-05-22 18:21:01 UTC (rev 14687)
@@ -42,4 +42,6 @@
void addIndexingParmeters(DirectoryProvider<?> provider, LuceneIndexingParameters indexingParams);
public String getIndexingStrategy();
+
+ public void close();
}
Modified: search/trunk/src/java/org/hibernate/search/event/FullTextIndexEventListener.java
===================================================================
--- search/trunk/src/java/org/hibernate/search/event/FullTextIndexEventListener.java 2008-05-22 15:43:24 UTC (rev 14686)
+++ search/trunk/src/java/org/hibernate/search/event/FullTextIndexEventListener.java 2008-05-22 18:21:01 UTC (rev 14687)
@@ -12,6 +12,7 @@
import org.hibernate.event.PostInsertEventListener;
import org.hibernate.event.PostUpdateEvent;
import org.hibernate.event.PostUpdateEventListener;
+import org.hibernate.event.Destructible;
import org.hibernate.search.backend.WorkType;
import org.hibernate.search.backend.Work;
import org.hibernate.search.engine.DocumentBuilder;
@@ -31,7 +32,7 @@
//TODO work on sharing the same indexWriters and readers across a single post operation...
//TODO implement and use a LockableDirectoryProvider that wraps a DP to handle the lock inside the LDP
public class FullTextIndexEventListener implements PostDeleteEventListener, PostInsertEventListener,
- PostUpdateEventListener, Initializable {
+ PostUpdateEventListener, Initializable, Destructible {
@SuppressWarnings( { "WeakerAccess" } )
protected boolean used;
@@ -87,4 +88,8 @@
Work work = new Work(entity, id, workType);
searchFactoryImplementor.getWorker().performWork( work, event.getSession() );
}
+
+ public void cleanup() {
+ searchFactoryImplementor.close();
+ }
}
Modified: search/trunk/src/java/org/hibernate/search/impl/SearchFactoryImpl.java
===================================================================
--- search/trunk/src/java/org/hibernate/search/impl/SearchFactoryImpl.java 2008-05-22 15:43:24 UTC (rev 14686)
+++ search/trunk/src/java/org/hibernate/search/impl/SearchFactoryImpl.java 2008-05-22 18:21:01 UTC (rev 14687)
@@ -44,6 +44,8 @@
import org.hibernate.search.store.DirectoryProviderFactory;
import org.hibernate.search.store.optimization.OptimizerStrategy;
import org.apache.lucene.analysis.Analyzer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
* @author Emmanuel Bernard
@@ -56,6 +58,8 @@
Version.touch();
}
+ private final Logger log = LoggerFactory.getLogger( SearchFactoryImpl.class );
+
private Map<Class, DocumentBuilder<Object>> documentBuilders = new HashMap<Class, DocumentBuilder<Object>>();
//keep track of the index modifiers per DirectoryProvider since multiple entity can use the same directory provider
private Map<DirectoryProvider, ReentrantLock> lockableDirectoryProviders =
@@ -68,6 +72,7 @@
private Map<String, FilterDef> filterDefinitions = new HashMap<String, FilterDef>();
private FilterCachingStrategy filterCachingStrategy;
private Map<String, Analyzer> analyzers;
+ private boolean stopped = false;
/**
* Each directory provider (index) can have its own performance settings.
@@ -113,6 +118,27 @@
return indexingStrategy;
}
+ public void close() {
+ if (!stopped) {
+ stopped = true;
+ try {
+ worker.close();
+ }
+ catch (Exception e) {
+ log.error( "Worker raises an exception on close()", e );
+ }
+ //TODO move to DirectoryProviderFactory for cleaner
+ for (DirectoryProvider dp : lockableDirectoryProviders.keySet() ) {
+ try {
+ dp.stop();
+ }
+ catch (Exception e) {
+ log.error( "DirectoryProvider raises an exception on stop() ", e );
+ }
+ }
+ }
+ }
+
private void bindFilterDefs(XClass mappedXClass) {
FullTextFilterDef defAnn = mappedXClass.getAnnotation( FullTextFilterDef.class );
if ( defAnn != null ) {
Modified: search/trunk/src/java/org/hibernate/search/store/DirectoryProvider.java
===================================================================
--- search/trunk/src/java/org/hibernate/search/store/DirectoryProvider.java 2008-05-22 15:43:24 UTC (rev 14686)
+++ search/trunk/src/java/org/hibernate/search/store/DirectoryProvider.java 2008-05-22 18:21:01 UTC (rev 14687)
@@ -30,11 +30,17 @@
* Executed after initialize, this method set up the heavy process of starting up the DirectoryProvider
* IO processing as well as backgroup processing are expected to be set up here
*
- * TODO stop() method, for now use finalize()
*/
void start();
/**
+ * Executed when the search factory is closed. This method should stop any background process as well as
+ * releasing any resource.
+ * This method should avoid raising exceptions and log potential errors instead
+ */
+ void stop();
+
+ /**
* Returns an initialized Lucene Directory. This method call <b>must</b> be threadsafe
*/
TDirectory getDirectory();
Modified: search/trunk/src/java/org/hibernate/search/store/FSDirectoryProvider.java
===================================================================
--- search/trunk/src/java/org/hibernate/search/store/FSDirectoryProvider.java 2008-05-22 15:43:24 UTC (rev 14686)
+++ search/trunk/src/java/org/hibernate/search/store/FSDirectoryProvider.java 2008-05-22 18:21:01 UTC (rev 14687)
@@ -9,6 +9,8 @@
import org.hibernate.search.Environment;
import org.hibernate.search.SearchException;
import org.hibernate.search.engine.SearchFactoryImplementor;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
* Use a Lucene FSDirectory
@@ -20,6 +22,8 @@
* @author Sanne Grinovero
*/
public class FSDirectoryProvider implements DirectoryProvider<FSDirectory> {
+
+ private final Logger log = LoggerFactory.getLogger( FSDirectoryProvider.class );
private FSDirectory directory;
private String indexName;
@@ -42,6 +46,15 @@
//all the process is done in initialize
}
+ public void stop() {
+ try {
+ directory.close();
+ }
+ catch (Exception e) {
+ log.error( "Unable to property close Lucene directory {}" + directory.getFile(), e );
+ }
+ }
+
public FSDirectory getDirectory() {
return directory;
}
Modified: search/trunk/src/java/org/hibernate/search/store/FSMasterDirectoryProvider.java
===================================================================
--- search/trunk/src/java/org/hibernate/search/store/FSMasterDirectoryProvider.java 2008-05-22 15:43:24 UTC (rev 14686)
+++ search/trunk/src/java/org/hibernate/search/store/FSMasterDirectoryProvider.java 2008-05-22 18:21:01 UTC (rev 14687)
@@ -117,6 +117,18 @@
return 37 * hash + indexName.hashCode();
}
+
+
+ public void stop() {
+ timer.cancel();
+ try {
+ directory.close();
+ }
+ catch (Exception e) {
+ log.error( "Unable to property close Lucene directory {}" + directory.getFile(), e );
+ }
+ }
+
class TriggerTask extends TimerTask {
private final ExecutorService executor;
@@ -194,10 +206,4 @@
log.trace( "Copy for {} took {} ms", indexName, (System.currentTimeMillis() - start) );
}
}
-
- public void finalize() throws Throwable {
- super.finalize();
- timer.cancel();
- //TODO find a better cycle from Hibernate core
- }
}
Modified: search/trunk/src/java/org/hibernate/search/store/FSSlaveDirectoryProvider.java
===================================================================
--- search/trunk/src/java/org/hibernate/search/store/FSSlaveDirectoryProvider.java 2008-05-22 15:43:24 UTC (rev 14686)
+++ search/trunk/src/java/org/hibernate/search/store/FSSlaveDirectoryProvider.java 2008-05-22 18:21:01 UTC (rev 14687)
@@ -226,9 +226,19 @@
}
}
- public void finalize() throws Throwable {
- super.finalize();
+ public void stop() {
timer.cancel();
- //TODO find a better cycle from Hibernate core
+ try {
+ directory1.close();
+ }
+ catch (Exception e) {
+ log.error( "Unable to property close Lucene directory {}" + directory1.getFile(), e );
+ }
+ try {
+ directory2.close();
+ }
+ catch (Exception e) {
+ log.error( "Unable to property close Lucene directory {}" + directory2.getFile(), e );
+ }
}
}
Modified: search/trunk/src/java/org/hibernate/search/store/RAMDirectoryProvider.java
===================================================================
--- search/trunk/src/java/org/hibernate/search/store/RAMDirectoryProvider.java 2008-05-22 15:43:24 UTC (rev 14686)
+++ search/trunk/src/java/org/hibernate/search/store/RAMDirectoryProvider.java 2008-05-22 18:21:01 UTC (rev 14687)
@@ -41,6 +41,8 @@
return directory;
}
+ public void stop() {}
+
@Override
public boolean equals(Object obj) {
// this code is actually broken since the value change after initialize call
Modified: search/trunk/src/test/org/hibernate/search/test/FSDirectoryTest.java
===================================================================
--- search/trunk/src/test/org/hibernate/search/test/FSDirectoryTest.java 2008-05-22 15:43:24 UTC (rev 14686)
+++ search/trunk/src/test/org/hibernate/search/test/FSDirectoryTest.java 2008-05-22 18:21:01 UTC (rev 14687)
@@ -190,6 +190,7 @@
}
s.getTransaction().commit();
s.close();
+ getSessions().close(); //run the searchfactory.close() operations
}
public void testSearchOnDeletedIndex() throws Exception {
Modified: search/trunk/src/test/org/hibernate/search/test/HANTestCase.java
===================================================================
--- search/trunk/src/test/org/hibernate/search/test/HANTestCase.java 2008-05-22 15:43:24 UTC (rev 14686)
+++ search/trunk/src/test/org/hibernate/search/test/HANTestCase.java 2008-05-22 18:21:01 UTC (rev 14687)
@@ -61,7 +61,7 @@
}
protected void setUp() throws Exception {
- if ( getSessions() == null || lastTestClass != getClass() ) {
+ if ( getSessions() == null || getSessions().isClosed() || lastTestClass != getClass() ) {
buildSessionFactory( getMappings(), getAnnotatedPackages(), getXmlFiles() );
lastTestClass = getClass();
}
Modified: search/trunk/src/test/org/hibernate/search/test/directoryProvider/FSSlaveAndMasterDPTest.java
===================================================================
--- search/trunk/src/test/org/hibernate/search/test/directoryProvider/FSSlaveAndMasterDPTest.java 2008-05-22 15:43:24 UTC (rev 14686)
+++ search/trunk/src/test/org/hibernate/search/test/directoryProvider/FSSlaveAndMasterDPTest.java 2008-05-22 18:21:01 UTC (rev 14687)
@@ -8,6 +8,7 @@
import org.apache.lucene.analysis.StopAnalyzer;
import org.apache.lucene.queryParser.QueryParser;
import org.hibernate.Session;
+import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.event.PostDeleteEventListener;
import org.hibernate.event.PostInsertEventListener;
@@ -87,6 +88,10 @@
assertEquals("Third copy did not work out", 1, result.size() );
fts2.close();
+ //run the searchfactory.close() operations
+ for ( SessionFactory sf : getSessionFactories() ) {
+ sf.close();
+ }
}
@@ -102,7 +107,7 @@
File slave = new File(root, "slave");
slave.mkdir();
-
+
super.setUp();
}
Modified: search/trunk/src/test/org/hibernate/search/test/worker/WorkerTestCase.java
===================================================================
--- search/trunk/src/test/org/hibernate/search/test/worker/WorkerTestCase.java 2008-05-22 15:43:24 UTC (rev 14686)
+++ search/trunk/src/test/org/hibernate/search/test/worker/WorkerTestCase.java 2008-05-22 18:21:01 UTC (rev 14687)
@@ -77,6 +77,7 @@
while ( work.count < iteration - 1 ) {
Thread.sleep( 20 );
}
+ getSessions().close();
System.out.println( iteration + " iterations (8 tx per iteration) in " + nThreads + " threads: " + ( System
.currentTimeMillis() - start ) );
}
16 years, 6 months
Hibernate SVN: r14686 - in core/trunk: testsuite/src/test/java/org/hibernate/test/cid and 1 other directory.
by hibernate-commits@lists.jboss.org
Author: steve.ebersole(a)jboss.com
Date: 2008-05-22 11:43:24 -0400 (Thu, 22 May 2008)
New Revision: 14686
Added:
core/trunk/testsuite/src/test/java/org/hibernate/test/cid/CompositeIdWithGeneratorTest.java
core/trunk/testsuite/src/test/java/org/hibernate/test/cid/PurchaseDetail.java
core/trunk/testsuite/src/test/java/org/hibernate/test/cid/PurchaseRecord.hbm.xml
core/trunk/testsuite/src/test/java/org/hibernate/test/cid/PurchaseRecord.java
core/trunk/testsuite/src/test/java/org/hibernate/test/cid/PurchaseRecordIdGenerator.java
Modified:
core/trunk/core/src/main/resources/org/hibernate/hibernate-mapping-3.0.dtd
Log:
HHH-2060 : composite-id + generator
Modified: core/trunk/core/src/main/resources/org/hibernate/hibernate-mapping-3.0.dtd
===================================================================
--- core/trunk/core/src/main/resources/org/hibernate/hibernate-mapping-3.0.dtd 2008-05-22 15:01:15 UTC (rev 14685)
+++ core/trunk/core/src/main/resources/org/hibernate/hibernate-mapping-3.0.dtd 2008-05-22 15:43:24 UTC (rev 14686)
@@ -174,7 +174,7 @@
key column. The class must implement java.io.Serializable and reimplement equals()
and hashCode(). -->
-<!ELEMENT composite-id ( meta*, (key-property|key-many-to-one)+ )>
+<!ELEMENT composite-id ( meta*, (key-property|key-many-to-one)+, generator? )>
<!ATTLIST composite-id class CDATA #IMPLIED>
<!ATTLIST composite-id mapped (true|false) "false">
<!ATTLIST composite-id name CDATA #IMPLIED>
Added: core/trunk/testsuite/src/test/java/org/hibernate/test/cid/CompositeIdWithGeneratorTest.java
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/cid/CompositeIdWithGeneratorTest.java (rev 0)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/cid/CompositeIdWithGeneratorTest.java 2008-05-22 15:43:24 UTC (rev 14686)
@@ -0,0 +1,505 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.test.cid;
+
+import java.util.Date;
+import java.util.Set;
+
+import junit.framework.Test;
+
+import org.hibernate.Session;
+import org.hibernate.Transaction;
+import org.hibernate.junit.functional.FunctionalTestCase;
+import org.hibernate.junit.functional.FunctionalTestClassTestSuite;
+
+/**
+ * Tests the use of composite-id with a generator.
+ * Test this behavior in all the various entity states (transient, managed, detached)
+ * and the different state transitions.
+ *
+ * For HHH-2060.
+ *
+ * @author Jacob Robertson
+ */
+public class CompositeIdWithGeneratorTest extends FunctionalTestCase {
+
+ public CompositeIdWithGeneratorTest(String str) {
+ super(str);
+ }
+
+ public String[] getMappings() {
+ return new String[] { "cid/PurchaseRecord.hbm.xml" };
+ }
+
+ public static Test suite() {
+ return new FunctionalTestClassTestSuite(CompositeIdWithGeneratorTest.class);
+ }
+
+ /**
+ * Basic test that id can be generated for composite-id.
+ */
+ public void testCompositeIdSimple() {
+ Session s = openSession();
+ Transaction t = s.beginTransaction();
+
+ // persist the record to get the id generated
+ PurchaseRecord record = new PurchaseRecord();
+ s.persist(record);
+
+ t.commit();
+ s.close();
+
+ // test that the id was generated
+ PurchaseRecord.Id generatedId = record.getId();
+ Date timestamp = record.getTimestamp();
+ assertNotNull(generatedId);
+ assertNotNull( generatedId.getPurchaseSequence() );
+ assertTrue(generatedId.getPurchaseNumber() > 0);
+
+ s = openSession();
+ t = s.beginTransaction();
+
+ // find the record, and see that the ids match
+ PurchaseRecord find = (PurchaseRecord) s.get(PurchaseRecord.class, generatedId);
+ assertNotNull(find);
+ assertEquals( generatedId, find.getId() );
+ assertEquals( timestamp, find.getTimestamp() );
+
+ t.commit();
+ s.close();
+
+ s = openSession();
+ t = s.beginTransaction();
+
+ // generate another new record
+ PurchaseRecord record2 = new PurchaseRecord();
+ s.persist(record2);
+
+ t.commit();
+ s.close();
+
+ PurchaseRecord.Id generatedId2 = record2.getId();
+ Date timestamp2 = record2.getTimestamp();
+
+ s = openSession();
+ t = s.beginTransaction();
+
+ PurchaseRecord find2 = (PurchaseRecord) s.get(PurchaseRecord.class, generatedId2);
+
+ t.commit();
+ s.close();
+
+ // test that the ids are different
+ PurchaseRecord.Id id1 = find.getId();
+ PurchaseRecord.Id id2 = find2.getId();
+ String seq1 = id1.getPurchaseSequence();
+ String seq2 = id2.getPurchaseSequence();
+ int num1 = id1.getPurchaseNumber();
+ int num2 = id2.getPurchaseNumber();
+
+ assertEquals( timestamp2, find2.getTimestamp() );
+ assertFalse( id1.equals(id2) );
+ assertFalse( seq1.equals(seq2) );
+ assertFalse(num1 == num2);
+ }
+
+ /**
+ * Tests the behavior of properties in detached objects.
+ */
+ public void testDetachedProperty() {
+ Session s = openSession();
+ Transaction t = s.beginTransaction();
+
+ // persist the record
+ PurchaseRecord record = new PurchaseRecord();
+ s.persist(record);
+
+ // close session so we know the record is detached
+ t.commit();
+ s.close();
+
+ PurchaseRecord.Id generatedId = record.getId();
+
+ // change a non-id property, but do not persist
+ Date persistedTimestamp = record.getTimestamp();
+ Date newTimestamp = new Date(persistedTimestamp.getTime() + 1);
+ record.setTimestamp(newTimestamp);
+
+ s = openSession();
+ t = s.beginTransaction();
+
+ PurchaseRecord find = (PurchaseRecord) s.get(PurchaseRecord.class, generatedId);
+
+ t.commit();
+ s.close();
+
+ // see that we get the original id, and the original timestamp
+ assertEquals( generatedId, find.getId() );
+ assertEquals( persistedTimestamp, find.getTimestamp() );
+
+ s = openSession();
+ t = s.beginTransaction();
+
+ // update with the new timestamp
+ s.update(record);
+
+ t.commit();
+ s.close();
+
+ // find the newly updated record
+ s = openSession();
+ t = s.beginTransaction();
+
+ PurchaseRecord find2 = (PurchaseRecord) s.get(PurchaseRecord.class, generatedId);
+
+ t.commit();
+ s.close();
+
+ // see that we get the original id, and the new timestamp
+ assertEquals( generatedId, find2.getId() );
+ assertEquals( newTimestamp, find2.getTimestamp() );
+ }
+
+ /**
+ * Tests the behavior of the id in detached objects.
+ */
+ public void testDetachedId() {
+ Session s = openSession();
+ Transaction t = s.beginTransaction();
+
+ Date timestamp1 = new Date();
+ Date timestamp2 = new Date(timestamp1.getTime() + 1);
+
+ // persist two records
+ PurchaseRecord record1 = new PurchaseRecord();
+ record1.setTimestamp(timestamp1);
+ PurchaseRecord record2 = new PurchaseRecord();
+ record2.setTimestamp(timestamp2);
+ s.persist(record1);
+ s.persist(record2);
+
+ // close session so we know the records are detached
+ t.commit();
+ s.close();
+
+ PurchaseRecord.Id generatedId1 = record1.getId();
+ PurchaseRecord.Id generatedId2 = record2.getId();
+
+ // change the ids around - effectively making record1 have the same id as record2
+ // do not persist yet
+ PurchaseRecord.Id toChangeId1 = new PurchaseRecord.Id();
+ toChangeId1.setPurchaseNumber( record2.getId().getPurchaseNumber() );
+ toChangeId1.setPurchaseSequence( record2.getId().getPurchaseSequence() );
+ record1.setId(toChangeId1);
+
+ s = openSession();
+ t = s.beginTransaction();
+
+ PurchaseRecord find1 = (PurchaseRecord) s.get(PurchaseRecord.class, generatedId1);
+ PurchaseRecord find2 = (PurchaseRecord) s.get(PurchaseRecord.class, generatedId2);
+
+ t.commit();
+ s.close();
+
+ // see that we get the original ids (and timestamps)
+ // i.e. weren't changed by changing the detached object
+ assertEquals( generatedId1, find1.getId() );
+ assertEquals( timestamp1, find1.getTimestamp() );
+ assertEquals( generatedId2, find2.getId() );
+ assertEquals( timestamp2, find2.getTimestamp() );
+
+ s = openSession();
+ t = s.beginTransaction();
+
+ // update with the new changed record id
+ s.update(record1);
+
+ t.commit();
+ s.close();
+
+ // test that record1 did not get a new generated id, and kept record2's id
+ PurchaseRecord.Id foundId1 = record1.getId();
+ assertSame(toChangeId1, foundId1);
+ assertEquals( toChangeId1.getPurchaseNumber(), foundId1.getPurchaseNumber() );
+ assertEquals( toChangeId1.getPurchaseSequence(), foundId1.getPurchaseSequence() );
+
+ // find record 2 and see that it has the timestamp originally found in record 1
+ s = openSession();
+ t = s.beginTransaction();
+
+ find2 = (PurchaseRecord) s.get(PurchaseRecord.class, generatedId2);
+
+ t.commit();
+ s.close();
+
+ // see that we get the original id (2), and the new timestamp (1)
+ assertEquals( timestamp1, find2.getTimestamp() );
+ assertEquals( generatedId2, find2.getId() );
+ }
+
+ /**
+ * Tests the behavior of saveOrUpdate (as opposed to calling "persist").
+ */
+ public void testSaveOrUpdate() {
+ Session s = openSession();
+ Transaction t = s.beginTransaction();
+
+ Date timestamp1 = new Date();
+ Date timestamp2 = new Date(timestamp1.getTime() + 1);
+
+ // persist the record
+ PurchaseRecord record = new PurchaseRecord();
+ record.setTimestamp(timestamp1);
+ s.saveOrUpdate(record);
+
+ t.commit();
+ s.close();
+
+ // test that the id was generated
+ PurchaseRecord.Id generatedId = record.getId();
+ assertNotNull(generatedId);
+ assertNotNull( generatedId.getPurchaseSequence() );
+
+ // change the timestamp
+ record.setTimestamp(timestamp2);
+
+ s = openSession();
+ t = s.beginTransaction();
+
+ s.saveOrUpdate(record);
+
+ t.commit();
+ s.close();
+
+ // see that we get the *same* id, and the new timestamp
+ assertSame( generatedId, record.getId() );
+ assertEquals( timestamp2, record.getTimestamp() );
+ }
+
+ /**
+ * Tests the behavior of load.
+ */
+ public void testLoad() {
+ Session s = openSession();
+ Transaction t = s.beginTransaction();
+
+ // persist the record, then get the id and timestamp back
+ PurchaseRecord record = new PurchaseRecord();
+ s.persist(record);
+
+ t.commit();
+ s.close();
+
+ PurchaseRecord.Id id = record.getId();
+ Date timestamp = record.getTimestamp();
+
+ // using the given id, load a transient record
+ PurchaseRecord toLoad = new PurchaseRecord();
+
+ s = openSession();
+ t = s.beginTransaction();
+
+ s.load(toLoad, id);
+
+ t.commit();
+ s.close();
+
+ // show that the correct timestamp and ids were loaded
+ assertEquals( id, toLoad.getId() );
+ assertEquals( timestamp, toLoad.getTimestamp() );
+ }
+
+ /**
+ * Tests the behavior of evict.
+ */
+ public void testEvict() {
+ Session s = openSession();
+ Transaction t = s.beginTransaction();
+
+ Date timestamp1 = new Date();
+ Date timestamp2 = new Date(timestamp1.getTime() + 1);
+
+ // persist the record, then evict it, then make changes to it ("within" the session)
+ PurchaseRecord record = new PurchaseRecord();
+ record.setTimestamp(timestamp1);
+ s.persist(record);
+ s.flush();
+ s.evict(record);
+
+ record.setTimestamp(timestamp2);
+
+ t.commit();
+ s.close();
+
+ PurchaseRecord.Id generatedId = record.getId();
+
+ // now, re-fetch the record and show that the timestamp change wasn't persisted
+ s = openSession();
+ t = s.beginTransaction();
+
+ PurchaseRecord persistent = (PurchaseRecord) s.get(PurchaseRecord.class, generatedId);
+
+ t.commit();
+ s.close();
+
+ assertEquals( generatedId, persistent.getId() );
+ assertEquals( timestamp1, persistent.getTimestamp() );
+ }
+
+ /**
+ * Tests the behavior of merge.
+ */
+ public void testMerge() {
+ Session s = openSession();
+ Transaction t = s.beginTransaction();
+
+ Date timestamp1 = new Date();
+ Date timestamp2 = new Date(timestamp1.getTime() + 1);
+
+ // persist the record
+ PurchaseRecord record = new PurchaseRecord();
+ s.persist(record);
+
+ t.commit();
+ s.close();
+
+ // test that the id was generated
+ PurchaseRecord.Id generatedId = record.getId();
+ assertNotNull(generatedId);
+ assertNotNull( generatedId.getPurchaseSequence() );
+
+ s = openSession();
+ t = s.beginTransaction();
+
+ // update detached object, retrieve persistent object, then merge
+ PurchaseRecord detached = record;
+ detached.setTimestamp(timestamp2);
+ PurchaseRecord persistent = (PurchaseRecord) s.get(PurchaseRecord.class, generatedId);
+
+ // show that the timestamp hasn't changed
+ assertEquals( timestamp1, persistent.getTimestamp() );
+
+ s.merge(detached);
+
+ t.commit();
+ s.close();
+
+ // show that the persistent object was changed only after the session flush
+ assertEquals( timestamp2, persistent.getTimestamp() );
+
+ // show that the persistent store was updated - not just the in-memory object
+ s = openSession();
+ t = s.beginTransaction();
+
+ persistent = (PurchaseRecord) s.get(PurchaseRecord.class, generatedId);
+
+ t.commit();
+ s.close();
+
+ assertEquals( timestamp2, persistent.getTimestamp() );
+ }
+
+ /**
+ * Tests the behavior of delete.
+ */
+ public void testDelete() {
+ Session s = openSession();
+ Transaction t = s.beginTransaction();
+
+ // persist the record
+ PurchaseRecord record = new PurchaseRecord();
+ s.saveOrUpdate(record);
+
+ t.commit();
+ s.close();
+
+ PurchaseRecord.Id generatedId = record.getId();
+
+ // re-fetch, then delete the record
+ s = openSession();
+ t = s.beginTransaction();
+
+ PurchaseRecord find = (PurchaseRecord) s.get(PurchaseRecord.class, generatedId);
+ s.delete(find);
+ assertFalse( s.contains(find) );
+
+ t.commit();
+ s.close();
+
+ // attempt to re-fetch - show it was deleted
+ s = openSession();
+ t = s.beginTransaction();
+
+ find = (PurchaseRecord) s.get(PurchaseRecord.class, generatedId);
+
+ t.commit();
+ s.close();
+
+ assertNull(find);
+ }
+
+ /**
+ * Simple test to demonstrate the ids can be generated even when using children.
+ */
+ public void testGeneratedIdsWithChildren() {
+
+ Session s = openSession();
+ Transaction t = s.beginTransaction();
+
+ // set up the record and details
+ PurchaseRecord record = new PurchaseRecord();
+ Set details = record.getDetails();
+ details.add( new PurchaseDetail(record, "p@1", 1) );
+ details.add( new PurchaseDetail(record, "p@2", 2) );
+
+ s.persist(record);
+
+ t.commit();
+ s.close();
+
+ // show that the ids were generated (non-zero) and come out the same
+ int foundPurchaseNumber = record.getId().getPurchaseNumber();
+ String foundPurchaseSequence = record.getId().getPurchaseSequence();
+ assertNotNull( record.getId() );
+ assertTrue(foundPurchaseNumber > 0);
+ assertNotNull(foundPurchaseSequence);
+
+ // search on detail1 by itself and show it got the parent's id
+ s = openSession();
+ t = s.beginTransaction();
+
+ // perform a find to show that it will wire together fine
+ PurchaseRecord foundRecord = (PurchaseRecord) s.get(PurchaseRecord.class,
+ new PurchaseRecord.Id(foundPurchaseNumber, foundPurchaseSequence)
+ );
+
+ t.commit();
+ s.close();
+
+ // some simple test to see it fetched
+ assertEquals( 2, foundRecord.getDetails().size() );
+ }
+
+}
+
Added: core/trunk/testsuite/src/test/java/org/hibernate/test/cid/PurchaseDetail.java
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/cid/PurchaseDetail.java (rev 0)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/cid/PurchaseDetail.java 2008-05-22 15:43:24 UTC (rev 14686)
@@ -0,0 +1,81 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.test.cid;
+
+
+/**
+ * @author Jacob Robertson
+ */
+public class PurchaseDetail {
+
+ private PurchaseRecord purchaseRecord;
+
+ private String productId;
+ private int quantity;
+
+ public PurchaseDetail(PurchaseRecord record, String productId, int quantity) {
+ this.productId = productId;
+ this.quantity = quantity;
+ this.purchaseRecord = record;
+ }
+ public PurchaseDetail() {}
+
+
+ /**
+ * @return the purchaseRecord
+ */
+ public PurchaseRecord getPurchaseRecord() {
+ return purchaseRecord;
+ }
+ /**
+ * @param purchaseRecord the purchaseRecord to set
+ */
+ public void setPurchaseRecord(PurchaseRecord purchaseRecord) {
+ this.purchaseRecord = purchaseRecord;
+ }
+ /**
+ * @return the quantity
+ */
+ public int getQuantity() {
+ return quantity;
+ }
+ /**
+ * @param quantity the quantity to set
+ */
+ public void setQuantity(int quantity) {
+ this.quantity = quantity;
+ }
+ /**
+ * @return the productId
+ */
+ public String getProductId() {
+ return productId;
+ }
+ /**
+ * @param productId the productId to set
+ */
+ public void setProductId(String productId) {
+ this.productId = productId;
+ }
+}
Added: core/trunk/testsuite/src/test/java/org/hibernate/test/cid/PurchaseRecord.hbm.xml
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/cid/PurchaseRecord.hbm.xml (rev 0)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/cid/PurchaseRecord.hbm.xml 2008-05-22 15:43:24 UTC (rev 14686)
@@ -0,0 +1,81 @@
+<?xml version="1.0"?>
+<!--
+ ~ Hibernate, Relational Persistence for Idiomatic Java
+ ~
+ ~ Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ ~ indicated by the @author tags or express copyright attribution
+ ~ statements applied by the authors. All third-party contributions are
+ ~ distributed under license by Red Hat Middleware LLC.
+ ~
+ ~ This copyrighted material is made available to anyone wishing to use, modify,
+ ~ copy, or redistribute it subject to the terms and conditions of the GNU
+ ~ Lesser General Public License, as published by the Free Software Foundation.
+ ~
+ ~ This program is distributed in the hope that it will be useful,
+ ~ but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ ~ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ ~ for more details.
+ ~
+ ~ You should have received a copy of the GNU Lesser General Public License
+ ~ along with this distribution; if not, write to:
+ ~ Free Software Foundation, Inc.
+ ~ 51 Franklin Street, Fifth Floor
+ ~ Boston, MA 02110-1301 USA
+ -->
+
+<!DOCTYPE hibernate-mapping PUBLIC
+ "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
+ "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
+
+<!--
+
+ This mapping demonstrates composite-id using a generator.
+
+-->
+
+<hibernate-mapping package="org.hibernate.test.cid">
+
+ <class name="PurchaseRecord">
+
+ <composite-id name="id"
+ class="PurchaseRecord$Id">
+ <key-property name="purchaseNumber"/>
+ <key-property name="purchaseSequence"/>
+ <generator class="org.hibernate.test.cid.PurchaseRecordIdGenerator"/>
+ </composite-id>
+
+ <set name="details"
+ lazy="false"
+ inverse="true"
+ cascade="all">
+ <key>
+ <column name="purchaseNumber"/>
+ <column name="purchaseSequence"/>
+ </key>
+ <one-to-many class="PurchaseDetail"/>
+ </set>
+
+ <property name="timestamp" column="timestamp"/>
+
+ </class>
+
+ <class name="PurchaseDetail">
+
+ <id name="productId"
+ type="string"
+ column="productId">
+ <generator class="assigned"/>
+ </id>
+
+ <property name="quantity"/>
+
+ <many-to-one name="purchaseRecord"
+ class="PurchaseRecord"
+ not-null="true">
+ <column name="purchaseNumber"/>
+ <column name="purchaseSequence"/>
+ </many-to-one>
+
+ </class>
+
+</hibernate-mapping>
Added: core/trunk/testsuite/src/test/java/org/hibernate/test/cid/PurchaseRecord.java
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/cid/PurchaseRecord.java (rev 0)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/cid/PurchaseRecord.java 2008-05-22 15:43:24 UTC (rev 14686)
@@ -0,0 +1,130 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.test.cid;
+
+import java.io.Serializable;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * @author Jacob Robertson
+ */
+public class PurchaseRecord {
+ public static class Id implements Serializable {
+ private int purchaseNumber;
+ private String purchaseSequence;
+
+ public Id(int purchaseNumber, String purchaseSequence) {
+ this.purchaseNumber = purchaseNumber;
+ this.purchaseSequence = purchaseSequence;
+ }
+ public Id() {}
+
+ /**
+ * @return Returns the purchaseNumber.
+ */
+ public int getPurchaseNumber() {
+ return purchaseNumber;
+ }
+ /**
+ * @param purchaseNumber The purchaseNumber to set.
+ */
+ public void setPurchaseNumber(int purchaseNumber) {
+ this.purchaseNumber = purchaseNumber;
+ }
+ /**
+ * @return the purchaseSequence
+ */
+ public String getPurchaseSequence() {
+ return purchaseSequence;
+ }
+ /**
+ * @param purchaseSequence the purchaseSequence to set
+ */
+ public void setPurchaseSequence(String purchaseSequence) {
+ this.purchaseSequence = purchaseSequence;
+ }
+ public int hashCode() {
+ return purchaseNumber + purchaseSequence.hashCode();
+ }
+ public boolean equals(Object other) {
+ if (other instanceof Id) {
+ Id that = (Id) other;
+ return purchaseSequence.equals(this.purchaseSequence) &&
+ that.purchaseNumber == this.purchaseNumber;
+ }
+ else {
+ return false;
+ }
+ }
+ }
+
+ private Id id;
+ private Date timestamp = new Date();
+ private Set details = new HashSet();
+
+ public PurchaseRecord() {}
+
+ /**
+ * @return Returns the id.
+ */
+ public Id getId() {
+ return id;
+ }
+ /**
+ * @param id The id to set.
+ */
+ public void setId(Id id) {
+ this.id = id;
+ }
+
+ /**
+ * @return the details
+ */
+ public Set getDetails() {
+ return details;
+ }
+
+ /**
+ * @param details the details to set
+ */
+ public void setDetails(Set details) {
+ this.details = details;
+ }
+
+ /**
+ * @return the timestamp
+ */
+ public Date getTimestamp() {
+ return timestamp;
+ }
+
+ /**
+ * @param timestamp the timestamp to set
+ */
+ public void setTimestamp(Date timestamp) {
+ this.timestamp = timestamp;
+ }
+}
Added: core/trunk/testsuite/src/test/java/org/hibernate/test/cid/PurchaseRecordIdGenerator.java
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/cid/PurchaseRecordIdGenerator.java (rev 0)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/cid/PurchaseRecordIdGenerator.java 2008-05-22 15:43:24 UTC (rev 14686)
@@ -0,0 +1,47 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.test.cid;
+
+import java.io.Serializable;
+
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.id.IdentityGenerator;
+
+/**
+ * Simple {@link IdentityGenerator} implementation for testing composite-id.
+ *
+ * @author Jacob Robertson
+ */
+public class PurchaseRecordIdGenerator extends IdentityGenerator {
+
+ private static int nextPurchaseNumber = 2;
+ private static int nextPurchaseSequence = 3;
+
+ public Serializable generate(SessionImplementor s, Object obj) {
+ return new PurchaseRecord.Id(
+ nextPurchaseNumber++,
+ String.valueOf(nextPurchaseSequence++));
+ }
+
+}
16 years, 6 months
Hibernate SVN: r14684 - core/trunk/cache-jbosscache2.
by hibernate-commits@lists.jboss.org
Author: bstansberry(a)jboss.com
Date: 2008-05-21 16:35:44 -0400 (Wed, 21 May 2008)
New Revision: 14684
Modified:
core/trunk/cache-jbosscache2/pom.xml
Log:
[HHH-2506 ] make javassist the default bytecode provider
[HHH-2875] cglib+asm repackage
Modified: core/trunk/cache-jbosscache2/pom.xml
===================================================================
--- core/trunk/cache-jbosscache2/pom.xml 2008-05-21 20:34:54 UTC (rev 14683)
+++ core/trunk/cache-jbosscache2/pom.xml 2008-05-21 20:35:44 UTC (rev 14684)
@@ -71,25 +71,13 @@
<version>1.2.14</version>
<scope>test</scope>
</dependency>
- <!-- these are optional on core :( and needed for testing -->
+ <!-- this is optional on core :( and needed for testing -->
<dependency>
<groupId>javassist</groupId>
<artifactId>javassist</artifactId>
<version>3.4.GA</version>
<scope>test</scope>
</dependency>
- <dependency>
- <groupId>cglib</groupId>
- <artifactId>cglib</artifactId>
- <version>2.1_3</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>asm</groupId>
- <artifactId>asm-attrs</artifactId>
- <version>1.5.3</version>
- <scope>test</scope>
- </dependency>
</dependencies>
<build>
16 years, 6 months
Hibernate SVN: r14683 - core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/access.
by hibernate-commits@lists.jboss.org
Author: bstansberry(a)jboss.com
Date: 2008-05-21 16:34:54 -0400 (Wed, 21 May 2008)
New Revision: 14683
Modified:
core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/access/OptimisticTransactionalAccessDelegate.java
Log:
Don't redundantly call ensureRegionRootExists()
Modified: core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/access/OptimisticTransactionalAccessDelegate.java
===================================================================
--- core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/access/OptimisticTransactionalAccessDelegate.java 2008-05-21 20:13:20 UTC (rev 14682)
+++ core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/access/OptimisticTransactionalAccessDelegate.java 2008-05-21 20:34:54 UTC (rev 14683)
@@ -89,7 +89,8 @@
public Object get(Object key, long txTimestamp) throws CacheException
{
region.ensureRegionRootExists();
- return super.get(key, txTimestamp);
+
+ return CacheHelper.get(cache, regionFqn, key);
}
/**
16 years, 6 months
Hibernate SVN: r14682 - in core/trunk: core/src/main/java/org/hibernate/bytecode/cglib and 7 other directories.
by hibernate-commits@lists.jboss.org
Author: steve.ebersole(a)jboss.com
Date: 2008-05-21 16:13:20 -0400 (Wed, 21 May 2008)
New Revision: 14682
Modified:
core/trunk/core/pom.xml
core/trunk/core/src/main/java/org/hibernate/bytecode/cglib/AccessOptimizerAdapter.java
core/trunk/core/src/main/java/org/hibernate/bytecode/cglib/BytecodeProviderImpl.java
core/trunk/core/src/main/java/org/hibernate/bytecode/cglib/CglibClassTransformer.java
core/trunk/core/src/main/java/org/hibernate/bytecode/cglib/InstantiationOptimizerAdapter.java
core/trunk/core/src/main/java/org/hibernate/bytecode/cglib/ProxyFactoryFactoryImpl.java
core/trunk/core/src/main/java/org/hibernate/cfg/Environment.java
core/trunk/core/src/main/java/org/hibernate/intercept/FieldInterceptionHelper.java
core/trunk/core/src/main/java/org/hibernate/intercept/cglib/CGLIBHelper.java
core/trunk/core/src/main/java/org/hibernate/intercept/cglib/FieldInterceptorImpl.java
core/trunk/core/src/main/java/org/hibernate/proxy/pojo/cglib/CGLIBLazyInitializer.java
core/trunk/core/src/main/java/org/hibernate/tool/instrument/cglib/InstrumentTask.java
core/trunk/testsuite/pom.xml
core/trunk/testsuite/src/test/java/org/hibernate/test/bytecode/cglib/CGLIBThreadLocalTest.java
Log:
HHH-2875 : cglib+asm repackage;
HHH-2506 : make javassist the default bytecode provider
Modified: core/trunk/core/pom.xml
===================================================================
--- core/trunk/core/pom.xml 2008-05-21 19:53:21 UTC (rev 14681)
+++ core/trunk/core/pom.xml 2008-05-21 20:13:20 UTC (rev 14682)
@@ -63,17 +63,11 @@
<optional>true</optional>
</dependency>
<dependency>
- <groupId>cglib</groupId>
- <artifactId>cglib</artifactId>
+ <groupId>org.hibernate</groupId>
+ <artifactId>hibernate-cglib-repack</artifactId>
<version>2.1_3</version>
<optional>true</optional>
</dependency>
- <dependency>
- <groupId>asm</groupId>
- <artifactId>asm-attrs</artifactId>
- <version>1.5.3</version>
- <optional>true</optional>
- </dependency>
</dependencies>
<build>
Modified: core/trunk/core/src/main/java/org/hibernate/bytecode/cglib/AccessOptimizerAdapter.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/bytecode/cglib/AccessOptimizerAdapter.java 2008-05-21 19:53:21 UTC (rev 14681)
+++ core/trunk/core/src/main/java/org/hibernate/bytecode/cglib/AccessOptimizerAdapter.java 2008-05-21 20:13:20 UTC (rev 14682)
@@ -2,9 +2,8 @@
import org.hibernate.bytecode.ReflectionOptimizer;
import org.hibernate.PropertyAccessException;
-import net.sf.cglib.beans.BulkBean;
-import net.sf.cglib.beans.BulkBeanException;
-import net.sf.cglib.reflect.FastClass;
+import org.hibernate.repackage.cglib.beans.BulkBean;
+import org.hibernate.repackage.cglib.beans.BulkBeanException;
import java.io.Serializable;
import java.io.ObjectOutputStream;
Modified: core/trunk/core/src/main/java/org/hibernate/bytecode/cglib/BytecodeProviderImpl.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/bytecode/cglib/BytecodeProviderImpl.java 2008-05-21 19:53:21 UTC (rev 14681)
+++ core/trunk/core/src/main/java/org/hibernate/bytecode/cglib/BytecodeProviderImpl.java 2008-05-21 20:13:20 UTC (rev 14682)
@@ -2,15 +2,9 @@
import java.lang.reflect.Modifier;
-import net.sf.cglib.beans.BulkBean;
-import net.sf.cglib.beans.BulkBeanException;
-import net.sf.cglib.reflect.FastClass;
-import net.sf.cglib.transform.ClassFilter;
-import net.sf.cglib.transform.ClassTransformer;
-import net.sf.cglib.transform.ClassTransformerFactory;
-import net.sf.cglib.transform.TransformingClassLoader;
-import net.sf.cglib.transform.impl.InterceptFieldFilter;
-import net.sf.cglib.transform.impl.InterceptFieldTransformer;
+import org.hibernate.repackage.cglib.beans.BulkBean;
+import org.hibernate.repackage.cglib.beans.BulkBeanException;
+import org.hibernate.repackage.cglib.reflect.FastClass;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.hibernate.bytecode.BytecodeProvider;
@@ -18,7 +12,6 @@
import org.hibernate.bytecode.ReflectionOptimizer;
import org.hibernate.bytecode.util.FieldFilter;
import org.hibernate.util.StringHelper;
-import org.objectweb.asm.Type;
/**
* Bytecode provider implementation for CGLIB.
@@ -29,6 +22,10 @@
private static final Logger log = LoggerFactory.getLogger( BytecodeProviderImpl.class );
+ public BytecodeProviderImpl() {
+ log.warn( "The CGLIB BytecodeProvider impl is considered deprecated and not recommended for use" );
+ }
+
public ProxyFactoryFactory getProxyFactoryFactory() {
return new ProxyFactoryFactoryImpl();
}
Modified: core/trunk/core/src/main/java/org/hibernate/bytecode/cglib/CglibClassTransformer.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/bytecode/cglib/CglibClassTransformer.java 2008-05-21 19:53:21 UTC (rev 14681)
+++ core/trunk/core/src/main/java/org/hibernate/bytecode/cglib/CglibClassTransformer.java 2008-05-21 20:13:20 UTC (rev 14682)
@@ -6,25 +6,25 @@
import java.io.IOException;
import java.io.ByteArrayOutputStream;
-import net.sf.cglib.transform.ClassTransformer;
-import net.sf.cglib.transform.TransformingClassGenerator;
-import net.sf.cglib.transform.ClassReaderGenerator;
-import net.sf.cglib.transform.impl.InterceptFieldEnabled;
-import net.sf.cglib.transform.impl.InterceptFieldFilter;
-import net.sf.cglib.transform.impl.InterceptFieldTransformer;
-import net.sf.cglib.core.ClassNameReader;
-import net.sf.cglib.core.DebuggingClassWriter;
+import org.hibernate.repackage.cglib.transform.ClassTransformer;
+import org.hibernate.repackage.cglib.transform.TransformingClassGenerator;
+import org.hibernate.repackage.cglib.transform.ClassReaderGenerator;
+import org.hibernate.repackage.cglib.transform.impl.InterceptFieldEnabled;
+import org.hibernate.repackage.cglib.transform.impl.InterceptFieldFilter;
+import org.hibernate.repackage.cglib.transform.impl.InterceptFieldTransformer;
+import org.hibernate.repackage.cglib.core.ClassNameReader;
+import org.hibernate.repackage.cglib.core.DebuggingClassWriter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.hibernate.bytecode.AbstractClassTransformerImpl;
import org.hibernate.bytecode.util.FieldFilter;
import org.hibernate.bytecode.util.ClassFilter;
import org.hibernate.HibernateException;
-import org.objectweb.asm.Attribute;
-import org.objectweb.asm.Type;
-import org.objectweb.asm.ClassReader;
-import org.objectweb.asm.ClassWriter;
-import org.objectweb.asm.attrs.Attributes;
+import org.hibernate.repackage.cglib.asm.Attribute;
+import org.hibernate.repackage.cglib.asm.Type;
+import org.hibernate.repackage.cglib.asm.ClassReader;
+import org.hibernate.repackage.cglib.asm.ClassWriter;
+import org.hibernate.repackage.cglib.asm.attrs.Attributes;
/**
* Enhance the classes allowing them to implements InterceptFieldEnabled
Modified: core/trunk/core/src/main/java/org/hibernate/bytecode/cglib/InstantiationOptimizerAdapter.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/bytecode/cglib/InstantiationOptimizerAdapter.java 2008-05-21 19:53:21 UTC (rev 14681)
+++ core/trunk/core/src/main/java/org/hibernate/bytecode/cglib/InstantiationOptimizerAdapter.java 2008-05-21 20:13:20 UTC (rev 14682)
@@ -1,7 +1,7 @@
package org.hibernate.bytecode.cglib;
import org.hibernate.bytecode.ReflectionOptimizer;
-import net.sf.cglib.reflect.FastClass;
+import org.hibernate.repackage.cglib.reflect.FastClass;
import org.hibernate.InstantiationException;
import java.io.Serializable;
Modified: core/trunk/core/src/main/java/org/hibernate/bytecode/cglib/ProxyFactoryFactoryImpl.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/bytecode/cglib/ProxyFactoryFactoryImpl.java 2008-05-21 19:53:21 UTC (rev 14681)
+++ core/trunk/core/src/main/java/org/hibernate/bytecode/cglib/ProxyFactoryFactoryImpl.java 2008-05-21 20:13:20 UTC (rev 14682)
@@ -6,13 +6,13 @@
import org.hibernate.proxy.pojo.cglib.CGLIBProxyFactory;
import org.hibernate.AssertionFailure;
import org.hibernate.HibernateException;
-import net.sf.cglib.proxy.Enhancer;
-import net.sf.cglib.proxy.CallbackFilter;
-import net.sf.cglib.proxy.MethodInterceptor;
-import net.sf.cglib.proxy.MethodProxy;
-import net.sf.cglib.proxy.NoOp;
-import net.sf.cglib.proxy.Callback;
-import net.sf.cglib.proxy.Factory;
+import org.hibernate.repackage.cglib.proxy.Enhancer;
+import org.hibernate.repackage.cglib.proxy.CallbackFilter;
+import org.hibernate.repackage.cglib.proxy.MethodInterceptor;
+import org.hibernate.repackage.cglib.proxy.MethodProxy;
+import org.hibernate.repackage.cglib.proxy.NoOp;
+import org.hibernate.repackage.cglib.proxy.Callback;
+import org.hibernate.repackage.cglib.proxy.Factory;
import java.lang.reflect.Method;
import java.util.HashMap;
Modified: core/trunk/core/src/main/java/org/hibernate/cfg/Environment.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cfg/Environment.java 2008-05-21 19:53:21 UTC (rev 14681)
+++ core/trunk/core/src/main/java/org/hibernate/cfg/Environment.java 2008-05-21 20:13:20 UTC (rev 14682)
@@ -681,9 +681,8 @@
return (String) ISOLATION_LEVELS.get( new Integer(isolation) );
}
-
public static BytecodeProvider buildBytecodeProvider(Properties properties) {
- String provider = PropertiesHelper.getString( Environment.BYTECODE_PROVIDER, properties, "cglib" );
+ String provider = PropertiesHelper.getString( BYTECODE_PROVIDER, properties, "javassist" );
log.info( "Bytecode provider name : " + provider );
return buildBytecodeProvider( provider );
}
@@ -695,10 +694,9 @@
else if ( "cglib".equals( providerName ) ) {
return new org.hibernate.bytecode.cglib.BytecodeProviderImpl();
}
- else {
- log.warn( "unrecognized bytecode provider [" + providerName + "], using cglib by default" );
- return new org.hibernate.bytecode.cglib.BytecodeProviderImpl();
- }
+
+ log.warn( "unrecognized bytecode provider [" + providerName + "], using javassist by default" );
+ return new org.hibernate.bytecode.javassist.BytecodeProviderImpl();
}
}
Modified: core/trunk/core/src/main/java/org/hibernate/intercept/FieldInterceptionHelper.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/intercept/FieldInterceptionHelper.java 2008-05-21 19:53:21 UTC (rev 14681)
+++ core/trunk/core/src/main/java/org/hibernate/intercept/FieldInterceptionHelper.java 2008-05-21 20:13:20 UTC (rev 14682)
@@ -26,7 +26,7 @@
public static boolean isInstrumented(Class entityClass) {
Class[] definedInterfaces = entityClass.getInterfaces();
for ( int i = 0; i < definedInterfaces.length; i++ ) {
- if ( "net.sf.cglib.transform.impl.InterceptFieldEnabled".equals( definedInterfaces[i].getName() )
+ if ( "org.hibernate.repackage.cglib.transform.impl.InterceptFieldEnabled".equals( definedInterfaces[i].getName() )
|| "org.hibernate.bytecode.javassist.FieldHandled".equals( definedInterfaces[i].getName() ) ) {
return true;
}
@@ -44,7 +44,7 @@
}
Class[] definedInterfaces = entity.getClass().getInterfaces();
for ( int i = 0; i < definedInterfaces.length; i++ ) {
- if ( "net.sf.cglib.transform.impl.InterceptFieldEnabled".equals( definedInterfaces[i].getName() ) ) {
+ if ( "org.hibernate.repackage.cglib.transform.impl.InterceptFieldEnabled".equals( definedInterfaces[i].getName() ) ) {
// we have a CGLIB enhanced entity
return CGLIBHelper.extractFieldInterceptor( entity );
}
@@ -64,7 +64,7 @@
if ( entity != null ) {
Class[] definedInterfaces = entity.getClass().getInterfaces();
for ( int i = 0; i < definedInterfaces.length; i++ ) {
- if ( "net.sf.cglib.transform.impl.InterceptFieldEnabled".equals( definedInterfaces[i].getName() ) ) {
+ if ( "org.hibernate.repackage.cglib.transform.impl.InterceptFieldEnabled".equals( definedInterfaces[i].getName() ) ) {
// we have a CGLIB enhanced entity
return CGLIBHelper.injectFieldInterceptor( entity, entityName, uninitializedFieldNames, session );
}
Modified: core/trunk/core/src/main/java/org/hibernate/intercept/cglib/CGLIBHelper.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/intercept/cglib/CGLIBHelper.java 2008-05-21 19:53:21 UTC (rev 14681)
+++ core/trunk/core/src/main/java/org/hibernate/intercept/cglib/CGLIBHelper.java 2008-05-21 20:13:20 UTC (rev 14682)
@@ -2,7 +2,7 @@
import org.hibernate.intercept.FieldInterceptor;
import org.hibernate.engine.SessionImplementor;
-import net.sf.cglib.transform.impl.InterceptFieldEnabled;
+import org.hibernate.repackage.cglib.transform.impl.InterceptFieldEnabled;
import java.util.Set;
Modified: core/trunk/core/src/main/java/org/hibernate/intercept/cglib/FieldInterceptorImpl.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/intercept/cglib/FieldInterceptorImpl.java 2008-05-21 19:53:21 UTC (rev 14681)
+++ core/trunk/core/src/main/java/org/hibernate/intercept/cglib/FieldInterceptorImpl.java 2008-05-21 20:13:20 UTC (rev 14682)
@@ -4,7 +4,7 @@
import java.io.Serializable;
import java.util.Set;
-import net.sf.cglib.transform.impl.InterceptFieldCallback;
+import org.hibernate.repackage.cglib.transform.impl.InterceptFieldCallback;
import org.hibernate.intercept.AbstractFieldInterceptor;
import org.hibernate.engine.SessionImplementor;
@@ -25,9 +25,9 @@
/**
* Package-protected constructor
*
- * @param session
- * @param uninitializedFields
- * @param entityName
+ * @param session The Hibernate session
+ * @param uninitializedFields Names of the fields we need to initialize on load
+ * @param entityName The entity name to which we are being bound
*/
FieldInterceptorImpl(SessionImplementor session, Set uninitializedFields, String entityName) {
super( session, uninitializedFields, entityName );
Modified: core/trunk/core/src/main/java/org/hibernate/proxy/pojo/cglib/CGLIBLazyInitializer.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/proxy/pojo/cglib/CGLIBLazyInitializer.java 2008-05-21 19:53:21 UTC (rev 14681)
+++ core/trunk/core/src/main/java/org/hibernate/proxy/pojo/cglib/CGLIBLazyInitializer.java 2008-05-21 20:13:20 UTC (rev 14682)
@@ -5,11 +5,11 @@
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
-import net.sf.cglib.proxy.Callback;
-import net.sf.cglib.proxy.CallbackFilter;
-import net.sf.cglib.proxy.Enhancer;
-import net.sf.cglib.proxy.InvocationHandler;
-import net.sf.cglib.proxy.NoOp;
+import org.hibernate.repackage.cglib.proxy.Callback;
+import org.hibernate.repackage.cglib.proxy.CallbackFilter;
+import org.hibernate.repackage.cglib.proxy.Enhancer;
+import org.hibernate.repackage.cglib.proxy.InvocationHandler;
+import org.hibernate.repackage.cglib.proxy.NoOp;
import org.hibernate.HibernateException;
import org.hibernate.LazyInitializationException;
Modified: core/trunk/core/src/main/java/org/hibernate/tool/instrument/cglib/InstrumentTask.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/tool/instrument/cglib/InstrumentTask.java 2008-05-21 19:53:21 UTC (rev 14681)
+++ core/trunk/core/src/main/java/org/hibernate/tool/instrument/cglib/InstrumentTask.java 2008-05-21 20:13:20 UTC (rev 14682)
@@ -6,12 +6,12 @@
import org.hibernate.bytecode.cglib.BytecodeProviderImpl;
import org.hibernate.bytecode.ClassTransformer;
import org.hibernate.tool.instrument.BasicInstrumentationTask;
-import org.objectweb.asm.ClassReader;
+import org.hibernate.repackage.cglib.asm.ClassReader;
import java.io.ByteArrayInputStream;
-import net.sf.cglib.core.ClassNameReader;
-import net.sf.cglib.transform.impl.InterceptFieldEnabled;
+import org.hibernate.repackage.cglib.core.ClassNameReader;
+import org.hibernate.repackage.cglib.transform.impl.InterceptFieldEnabled;
/**
* An Ant task for instrumenting persistent classes in order to enable
Modified: core/trunk/testsuite/pom.xml
===================================================================
--- core/trunk/testsuite/pom.xml 2008-05-21 19:53:21 UTC (rev 14681)
+++ core/trunk/testsuite/pom.xml 2008-05-21 20:13:20 UTC (rev 14682)
@@ -34,15 +34,10 @@
<version>3.4.GA</version>
</dependency>
<dependency>
- <groupId>cglib</groupId>
- <artifactId>cglib</artifactId>
+ <groupId>org.hibernate</groupId>
+ <artifactId>hibernate-cglib-repack</artifactId>
<version>2.1_3</version>
</dependency>
- <dependency>
- <groupId>asm</groupId>
- <artifactId>asm-attrs</artifactId>
- <version>1.5.3</version>
- </dependency>
<!-- optional dom4j dependency; needed here for dom4j (de)serialization -->
<dependency>
<groupId>jaxen</groupId>
Modified: core/trunk/testsuite/src/test/java/org/hibernate/test/bytecode/cglib/CGLIBThreadLocalTest.java
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/bytecode/cglib/CGLIBThreadLocalTest.java 2008-05-21 19:53:21 UTC (rev 14681)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/bytecode/cglib/CGLIBThreadLocalTest.java 2008-05-21 20:13:20 UTC (rev 14682)
@@ -7,10 +7,8 @@
import org.hibernate.test.bytecode.*;
import junit.framework.*;
-import java.text.*;
import java.lang.reflect.*;
-import net.sf.cglib.proxy.*;
/**
* Test that the static thread local callback object is cleared out of the proxy class after instantiated.
16 years, 6 months
Hibernate SVN: r14681 - core/trunk/parent.
by hibernate-commits@lists.jboss.org
Author: steve.ebersole(a)jboss.com
Date: 2008-05-21 15:53:21 -0400 (Wed, 21 May 2008)
New Revision: 14681
Modified:
core/trunk/parent/pom.xml
Log:
made recomended changes wrt defining plugin versions in pluginManagement
Modified: core/trunk/parent/pom.xml
===================================================================
--- core/trunk/parent/pom.xml 2008-05-21 18:44:27 UTC (rev 14680)
+++ core/trunk/parent/pom.xml 2008-05-21 19:53:21 UTC (rev 14681)
@@ -117,7 +117,6 @@
<!-- 2.0.8 not released at this time, so I instead say anything greater that 2.0.7 -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
- <version>1.0-alpha-3</version>
<executions>
<execution>
<id>enforce-java</id>
@@ -141,7 +140,6 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
- <version>2.0.2</version>
<configuration>
<source>1.4</source>
<target>1.4</target>
@@ -151,7 +149,6 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
- <version>2.1</version>
<configuration>
<archive>
<manifest>
@@ -164,6 +161,13 @@
</archive>
</configuration>
</plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <configuration>
+ <redirectTestOutputToFile>true</redirectTestOutputToFile>
+ </configuration>
+ </plugin>
</plugins>
<pluginManagement>
<plugins>
@@ -172,6 +176,26 @@
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.4</version>
</plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <version>2.4.3</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jar-plugin</artifactId>
+ <version>2.1</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-enforcer-plugin</artifactId>
+ <version>1.0-alpha-3</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>2.0.2</version>
+ </plugin>
</plugins>
</pluginManagement>
<extensions>
@@ -187,16 +211,12 @@
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-surefire-plugin</artifactId>
- <version>2.4.2</version>
- <configuration>
- <redirectTestOutputToFile>true</redirectTestOutputToFile>
- </configuration>
+ <artifactId>maven-surefire-report-plugin</artifactId>
+ <version>2.4.3</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
- <version>2.4</version>
<configuration>
<links>
<link>http://java.sun.com/j2se/1.4.2/docs/api/</link>
16 years, 6 months
Hibernate SVN: r14680 - cglib/tags.
by hibernate-commits@lists.jboss.org
Author: steve.ebersole(a)jboss.com
Date: 2008-05-21 14:44:27 -0400 (Wed, 21 May 2008)
New Revision: 14680
Added:
cglib/tags/hibernate-cglib-repack-2.1_3/
Log:
[maven-scm] copy for tag hibernate-cglib-repack-2.1_3
Copied: cglib/tags/hibernate-cglib-repack-2.1_3 (from rev 14679, cglib/trunk)
16 years, 6 months