[hibernate-commits] Hibernate SVN: r20803 - in search/trunk/hibernate-search/src: test/java/org/hibernate/search/test/engine and 1 other directory.
hibernate-commits at lists.jboss.org
hibernate-commits at lists.jboss.org
Mon Oct 11 14:18:15 EDT 2010
Author: epbernard
Date: 2010-10-11 14:18:15 -0400 (Mon, 11 Oct 2010)
New Revision: 20803
Added:
search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/engine/TransactionSynchronizationTest.java
Modified:
search/trunk/hibernate-search/src/main/java/org/hibernate/search/backend/impl/EventSourceTransactionContext.java
Log:
HSEARCH-606 Do not register for tx synchronization on local tx
When the transaction is local (ie the TransactionManager is null - not great but I don't have a better approach atm), avoid registering the Synchronization event to the transaction and exclusively use the actionQueue.registerProcess.
Modified: search/trunk/hibernate-search/src/main/java/org/hibernate/search/backend/impl/EventSourceTransactionContext.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/backend/impl/EventSourceTransactionContext.java 2010-10-11 15:00:05 UTC (rev 20802)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/backend/impl/EventSourceTransactionContext.java 2010-10-11 18:18:15 UTC (rev 20803)
@@ -27,6 +27,7 @@
import java.io.Serializable;
import javax.transaction.Status;
import javax.transaction.Synchronization;
+import javax.transaction.TransactionManager;
import org.slf4j.Logger;
@@ -92,12 +93,19 @@
* In a JTA env, the before transaction completion is called before the flush, so not all changes are yet
* written. However, Synchronization-s do propagate exceptions, so they can be safely used.
*/
-
final ActionQueue actionQueue = eventSource.getActionQueue();
- actionQueue.registerProcess( new DelegateToSynchronizationOnBeforeTx( synchronization ) );
- eventSource.getTransaction().registerSynchronization(
- new BeforeCommitSynchronizationDelegator( synchronization )
- );
+ boolean isLocal = isLocalTransaction();
+ if ( isLocal ) {
+ //if local tx never use Synchronization
+ actionQueue.registerProcess( new DelegateToSynchronizationOnBeforeTx( synchronization ) );
+ }
+ else {
+ //TODO could we remove the action queue registration in this case?
+ actionQueue.registerProcess( new DelegateToSynchronizationOnBeforeTx( synchronization ) );
+ eventSource.getTransaction().registerSynchronization(
+ new BeforeCommitSynchronizationDelegator( synchronization )
+ );
+ }
//executed in all environments
actionQueue.registerProcess( new DelegateToSynchronizationOnAfterTx( synchronization ) );
@@ -116,7 +124,13 @@
}
}
}
-
+
+ private boolean isLocalTransaction() {
+ //TODO make it better but I don't know how we can optimize it.
+ final TransactionManager transactionManager = eventSource.getFactory().getTransactionManager();
+ return transactionManager == null;
+ }
+
private FullTextIndexEventListener getIndexWorkFlushEventListener() {
if ( this.flushListener != null) {
//for the "transient" case: might have been nullified.
Added: search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/engine/TransactionSynchronizationTest.java
===================================================================
--- search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/engine/TransactionSynchronizationTest.java (rev 0)
+++ search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/engine/TransactionSynchronizationTest.java 2010-10-11 18:18:15 UTC (rev 20803)
@@ -0,0 +1,67 @@
+package org.hibernate.search.test.engine;
+
+import org.hibernate.Transaction;
+import org.hibernate.search.FullTextSession;
+import org.hibernate.search.Search;
+import org.hibernate.search.annotations.Field;
+import org.hibernate.search.annotations.FieldBridge;
+import org.hibernate.search.annotations.Indexed;
+import org.hibernate.search.bridge.builtin.ClassBridge;
+import org.hibernate.search.test.SearchTestCase;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.Table;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class TransactionSynchronizationTest extends SearchTestCase {
+
+ public void testProperExceptionPropagation() throws Exception {
+ /**
+ * This test relies on the fact that a bridge accepting an incompatible type raise
+ * an exception when used.
+ */
+ FullTextSession fts = Search.getFullTextSession( openSession() );
+ boolean raised = false;
+ final Transaction transaction = fts.beginTransaction();
+ try {
+ Test test = new Test();
+ test.setIncorrectType("not a class");
+ fts.persist(test);
+ transaction.commit();
+ fail("An exception should have been raised");
+ }
+ catch (Exception e) {
+ //good
+ raised = true;
+ transaction.rollback();
+ }
+ assertTrue("An exception should have been raised", raised);
+ fts.close();
+ }
+
+ @Override
+ protected Class<?>[] getAnnotatedClasses() {
+ return new Class<?>[] {
+ Test.class
+ };
+ }
+
+ @Entity
+ @Indexed
+ @Table(name="Test007")
+ public static class Test {
+ @Id @GeneratedValue
+ public Integer getId() { return id; }
+ public void setId(Integer id) { this.id = id; }
+ private Integer id;
+
+ @Field(bridge = @FieldBridge(impl = ClassBridge.class))
+ public String getIncorrectType() { return incorrectType; }
+ public void setIncorrectType(String incorrectType) { this.incorrectType = incorrectType; }
+ private String incorrectType;
+ }
+}
More information about the hibernate-commits
mailing list