Hibernate SVN: r19189 - search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/embedded/nested.
by hibernate-commits@lists.jboss.org
Author: epbernard
Date: 2010-04-08 08:43:51 -0400 (Thu, 08 Apr 2010)
New Revision: 19189
Modified:
search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/embedded/nested/NestedEmbeddedTest.java
Log:
HSEARCH-496 make the test pass on postgres
Modified: search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/embedded/nested/NestedEmbeddedTest.java
===================================================================
--- search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/embedded/nested/NestedEmbeddedTest.java 2010-04-08 12:28:24 UTC (rev 19188)
+++ search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/embedded/nested/NestedEmbeddedTest.java 2010-04-08 12:43:51 UTC (rev 19189)
@@ -79,6 +79,7 @@
s.clear();
session = Search.getFullTextSession( s );
+ tx = s.beginTransaction();
query = parser.parse( "foo" );
result = session.createFullTextQuery( query, Product.class ).list();
@@ -88,6 +89,7 @@
result = session.createFullTextQuery( query, Product.class ).list();
assertEquals( "change in embedded not reflected in root index", 1, result.size() );
+ tx.commit();
s.close();
}
@@ -144,7 +146,8 @@
result = session.createFullTextQuery( query, Person.class ).list();
assertEquals( "change in embedded not reflected in root index", 1, result.size() );
- s.close();
+ session.close();
+ //s.close();
}
protected void configure(org.hibernate.cfg.Configuration cfg) {
14 years, 1 month
Hibernate SVN: r19187 - in search/trunk/hibernate-search/src: main/java/org/hibernate/search/bridge and 6 other directories.
by hibernate-commits@lists.jboss.org
Author: sannegrinovero
Date: 2010-04-08 05:50:52 -0400 (Thu, 08 Apr 2010)
New Revision: 19187
Added:
search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/compression/
search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/compression/CompressionTest.java
search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/compression/HTMLBoldFieldBridge.java
search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/compression/LargeDocument.java
Modified:
search/trunk/hibernate-search/src/main/docbook/en-US/modules/mapping.xml
search/trunk/hibernate-search/src/main/java/org/hibernate/search/bridge/LuceneOptions.java
search/trunk/hibernate-search/src/main/java/org/hibernate/search/bridge/String2FieldBridgeAdaptor.java
search/trunk/hibernate-search/src/main/java/org/hibernate/search/bridge/TwoWayString2FieldBridgeAdaptor.java
search/trunk/hibernate-search/src/main/java/org/hibernate/search/engine/DocumentBuilderContainedEntity.java
search/trunk/hibernate-search/src/main/java/org/hibernate/search/engine/DocumentBuilderIndexedEntity.java
search/trunk/hibernate-search/src/main/java/org/hibernate/search/engine/LuceneOptionsImpl.java
search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/bridge/CatDeptsFieldsClassBridge.java
search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/bridge/CatFieldsClassBridge.java
search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/bridge/DateSplitBridge.java
search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/bridge/EquipmentType.java
search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/bridge/TruncateFieldBridge.java
search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/configuration/CatDeptsFieldsClassBridge.java
search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/configuration/EquipmentType.java
search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/id/PersonPKBridge.java
Log:
HSEARCH-425 Reimplement support for compressed fields (support removed in Lucene3)
Modified: search/trunk/hibernate-search/src/main/docbook/en-US/modules/mapping.xml
===================================================================
--- search/trunk/hibernate-search/src/main/docbook/en-US/modules/mapping.xml 2010-04-08 09:09:22 UTC (rev 19186)
+++ search/trunk/hibernate-search/src/main/docbook/en-US/modules/mapping.xml 2010-04-08 09:50:52 UTC (rev 19187)
@@ -1340,7 +1340,7 @@
to use a slightly extended version of <literal>StringBridge</literal>
named <classname>TwoWayStringBridge</classname>. Hibernate Search
needs to read the string representation of the identifier and generate
- the object out of it. There is not difference in the way the
+ the object out of it. There is no difference in the way the
<literal>@FieldBridge</literal> annotation is used.</para>
<example>
@@ -1395,8 +1395,8 @@
greatest possible flexibility you can also implement a bridge as a
<classname>FieldBridge</classname>. This interface gives you a
property value and let you map it the way you want in your Lucene
- <classname>Document</classname>.The interface is very similar in its
- concept to the Hibernate<classname> UserType</classname>s.</para>
+ <classname>Document</classname>. The interface is very similar in its
+ concept to the Hibernate <classname>UserType</classname>s.</para>
<para>You can for example store a given property in two different
document fields:</para>
@@ -1408,7 +1408,6 @@
<programlisting>/**
* Store the date in 3 different fields - year, month, day - to ease Range Query per
* year, month or day (eg get all the elements of December for the last 5 years).
- *
* @author Emmanuel Bernard
*/
public class DateSplitBridge implements FieldBridge {
@@ -1424,25 +1423,22 @@
int day = cal.get(Calendar.DAY_OF_MONTH);
// set year
- Field field = new Field(name + ".year", String.valueOf(year),
- luceneOptions.getStore(), luceneOptions.getIndex(),
- luceneOptions.getTermVector());
- field.setBoost(luceneOptions.getBoost());
- document.add(field);
+ luceneOptions.addFieldToDocument(
+ name + ".year",
+ String.valueOf( year ),
+ document );
// set month and pad it if needed
- field = new Field(name + ".month", month < 10 ? "0" : ""
- + String.valueOf(month), luceneOptions.getStore(),
- luceneOptions.getIndex(), luceneOptions.getTermVector());
- field.setBoost(luceneOptions.getBoost());
- document.add(field);
+ luceneOptions.addFieldToDocument(
+ name + ".month",
+ month < 10 ? "0" : "" + String.valueOf( month ),
+ document );
// set day and pad it if needed
- field = new Field(name + ".day", day < 10 ? "0" : ""
- + String.valueOf(day), luceneOptions.getStore(),
- luceneOptions.getIndex(), luceneOptions.getTermVector());
- field.setBoost(luceneOptions.getBoost());
- document.add(field);
+ luceneOptions.addFieldToDocument(
+ name + ".day",
+ day < 10 ? "0" : "" + String.valueOf( day ),
+ document );
}
}
@@ -1450,6 +1446,20 @@
<emphasis role="bold">@FieldBridge(impl = DateSplitBridge.class)</emphasis>
private Date date; </programlisting>
</example>
+
+ <para>In the previous example the fields where not added directly to Document
+ but we where delegating this task to the <classname>LuceneOptions</classname> helper; this will apply the
+ options you have selected on <literal>@Field</literal>, like <literal>Store</literal>
+ or <literal>TermVector</literal> options, or apply the choosen <classname>@Boost</classname>
+ value. It is especially useful to encapsulate the complexity of <literal>COMPRESS</literal>
+ implementations so it's recommended to delegate to <classname>LuceneOptions</classname> to add fields to the
+ <classname>Document</classname>, but nothing stops you from editing
+ the <classname>Document</classname> directly and ignore the <classname>LuceneOptions</classname> in case you need to.
+ </para>
+ <tip><para>Classes like <classname>LuceneOptions</classname> are created to shield your application from
+ changes in Lucene API and simplify your code. Use them if you can, but if you need more flexibility
+ you're not required to.</para></tip>
+
</section>
<section>
@@ -1485,7 +1495,6 @@
...
}
-
public class CatFieldsClassBridge implements FieldBridge, ParameterizedBridge {
private String sepChar;
@@ -2199,7 +2208,7 @@
@Fields({
@Field,
@Field(name="street1_abridged",
- bridge= @FieldBridge(impl = ConcatStringBridge.class,
+ bridge = @FieldBridge( impl = ConcatStringBridge.class,
params = @Parameter( name="size", value="4" ))
})
private String address1;
Modified: search/trunk/hibernate-search/src/main/java/org/hibernate/search/bridge/LuceneOptions.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/bridge/LuceneOptions.java 2010-04-08 09:09:22 UTC (rev 19186)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/bridge/LuceneOptions.java 2010-04-08 09:50:52 UTC (rev 19187)
@@ -24,23 +24,42 @@
*/
package org.hibernate.search.bridge;
+import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
/**
* A wrapper class for Lucene parameters needed for indexing.
*
* @author Emmanuel Bernard
+ * @author Sanne Grinovero
*/
public interface LuceneOptions {
+
+ void addFieldToDocument(String name, String indexedString, Document document);
+
+ /**
+ * Might be removed in version 3.3 to better support Lucene 3
+ * which is missing COMPRESS Store Type.
+ * To use compression either use #addFieldToDocument or refer
+ * to Lucene documentation to implement your own compression
+ * strategy.
+ * @deprecated use addToDocument to add fields to the Document if possible
+ */
Field.Store getStore();
+ /**
+ * @deprecated likely to be removed in version 3.3, use #addFieldToDocument
+ */
Field.Index getIndex();
+ /**
+ * @deprecated likely to be removed in version 3.3, use #addFieldToDocument
+ */
Field.TermVector getTermVector();
/**
- * @return the boost value. If <code>boost == null</code>, the default boost value
- * 1.0 is returned.
+ * @deprecated likely to be removed in version 3.3, use #addFieldToDocument
*/
Float getBoost();
+
}
Modified: search/trunk/hibernate-search/src/main/java/org/hibernate/search/bridge/String2FieldBridgeAdaptor.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/bridge/String2FieldBridgeAdaptor.java 2010-04-08 09:09:22 UTC (rev 19186)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/bridge/String2FieldBridgeAdaptor.java 2010-04-08 09:50:52 UTC (rev 19187)
@@ -25,8 +25,6 @@
package org.hibernate.search.bridge;
import org.apache.lucene.document.Document;
-import org.apache.lucene.document.Field;
-import org.hibernate.util.StringHelper;
/**
* Bridge to use a StringBridge as a FieldBridge.
@@ -42,13 +40,7 @@
public void set(String name, Object value, Document document, LuceneOptions luceneOptions) {
String indexedString = stringBridge.objectToString( value );
- //Do not add fields on empty strings, seems a sensible default in most situations
- //TODO if Store, probably also save empty ones
- if ( StringHelper.isNotEmpty( indexedString ) ) {
- Field field = new Field( name, indexedString, luceneOptions.getStore(), luceneOptions.getIndex(), luceneOptions.getTermVector() );
- field.setBoost( luceneOptions.getBoost() );
- document.add( field );
- }
+ luceneOptions.addFieldToDocument( name, indexedString, document );
}
}
Modified: search/trunk/hibernate-search/src/main/java/org/hibernate/search/bridge/TwoWayString2FieldBridgeAdaptor.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/bridge/TwoWayString2FieldBridgeAdaptor.java 2010-04-08 09:09:22 UTC (rev 19186)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/bridge/TwoWayString2FieldBridgeAdaptor.java 2010-04-08 09:50:52 UTC (rev 19187)
@@ -24,8 +24,12 @@
*/
package org.hibernate.search.bridge;
+import java.util.zip.DataFormatException;
+
+import org.apache.lucene.document.CompressionTools;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
+import org.hibernate.search.SearchException;
/**
* Bridge to use a TwoWayStringBridge as a TwoWayFieldBridge
@@ -52,7 +56,19 @@
return stringBridge.stringToObject( null );
}
else {
- return stringBridge.stringToObject( field.stringValue() );
+ String stringValue;
+ if ( field.isBinary() ) {
+ try {
+ stringValue = CompressionTools.decompressString( field.getBinaryValue() );
+ }
+ catch (DataFormatException e) {
+ throw new SearchException( "Field " + name + " looks like binary but couldn't be decompressed" );
+ }
+ }
+ else {
+ stringValue = field.stringValue();
+ }
+ return stringBridge.stringToObject( stringValue );
}
}
}
Modified: search/trunk/hibernate-search/src/main/java/org/hibernate/search/engine/DocumentBuilderContainedEntity.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/engine/DocumentBuilderContainedEntity.java 2010-04-08 09:09:22 UTC (rev 19186)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/engine/DocumentBuilderContainedEntity.java 2010-04-08 09:50:52 UTC (rev 19187)
@@ -459,7 +459,7 @@
private void bindClassBridgeAnnotation(String prefix, PropertiesMetadata propertiesMetadata, ClassBridge ann, InitContext context) {
String fieldName = prefix + ann.name();
propertiesMetadata.classNames.add( fieldName );
- propertiesMetadata.classStores.add( getStore( ann.store() ) );
+ propertiesMetadata.classStores.add( ann.store() );
propertiesMetadata.classIndexes.add( getIndex( ann.index() ) );
propertiesMetadata.classTermVectors.add( getTermVector( ann.termVector() ) );
propertiesMetadata.classBridges.add( BridgeFactory.extractType( ann ) );
@@ -480,7 +480,7 @@
propertiesMetadata.fieldGetters.add( member );
String fieldName = prefix + ReflectionHelper.getAttributeName( member, fieldAnn.name() );
propertiesMetadata.fieldNames.add( fieldName );
- propertiesMetadata.fieldStore.add( getStore( fieldAnn.store() ) );
+ propertiesMetadata.fieldStore.add( fieldAnn.store() );
propertiesMetadata.fieldIndex.add( getIndex( fieldAnn.index() ) );
propertiesMetadata.fieldBoosts.add( getBoost( member, fieldAnn ) );
propertiesMetadata.dynamicFieldBoosts.add( getDynamicBoost( member ) );
@@ -540,19 +540,6 @@
return localPrefix;
}
- protected Field.Store getStore(Store store) {
- switch ( store ) {
- case NO:
- return Field.Store.NO;
- case YES:
- return Field.Store.YES;
- case COMPRESS:
- return Field.Store.COMPRESS;
- default:
- throw new AssertionFailure( "Unexpected Store: " + store );
- }
- }
-
protected Field.TermVector getTermVector(TermVector vector) {
switch ( vector ) {
case NO:
@@ -785,7 +772,7 @@
public final List<String> fieldNames = new ArrayList<String>();
public final List<XMember> fieldGetters = new ArrayList<XMember>();
public final List<FieldBridge> fieldBridges = new ArrayList<FieldBridge>();
- public final List<Field.Store> fieldStore = new ArrayList<Field.Store>();
+ public final List<Store> fieldStore = new ArrayList<Store>();
public final List<Field.Index> fieldIndex = new ArrayList<Field.Index>();
public final List<Float> fieldBoosts = new ArrayList<Float>();
public final List<BoostStrategy> dynamicFieldBoosts = new ArrayList<BoostStrategy>();
@@ -797,7 +784,7 @@
public final List<XMember> containedInGetters = new ArrayList<XMember>();
public final List<String> classNames = new ArrayList<String>();
- public final List<Field.Store> classStores = new ArrayList<Field.Store>();
+ public final List<Store> classStores = new ArrayList<Store>();
public final List<Field.Index> classIndexes = new ArrayList<Field.Index>();
public final List<FieldBridge> classBridges = new ArrayList<FieldBridge>();
public final List<Field.TermVector> classTermVectors = new ArrayList<Field.TermVector>();
Modified: search/trunk/hibernate-search/src/main/java/org/hibernate/search/engine/DocumentBuilderIndexedEntity.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/engine/DocumentBuilderIndexedEntity.java 2010-04-08 09:09:22 UTC (rev 19186)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/engine/DocumentBuilderIndexedEntity.java 2010-04-08 09:50:52 UTC (rev 19187)
@@ -206,7 +206,7 @@
propertiesMetadata.fieldGetters.add( member );
String fieldName = prefix + attributeName;
propertiesMetadata.fieldNames.add( fieldName );
- propertiesMetadata.fieldStore.add( getStore( Store.YES ) );
+ propertiesMetadata.fieldStore.add( Store.YES );
propertiesMetadata.fieldIndex.add( getIndex( Index.UN_TOKENIZED ) );
propertiesMetadata.fieldTermVectors.add( getTermVector( TermVector.NO ) );
propertiesMetadata.fieldBridges.add( BridgeFactory.guessType( null, member, reflectionManager ) );
@@ -403,7 +403,7 @@
// now add the entity id to the document
LuceneOptions luceneOptions = new LuceneOptionsImpl(
- Field.Store.YES,
+ Store.YES,
Field.Index.NOT_ANALYZED_NO_NORMS, Field.TermVector.NO, idBoost
);
idBridge.set( idKeywordName, id, doc, luceneOptions );
@@ -623,7 +623,7 @@
populateResult(
builderIndexedEntity.idKeywordName,
builderIndexedEntity.idBridge,
- Field.Store.YES,
+ Store.YES,
fields,
result,
document
@@ -635,19 +635,19 @@
return result;
}
- private static void populateResult(String fieldName, FieldBridge fieldBridge, Field.Store store,
+ private static void populateResult(String fieldName, FieldBridge fieldBridge, Store store,
String[] fields, Object[] result, Document document) {
int matchingPosition = getFieldPosition( fields, fieldName );
if ( matchingPosition != -1 ) {
//TODO make use of an isTwoWay() method
- if ( store != Field.Store.NO && TwoWayFieldBridge.class.isAssignableFrom( fieldBridge.getClass() ) ) {
+ if ( store != Store.NO && TwoWayFieldBridge.class.isAssignableFrom( fieldBridge.getClass() ) ) {
result[matchingPosition] = ( ( TwoWayFieldBridge ) fieldBridge ).get( fieldName, document );
if ( log.isTraceEnabled() ) {
log.trace( "Field {} projected as {}", fieldName, result[matchingPosition] );
}
}
else {
- if ( store == Field.Store.NO ) {
+ if ( store == Store.NO ) {
throw new SearchException( "Projecting an unstored field: " + fieldName );
}
else {
Modified: search/trunk/hibernate-search/src/main/java/org/hibernate/search/engine/LuceneOptionsImpl.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/engine/LuceneOptionsImpl.java 2010-04-08 09:09:22 UTC (rev 19186)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/engine/LuceneOptionsImpl.java 2010-04-08 09:50:52 UTC (rev 19187)
@@ -24,10 +24,14 @@
*/
package org.hibernate.search.engine;
+import org.apache.lucene.document.CompressionTools;
+import org.apache.lucene.document.Document;
+import org.apache.lucene.document.Field;
import org.apache.lucene.document.Field.Index;
-import org.apache.lucene.document.Field.Store;
import org.apache.lucene.document.Field.TermVector;
+import org.hibernate.annotations.common.util.StringHelper;
+import org.hibernate.search.annotations.Store;
import org.hibernate.search.bridge.LuceneOptions;
/**
@@ -35,36 +39,53 @@
* This is a package level class
*
* @author Hardy Ferentschik
+ * @author Sanne Grinovero
*/
class LuceneOptionsImpl implements LuceneOptions {
- private final Store store;
- private final Index index;
+
+ private final boolean storeCompressed;
+ private final boolean storeUncompressed;
+ private final Index indexMode;
private final TermVector termVector;
private final Float boost;
+ private final Store storeType;
- public LuceneOptionsImpl(Store store, Index index, TermVector termVector, Float boost) {
- this.store = store;
- this.index = index;
+ public LuceneOptionsImpl(Store store, Index indexMode, TermVector termVector, Float boost) {
+ this.indexMode = indexMode;
this.termVector = termVector;
this.boost = boost;
+ this.storeType = store;
+ this.storeCompressed = store.equals( Store.COMPRESS );
+ this.storeUncompressed = store.equals( Store.YES );
}
- public Store getStore() {
- return store;
+ public void addFieldToDocument(String name, String indexedString, Document document) {
+ //Do not add fields on empty strings, seems a sensible default in most situations
+ //TODO if Store, probably also save empty ones
+ if ( StringHelper.isNotEmpty( indexedString ) ) {
+ if ( ! ( indexMode.equals( Index.NO ) && storeCompressed ) ) {
+ standardFieldAdd( name, indexedString, document );
+ }
+ if ( storeCompressed ) {
+ compressedFieldAdd( name, indexedString, document );
+ }
+ }
}
- public Index getIndex() {
- return index;
+ private void standardFieldAdd(String name, String indexedString, Document document) {
+ Field field = new Field( name, false, indexedString, storeUncompressed ? Field.Store.YES : Field.Store.NO , indexMode, termVector );
+ if ( boost != null )
+ field.setBoost( boost );
+ document.add( field );
}
-
- public TermVector getTermVector() {
- return termVector;
+
+ private void compressedFieldAdd(String name, String indexedString, Document document) {
+ byte[] compressedString = CompressionTools.compressString( indexedString );
+ // indexed is implicitly set to false when using byte[]
+ Field field = new Field( name, compressedString, Field.Store.YES );
+ document.add( field );
}
- /**
- * @return the boost value. If <code>boost == null</code>, the default boost value
- * 1.0 is returned.
- */
public Float getBoost() {
if ( boost != null ) {
return boost;
@@ -72,4 +93,33 @@
return 1.0f;
}
}
+
+ public Index getIndex() {
+ return this.indexMode;
+ }
+
+ /**
+ * @deprecated likely to be removed in 3.3
+ */
+ public org.apache.lucene.document.Field.Store getStore() {
+ if (storeCompressed)
+ return org.apache.lucene.document.Field.Store.COMPRESS;
+ else if (storeUncompressed)
+ return org.apache.lucene.document.Field.Store.YES;
+ else
+ return org.apache.lucene.document.Field.Store.NO;
+ }
+
+ public TermVector getTermVector() {
+ return this.termVector;
+ }
+
+ /**
+ * Might be useful for a bridge implementation, but not currently part
+ * of LuceneOptions API as we are considering to remove the getters.
+ */
+ public Store getStoreStrategy() {
+ return storeType;
+ }
+
}
Modified: search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/bridge/CatDeptsFieldsClassBridge.java
===================================================================
--- search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/bridge/CatDeptsFieldsClassBridge.java 2010-04-08 09:09:22 UTC (rev 19186)
+++ search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/bridge/CatDeptsFieldsClassBridge.java 2010-04-08 09:50:52 UTC (rev 19187)
@@ -27,7 +27,6 @@
import java.util.Map;
import org.apache.lucene.document.Document;
-import org.apache.lucene.document.Field;
import org.hibernate.search.bridge.FieldBridge;
import org.hibernate.search.bridge.LuceneOptions;
import org.hibernate.search.bridge.ParameterizedBridge;
@@ -58,9 +57,7 @@
if ( fieldValue2 == null ) {
fieldValue2 = "";
}
- String fieldValue = fieldValue1 + sepChar + fieldValue2;
- Field field = new Field( name, fieldValue, luceneOptions.getStore(), luceneOptions.getIndex(), luceneOptions.getTermVector() );
- field.setBoost( luceneOptions.getBoost() );
- document.add( field );
+ String indexedString = fieldValue1 + sepChar + fieldValue2;
+ luceneOptions.addFieldToDocument( name, indexedString, document );
}
}
Modified: search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/bridge/CatFieldsClassBridge.java
===================================================================
--- search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/bridge/CatFieldsClassBridge.java 2010-04-08 09:09:22 UTC (rev 19186)
+++ search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/bridge/CatFieldsClassBridge.java 2010-04-08 09:50:52 UTC (rev 19187)
@@ -27,7 +27,6 @@
import java.util.Map;
import org.apache.lucene.document.Document;
-import org.apache.lucene.document.Field;
import org.hibernate.search.bridge.FieldBridge;
import org.hibernate.search.bridge.LuceneOptions;
import org.hibernate.search.bridge.ParameterizedBridge;
@@ -58,9 +57,7 @@
if ( fieldValue2 == null ) {
fieldValue2 = "";
}
- String fieldValue = fieldValue1 + sepChar + fieldValue2;
- Field field = new Field( name, fieldValue, luceneOptions.getStore(), luceneOptions.getIndex(), luceneOptions.getTermVector() );
- field.setBoost( luceneOptions.getBoost() );
- document.add( field );
+ String indexedString = fieldValue1 + sepChar + fieldValue2;
+ luceneOptions.addFieldToDocument( name, indexedString, document );
}
}
Modified: search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/bridge/DateSplitBridge.java
===================================================================
--- search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/bridge/DateSplitBridge.java 2010-04-08 09:09:22 UTC (rev 19186)
+++ search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/bridge/DateSplitBridge.java 2010-04-08 09:50:52 UTC (rev 19187)
@@ -30,7 +30,6 @@
import java.util.TimeZone;
import org.apache.lucene.document.Document;
-import org.apache.lucene.document.Field;
import org.hibernate.search.bridge.FieldBridge;
import org.hibernate.search.bridge.LuceneOptions;
@@ -52,24 +51,14 @@
int day = cal.get(Calendar.DAY_OF_MONTH);
// set year
- Field field = new Field(name + ".year", String.valueOf(year),
- luceneOptions.getStore(), luceneOptions.getIndex(),
- luceneOptions.getTermVector());
- field.setBoost(luceneOptions.getBoost());
- document.add(field);
+ luceneOptions.addFieldToDocument( name + ".year", String.valueOf( year ), document );
// set month and pad it if needed
- field = new Field(name + ".month", month < 10 ? "0" : ""
- + String.valueOf(month), luceneOptions.getStore(),
- luceneOptions.getIndex(), luceneOptions.getTermVector());
- field.setBoost(luceneOptions.getBoost());
- document.add(field);
+ luceneOptions.addFieldToDocument( name + ".month",
+ month < 10 ? "0" : "" + String.valueOf( month ), document );
// set day and pad it if needed
- field = new Field(name + ".day", day < 10 ? "0" : ""
- + String.valueOf(day), luceneOptions.getStore(),
- luceneOptions.getIndex(), luceneOptions.getTermVector());
- field.setBoost(luceneOptions.getBoost());
- document.add(field);
+ luceneOptions.addFieldToDocument( name + ".day",
+ day < 10 ? "0" : "" + String.valueOf( day ), document );
}
}
Modified: search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/bridge/EquipmentType.java
===================================================================
--- search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/bridge/EquipmentType.java 2010-04-08 09:09:22 UTC (rev 19186)
+++ search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/bridge/EquipmentType.java 2010-04-08 09:50:52 UTC (rev 19187)
@@ -27,7 +27,6 @@
import java.util.Map;
import org.apache.lucene.document.Document;
-import org.apache.lucene.document.Field;
import org.hibernate.search.bridge.FieldBridge;
import org.hibernate.search.bridge.LuceneOptions;
@@ -51,16 +50,11 @@
// a requirement. It just works that way in this instance. The
// actual name could be supplied by hard coding it below.
Departments deps = ( Departments ) value;
- Field field;
String fieldValue1 = deps.getManufacturer();
if ( fieldValue1 != null ) {
- String fieldValue = ( String ) equips.get( fieldValue1 );
- field = new Field(
- name, fieldValue, luceneOptions.getStore(), luceneOptions.getIndex(), luceneOptions.getTermVector()
- );
- field.setBoost( luceneOptions.getBoost() );
- document.add( field );
+ String indexedString = ( String ) equips.get( fieldValue1 );
+ luceneOptions.addFieldToDocument( name, indexedString, document );
}
}
}
Modified: search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/bridge/TruncateFieldBridge.java
===================================================================
--- search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/bridge/TruncateFieldBridge.java 2010-04-08 09:09:22 UTC (rev 19186)
+++ search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/bridge/TruncateFieldBridge.java 2010-04-08 09:50:52 UTC (rev 19187)
@@ -28,26 +28,23 @@
import org.apache.lucene.document.Field;
import org.hibernate.search.bridge.FieldBridge;
import org.hibernate.search.bridge.LuceneOptions;
-import org.hibernate.util.StringHelper;
/**
* @author Emmanuel Bernard
*/
public class TruncateFieldBridge implements FieldBridge {
+
public Object get(String name, Document document) {
Field field = document.getField( name );
return field.stringValue();
}
public void set(String name, Object value, Document document, LuceneOptions luceneOptions) {
- String indexedString = (String) value;
- //Do not add fields on empty strings, seems a sensible default in most situations
- if ( StringHelper.isNotEmpty( indexedString ) ) {
- Field field = new Field(name, indexedString.substring(0,
- indexedString.length() / 2), luceneOptions.getStore(),
- luceneOptions.getIndex(), luceneOptions.getTermVector());
- field.setBoost( luceneOptions.getBoost() );
- document.add( field );
+ String stringValue = (String) value;
+ if ( stringValue != null ) {
+ String indexedString = stringValue.substring( 0, stringValue.length() / 2 );
+ luceneOptions.addFieldToDocument( name, indexedString, document );
}
}
+
}
Added: search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/compression/CompressionTest.java
===================================================================
--- search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/compression/CompressionTest.java (rev 0)
+++ search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/compression/CompressionTest.java 2010-04-08 09:50:52 UTC (rev 19187)
@@ -0,0 +1,193 @@
+/* $Id$
+ *
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009, Red Hat, Inc. and/or its affiliates 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, Inc.
+ *
+ * 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.search.test.compression;
+
+import java.util.List;
+import java.util.zip.DataFormatException;
+
+import junit.framework.Assert;
+
+import org.apache.lucene.analysis.SimpleAnalyzer;
+import org.apache.lucene.document.CompressionTools;
+import org.apache.lucene.document.Document;
+import org.apache.lucene.document.Field;
+import org.apache.lucene.index.IndexReader;
+import org.apache.lucene.queryParser.ParseException;
+import org.apache.lucene.queryParser.QueryParser;
+import org.apache.lucene.search.IndexSearcher;
+import org.apache.lucene.search.MatchAllDocsQuery;
+import org.apache.lucene.search.Query;
+import org.apache.lucene.search.ScoreDoc;
+import org.apache.lucene.search.TopDocs;
+import org.hibernate.Session;
+import org.hibernate.search.FullTextQuery;
+import org.hibernate.search.FullTextSession;
+import org.hibernate.search.Search;
+import org.hibernate.search.store.DirectoryProvider;
+import org.hibernate.search.test.SearchTestCase;
+
+public class CompressionTest extends SearchTestCase {
+
+ /**
+ * verifies the fields are really stored in compressed format
+ */
+ public void testFieldWasCompressed() throws Exception {
+ DirectoryProvider[] directoryProviders = getSearchFactory().getDirectoryProviders( LargeDocument.class );
+ IndexReader indexReader = getSearchFactory().getReaderProvider().openReader( directoryProviders );
+ try {
+ IndexSearcher searcher = new IndexSearcher( indexReader );
+ TopDocs topDocs = searcher.search( new MatchAllDocsQuery(), null, 10 );
+ Assert.assertEquals( 1, topDocs.totalHits );
+
+ ScoreDoc doc = topDocs.scoreDocs[0];
+ Document document = indexReader.document( doc.doc );
+ {
+ Field[] fields = document.getFields( "title" );
+ Assert.assertEquals( 1, fields.length );
+ Assert.assertFalse( fields[0].isCompressed() );
+ Assert.assertTrue( fields[0].isIndexed() );
+ Assert.assertTrue( fields[0].isStored() );
+ Assert.assertEquals(
+ "Hibernate in Action, third edition",
+ fields[0].stringValue()
+ );
+ }
+ {
+ Field[] fields = document.getFields( "abstract" );
+ Assert.assertEquals( 1, fields.length );
+ Assert.assertTrue( isCompressed( fields[0] ) );
+ Assert.assertTrue( fields[0].isCompressed() );
+ Assert.assertEquals(
+ "<b>JPA2 with Hibernate</b>",
+ restoreValue( fields[0] )
+ );
+ }
+ {
+ Field[] fields = document.getFields( "text" );
+ Assert.assertEquals( 1, fields.length );
+ Assert.assertTrue( isCompressed( fields[0] ) );
+ Assert.assertEquals(
+ "This is a placeholder for the new text that you should write",
+ restoreValue( fields[0] )
+ );
+ }
+ }
+ finally {
+ getSearchFactory().getReaderProvider().closeReader( indexReader );
+ }
+ }
+
+ /**
+ * Verifies the compressed fields are also searchable
+ */
+ public void testCompressedFieldSearch() throws ParseException {
+ assertFindsN( 1, "title:third" );
+ assertFindsN( 1, "abstract:jpa2" );
+ assertFindsN( 1, "text:write" );
+ assertFindsN( 0, "text:jpa2" );
+ }
+
+ private void assertFindsN(int expectedToFind, String queryString) throws ParseException {
+ openSession().beginTransaction();
+ try {
+ FullTextSession fullTextSession = Search.getFullTextSession( session );
+ QueryParser qparser = new QueryParser( getTargetLuceneVersion(), "", new SimpleAnalyzer() );
+ Query query = qparser.parse( queryString );
+ FullTextQuery fullTextQuery = fullTextSession.createFullTextQuery(
+ query,
+ LargeDocument.class );
+ List<LargeDocument> list = fullTextQuery.list();
+ Assert.assertEquals( expectedToFind, list.size() );
+ if ( expectedToFind == 1 )
+ Assert.assertEquals( "Hibernate in Action, third edition", list.get( 0 ).getTitle() );
+ }
+ finally {
+ session.getTransaction().commit();
+ session.close();
+ }
+ }
+
+ /**
+ * Verify that projection is able to inflate stored data
+ */
+ public void testProjectionOnCompressedFields() {
+ openSession().beginTransaction();
+ try {
+ FullTextSession fullTextSession = Search.getFullTextSession( session );
+ FullTextQuery fullTextQuery = fullTextSession.createFullTextQuery(
+ new MatchAllDocsQuery(),
+ LargeDocument.class );
+ List list = fullTextQuery.setProjection( "title", "abstract", "text" ).list();
+ Assert.assertEquals( 1, list.size() );
+ Object[] results = (Object[]) list.get( 0 );
+ Assert.assertEquals( "Hibernate in Action, third edition", results[0] );
+ Assert.assertEquals( "JPA2 with Hibernate", results[1] );
+ Assert.assertEquals( "This is a placeholder for the new text that you should write", results[2] );
+ }
+ finally {
+ session.getTransaction().commit();
+ session.close();
+ }
+ }
+
+ // test helpers:
+
+ private String restoreValue(Field field) throws DataFormatException {
+ if ( field.isBinary() ) {
+ Assert.assertNull( "we rely on this in the Projection implementation", field.stringValue() );
+ return CompressionTools.decompressString( field.getBinaryValue() );
+ }
+ else {
+ return field.stringValue();
+ }
+ }
+
+ private boolean isCompressed(Field field) {
+ return ( field.isBinary() || field.isCompressed() );
+ }
+
+ // test setup:
+
+ protected Class<?>[] getMappings() {
+ return new Class[] {
+ LargeDocument.class
+ };
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ Session s = openSession();
+ s.getTransaction().begin();
+ s.persist(
+ new LargeDocument( "Hibernate in Action, third edition",
+ "JPA2 with Hibernate",
+ "This is a placeholder for the new text that you should write" )
+ );
+ s.getTransaction().commit();
+ s.close();
+ }
+
+}
+
Added: search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/compression/HTMLBoldFieldBridge.java
===================================================================
--- search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/compression/HTMLBoldFieldBridge.java (rev 0)
+++ search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/compression/HTMLBoldFieldBridge.java 2010-04-08 09:50:52 UTC (rev 19187)
@@ -0,0 +1,64 @@
+/* $Id$
+ *
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009, Red Hat, Inc. and/or its affiliates 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, Inc.
+ *
+ * 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.search.test.compression;
+
+import org.apache.lucene.document.Document;
+import org.apache.lucene.document.Field;
+import org.hibernate.search.bridge.FieldBridge;
+import org.hibernate.search.bridge.LuceneOptions;
+import org.hibernate.search.bridge.TwoWayFieldBridge;
+
+/**
+ * This FieldBridge is storing strings in the index wrapping the
+ * entity value in html bold tags.
+ * It's using deprecated method "getStore" to verify backwards compatibility
+ * Almost useless, needed for CompressionTest
+ * @see LuceneOptions
+ * @author Sanne Grinovero
+ */
+public class HTMLBoldFieldBridge implements FieldBridge, TwoWayFieldBridge {
+
+ public void set(String name, Object value, Document document, LuceneOptions luceneOptions) {
+ String fieldValue = objectToString( value );
+ Field field = new Field( name, fieldValue, luceneOptions.getStore(),
+ luceneOptions.getIndex(), luceneOptions.getTermVector() );
+ field.setBoost( luceneOptions.getBoost() );
+ document.add( field );
+ }
+
+ public Object get(String name, Document document) {
+ Field field = document.getField( name );
+ String stringValue = field.stringValue();
+ return stringValue.substring( 3, stringValue.length()-4 );
+ }
+
+ public String objectToString(Object value) {
+ String originalValue = value.toString();
+ String fieldValue = "<b>" + originalValue + "</b>";
+ return fieldValue;
+ }
+
+}
+
Added: search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/compression/LargeDocument.java
===================================================================
--- search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/compression/LargeDocument.java (rev 0)
+++ search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/compression/LargeDocument.java 2010-04-08 09:50:52 UTC (rev 19187)
@@ -0,0 +1,97 @@
+/* $Id$
+ *
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009, Red Hat, Inc. and/or its affiliates 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, Inc.
+ *
+ * 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.search.test.compression;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+
+import org.hibernate.search.annotations.DocumentId;
+import org.hibernate.search.annotations.Field;
+import org.hibernate.search.annotations.FieldBridge;
+import org.hibernate.search.annotations.Index;
+import org.hibernate.search.annotations.Indexed;
+import org.hibernate.search.annotations.Store;
+
+@Entity
+@Indexed
+public class LargeDocument {
+
+ private Long id;
+ private String title;
+ private String summary;
+ private String text;
+
+ LargeDocument() {
+ }
+
+ public LargeDocument(String title, String summary, String text) {
+ super();
+ this.summary = summary;
+ this.text = text;
+ this.title = title;
+ }
+
+ @Id
+ @GeneratedValue
+ @DocumentId
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ @Field( store = Store.YES, index = Index.TOKENIZED )
+ public String getTitle() {
+ return title;
+ }
+
+ public void setTitle(String title) {
+ this.title = title;
+ }
+
+ @Field( name="abstract", store = Store.COMPRESS, index = Index.TOKENIZED,
+ bridge = @FieldBridge( impl = HTMLBoldFieldBridge.class ) )
+ public String getSummary() {
+ return summary;
+ }
+
+ public void setSummary(String summary) {
+ this.summary = summary;
+ }
+
+ @Field( store = Store.COMPRESS, index = Index.TOKENIZED )
+ public String getText() {
+ return text;
+ }
+
+ public void setText(String text) {
+ this.text = text;
+ }
+
+}
+
Modified: search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/configuration/CatDeptsFieldsClassBridge.java
===================================================================
--- search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/configuration/CatDeptsFieldsClassBridge.java 2010-04-08 09:09:22 UTC (rev 19186)
+++ search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/configuration/CatDeptsFieldsClassBridge.java 2010-04-08 09:50:52 UTC (rev 19187)
@@ -27,7 +27,6 @@
import java.util.Map;
import org.apache.lucene.document.Document;
-import org.apache.lucene.document.Field;
import org.hibernate.search.bridge.FieldBridge;
import org.hibernate.search.bridge.LuceneOptions;
import org.hibernate.search.bridge.ParameterizedBridge;
@@ -58,9 +57,7 @@
if ( fieldValue2 == null ) {
fieldValue2 = "";
}
- String fieldValue = fieldValue1 + sepChar + fieldValue2;
- Field field = new Field( name, fieldValue, luceneOptions.getStore(), luceneOptions.getIndex(), luceneOptions.getTermVector() );
- field.setBoost( luceneOptions.getBoost() );
- document.add( field );
+ String indexedString = fieldValue1 + sepChar + fieldValue2;
+ luceneOptions.addFieldToDocument( name, indexedString, document );
}
}
Modified: search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/configuration/EquipmentType.java
===================================================================
--- search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/configuration/EquipmentType.java 2010-04-08 09:09:22 UTC (rev 19186)
+++ search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/configuration/EquipmentType.java 2010-04-08 09:50:52 UTC (rev 19187)
@@ -27,7 +27,6 @@
import java.util.Map;
import org.apache.lucene.document.Document;
-import org.apache.lucene.document.Field;
import org.hibernate.search.bridge.FieldBridge;
import org.hibernate.search.bridge.LuceneOptions;
@@ -38,6 +37,7 @@
*/
@SuppressWarnings("unchecked")
public class EquipmentType implements FieldBridge, ParameterizedBridge {
+
private Map equips;
public void setParameterValues(Map parameters) {
@@ -51,16 +51,12 @@
// a requirement. It just works that way in this instance. The
// actual name could be supplied by hard coding it below.
Departments deps = ( Departments ) value;
- Field field;
- String fieldValue1 = deps.getManufacturer();
+ String fieldValue = deps.getManufacturer();
- if ( fieldValue1 != null ) {
- String fieldValue = ( String ) equips.get( fieldValue1 );
- field = new Field(
- name, fieldValue, luceneOptions.getStore(), luceneOptions.getIndex(), luceneOptions.getTermVector()
- );
- field.setBoost( luceneOptions.getBoost() );
- document.add( field );
+ if ( fieldValue != null ) {
+ String indexedString = ( String ) equips.get( fieldValue );
+ luceneOptions.addFieldToDocument( name, indexedString, document );
}
}
+
}
Modified: search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/id/PersonPKBridge.java
===================================================================
--- search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/id/PersonPKBridge.java 2010-04-08 09:09:22 UTC (rev 19186)
+++ search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/id/PersonPKBridge.java 2010-04-08 09:50:52 UTC (rev 19187)
@@ -55,35 +55,13 @@
PersonPK id = ( PersonPK ) value;
//store each property in a unique field
- Field field = new Field(
- name + ".firstName",
- id.getFirstName(),
- luceneOptions.getStore(),
- luceneOptions.getIndex(),
- luceneOptions.getTermVector()
- );
- field.setBoost( luceneOptions.getBoost() );
- document.add( field );
+ luceneOptions.addFieldToDocument( name + ".firstName", id.getFirstName(), document );
- field = new Field(
- name + ".lastName",
- id.getLastName(),
- luceneOptions.getStore(),
- luceneOptions.getIndex(),
- luceneOptions.getTermVector()
- );
- field.setBoost( luceneOptions.getBoost() );
- document.add( field );
-
+ luceneOptions.addFieldToDocument( name + ".lastName", id.getLastName(), document );
+
//store the unique string representation in the named field
- field = new Field(
- name,
- objectToString( id ),
- luceneOptions.getStore(),
- luceneOptions.getIndex(),
- luceneOptions.getTermVector()
- );
- field.setBoost( luceneOptions.getBoost() );
- document.add( field );
+ luceneOptions.addFieldToDocument( name, objectToString( id ), document );
+
}
+
}
14 years, 1 month
Hibernate SVN: r19186 - search/trunk/hibernate-search/src/main/java/org/hibernate/search/store.
by hibernate-commits@lists.jboss.org
Author: sannegrinovero
Date: 2010-04-08 05:09:22 -0400 (Thu, 08 Apr 2010)
New Revision: 19186
Modified:
search/trunk/hibernate-search/src/main/java/org/hibernate/search/store/FSMasterDirectoryProvider.java
search/trunk/hibernate-search/src/main/java/org/hibernate/search/store/FSSlaveDirectoryProvider.java
Log:
HSEARCH-492 FSMasterDirectoryProvider and FSSlaveDirectoryProvider don't shutdown the Executor
Modified: search/trunk/hibernate-search/src/main/java/org/hibernate/search/store/FSMasterDirectoryProvider.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/store/FSMasterDirectoryProvider.java 2010-04-08 07:08:28 UTC (rev 19185)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/store/FSMasterDirectoryProvider.java 2010-04-08 09:09:22 UTC (rev 19186)
@@ -29,7 +29,7 @@
import java.util.Properties;
import java.util.Timer;
import java.util.TimerTask;
-import java.util.concurrent.Executor;
+import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.locks.Lock;
@@ -77,6 +77,7 @@
private File indexDir;
private String directoryProviderName;
private Properties properties;
+ private TriggerTask task;
public void initialize(String directoryProviderName, Properties properties, SearchFactoryImplementor searchFactoryImplementor) {
this.properties = properties;
@@ -124,7 +125,7 @@
catch (IOException e) {
throw new SearchException( "Unable to initialize index: " + directoryProviderName, e );
}
- TimerTask task = new FSMasterDirectoryProvider.TriggerTask( indexDir, sourceDir, this );
+ task = new FSMasterDirectoryProvider.TriggerTask( indexDir, sourceDir, this );
long period = DirectoryProviderHelper.getRefreshPeriod( properties, directoryProviderName );
timer.scheduleAtFixedRate( task, period, period );
this.current = currentLocal; //write to volatile to publish all state
@@ -166,6 +167,7 @@
@SuppressWarnings("unused")
int readCurrentState = current; //Another unneeded value, to ensure visibility of state protected by memory barrier
timer.cancel();
+ task.stop();
try {
directory.close();
}
@@ -176,7 +178,7 @@
private class TriggerTask extends TimerTask {
- private final Executor executor;
+ private final ExecutorService executor;
private final FSMasterDirectoryProvider.CopyDirectory copyTask;
public TriggerTask(File source, File destination, DirectoryProvider<FSDirectory> directoryProvider) {
@@ -192,6 +194,10 @@
log.info( "Skipping directory synchronization, previous work still in progress: {}", indexName );
}
}
+
+ public void stop() {
+ executor.shutdownNow();
+ }
}
private class CopyDirectory implements Runnable {
Modified: search/trunk/hibernate-search/src/main/java/org/hibernate/search/store/FSSlaveDirectoryProvider.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/store/FSSlaveDirectoryProvider.java 2010-04-08 07:08:28 UTC (rev 19185)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/store/FSSlaveDirectoryProvider.java 2010-04-08 09:09:22 UTC (rev 19186)
@@ -29,7 +29,7 @@
import java.util.Properties;
import java.util.Timer;
import java.util.TimerTask;
-import java.util.concurrent.Executor;
+import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -72,6 +72,7 @@
private File indexDir;
private String directoryProviderName;
private Properties properties;
+ private TriggerTask task;
public void initialize(String directoryProviderName, Properties properties, SearchFactoryImplementor searchFactoryImplementor) {
this.properties = properties;
@@ -144,7 +145,7 @@
catch ( IOException e ) {
throw new SearchException( "Unable to initialize index: " + directoryProviderName, e );
}
- TimerTask task = new TriggerTask( sourceIndexDir, indexDir );
+ task = new TriggerTask( sourceIndexDir, indexDir );
long period = DirectoryProviderHelper.getRefreshPeriod( properties, directoryProviderName );
timer.scheduleAtFixedRate( task, period, period );
this.current = currentToBe;
@@ -195,7 +196,7 @@
class TriggerTask extends TimerTask {
- private final Executor executor;
+ private final ExecutorService executor;
private final CopyDirectory copyTask;
public TriggerTask(File sourceIndexDir, File destination) {
@@ -215,6 +216,10 @@
}
}
}
+
+ public void stop() {
+ executor.shutdownNow();
+ }
}
class CopyDirectory implements Runnable {
@@ -301,6 +306,7 @@
@SuppressWarnings("unused")
int readCurrentState = current; //unneded value, but ensure visibility of state protected by memory barrier
timer.cancel();
+ task.stop();
try {
directory1.close();
}
14 years, 1 month
Hibernate SVN: r19185 - search/trunk/hibernate-search-archetype.
by hibernate-commits@lists.jboss.org
Author: stliu
Date: 2010-04-08 03:08:28 -0400 (Thu, 08 Apr 2010)
New Revision: 19185
Modified:
search/trunk/hibernate-search-archetype/
Log:
ignore eclipse metadata files
Property changes on: search/trunk/hibernate-search-archetype
___________________________________________________________________
Name: svn:ignore
- target
+ target
.settings
.classpath
.project
14 years, 1 month
Hibernate SVN: r19184 - search/trunk/hibernate-search-testing.
by hibernate-commits@lists.jboss.org
Author: stliu
Date: 2010-04-08 03:07:53 -0400 (Thu, 08 Apr 2010)
New Revision: 19184
Modified:
search/trunk/hibernate-search-testing/
Log:
ignore eclipse metadata files
Property changes on: search/trunk/hibernate-search-testing
___________________________________________________________________
Name: svn:ignore
- target
+ target
.settings
.classpath
.project
14 years, 1 month
Hibernate SVN: r19183 - in core/trunk: core/src/main/java/org/hibernate/loader/criteria and 1 other directories.
by hibernate-commits@lists.jboss.org
Author: gbadner
Date: 2010-04-07 20:24:12 -0400 (Wed, 07 Apr 2010)
New Revision: 19183
Modified:
core/trunk/core/src/main/java/org/hibernate/criterion/CriteriaQuery.java
core/trunk/core/src/main/java/org/hibernate/criterion/PropertyProjection.java
core/trunk/core/src/main/java/org/hibernate/loader/criteria/CriteriaQueryTranslator.java
core/trunk/testsuite/src/test/java/org/hibernate/test/criteria/CriteriaQueryTest.java
Log:
HHH-5063 HHH-5082 : Invalid projections when alias is same as property name; QueryException thrown when grouping by component
Modified: core/trunk/core/src/main/java/org/hibernate/criterion/CriteriaQuery.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/criterion/CriteriaQuery.java 2010-04-07 22:46:58 UTC (rev 19182)
+++ core/trunk/core/src/main/java/org/hibernate/criterion/CriteriaQuery.java 2010-04-08 00:24:12 UTC (rev 19183)
@@ -44,11 +44,19 @@
/**
* Get the names of the columns mapped by a property path,
* ignoring projection aliases
+ * @throws org.hibernate.QueryException if the property maps to more than 1 column
*/
public String getColumn(Criteria criteria, String propertyPath)
throws HibernateException;
/**
+ * Get the names of the columns mapped by a property path,
+ * ignoring projection aliases
+ */
+ public String[] getColumns(String propertyPath, Criteria criteria)
+ throws HibernateException;
+
+ /**
* Get the type of a property path, ignoring projection aliases
*/
public Type getType(Criteria criteria, String propertyPath)
Modified: core/trunk/core/src/main/java/org/hibernate/criterion/PropertyProjection.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/criterion/PropertyProjection.java 2010-04-07 22:46:58 UTC (rev 19182)
+++ core/trunk/core/src/main/java/org/hibernate/criterion/PropertyProjection.java 2010-04-08 00:24:12 UTC (rev 19183)
@@ -27,6 +27,7 @@
import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.type.Type;
+import org.hibernate.util.StringHelper;
/**
* A property value, or grouped property value
@@ -62,7 +63,7 @@
public String toSqlString(Criteria criteria, int position, CriteriaQuery criteriaQuery)
throws HibernateException {
StringBuffer buf = new StringBuffer();
- String[] cols = criteriaQuery.getColumnsUsingProjection( criteria, propertyName );
+ String[] cols = criteriaQuery.getColumns( propertyName, criteria );
for ( int i=0; i<cols.length; i++ ) {
buf.append( cols[i] )
.append(" as y")
@@ -84,7 +85,7 @@
return super.toGroupSqlString(criteria, criteriaQuery);
}
else {
- return criteriaQuery.getColumn(criteria, propertyName);
+ return StringHelper.join( ", ", criteriaQuery.getColumns( propertyName, criteria ) );
}
}
Modified: core/trunk/core/src/main/java/org/hibernate/loader/criteria/CriteriaQueryTranslator.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/loader/criteria/CriteriaQueryTranslator.java 2010-04-07 22:46:58 UTC (rev 19182)
+++ core/trunk/core/src/main/java/org/hibernate/loader/criteria/CriteriaQueryTranslator.java 2010-04-08 00:24:12 UTC (rev 19183)
@@ -477,7 +477,7 @@
);
}
- private String[] getColumns(
+ public String[] getColumns(
String propertyName,
Criteria subcriteria) throws HibernateException {
return getPropertyMapping( getEntityName( subcriteria, propertyName ) )
Modified: core/trunk/testsuite/src/test/java/org/hibernate/test/criteria/CriteriaQueryTest.java
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/criteria/CriteriaQueryTest.java 2010-04-07 22:46:58 UTC (rev 19182)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/criteria/CriteriaQueryTest.java 2010-04-08 00:24:12 UTC (rev 19183)
@@ -1,6 +1,7 @@
//$Id: CriteriaQueryTest.java 10976 2006-12-12 23:22:26Z steve.ebersole(a)jboss.com $
package org.hibernate.test.criteria;
+import java.util.Iterator;
import java.util.List;
import java.util.Map;
@@ -9,6 +10,8 @@
import org.hibernate.Criteria;
import org.hibernate.FetchMode;
import org.hibernate.Hibernate;
+import org.hibernate.JDBCException;
+import org.hibernate.QueryException;
import org.hibernate.ScrollableResults;
import org.hibernate.Session;
import org.hibernate.Transaction;
@@ -186,7 +189,143 @@
session.close();
}
-
+
+ public void testSubselectWithComponent() {
+
+ Session session = openSession();
+ Transaction t = session.beginTransaction();
+
+ Course course = new Course();
+ course.setCourseCode("HIB");
+ course.setDescription("Hibernate Training");
+ session.persist(course);
+
+ CityState odessaWa = new CityState( "Odessa", "WA" );
+
+ Student gavin = new Student();
+ gavin.setName("Gavin King");
+ gavin.setStudentNumber(232);
+ gavin.setCityState( odessaWa );
+ session.persist(gavin);
+
+ Enrolment enrolment2 = new Enrolment();
+ enrolment2.setCourse(course);
+ enrolment2.setCourseCode(course.getCourseCode());
+ enrolment2.setSemester((short) 3);
+ enrolment2.setYear((short) 1998);
+ enrolment2.setStudent(gavin);
+ enrolment2.setStudentNumber(gavin.getStudentNumber());
+ gavin.getEnrolments().add(enrolment2);
+ session.persist(enrolment2);
+
+ DetachedCriteria dc = DetachedCriteria.forClass(Student.class)
+ .add( Property.forName("cityState").eq( odessaWa ) )
+ .setProjection( Property.forName("cityState") );
+
+ session.createCriteria(Student.class)
+ .add( Subqueries.exists(dc) )
+ .list();
+ t.commit();
+ session.close();
+
+ session = openSession();
+ t = session.beginTransaction();
+ try {
+ session.createCriteria(Student.class)
+ .add( Subqueries.propertyEqAll("cityState", dc) )
+ .list();
+ fail( "should have failed because cannot compare subquery results with multiple columns" );
+ }
+ catch ( QueryException ex ) {
+ // expected
+ }
+ finally {
+ t.rollback();
+ session.close();
+ }
+
+ session = openSession();
+ t = session.beginTransaction();
+ try {
+ session.createCriteria(Student.class)
+ .add( Property.forName("cityState").eqAll(dc) )
+ .list();
+ fail( "should have failed because cannot compare subquery results with multiple columns" );
+ }
+ catch ( QueryException ex ) {
+ // expected
+ }
+ finally {
+ t.rollback();
+ session.close();
+ }
+
+ session = openSession();
+ t = session.beginTransaction();
+ try {
+ session.createCriteria(Student.class)
+ .add( Subqueries.in( odessaWa, dc) )
+ .list();
+ fail( "should have failed because cannot compare subquery results with multiple columns" );
+ }
+ catch ( JDBCException ex ) {
+ // expected
+ }
+ finally {
+ t.rollback();
+ session.close();
+ }
+
+ session = openSession();
+ t = session.beginTransaction();
+ DetachedCriteria dc2 = DetachedCriteria.forClass(Student.class, "st1")
+ .add( Property.forName("st1.cityState").eqProperty("st2.cityState") )
+ .setProjection( Property.forName("cityState") );
+ try {
+ session.createCriteria(Student.class, "st2")
+ .add( Subqueries.eq( odessaWa, dc2) )
+ .list();
+ fail( "should have failed because cannot compare subquery results with multiple columns" );
+ }
+ catch ( JDBCException ex ) {
+ // expected
+ }
+ finally {
+ t.rollback();
+ session.close();
+ }
+
+ session = openSession();
+ t = session.beginTransaction();
+ DetachedCriteria dc3 = DetachedCriteria.forClass(Student.class, "st")
+ .createCriteria("enrolments")
+ .createCriteria("course")
+ .add( Property.forName("description").eq("Hibernate Training") )
+ .setProjection( Property.forName("st.cityState") );
+ try {
+ session.createCriteria(Enrolment.class, "e")
+ .add( Subqueries.eq( odessaWa, dc3) )
+ .list();
+ fail( "should have failed because cannot compare subquery results with multiple columns" );
+ }
+ catch ( JDBCException ex ) {
+ // expected
+ }
+ finally {
+ t.rollback();
+ session.close();
+ }
+
+ session = openSession();
+ t = session.beginTransaction();
+ session.delete(enrolment2);
+ session.delete(gavin);
+ session.delete(course);
+ t.commit();
+ session.close();
+
+ }
+
public void testDetachedCriteria() {
DetachedCriteria dc = DetachedCriteria.forClass(Student.class)
@@ -511,11 +650,15 @@
Course course = new Course();
course.setCourseCode("HIB");
course.setDescription("Hibernate Training");
+ course.getCourseMeetings().add( new CourseMeeting( course, "Monday", 1, "1313 Mockingbird Lane" ) );
s.save(course);
-
+
Student gavin = new Student();
gavin.setName("Gavin King");
gavin.setStudentNumber(667);
+ CityState odessaWa = new CityState( "Odessa", "WA" );
+ gavin.setCityState( odessaWa );
+ gavin.setPreferredCourse( course );
s.save(gavin);
Student xam = new Student();
@@ -544,7 +687,65 @@
s.save(enrolment);
s.flush();
-
+
+ List resultList = s.createCriteria(Enrolment.class)
+ .setProjection( Projections.projectionList()
+ .add( Property.forName( "student" ), "student" )
+ .add( Property.forName( "course" ), "course" )
+ .add( Property.forName( "semester" ), "semester" )
+ .add( Property.forName("year"), "year" )
+ )
+ .list();
+ assertEquals( 2, resultList.size() );
+ for ( Iterator it = resultList.iterator(); it.hasNext(); ) {
+ Object[] objects = ( Object[] ) it.next();
+ assertEquals( 4, objects.length );
+ assertTrue( objects[ 0 ] instanceof Student );
+ assertTrue( objects[ 1 ] instanceof Course );
+ assertTrue( objects[ 2 ] instanceof Short );
+ assertTrue( objects[ 3 ] instanceof Short );
+ }
+
+ resultList = s.createCriteria(Student.class)
+ .setProjection( Projections.projectionList()
+ .add( Projections.id().as( "studentNumber" ))
+ .add( Property.forName( "name" ), "name" )
+ .add( Property.forName( "cityState" ), "cityState" )
+ .add( Property.forName("preferredCourse"), "preferredCourse" )
+ )
+ .list();
+ assertEquals( 2, resultList.size() );
+ for ( Iterator it = resultList.iterator(); it.hasNext(); ) {
+ Object[] objects = ( Object[] ) it.next();
+ assertEquals( 4, objects.length );
+ assertTrue( objects[ 0 ] instanceof Long );
+ assertTrue( objects[ 1 ] instanceof String );
+ if ( "Gavin King".equals( objects[ 1 ] ) ) {
+ assertTrue( objects[ 2 ] instanceof CityState );
+ assertTrue( objects[ 3 ] instanceof Course );
+ }
+ else {
+ assertNull( objects[ 2 ] );
+ assertNull( objects[ 3 ] );
+ }
+ }
+
+ Object[] aResult = ( Object[] ) s.createCriteria(Student.class)
+ .add( Restrictions.idEq( new Long( 667 ) ) )
+ .setProjection( Projections.projectionList()
+ .add( Projections.id().as( "studentNumber" ))
+ .add( Property.forName( "name" ), "name" )
+ .add( Property.forName( "cityState" ), "cityState" )
+ .add( Property.forName("preferredCourse"), "preferredCourse" )
+ )
+ .uniqueResult();
+ assertNotNull( aResult );
+ assertEquals( 4, aResult.length );
+ assertTrue( aResult[ 0 ] instanceof Long );
+ assertTrue( aResult[ 1 ] instanceof String );
+ assertTrue( aResult[ 2 ] instanceof CityState );
+ assertTrue( aResult[ 3 ] instanceof Course );
+
Long count = (Long) s.createCriteria(Enrolment.class)
.setProjection( Property.forName("studentNumber").count().setDistinct() )
.uniqueResult();
@@ -621,7 +822,23 @@
StudentDTO dto = (StudentDTO) resultWithAliasedBean.get(0);
assertNotNull(dto.getDescription());
assertNotNull(dto.getName());
-
+
+ CourseMeeting courseMeetingDto = ( CourseMeeting ) s.createCriteria(CourseMeeting.class)
+ .setProjection( Projections.projectionList()
+ .add( Property.forName("id").as("id") )
+ .add( Property.forName("course").as("course") )
+ )
+ .addOrder( Order.desc("id") )
+ .setResultTransformer( Transformers.aliasToBean(CourseMeeting.class) )
+ .uniqueResult();
+
+ assertNotNull( courseMeetingDto.getId() );
+ assertEquals( course.getCourseCode(), courseMeetingDto.getId().getCourseCode() );
+ assertEquals( "Monday", courseMeetingDto.getId().getDay() );
+ assertEquals( "1313 Mockingbird Lane", courseMeetingDto.getId().getLocation() );
+ assertEquals( 1, courseMeetingDto.getId().getPeriod() );
+ assertEquals( course.getDescription(), courseMeetingDto.getCourse().getDescription() );
+
s.createCriteria(Student.class)
.add( Restrictions.like("name", "Gavin", MatchMode.START) )
.addOrder( Order.asc("name") )
@@ -679,6 +896,204 @@
s.close();
}
+ public void testDistinctProjectionsOfComponents() {
+ Session s = openSession();
+ Transaction t = s.beginTransaction();
+
+ Course course = new Course();
+ course.setCourseCode("HIB");
+ course.setDescription("Hibernate Training");
+ s.save(course);
+
+ Student gavin = new Student();
+ gavin.setName("Gavin King");
+ gavin.setStudentNumber(667);
+ gavin.setCityState( new CityState( "Odessa", "WA" ) );
+ s.save(gavin);
+
+ Student xam = new Student();
+ xam.setName("Max Rydahl Andersen");
+ xam.setStudentNumber(101);
+ xam.setPreferredCourse( course );
+ xam.setCityState( new CityState( "Odessa", "WA" ) );
+ s.save(xam);
+
+ Enrolment enrolment = new Enrolment();
+ enrolment.setCourse(course);
+ enrolment.setCourseCode(course.getCourseCode());
+ enrolment.setSemester((short) 1);
+ enrolment.setYear((short) 1999);
+ enrolment.setStudent(xam);
+ enrolment.setStudentNumber(xam.getStudentNumber());
+ xam.getEnrolments().add(enrolment);
+ s.save(enrolment);
+
+ enrolment = new Enrolment();
+ enrolment.setCourse(course);
+ enrolment.setCourseCode(course.getCourseCode());
+ enrolment.setSemester((short) 3);
+ enrolment.setYear((short) 1998);
+ enrolment.setStudent(gavin);
+ enrolment.setStudentNumber(gavin.getStudentNumber());
+ gavin.getEnrolments().add(enrolment);
+ s.save(enrolment);
+
+ s.flush();
+
+ Object result = s.createCriteria( Student.class )
+ .setProjection( Projections.distinct( Property.forName( "cityState" ) ) )
+ .uniqueResult();
+ assertTrue( result instanceof CityState );
+ assertEquals( ( ( CityState ) result ).getCity(), "Odessa" );
+ assertEquals( ( ( CityState ) result ).getState(), "WA" );
+
+ result = s.createCriteria( Student.class )
+ .setProjection( Projections.distinct( Property.forName( "cityState" ).as( "cityState" ) ) )
+ .addOrder( Order.asc( "cityState" ) )
+ .uniqueResult();
+ assertTrue( result instanceof CityState );
+ assertEquals( ( ( CityState ) result ).getCity(), "Odessa" );
+ assertEquals( ( ( CityState ) result ).getState(), "WA" );
+
+ t.commit();
+ s.close();
+
+ s = openSession();
+ t = s.beginTransaction();
+ try {
+ result = s.createCriteria( Student.class )
+ .setProjection( Projections.count( "cityState" ) )
+ .uniqueResult();
+ fail( "should have failed with QueryException" );
+ }
+ catch ( QueryException ex ) {
+ //expected
+ }
+ finally {
+ t.rollback();
+ }
+ s.close();
+
+ s = openSession();
+ t = s.beginTransaction();
+ s.delete(gavin);
+ s.delete(xam);
+ s.delete(course);
+
+ t.commit();
+ s.close();
+ }
+
+ public void testGroupByComponent() {
+ Session s = openSession();
+ Transaction t = s.beginTransaction();
+
+ Course course = new Course();
+ course.setCourseCode("HIB");
+ course.setDescription("Hibernate Training");
+ s.save(course);
+
+ Student gavin = new Student();
+ gavin.setName("Gavin King");
+ gavin.setStudentNumber(667);
+ gavin.setCityState( new CityState( "Odessa", "WA" ) );
+ s.save(gavin);
+
+ Student xam = new Student();
+ xam.setName("Max Rydahl Andersen");
+ xam.setStudentNumber(101);
+ xam.setPreferredCourse( course );
+ xam.setCityState( new CityState( "Odessa", "WA" ) );
+ s.save(xam);
+
+ Enrolment enrolment = new Enrolment();
+ enrolment.setCourse(course);
+ enrolment.setCourseCode(course.getCourseCode());
+ enrolment.setSemester((short) 1);
+ enrolment.setYear((short) 1999);
+ enrolment.setStudent(xam);
+ enrolment.setStudentNumber(xam.getStudentNumber());
+ xam.getEnrolments().add(enrolment);
+ s.save(enrolment);
+
+ enrolment = new Enrolment();
+ enrolment.setCourse(course);
+ enrolment.setCourseCode(course.getCourseCode());
+ enrolment.setSemester((short) 3);
+ enrolment.setYear((short) 1998);
+ enrolment.setStudent(gavin);
+ enrolment.setStudentNumber(gavin.getStudentNumber());
+ gavin.getEnrolments().add(enrolment);
+ s.save(enrolment);
+
+ s.flush();
+
+ Object result = s.createCriteria( Student.class )
+ .setProjection( Projections.groupProperty( "cityState" ) )
+ .uniqueResult();
+ assertTrue( result instanceof CityState );
+ assertEquals( ( ( CityState ) result ).getCity(), "Odessa" );
+ assertEquals( ( ( CityState ) result ).getState(), "WA" );
+
+ result = s.createCriteria( Student.class, "st")
+ .setProjection( Projections.groupProperty( "st.cityState" ) )
+ .uniqueResult();
+ assertTrue( result instanceof CityState );
+ assertEquals( ( ( CityState ) result ).getCity(), "Odessa" );
+ assertEquals( ( ( CityState ) result ).getState(), "WA" );
+
+ result = s.createCriteria( Student.class, "st")
+ .setProjection( Projections.groupProperty( "st.cityState" ) )
+ .addOrder( Order.asc( "cityState" ) )
+ .uniqueResult();
+ assertTrue( result instanceof CityState );
+ assertEquals( ( ( CityState ) result ).getCity(), "Odessa" );
+ assertEquals( ( ( CityState ) result ).getState(), "WA" );
+
+ result = s.createCriteria( Student.class, "st")
+ .setProjection( Projections.groupProperty( "st.cityState" ).as( "cityState" ) )
+ .addOrder( Order.asc( "cityState" ) )
+ .uniqueResult();
+ assertTrue( result instanceof CityState );
+ assertEquals( ( ( CityState ) result ).getCity(), "Odessa" );
+ assertEquals( ( ( CityState ) result ).getState(), "WA" );
+
+ result = s.createCriteria( Student.class, "st")
+ .setProjection( Projections.groupProperty( "st.cityState" ).as( "cityState" ) )
+ .addOrder( Order.asc( "cityState" ) )
+ .uniqueResult();
+ assertTrue( result instanceof CityState );
+ assertEquals( ( ( CityState ) result ).getCity(), "Odessa" );
+ assertEquals( ( ( CityState ) result ).getState(), "WA" );
+
+ result = s.createCriteria( Student.class, "st")
+ .setProjection( Projections.groupProperty( "st.cityState" ).as( "cityState" ) )
+ .add( Restrictions.eq( "st.cityState", new CityState( "Odessa", "WA" ) ) )
+ .addOrder( Order.asc( "cityState" ) )
+ .uniqueResult();
+ assertTrue( result instanceof CityState );
+ assertEquals( ( ( CityState ) result ).getCity(), "Odessa" );
+ assertEquals( ( ( CityState ) result ).getState(), "WA" );
+
+ List list = s.createCriteria(Enrolment.class)
+ .createAlias("student", "st")
+ .createAlias("course", "co")
+ .setProjection( Projections.projectionList()
+ .add( Property.forName("co.courseCode").group() )
+ .add( Property.forName("st.cityState").group() )
+ .add( Property.forName("year").group() )
+ )
+ .list();
+
+
+ s.delete(gavin);
+ s.delete(xam);
+ s.delete(course);
+
+ t.commit();
+ s.close();
+ }
+
public void testRestrictionOnSubclassCollection() {
Session s = openSession();
Transaction t = s.beginTransaction();
@@ -805,6 +1220,22 @@
s.close();
}
+ public void testProjectedCompositeIdWithAlias() {
+ Session s = openSession();
+ Transaction t = s.beginTransaction();
+
+ Course course = new Course();
+ course.setCourseCode("HIB");
+ course.setDescription("Hibernate Training");
+ course.getCourseMeetings().add( new CourseMeeting( course, "Monday", 1, "1313 Mockingbird Lane" ) );
+ s.save(course);
+ s.flush();
+
+ List data = ( List ) s.createCriteria( CourseMeeting.class).setProjection( Projections.id().as( "id" ) ).list();
+ t.rollback();
+ s.close();
+ }
+
public void testProjectedComponent() {
Session s = openSession();
Transaction t = s.beginTransaction();
14 years, 2 months
Hibernate SVN: r19182 - in core/trunk: distribution and 1 other directories.
by hibernate-commits@lists.jboss.org
Author: steve.ebersole(a)jboss.com
Date: 2010-04-07 18:46:58 -0400 (Wed, 07 Apr 2010)
New Revision: 19182
Added:
core/trunk/core/src/main/javadoc/stylesheet.css
Modified:
core/trunk/core/src/main/javadoc/package.html
core/trunk/distribution/pom.xml
core/trunk/distribution/src/assembly/dist.xml
Log:
HHH-3997 - Build javadocs
Modified: core/trunk/core/src/main/javadoc/package.html
===================================================================
--- core/trunk/core/src/main/javadoc/package.html 2010-04-07 13:48:43 UTC (rev 19181)
+++ core/trunk/core/src/main/javadoc/package.html 2010-04-07 22:46:58 UTC (rev 19182)
@@ -1,39 +1,31 @@
<body>
-<h2>Hibernate API</h2>
+Hibernate JavaDoc documentation.
+<br>
-This documentation concentrates upon the following <b>Core API</b> interfaces:
-<li><tt>org.hibernate.Hibernate</tt></li>
-<li><tt>org.hibernate.Session</tt></li>
-<li><tt>org.hibernate.SessionFactory</tt></li>
-<li><tt>org.hibernate.Transaction</tt></li>
-<li><tt>org.hibernate.Query</tt></li>
-<li><tt>org.hibernate.Criteria</tt></li>
-<li><tt>org.hibernate.ScrollableResults</tt></li>
-<li><tt>org.hibernate.cfg.Configuration</tt></li>
-<li><tt>org.hibernate.criterion.Restrictions</tt></li>
-<li><tt>org.hibernate.criterion.Order</tt></li>
-<li><tt>org.hibernate.criterion.Example</tt></li>
-These interfaces are fully intended to be exposed to application code.<br>
+The following are considered to define the "core API" of Hibernate, meaning it is fully intended that they
+be exposed to application code:
+<ul>
+ <li>{@link org.hibernate.Hibernate}</li>
+ <li>{@link org.hibernate.Session}</li>
+ <li>{@link org.hibernate.SessionFactory}</li>
+ <li>{@link org.hibernate.Transaction}</li>
+ <li>{@link org.hibernate.Query}</li>
+ <li>{@link org.hibernate.Criteria}</li>
+ <li>{@link org.hibernate.ScrollableResults}</li>
+ <li>{@link org.hibernate.cfg.Configuration}</li>
+ <li>{@link org.hibernate.criterion.Restrictions}</li>
+ <li>{@link org.hibernate.criterion.Order}</li>
+ <li>{@link org.hibernate.criterion.Example}</li>
+</ul>
<br>
-The <b>Extension API</b> is intended to be used by application programmers
+
+The <b>Extension SPIs</b> are intended to be used by application programmers
to extend Hibernate functionality. None of these interfaces are intended
to be called by the application - they are called internally by Hibernate.
-This API is less stable than the Core API. The safest way to extend
-functionality is to contribute extensions back to the project; that way
-extensions will be updated when the Extension API changes.<br>
+These contracts are less stable than the Core API. The safest way to extend
+functionality is to contribute extensions back to the project.<br>
<br>
-Full Hibernate documentation may be found at
-<a href="http://hibernate.org">hibernate.org</a>.
-@see org.hibernate.Hibernate
-@see org.hibernate.Session
-@see org.hibernate.SessionFactory
-@see org.hibernate.Transaction
-@see org.hibernate.Query
-@see org.hibernate.Criteria
-@see org.hibernate.ScrollableResults
-@see org.hibernate.cfg.Configuration
-@see org.hibernate.criterion.Restrictions
-@see org.hibernate.criterion.Order
-@see org.hibernate.criterion.Example
+
+You can find all the Hibernate documentation at <a href="http://docs.jboss.org/hibernate"></a>.
</body>
Added: core/trunk/core/src/main/javadoc/stylesheet.css
===================================================================
--- core/trunk/core/src/main/javadoc/stylesheet.css (rev 0)
+++ core/trunk/core/src/main/javadoc/stylesheet.css 2010-04-07 22:46:58 UTC (rev 19182)
@@ -0,0 +1,118 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2010, Red Hat Inc. 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 Inc.
+ *
+ * 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
+ */
+
+/*
+ * Custom Hibernate javadoc style sheet
+ */
+
+/* Page background color */
+body {
+ font-family: Arial;
+ background-color: white;
+ font-size: 10pt;
+}
+td {
+ font-family: Arial;
+ font-size: 10pt;
+}
+
+/* Table colors */
+.TableHeadingColor { background: #F4F4F4 }
+.TableSubHeadingColor { background: #F4F4F4 }
+.TableRowColor { background: #FFFFFF }
+
+/* Font used in left-hand frame lists */
+.FrameTitleFont { font-size: normal; font-family: Arial }
+.FrameHeadingFont { font-size: normal; font-family: Arial }
+.FrameItemFont { font-size: normal; font-family: Arial }
+
+/* Navigation bar fonts and colors */
+.NavBarCell1 { background-color:#F4F4F4;}
+.NavBarCell1Rev { background-color:silver;}
+.NavBarFont1 { font-family: Arial, Helvetica, sans-serif; color:#000000;}
+.NavBarFont1Rev { font-family: Arial, Helvetica, sans-serif; color:#FFFFFF;}
+.NavBarCell2 { font-family: Arial, Helvetica, sans-serif; background-color:#FFFFFF;}
+.NavBarCell3 { font-family: Arial, Helvetica, sans-serif; background-color:#FFFFFF;}
+
+/* Links */
+A { color: #003399; }
+A:active { color: #003399; }
+A:visited { color: #888888; }
+
+
+P, OL, UL, LI, DL, DT, DD, BLOCKQUOTE {
+ color: #000000;
+}
+
+TD, TH, SPAN {
+ color: #000000;
+}
+
+BLOCKQUOTE {
+ margin-right: 0px;
+}
+
+TT {
+font-size: 90%;
+ font-family: "Courier New", Courier, monospace;
+ color: #000000;
+}
+
+PRE {
+font-size: 90%;
+ padding: 5px;
+ border-style: solid;
+ border-width: 1px;
+ border-color: #CCCCCC;
+ background-color: #F4F4F4;
+}
+
+UL, OL, LI {
+ list-style: disc;
+}
+
+HR {
+ width: 100%;
+ height: 1px;
+ background-color: #CCCCCC;
+ border-width: 0px;
+ padding: 0px;
+ color: #CCCCCC;
+}
+
+.variablelist {
+ padding-top: 10;
+ padding-bottom:10;
+ margin:0;
+}
+
+.itemizedlist, UL {
+ padding-top: 0;
+ padding-bottom:0;
+ margin:0;
+}
+
+.term {
+ font-weight:bold;
+}
Modified: core/trunk/distribution/pom.xml
===================================================================
--- core/trunk/distribution/pom.xml 2010-04-07 13:48:43 UTC (rev 19181)
+++ core/trunk/distribution/pom.xml 2010-04-07 22:46:58 UTC (rev 19182)
@@ -44,6 +44,104 @@
<build>
<plugins>
<plugin>
+ <groupId>org.codehaus.groovy.maven</groupId>
+ <artifactId>gmaven-plugin</artifactId>
+ <version>1.0</version>
+ <executions>
+ <execution>
+ <phase>generate-sources</phase>
+ <goals>
+ <goal>execute</goal>
+ </goals>
+ <configuration>
+ <source><![CDATA[
+ def sourcePathName = 'javadocSourcePath'
+ sourcePath = ant.path( id:sourcePathName ) {
+ ant.pathElement( path: '../annotations/src/main/java' )
+ ant.pathElement( path: '../cache-ehcache/src/main/java' )
+ ant.pathElement( path: '../cache-infinispan/src/main/java' )
+ ant.pathElement( path: '../cache-jbosscache/src/main/java' )
+ ant.pathElement( path: '../cache-oscache/src/main/java' )
+ ant.pathElement( path: '../cache-swarmcache/src/main/java' )
+ ant.pathElement( path: '../connection-c3p0/src/main/java' )
+ ant.pathElement( path: '../connection-proxool/src/main/java' )
+ ant.pathElement( path: '../entitymanager/src/main/java' )
+ ant.pathElement( path: '../envers/src/main/java' )
+ ant.pathElement( path: '../testing/src/main/java' )
+ ant.pathElement( path: '../core/src/main/java:core/target/generated-sources/antlr' )
+ }
+
+ def classPathName = 'javadocClassPath'
+ classPath = ant.path( id:classPathName );
+ project.compileClasspathElements.each{ element ->
+ classPath.createPathElement().path = element
+ }
+
+ ant.javadoc(
+ executable: '${jdk16_home}/bin/javadoc',
+ maxmemory: '512m',
+ destdir: 'target/javadocs',
+ sourcepathref: sourcePathName,
+ classpathref: classPathName,
+ overview: '../core/src/main/javadoc/package.html',
+ stylesheetfile: '../core/src/main/javadoc/stylesheet.css',
+ windowtitle: 'Hibernate JavaDocs',
+ doctitle: 'Hibernate JavaDoc (${project.version})',
+ bottom: 'Copyright © 2001-2010 <a href="http://redhat.com">Red Hat, Inc.</a> All Rights Reserved.',
+ use: true
+ ) {
+ ant.link( href: 'http://java.sun.com/j2se/1.5.0/docs/api' )
+ ant.link( href: 'http://java.sun.com/javaee/5/docs/api/' )
+ ant.tag( name: 'todo', description: 'To do:' )
+ ant.tag( name: 'noinspection', enabled: false )
+ ant.group( title: 'Core API' ) {
+ ant.package( name: 'org.hibernate' )
+ ant.package( name: 'org.hibernate.classic' )
+ ant.package( name: 'org.hibernate.criterion' )
+ ant.package( name: 'org.hibernate.mapping' )
+ ant.package( name: 'org.hibernate.metadata' )
+ ant.package( name: 'org.hibernate.cfg' )
+ ant.package( name: 'org.hibernate.stat' )
+ }
+ ant.group( title: 'Extension SPI' ) {
+ ant.package( name: 'org.hibernate.id*' )
+ ant.package( name: 'org.hibernate.connection' )
+ ant.package( name: 'org.hibernate.transaction' )
+ ant.package( name: 'org.hibernate.type' )
+ ant.package( name: 'org.hibernate.dialect*' )
+ ant.package( name: 'org.hibernate.cache*' )
+ ant.package( name: 'org.hibernate.event*' )
+ ant.package( name: 'org.hibernate.property' )
+ ant.package( name: 'org.hibernate.loader*' )
+ ant.package( name: 'org.hibernate.persister*' )
+ ant.package( name: ':org.hibernate.proxy' )
+ ant.package( name: 'org.hibernate.tuple' )
+ ant.package( name: 'org.hibernate.transform' )
+ ant.package( name: 'org.hibernate.collection' )
+ ant.package( name: 'org.hibernate.jdbc' )
+ ant.package( name: 'org.hibernate.usertype' )
+ }
+ ant.group( title: 'Bytecode providers' ) {
+ ant.package( name: 'org.hibernate.bytecode*' )
+ ant.package( name: 'org.hibernate.intercept*' )
+ }
+ ant.group( title: 'Infinispan Integration' ) {
+ ant.package( name: 'org.hibernate.cache.infinispan*' )
+ }
+ ant.group( title: 'JBossCache Integration' ) {
+ ant.package( name: 'org.hibernate.cache.jbc*' )
+ }
+ ant.group( title: 'Testing Support' ) {
+ ant.package( name: 'org.hibernate.junit*' )
+ }
+ }
+ ]]>
+ </source>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
@@ -160,6 +258,50 @@
<artifactId>cglib</artifactId>
<optional>true</optional>
</dependency>
+
+ <!-- Because Maven is retarded -->
+ <dependency>
+ <groupId>org.hibernate</groupId>
+ <artifactId>hibernate-validator</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>javax.validation</groupId>
+ <artifactId>validation-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.jboss.javaee</groupId>
+ <artifactId>jboss-jacc-api_JDK4</artifactId>
+ <version>1.1.0</version>
+ <scope>provided</scope>
+ <exclusions>
+ <exclusion>
+ <groupId>org.jboss.javaee</groupId>
+ <artifactId>jboss-servlet-api_3.0</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.jboss.logging</groupId>
+ <artifactId>jboss-logging-spi</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.jboss</groupId>
+ <artifactId>jboss-common-core</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>3.8.1</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>ant</groupId>
+ <artifactId>ant</artifactId>
+ <version>1.6.5</version>
+ <scope>provided</scope>
+ </dependency>
</dependencies>
<profiles>
Modified: core/trunk/distribution/src/assembly/dist.xml
===================================================================
--- core/trunk/distribution/src/assembly/dist.xml 2010-04-07 13:48:43 UTC (rev 19181)
+++ core/trunk/distribution/src/assembly/dist.xml 2010-04-07 22:46:58 UTC (rev 19182)
@@ -199,6 +199,16 @@
<include>**/**</include>
</includes>
</fileSet>
+ <!--
+ Build the 'documentation/javadocs' directory containing the aggregated javadocs
+ -->
+ <fileSet>
+ <directory>target/javadocs/</directory>
+ <outputDirectory>documentation/javadocs</outputDirectory>
+ <includes>
+ <include>**/**</include>
+ </includes>
+ </fileSet>
</fileSets>
</assembly>
\ No newline at end of file
14 years, 2 months
Hibernate SVN: r19181 - in search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/embedded/nested: containedIn and 1 other directory.
by hibernate-commits@lists.jboss.org
Author: epbernard
Date: 2010-04-07 09:48:43 -0400 (Wed, 07 Apr 2010)
New Revision: 19181
Added:
search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/embedded/nested/containedIn/
search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/embedded/nested/containedIn/HelpItem.java
search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/embedded/nested/containedIn/HelpItemTag.java
search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/embedded/nested/containedIn/NestedContainedInTest.java
search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/embedded/nested/containedIn/Tag.java
Log:
HSEARCH-488 add tests on nested @ContainedIn
Added: search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/embedded/nested/containedIn/HelpItem.java
===================================================================
--- search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/embedded/nested/containedIn/HelpItem.java (rev 0)
+++ search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/embedded/nested/containedIn/HelpItem.java 2010-04-07 13:48:43 UTC (rev 19181)
@@ -0,0 +1,74 @@
+package org.hibernate.search.test.embedded.nested.containedIn;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.OneToMany;
+import javax.persistence.Version;
+
+import org.hibernate.search.annotations.Field;
+import org.hibernate.search.annotations.Indexed;
+import org.hibernate.search.annotations.IndexedEmbedded;
+import org.hibernate.search.annotations.Store;
+
+/**
+ * @author Emmanuel Bernard
+ */
+@Indexed
+@Entity
+public class HelpItem {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.AUTO)
+ private Long id;
+
+ @Version()
+ private Long version;
+
+ @Field(index = org.hibernate.search.annotations.Index.TOKENIZED, store = Store.NO)
+ private String title;
+
+ @OneToMany(fetch = FetchType.LAZY, mappedBy = "helpItem")
+ @IndexedEmbedded
+ private List<HelpItemTag> tags;
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public Long getVersion() {
+ return version;
+ }
+
+ public void setVersion(Long version) {
+ this.version = version;
+ }
+
+ public String getTitle() {
+ return title;
+ }
+
+ public void setTitle(String title) {
+ this.title = title;
+ }
+
+ public List<HelpItemTag> getTags() {
+ if ( tags == null ) {
+ tags = new ArrayList<HelpItemTag>();
+ }
+ return tags;
+ }
+
+ public void setTags(List<HelpItemTag> tags) {
+ this.tags = tags;
+ }
+}
\ No newline at end of file
Added: search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/embedded/nested/containedIn/HelpItemTag.java
===================================================================
--- search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/embedded/nested/containedIn/HelpItemTag.java (rev 0)
+++ search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/embedded/nested/containedIn/HelpItemTag.java 2010-04-07 13:48:43 UTC (rev 19181)
@@ -0,0 +1,71 @@
+package org.hibernate.search.test.embedded.nested.containedIn;
+
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.Version;
+
+import org.hibernate.search.annotations.ContainedIn;
+import org.hibernate.search.annotations.IndexedEmbedded;
+
+/**
+ * @author Emmanuel Bernard
+ */
+@Entity
+public class HelpItemTag {
+
+ private static final long serialVersionUID = 1L;
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.AUTO)
+ private Long id;
+
+ @Version
+ private Long version;
+
+ @ManyToOne(fetch = FetchType.LAZY)
+ @JoinColumn(name = "helpItem", nullable = false)
+ @ContainedIn
+ private HelpItem helpItem;
+
+ @ManyToOne(fetch = FetchType.LAZY)
+ @JoinColumn(name = "tag", nullable = false)
+ @IndexedEmbedded
+ private Tag tag;
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public Long getVersion() {
+ return version;
+ }
+
+ public void setVersion(Long version) {
+ this.version = version;
+ }
+
+ public HelpItem getHelpItem() {
+ return helpItem;
+ }
+
+ public void setHelpItem(HelpItem helpItem) {
+ this.helpItem = helpItem;
+ }
+
+ public Tag getTag() {
+ return tag;
+ }
+
+ public void setTag(Tag tag) {
+ this.tag = tag;
+ }
+}
Added: search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/embedded/nested/containedIn/NestedContainedInTest.java
===================================================================
--- search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/embedded/nested/containedIn/NestedContainedInTest.java (rev 0)
+++ search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/embedded/nested/containedIn/NestedContainedInTest.java 2010-04-07 13:48:43 UTC (rev 19181)
@@ -0,0 +1,89 @@
+package org.hibernate.search.test.embedded.nested.containedIn;
+
+import org.apache.lucene.index.Term;
+import org.apache.lucene.search.Query;
+import org.apache.lucene.search.TermQuery;
+
+import org.hibernate.Transaction;
+import org.hibernate.search.FullTextQuery;
+import org.hibernate.search.FullTextSession;
+import org.hibernate.search.Search;
+import org.hibernate.search.test.SearchTestCase;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class NestedContainedInTest extends SearchTestCase {
+
+ public void testAddHelpItem() {
+ String tagName = "animal";
+ createHelpItem( tagName );
+ openSession( );
+ doQuery( tagName );
+ session.close();
+ }
+
+ public void testChangeTagName() {
+
+ String tagName = "animal";
+ createHelpItem( tagName );
+
+ openSession( );
+ HelpItem check = doQuery( tagName );
+
+ Tag tag = check.getTags().get( 0 ).getTag();
+
+ Transaction tx = session.beginTransaction();
+ String newTagName = "automobile";
+ tag.setName( newTagName );
+ session.saveOrUpdate( tag );
+ tx.commit();
+
+ doQuery( newTagName );
+ session.close();
+ }
+
+ private void createHelpItem(String tagName) {
+ openSession( );
+ Transaction tx = session.beginTransaction();
+ HelpItem helpItem = new HelpItem();
+ helpItem.setTitle( "The quick brown fox jumps over the lazy dog." );
+
+ Tag tag = new Tag();
+ tag.setName( tagName );
+
+ HelpItemTag helpItemTag = new HelpItemTag();
+ helpItemTag.setHelpItem( helpItem );
+ helpItemTag.setTag( tag );
+
+ helpItem.getTags().add( helpItemTag );
+ tag.getHelpItems().add( helpItemTag );
+
+ session.save( helpItem );
+ session.save( tag );
+ session.save( helpItemTag );
+
+ tx.commit();
+ session.close();
+ }
+
+ private HelpItem doQuery(String tagName) {
+ FullTextSession fullTextSession = Search.getFullTextSession( session );
+ Query termQuery = new TermQuery( new Term( "tags.tag.name", tagName ) );
+ FullTextQuery fullTextQuery =
+ fullTextSession.createFullTextQuery( termQuery, HelpItem.class );
+ HelpItem check = ( HelpItem ) fullTextQuery.uniqueResult();
+ assertNotNull( "No HelpItem with Tag '" + tagName + "' found in Lucene index.", check );
+ assertTrue( check.getTags().get( 0 ).getTag().getName().equals( tagName ) );
+ return check;
+ }
+
+ @Override
+ protected Class<?>[] getMappings() {
+ return new Class<?>[] {
+ HelpItem.class,
+ HelpItemTag.class,
+ Tag.class
+ };
+ }
+}
Added: search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/embedded/nested/containedIn/Tag.java
===================================================================
--- search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/embedded/nested/containedIn/Tag.java (rev 0)
+++ search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/embedded/nested/containedIn/Tag.java 2010-04-07 13:48:43 UTC (rev 19181)
@@ -0,0 +1,76 @@
+package org.hibernate.search.test.embedded.nested.containedIn;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.OneToMany;
+import javax.persistence.Version;
+
+import org.hibernate.search.annotations.Boost;
+import org.hibernate.search.annotations.ContainedIn;
+import org.hibernate.search.annotations.Field;
+import org.hibernate.search.annotations.Store;
+
+/**
+ * @author Emmanuel Bernard
+ */
+@Entity
+public class Tag {
+ @Id
+ @GeneratedValue(strategy = GenerationType.AUTO)
+ private Long id;
+
+ @Version
+ private Long version;
+
+ @Column(nullable = false, length = 50)
+ @Field(index = org.hibernate.search.annotations.Index.TOKENIZED, store = Store.NO)
+ @Boost(1.5f)
+ private String name;
+
+ @OneToMany(fetch = FetchType.LAZY, mappedBy = "tag")
+ @ContainedIn
+ private List<HelpItemTag> helpItems;
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public Long getVersion() {
+ return version;
+ }
+
+ public void setVersion(Long version) {
+ this.version = version;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public List<HelpItemTag> getHelpItems() {
+ if ( helpItems == null ) {
+ helpItems = new ArrayList<HelpItemTag>();
+ }
+ return helpItems;
+ }
+
+ public void setHelpItems(List<HelpItemTag> helpItems) {
+ this.helpItems = helpItems;
+ }
+
+}
14 years, 2 months
Hibernate SVN: r19180 - in core/trunk/envers/src: main/java/org/hibernate/envers/event and 3 other directories.
by hibernate-commits@lists.jboss.org
Author: adamw
Date: 2010-04-06 16:35:15 -0400 (Tue, 06 Apr 2010)
New Revision: 19180
Added:
core/trunk/envers/src/main/java/org/hibernate/envers/synchronization/AuditProcess.java
core/trunk/envers/src/main/java/org/hibernate/envers/synchronization/AuditProcessManager.java
Removed:
core/trunk/envers/src/main/java/org/hibernate/envers/synchronization/AuditSync.java
core/trunk/envers/src/main/java/org/hibernate/envers/synchronization/AuditSyncManager.java
Modified:
core/trunk/envers/src/main/java/org/hibernate/envers/configuration/AuditConfiguration.java
core/trunk/envers/src/main/java/org/hibernate/envers/event/AuditEventListener.java
core/trunk/envers/src/main/java/org/hibernate/envers/reader/AuditReaderImpl.java
core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/reventity/ExceptionListener.java
Log:
HHH-3543: using BeforeTransactionCompletionProcess instead of a transaction synchronization. That way exceptions are not swallowed if one is thrown in the audit synchronization/process, and the tx is rolled back
Modified: core/trunk/envers/src/main/java/org/hibernate/envers/configuration/AuditConfiguration.java
===================================================================
--- core/trunk/envers/src/main/java/org/hibernate/envers/configuration/AuditConfiguration.java 2010-04-06 20:34:27 UTC (rev 19179)
+++ core/trunk/envers/src/main/java/org/hibernate/envers/configuration/AuditConfiguration.java 2010-04-06 20:35:15 UTC (rev 19180)
@@ -30,7 +30,7 @@
import org.hibernate.envers.entities.EntitiesConfigurations;
import org.hibernate.envers.revisioninfo.RevisionInfoNumberReader;
import org.hibernate.envers.revisioninfo.RevisionInfoQueryCreator;
-import org.hibernate.envers.synchronization.AuditSyncManager;
+import org.hibernate.envers.synchronization.AuditProcessManager;
import org.hibernate.cfg.Configuration;
import org.hibernate.cfg.AnnotationConfiguration;
@@ -42,7 +42,7 @@
public class AuditConfiguration {
private final GlobalConfiguration globalCfg;
private final AuditEntitiesConfiguration auditEntCfg;
- private final AuditSyncManager auditSyncManager;
+ private final AuditProcessManager auditProcessManager;
private final EntitiesConfigurations entCfg;
private final RevisionInfoQueryCreator revisionInfoQueryCreator;
private final RevisionInfoNumberReader revisionInfoNumberReader;
@@ -51,8 +51,8 @@
return auditEntCfg;
}
- public AuditSyncManager getSyncManager() {
- return auditSyncManager;
+ public AuditProcessManager getSyncManager() {
+ return auditProcessManager;
}
public GlobalConfiguration getGlobalCfg() {
@@ -80,7 +80,7 @@
RevisionInfoConfigurationResult revInfoCfgResult = revInfoCfg.configure(cfg, reflectionManager);
auditEntCfg = new AuditEntitiesConfiguration(properties, revInfoCfgResult.getRevisionInfoEntityName());
globalCfg = new GlobalConfiguration(properties);
- auditSyncManager = new AuditSyncManager(revInfoCfgResult.getRevisionInfoGenerator());
+ auditProcessManager = new AuditProcessManager(revInfoCfgResult.getRevisionInfoGenerator());
revisionInfoQueryCreator = revInfoCfgResult.getRevisionInfoQueryCreator();
revisionInfoNumberReader = revInfoCfgResult.getRevisionInfoNumberReader();
entCfg = new EntitiesConfigurator().configure(cfg, reflectionManager, globalCfg, auditEntCfg,
Modified: core/trunk/envers/src/main/java/org/hibernate/envers/event/AuditEventListener.java
===================================================================
--- core/trunk/envers/src/main/java/org/hibernate/envers/event/AuditEventListener.java 2010-04-06 20:34:27 UTC (rev 19179)
+++ core/trunk/envers/src/main/java/org/hibernate/envers/event/AuditEventListener.java 2010-04-06 20:35:15 UTC (rev 19180)
@@ -31,7 +31,7 @@
import org.hibernate.envers.entities.RelationType;
import org.hibernate.envers.entities.mapper.PersistentCollectionChangeData;
import org.hibernate.envers.entities.mapper.id.IdMapper;
-import org.hibernate.envers.synchronization.AuditSync;
+import org.hibernate.envers.synchronization.AuditProcess;
import org.hibernate.envers.synchronization.work.*;
import org.hibernate.envers.tools.Tools;
import org.hibernate.envers.RevisionType;
@@ -68,7 +68,7 @@
private AuditConfiguration verCfg;
- private void generateBidirectionalCollectionChangeWorkUnits(AuditSync verSync, EntityPersister entityPersister,
+ private void generateBidirectionalCollectionChangeWorkUnits(AuditProcess auditProcess, EntityPersister entityPersister,
String entityName, Object[] newState, Object[] oldState,
SessionImplementor session) {
// Checking if this is enabled in configuration ...
@@ -112,7 +112,7 @@
id = (Serializable) idMapper.mapToIdFromEntity(newValue);
}
- verSync.addWorkUnit(new CollectionChangeWorkUnit(session, toEntityName, verCfg, id, newValue));
+ auditProcess.addWorkUnit(new CollectionChangeWorkUnit(session, toEntityName, verCfg, id, newValue));
}
if (oldValue != null) {
@@ -132,7 +132,7 @@
id = (Serializable) idMapper.mapToIdFromEntity(oldValue);
}
- verSync.addWorkUnit(new CollectionChangeWorkUnit(session, toEntityName, verCfg, id, oldValue));
+ auditProcess.addWorkUnit(new CollectionChangeWorkUnit(session, toEntityName, verCfg, id, oldValue));
}
}
}
@@ -143,14 +143,14 @@
String entityName = event.getPersister().getEntityName();
if (verCfg.getEntCfg().isVersioned(entityName)) {
- AuditSync verSync = verCfg.getSyncManager().get(event.getSession());
+ AuditProcess auditProcess = verCfg.getSyncManager().get(event.getSession());
AuditWorkUnit workUnit = new AddWorkUnit(event.getSession(), event.getPersister().getEntityName(), verCfg,
event.getId(), event.getPersister(), event.getState());
- verSync.addWorkUnit(workUnit);
+ auditProcess.addWorkUnit(workUnit);
if (workUnit.containsWork()) {
- generateBidirectionalCollectionChangeWorkUnits(verSync, event.getPersister(), entityName, event.getState(),
+ generateBidirectionalCollectionChangeWorkUnits(auditProcess, event.getPersister(), entityName, event.getState(),
null, event.getSession());
}
}
@@ -160,14 +160,14 @@
String entityName = event.getPersister().getEntityName();
if (verCfg.getEntCfg().isVersioned(entityName)) {
- AuditSync verSync = verCfg.getSyncManager().get(event.getSession());
+ AuditProcess auditProcess = verCfg.getSyncManager().get(event.getSession());
AuditWorkUnit workUnit = new ModWorkUnit(event.getSession(), event.getPersister().getEntityName(), verCfg,
event.getId(), event.getPersister(), event.getState(), event.getOldState());
- verSync.addWorkUnit(workUnit);
+ auditProcess.addWorkUnit(workUnit);
if (workUnit.containsWork()) {
- generateBidirectionalCollectionChangeWorkUnits(verSync, event.getPersister(), entityName, event.getState(),
+ generateBidirectionalCollectionChangeWorkUnits(auditProcess, event.getPersister(), entityName, event.getState(),
event.getOldState(), event.getSession());
}
}
@@ -177,20 +177,20 @@
String entityName = event.getPersister().getEntityName();
if (verCfg.getEntCfg().isVersioned(entityName)) {
- AuditSync verSync = verCfg.getSyncManager().get(event.getSession());
+ AuditProcess auditProcess = verCfg.getSyncManager().get(event.getSession());
AuditWorkUnit workUnit = new DelWorkUnit(event.getSession(), event.getPersister().getEntityName(), verCfg,
event.getId(), event.getPersister(), event.getDeletedState());
- verSync.addWorkUnit(workUnit);
+ auditProcess.addWorkUnit(workUnit);
if (workUnit.containsWork()) {
- generateBidirectionalCollectionChangeWorkUnits(verSync, event.getPersister(), entityName, null,
+ generateBidirectionalCollectionChangeWorkUnits(auditProcess, event.getPersister(), entityName, null,
event.getDeletedState(), event.getSession());
}
}
}
- private void generateBidirectionalCollectionChangeWorkUnits(AuditSync verSync, AbstractCollectionEvent event,
+ private void generateBidirectionalCollectionChangeWorkUnits(AuditProcess auditProcess, AbstractCollectionEvent event,
PersistentCollectionChangeWorkUnit workUnit,
RelationDescription rd) {
// Checking if this is enabled in configuration ...
@@ -209,13 +209,13 @@
Object relatedObj = changeData.getChangedElement();
Serializable relatedId = (Serializable) relatedIdMapper.mapToIdFromEntity(relatedObj);
- verSync.addWorkUnit(new CollectionChangeWorkUnit(event.getSession(), relatedEntityName, verCfg,
+ auditProcess.addWorkUnit(new CollectionChangeWorkUnit(event.getSession(), relatedEntityName, verCfg,
relatedId, relatedObj));
}
}
}
- private void generateFakeBidirecationalRelationWorkUnits(AuditSync verSync, PersistentCollection newColl, Serializable oldColl,
+ private void generateFakeBidirecationalRelationWorkUnits(AuditProcess auditProcess, PersistentCollection newColl, Serializable oldColl,
String collectionEntityName, String referencingPropertyName,
AbstractCollectionEvent event,
RelationDescription rd) {
@@ -242,13 +242,13 @@
AuditWorkUnit nestedWorkUnit = new CollectionChangeWorkUnit(event.getSession(), realRelatedEntityName, verCfg,
relatedId, relatedObj);
- verSync.addWorkUnit(new FakeBidirectionalRelationWorkUnit(event.getSession(), realRelatedEntityName, verCfg,
+ auditProcess.addWorkUnit(new FakeBidirectionalRelationWorkUnit(event.getSession(), realRelatedEntityName, verCfg,
relatedId, referencingPropertyName, event.getAffectedOwnerOrNull(), rd, revType,
changeData.getChangedElementIndex(), nestedWorkUnit));
}
// We also have to generate a collection change work unit for the owning entity.
- verSync.addWorkUnit(new CollectionChangeWorkUnit(event.getSession(), collectionEntityName, verCfg,
+ auditProcess.addWorkUnit(new CollectionChangeWorkUnit(event.getSession(), collectionEntityName, verCfg,
event.getAffectedOwnerIdOrNull(), event.getAffectedOwnerOrNull()));
}
@@ -257,7 +257,7 @@
String entityName = event.getAffectedOwnerEntityName();
if (verCfg.getEntCfg().isVersioned(entityName)) {
- AuditSync verSync = verCfg.getSyncManager().get(event.getSession());
+ AuditProcess auditProcess = verCfg.getSyncManager().get(event.getSession());
String ownerEntityName = ((AbstractCollectionPersister) collectionEntry.getLoadedPersister()).getOwnerEntityName();
String referencingPropertyName = collectionEntry.getRole().substring(ownerEntityName.length() + 1);
@@ -266,20 +266,20 @@
// null in case of collections of non-entities.
RelationDescription rd = verCfg.getEntCfg().get(entityName).getRelationDescription(referencingPropertyName);
if (rd != null && rd.getMappedByPropertyName() != null) {
- generateFakeBidirecationalRelationWorkUnits(verSync, newColl, oldColl, entityName,
+ generateFakeBidirecationalRelationWorkUnits(auditProcess, newColl, oldColl, entityName,
referencingPropertyName, event, rd);
} else {
PersistentCollectionChangeWorkUnit workUnit = new PersistentCollectionChangeWorkUnit(event.getSession(),
entityName, verCfg, newColl, collectionEntry, oldColl, event.getAffectedOwnerIdOrNull(),
referencingPropertyName);
- verSync.addWorkUnit(workUnit);
+ auditProcess.addWorkUnit(workUnit);
if (workUnit.containsWork()) {
// There are some changes: a revision needs also be generated for the collection owner
- verSync.addWorkUnit(new CollectionChangeWorkUnit(event.getSession(), event.getAffectedOwnerEntityName(),
+ auditProcess.addWorkUnit(new CollectionChangeWorkUnit(event.getSession(), event.getAffectedOwnerEntityName(),
verCfg, event.getAffectedOwnerIdOrNull(), event.getAffectedOwnerOrNull()));
- generateBidirectionalCollectionChangeWorkUnits(verSync, event, workUnit, rd);
+ generateBidirectionalCollectionChangeWorkUnits(auditProcess, event, workUnit, rd);
}
}
}
Modified: core/trunk/envers/src/main/java/org/hibernate/envers/reader/AuditReaderImpl.java
===================================================================
--- core/trunk/envers/src/main/java/org/hibernate/envers/reader/AuditReaderImpl.java 2010-04-06 20:34:27 UTC (rev 19179)
+++ core/trunk/envers/src/main/java/org/hibernate/envers/reader/AuditReaderImpl.java 2010-04-06 20:35:15 UTC (rev 19180)
@@ -35,8 +35,9 @@
import org.hibernate.envers.query.AuditQueryCreator;
import static org.hibernate.envers.tools.ArgumentsTools.checkNotNull;
import static org.hibernate.envers.tools.ArgumentsTools.checkPositive;
-import org.hibernate.envers.synchronization.AuditSync;
+import org.hibernate.envers.synchronization.AuditProcess;
+
import org.hibernate.NonUniqueResultException;
import org.hibernate.Query;
import org.hibernate.Session;
@@ -201,10 +202,10 @@
}
// Obtaining the current audit sync
- AuditSync auditSync = verCfg.getSyncManager().get((EventSource) session);
+ AuditProcess auditProcess = verCfg.getSyncManager().get((EventSource) session);
// And getting the current revision data
- return (T) auditSync.getCurrentRevisionData(session, persist);
+ return (T) auditProcess.getCurrentRevisionData(session, persist);
}
public AuditQueryCreator createQuery() {
Copied: core/trunk/envers/src/main/java/org/hibernate/envers/synchronization/AuditProcess.java (from rev 19150, core/trunk/envers/src/main/java/org/hibernate/envers/synchronization/AuditSync.java)
===================================================================
--- core/trunk/envers/src/main/java/org/hibernate/envers/synchronization/AuditProcess.java (rev 0)
+++ core/trunk/envers/src/main/java/org/hibernate/envers/synchronization/AuditProcess.java 2010-04-06 20:35:15 UTC (rev 19180)
@@ -0,0 +1,156 @@
+/*
+ * 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.envers.synchronization;
+
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.Map;
+import java.util.Queue;
+
+import org.hibernate.action.BeforeTransactionCompletionProcess;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.envers.revisioninfo.RevisionInfoGenerator;
+import org.hibernate.envers.synchronization.work.AuditWorkUnit;
+import org.hibernate.envers.tools.Pair;
+
+import org.hibernate.FlushMode;
+import org.hibernate.Session;
+
+/**
+ * @author Adam Warski (adam at warski dot org)
+ */
+public class AuditProcess implements BeforeTransactionCompletionProcess {
+ private final RevisionInfoGenerator revisionInfoGenerator;
+
+ private final LinkedList<AuditWorkUnit> workUnits;
+ private final Queue<AuditWorkUnit> undoQueue;
+ private final Map<Pair<String, Object>, AuditWorkUnit> usedIds;
+
+ private Object revisionData;
+
+ public AuditProcess(RevisionInfoGenerator revisionInfoGenerator) {
+ this.revisionInfoGenerator = revisionInfoGenerator;
+
+ workUnits = new LinkedList<AuditWorkUnit>();
+ undoQueue = new LinkedList<AuditWorkUnit>();
+ usedIds = new HashMap<Pair<String, Object>, AuditWorkUnit>();
+ }
+
+ private void removeWorkUnit(AuditWorkUnit vwu) {
+ workUnits.remove(vwu);
+ if (vwu.isPerformed()) {
+ // If this work unit has already been performed, it must be deleted (undone) first.
+ undoQueue.offer(vwu);
+ }
+ }
+
+ public void addWorkUnit(AuditWorkUnit vwu) {
+ if (vwu.containsWork()) {
+ Object entityId = vwu.getEntityId();
+
+ if (entityId == null) {
+ // Just adding the work unit - it's not associated with any persistent entity.
+ workUnits.offer(vwu);
+ } else {
+ String entityName = vwu.getEntityName();
+ Pair<String, Object> usedIdsKey = Pair.make(entityName, entityId);
+
+ if (usedIds.containsKey(usedIdsKey)) {
+ AuditWorkUnit other = usedIds.get(usedIdsKey);
+
+ AuditWorkUnit result = vwu.dispatch(other);
+
+ if (result != other) {
+ removeWorkUnit(other);
+
+ if (result != null) {
+ usedIds.put(usedIdsKey, result);
+ workUnits.offer(result);
+ } // else: a null result means that no work unit should be kept
+ } // else: the result is the same as the work unit already added. No need to do anything.
+ } else {
+ usedIds.put(usedIdsKey, vwu);
+ workUnits.offer(vwu);
+ }
+ }
+ }
+ }
+
+ private void executeInSession(Session session) {
+ // Making sure the revision data is persisted.
+ getCurrentRevisionData(session, true);
+
+ AuditWorkUnit vwu;
+
+ // First undoing any performed work units
+ while ((vwu = undoQueue.poll()) != null) {
+ vwu.undo(session);
+ }
+
+ while ((vwu = workUnits.poll()) != null) {
+ vwu.perform(session, revisionData);
+ }
+ }
+
+ public Object getCurrentRevisionData(Session session, boolean persist) {
+ // Generating the revision data if not yet generated
+ if (revisionData == null) {
+ revisionData = revisionInfoGenerator.generate();
+ }
+
+ // Saving the revision data, if not yet saved and persist is true
+ if (!session.contains(revisionData) && persist) {
+ revisionInfoGenerator.saveRevisionData(session, revisionData);
+ }
+
+ return revisionData;
+ }
+
+ public void doBeforeTransactionCompletion(SessionImplementor session) {
+ if (workUnits.size() == 0 && undoQueue.size() == 0) {
+ return;
+ }
+
+ // see: http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4178431
+ if (FlushMode.isManualFlushMode(session.getFlushMode())) {
+ Session temporarySession = null;
+ try {
+ temporarySession = session.getFactory().openTemporarySession();
+
+ executeInSession(temporarySession);
+
+ temporarySession.flush();
+ } finally {
+ if (temporarySession != null) {
+ temporarySession.close();
+ }
+ }
+ } else {
+ executeInSession((Session) session);
+
+ // Explicity flushing the session, as the auto-flush may have already happened.
+ session.flush();
+ }
+ }
+}
Copied: core/trunk/envers/src/main/java/org/hibernate/envers/synchronization/AuditProcessManager.java (from rev 19150, core/trunk/envers/src/main/java/org/hibernate/envers/synchronization/AuditSyncManager.java)
===================================================================
--- core/trunk/envers/src/main/java/org/hibernate/envers/synchronization/AuditProcessManager.java (rev 0)
+++ core/trunk/envers/src/main/java/org/hibernate/envers/synchronization/AuditProcessManager.java 2010-04-06 20:35:15 UTC (rev 19180)
@@ -0,0 +1,68 @@
+/*
+ * 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.envers.synchronization;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.hibernate.action.AfterTransactionCompletionProcess;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.envers.revisioninfo.RevisionInfoGenerator;
+
+import org.hibernate.Transaction;
+import org.hibernate.event.EventSource;
+
+/**
+ * @author Adam Warski (adam at warski dot org)
+ */
+public class AuditProcessManager {
+ private final Map<Transaction, AuditProcess> auditProcesses;
+ private final RevisionInfoGenerator revisionInfoGenerator;
+
+ public AuditProcessManager(RevisionInfoGenerator revisionInfoGenerator) {
+ auditProcesses = new ConcurrentHashMap<Transaction, AuditProcess>();
+
+ this.revisionInfoGenerator = revisionInfoGenerator;
+ }
+
+ public AuditProcess get(EventSource session) {
+ final Transaction transaction = session.getTransaction();
+
+ AuditProcess auditProcess = auditProcesses.get(transaction);
+ if (auditProcess == null) {
+ // No worries about registering a transaction twice - a transaction is single thread
+ auditProcess = new AuditProcess(revisionInfoGenerator);
+ auditProcesses.put(transaction, auditProcess);
+
+ session.getActionQueue().registerProcess(auditProcess);
+ session.getActionQueue().registerProcess(new AfterTransactionCompletionProcess() {
+ public void doAfterTransactionCompletion(boolean success, SessionImplementor session) {
+ auditProcesses.remove(transaction);
+ }
+ });
+ }
+
+ return auditProcess;
+ }
+}
Deleted: core/trunk/envers/src/main/java/org/hibernate/envers/synchronization/AuditSync.java
===================================================================
--- core/trunk/envers/src/main/java/org/hibernate/envers/synchronization/AuditSync.java 2010-04-06 20:34:27 UTC (rev 19179)
+++ core/trunk/envers/src/main/java/org/hibernate/envers/synchronization/AuditSync.java 2010-04-06 20:35:15 UTC (rev 19180)
@@ -1,180 +0,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
- */
-package org.hibernate.envers.synchronization;
-
-import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.Map;
-import java.util.Queue;
-import javax.transaction.Synchronization;
-
-import org.hibernate.envers.revisioninfo.RevisionInfoGenerator;
-import org.hibernate.envers.synchronization.work.AuditWorkUnit;
-import org.hibernate.envers.tools.Pair;
-
-import org.hibernate.FlushMode;
-import org.hibernate.Session;
-import org.hibernate.Transaction;
-import org.hibernate.event.EventSource;
-
-/**
- * @author Adam Warski (adam at warski dot org)
- */
-public class AuditSync implements Synchronization {
- private final RevisionInfoGenerator revisionInfoGenerator;
- private final AuditSyncManager manager;
- private final EventSource session;
-
- private final Transaction transaction;
- private final LinkedList<AuditWorkUnit> workUnits;
- private final Queue<AuditWorkUnit> undoQueue;
- private final Map<Pair<String, Object>, AuditWorkUnit> usedIds;
-
- private Object revisionData;
-
- public AuditSync(AuditSyncManager manager, EventSource session, RevisionInfoGenerator revisionInfoGenerator) {
- this.manager = manager;
- this.session = session;
- this.revisionInfoGenerator = revisionInfoGenerator;
-
- transaction = session.getTransaction();
- workUnits = new LinkedList<AuditWorkUnit>();
- undoQueue = new LinkedList<AuditWorkUnit>();
- usedIds = new HashMap<Pair<String, Object>, AuditWorkUnit>();
- }
-
- private void removeWorkUnit(AuditWorkUnit vwu) {
- workUnits.remove(vwu);
- if (vwu.isPerformed()) {
- // If this work unit has already been performed, it must be deleted (undone) first.
- undoQueue.offer(vwu);
- }
- }
-
- public void addWorkUnit(AuditWorkUnit vwu) {
- if (vwu.containsWork()) {
- Object entityId = vwu.getEntityId();
-
- if (entityId == null) {
- // Just adding the work unit - it's not associated with any persistent entity.
- workUnits.offer(vwu);
- } else {
- String entityName = vwu.getEntityName();
- Pair<String, Object> usedIdsKey = Pair.make(entityName, entityId);
-
- if (usedIds.containsKey(usedIdsKey)) {
- AuditWorkUnit other = usedIds.get(usedIdsKey);
-
- AuditWorkUnit result = vwu.dispatch(other);
-
- if (result != other) {
- removeWorkUnit(other);
-
- if (result != null) {
- usedIds.put(usedIdsKey, result);
- workUnits.offer(result);
- } // else: a null result means that no work unit should be kept
- } // else: the result is the same as the work unit already added. No need to do anything.
- } else {
- usedIds.put(usedIdsKey, vwu);
- workUnits.offer(vwu);
- }
- }
- }
- }
-
- private void executeInSession(Session session) {
- // Making sure the revision data is persisted.
- getCurrentRevisionData(session, true);
-
- AuditWorkUnit vwu;
-
- // First undoing any performed work units
- while ((vwu = undoQueue.poll()) != null) {
- vwu.undo(session);
- }
-
- while ((vwu = workUnits.poll()) != null) {
- vwu.perform(session, revisionData);
- }
- }
-
- public Object getCurrentRevisionData(Session session, boolean persist) {
- // Generating the revision data if not yet generated
- if (revisionData == null) {
- revisionData = revisionInfoGenerator.generate();
- }
-
- // Saving the revision data, if not yet saved and persist is true
- if (!session.contains(revisionData) && persist) {
- revisionInfoGenerator.saveRevisionData(session, revisionData);
- }
-
- return revisionData;
- }
-
- public void beforeCompletion() {
- if (workUnits.size() == 0 && undoQueue.size() == 0) {
- return;
- }
-
- try {
- // see: http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4178431
- if (FlushMode.isManualFlushMode(session.getFlushMode()) || session.isClosed()) {
- Session temporarySession = null;
- try {
- temporarySession = session.getFactory().openTemporarySession();
-
- executeInSession(temporarySession);
-
- temporarySession.flush();
- } finally {
- if (temporarySession != null) {
- temporarySession.close();
- }
- }
- } else {
- executeInSession(session);
-
- // Explicity flushing the session, as the auto-flush may have already happened.
- session.flush();
- }
- } catch (RuntimeException e) {
- // Rolling back the transaction in case of any exceptions
- //noinspection finally
- try {
- if (session.getTransaction().isActive()) {
- session.getTransaction().rollback();
- }
- } finally {
- //noinspection ThrowFromFinallyBlock
- throw e;
- }
- }
- }
-
- public void afterCompletion(int i) {
- manager.remove(transaction);
- }
-}
Deleted: core/trunk/envers/src/main/java/org/hibernate/envers/synchronization/AuditSyncManager.java
===================================================================
--- core/trunk/envers/src/main/java/org/hibernate/envers/synchronization/AuditSyncManager.java 2010-04-06 20:34:27 UTC (rev 19179)
+++ core/trunk/envers/src/main/java/org/hibernate/envers/synchronization/AuditSyncManager.java 2010-04-06 20:35:15 UTC (rev 19180)
@@ -1,65 +0,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
- */
-package org.hibernate.envers.synchronization;
-
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-
-import org.hibernate.envers.revisioninfo.RevisionInfoGenerator;
-
-import org.hibernate.Transaction;
-import org.hibernate.event.EventSource;
-
-/**
- * @author Adam Warski (adam at warski dot org)
- */
-public class AuditSyncManager {
- private final Map<Transaction, AuditSync> auditSyncs;
- private final RevisionInfoGenerator revisionInfoGenerator;
-
- public AuditSyncManager(RevisionInfoGenerator revisionInfoGenerator) {
- auditSyncs = new ConcurrentHashMap<Transaction, AuditSync>();
-
- this.revisionInfoGenerator = revisionInfoGenerator;
- }
-
- public AuditSync get(EventSource session) {
- Transaction transaction = session.getTransaction();
-
- AuditSync verSync = auditSyncs.get(transaction);
- if (verSync == null) {
- // No worries about registering a transaction twice - a transaction is single thread
- verSync = new AuditSync(this, session, revisionInfoGenerator);
- auditSyncs.put(transaction, verSync);
-
- transaction.registerSynchronization(verSync);
- }
-
- return verSync;
- }
-
- public void remove(Transaction transaction) {
- auditSyncs.remove(transaction);
- }
-}
Modified: core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/reventity/ExceptionListener.java
===================================================================
--- core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/reventity/ExceptionListener.java 2010-04-06 20:34:27 UTC (rev 19179)
+++ core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/reventity/ExceptionListener.java 2010-04-06 20:35:15 UTC (rev 19180)
@@ -40,7 +40,7 @@
cfg.addAnnotatedClass(ExceptionListenerRevEntity.class);
}
- @Test
+ @Test(expectedExceptions = RuntimeException.class)
public void testTransactionRollback() throws InterruptedException {
// Trying to persist an entity - however the listener should throw an exception, so the entity
// shouldn't be persisted
@@ -49,9 +49,12 @@
StrTestEntity te = new StrTestEntity("x");
em.persist(te);
em.getTransaction().commit();
+ }
+ @Test(dependsOnMethods = "testTransactionRollback")
+ public void testDataNotPersisted() {
// Checking if the entity became persisted
- em = getEntityManager();
+ EntityManager em = getEntityManager();
em.getTransaction().begin();
Long count = (Long) em.createQuery("select count(s) from StrTestEntity s where s.str = 'x'").getSingleResult();
assert count == 0l;
14 years, 2 months
Hibernate SVN: r19179 - in search/trunk/hibernate-search/src: main/java/org/hibernate/search/exception/impl and 2 other directories.
by hibernate-commits@lists.jboss.org
Author: sannegrinovero
Date: 2010-04-06 16:34:27 -0400 (Tue, 06 Apr 2010)
New Revision: 19179
Removed:
search/trunk/hibernate-search/src/main/java/org/hibernate/search/exception/impl/RethrowErrorHandler.java
search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/errorhandling/RethrowErrorHandlingTest.java
Modified:
search/trunk/hibernate-search/src/main/docbook/en-US/modules/configuration.xml
search/trunk/hibernate-search/src/main/java/org/hibernate/search/impl/SearchFactoryImpl.java
Log:
HSEARCH-421 Exceptions happening in backend are unnoticed (Amin Mohammed-Coleman)
Modified: search/trunk/hibernate-search/src/main/docbook/en-US/modules/configuration.xml
===================================================================
--- search/trunk/hibernate-search/src/main/docbook/en-US/modules/configuration.xml 2010-04-06 18:29:09 UTC (rev 19178)
+++ search/trunk/hibernate-search/src/main/docbook/en-US/modules/configuration.xml 2010-04-06 20:34:27 UTC (rev 19179)
@@ -1160,4 +1160,46 @@
</section>
+
+ <section>
+ <title>Exception Handling Configuration</title>
+
+ <para>Hibernate Search allows you to configure how exceptions are handled
+ during the indexing process. If no configuration is provided then
+ exceptions are logged to the log output by default. It is possible to
+ explicitly declare the exception logging mechanism as seen below:</para>
+
+ <para><programlisting>hibernate.search.error_handler log</programlisting>The
+ default exception handling occurs for both synchronous and asynchronous
+ indexing. Hibernate Search provides an easy mechanism to override the
+ default error handling implementation.</para>
+
+ <para>In order to provide your own implementation you must implement the
+ <code>ErrorHandler</code> interface, which provides <code>handle (
+ ErrorContext context )</code> method. The <code>ErrorContext</code>
+ provides a reference to the primary <code>LuceneWork</code> that failed, the
+ underlying exception and any subsequent <code>LuceneWork</code> that could
+ not be processed due to the primary exception.</para>
+
+ <para><programlisting>public interface ErrorContext {
+ List<LuceneWork> getFailingOperations();
+ LuceneWork getOperationAtFault();
+ Throwable getThrowable();
+ boolean hasErrors();
+}</programlisting></para>
+
+ <para>The following provides an example implementation of
+ <code>ErrorHandler</code>:</para>
+
+ <para><programlisting>public class CustomErrorHandler implements ErrorHandler {
+ public void handle ( ErrorContext context ) {
+ ...
+ //publish error context to some internal error handling system
+ ...
+ }
+}</programlisting>To register this error handler with Hibernate Search you
+ must declare the <code>CustomErrorHandler</code> fully qualified classname
+ in the configuration properties:</para>
+ <para><programlisting>hibernate.search.error_handler CustomerErrorHandler</programlisting></para>
+ </section>
</chapter>
\ No newline at end of file
Deleted: search/trunk/hibernate-search/src/main/java/org/hibernate/search/exception/impl/RethrowErrorHandler.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/exception/impl/RethrowErrorHandler.java 2010-04-06 18:29:09 UTC (rev 19178)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/exception/impl/RethrowErrorHandler.java 2010-04-06 20:34:27 UTC (rev 19179)
@@ -1,45 +0,0 @@
-/* $Id$
- *
- * Hibernate, Relational Persistence for Idiomatic Java
- *
- * Copyright (c) 2009, Red Hat, Inc. and/or its affiliates 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, Inc.
- *
- * 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.search.exception.impl;
-
-import org.hibernate.search.SearchException;
-import org.hibernate.search.exception.ErrorHandler;
-
-/**
- * This ErrorHandler will throw the exceptions it caught,
- * appending some context to the exception message.
- *
- * @author Sanne Grinovero
- * @since 3.2
- */
-public class RethrowErrorHandler extends LogErrorHandler implements ErrorHandler {
-
- @Override
- protected void logError(String errorMsg, Throwable exceptionThatOccurred) {
- throw new SearchException( errorMsg, exceptionThatOccurred );
- }
-
-}
-
Modified: search/trunk/hibernate-search/src/main/java/org/hibernate/search/impl/SearchFactoryImpl.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/impl/SearchFactoryImpl.java 2010-04-06 18:29:09 UTC (rev 19178)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/impl/SearchFactoryImpl.java 2010-04-06 20:34:27 UTC (rev 19179)
@@ -92,7 +92,6 @@
import org.slf4j.Logger;
import org.hibernate.search.exception.ErrorHandler;
import org.hibernate.search.exception.impl.LogErrorHandler;
-import org.hibernate.search.exception.impl.RethrowErrorHandler;
/**
* @author Emmanuel Bernard
@@ -702,26 +701,11 @@
boolean sync = BatchedQueueingProcessor.isConfiguredAsSync( configuration );
String errorHandlerClassName = configuration.getProperty( Environment.ERROR_HANDLER );
if ( StringHelper.isEmpty( errorHandlerClassName ) ) {
- // default error handler depends on sync/async:
- if ( sync ) {
- return new RethrowErrorHandler();
- }
- else {
- return new LogErrorHandler();
- }
+ return new LogErrorHandler();
}
else if ( errorHandlerClassName.trim().equals( "log" ) ) {
return new LogErrorHandler();
}
- else if ( errorHandlerClassName.trim().equals( "rethrow" ) ) {
- if ( ! sync ) {
- // RethrowErrorHandler won't work when backend is async:
- throw new SearchException( "The \"rethrow\" ErrorHandler is not compatible with aync backend" );
- }
- else {
- return new RethrowErrorHandler();
- }
- }
else {
return PluginLoader.instanceFromName( ErrorHandler.class, errorHandlerClassName,
SearchFactoryImpl.class, "Error Handler" );
Deleted: search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/errorhandling/RethrowErrorHandlingTest.java
===================================================================
--- search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/errorhandling/RethrowErrorHandlingTest.java 2010-04-06 18:29:09 UTC (rev 19178)
+++ search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/errorhandling/RethrowErrorHandlingTest.java 2010-04-06 20:34:27 UTC (rev 19179)
@@ -1,82 +0,0 @@
-/* $Id$
- *
- * Hibernate, Relational Persistence for Idiomatic Java
- *
- * Copyright (c) 2009, Red Hat, Inc. and/or its affiliates 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, Inc.
- *
- * 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.search.test.errorhandling;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import junit.framework.Assert;
-
-import org.hibernate.search.Environment;
-import org.hibernate.search.SearchException;
-import org.hibernate.search.backend.BackendQueueProcessorFactory;
-import org.hibernate.search.backend.LuceneWork;
-import org.hibernate.search.exception.ErrorHandler;
-import org.hibernate.search.exception.impl.RethrowErrorHandler;
-import org.hibernate.search.impl.SearchFactoryImpl;
-
-/**
- * Verifies the RethrowErrorHandler is able to propagate exceptions back to the
- * committing thread.
- *
- * @author Sanne Grinovero
- */
-public class RethrowErrorHandlingTest extends LuceneErrorHandlingTest {
-
- @Override
- public void testErrorHandling(){
- SearchFactoryImpl searchFactoryImpl = getSearchFactoryImpl();
- ErrorHandler errorHandler = searchFactoryImpl.getErrorHandler();
- Assert.assertTrue( errorHandler instanceof RethrowErrorHandler );
- BackendQueueProcessorFactory queueProcessorFactory = searchFactoryImpl.getBackendQueueProcessorFactory();
- List<LuceneWork> queue = new ArrayList<LuceneWork>();
- queue.add( new HarmlessWork( "firstWork" ) );
- queue.add( new HarmlessWork( "secondWork" ) );
- Runnable processor = queueProcessorFactory.getProcessor( queue );
- workcounter.set( 0 ); // reset work counter
- processor.run();
- Assert.assertEquals( 2, workcounter.get() );
-
- workcounter.set( 0 ); // reset work counter
- queue.add( new FailingWork( "firstFailure" ) );
- queue.add( new HarmlessWork( "thirdWork" ) );
- queue.add( new HarmlessWork( "fourthWork" ) );
- processor = queueProcessorFactory.getProcessor( queue );
- try {
- processor.run();
- Assert.fail( "should have thrown a SearchException" );
- }
- catch (SearchException se) {
- //expected
- }
- }
-
- protected void configure(org.hibernate.cfg.Configuration cfg) {
- super.configure( cfg );
- cfg.setProperty( Environment.ERROR_HANDLER, "rethrow" );
- }
-
-}
-
14 years, 2 months