From 89eabb920dda69df83a60fa5d327017b4dbeb5a6 Mon Sep 17 00:00:00 2001
From: Gail Badner
Date: Wed, 23 Feb 2011 15:37:37 -0800
Subject: [PATCH 01/19] HHH-5957 : Provide a way for dialects to override a
SqlTypeDescriptor
---
.../java/org/hibernate/dialect/Dialect.java | 64 ++++++
.../hibernate/dialect/PostgreSQLDialect.java | 39 +++-
...AbstractSingleColumnStandardBasicType.java | 4 +
.../type/AbstractStandardBasicType.java | 16 +-
.../java/org/hibernate/type/BlobType.java | 2 +-
.../type/CharacterArrayClobType.java | 2 +-
.../java/org/hibernate/type/ClobType.java | 2 +-
.../hibernate/type/MaterializedBlobType.java | 2 +-
.../hibernate/type/MaterializedClobType.java | 2 +-
.../type/PrimitiveCharacterArrayClobType.java | 2 +-
.../hibernate/type/StandardBasicTypes.java | 91 ++++----
.../java/org/hibernate/type/TypeFactory.java | 4 +
.../java/org/hibernate/type/TypeResolver.java | 57 ++++-
.../type/WrappedMaterializedBlobType.java | 2 +-
.../type/descriptor/WrapperOptions.java | 4 +
.../descriptor/java/BlobTypeDescriptor.java | 12 +-
.../descriptor/java/ClobTypeDescriptor.java | 15 +-
.../descriptor/sql/BlobTypeDescriptor.java | 91 ++++++--
.../descriptor/sql/ClobTypeDescriptor.java | 68 ++++--
.../annotations/lob/MaterializedBlobTest.java | 2 +-
.../test/typeoverride/Entity.hbm.xml | 39 ++++
.../hibernate/test/typeoverride/Entity.java | 55 +++++
...ectOverridePrefixedVarcharSqlTypeDesc.java | 41 ++++
.../H2DialectOverrideVarcharSqlCode.java | 42 ++++
.../StoredPrefixedStringType.java | 105 +++++++++
.../test/typeoverride/TypeOverrideTest.java | 208 ++++++++++++++++++
.../sql/StringValueMappingTest.java | 8 +-
27 files changed, 883 insertions(+), 96 deletions(-)
create mode 100644 hibernate-core/src/test/java/org/hibernate/test/typeoverride/Entity.hbm.xml
create mode 100644 hibernate-core/src/test/java/org/hibernate/test/typeoverride/Entity.java
create mode 100644 hibernate-core/src/test/java/org/hibernate/test/typeoverride/H2DialectOverridePrefixedVarcharSqlTypeDesc.java
create mode 100644 hibernate-core/src/test/java/org/hibernate/test/typeoverride/H2DialectOverrideVarcharSqlCode.java
create mode 100644 hibernate-core/src/test/java/org/hibernate/test/typeoverride/StoredPrefixedStringType.java
create mode 100644 hibernate-core/src/test/java/org/hibernate/test/typeoverride/TypeOverrideTest.java
diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/Dialect.java b/hibernate-core/src/main/java/org/hibernate/dialect/Dialect.java
index 2a6023a362..09499f3fc9 100644
--- a/hibernate-core/src/main/java/org/hibernate/dialect/Dialect.java
+++ b/hibernate-core/src/main/java/org/hibernate/dialect/Dialect.java
@@ -67,6 +67,9 @@ import org.hibernate.sql.CaseFragment;
import org.hibernate.sql.ForUpdateFragment;
import org.hibernate.sql.JoinFragment;
import org.hibernate.type.StandardBasicTypes;
+import org.hibernate.type.descriptor.sql.BlobTypeDescriptor;
+import org.hibernate.type.descriptor.sql.ClobTypeDescriptor;
+import org.hibernate.type.descriptor.sql.SqlTypeDescriptor;
import org.hibernate.util.ReflectHelper;
import org.hibernate.util.StringHelper;
@@ -293,6 +296,67 @@ public abstract class Dialect {
typeNames.put( code, name );
}
+ /**
+ * Allows the dialect to override a {@link SqlTypeDescriptor}.
+ *
+ * If sqlTypeDescriptor
is a "standard basic" SQL type
+ * descriptor, then this method uses {@link #getSqlTypeDescriptorOverride}
+ * to get an optional override based on the SQL code returned by
+ * {@link SqlTypeDescriptor#getSqlType()}.
+ *
+ * If this dialect does not provide an override, then this method
+ * simply returns sqlTypeDescriptor
+ *
+ * @param sqlTypeDescriptor The {@link SqlTypeDescriptor} to override
+ * @return The {@link SqlTypeDescriptor} that should be used for this dialect;
+ * if there is no override, then sqlTypeDescriptor
is returned.
+ * @throws IllegalArgumentException if sqlTypeDescriptor
is null.
+ *
+ * @see {@link SqlTypeDescriptor}
+ * @see {@link #getSqlTypeDescriptorOverride}
+ * @see {@link StandardBasicTypes#isStandardBasicSqlTypeDescriptor(org.hibernate.type.descriptor.sql.SqlTypeDescriptor)}
+ */
+ public SqlTypeDescriptor resolveSqlTypeDescriptor(SqlTypeDescriptor sqlTypeDescriptor) {
+ if ( sqlTypeDescriptor == null ) {
+ throw new IllegalArgumentException( "sqlTypeDescriptor is null" );
+ }
+ SqlTypeDescriptor overrideBySqlCode = null;
+ if ( StandardBasicTypes.isStandardBasicSqlTypeDescriptor( sqlTypeDescriptor ) ) {
+ overrideBySqlCode = getSqlTypeDescriptorOverride( sqlTypeDescriptor.getSqlType() );
+ }
+ return overrideBySqlCode == null ? sqlTypeDescriptor : overrideBySqlCode;
+ }
+
+ /**
+ * Returns the {@link SqlTypeDescriptor} that should override the
+ * "standard basic" SQL type descriptor for values of the specified
+ * column type, or null, if there is no override.
+ *
+ * @param sqlCode A {@link Types} constant indicating the SQL column type
+ * @return The {@link SqlTypeDescriptor} that should override the
+ * "standard basic" SQL type descriptor, or null, if there is no override.
+ *
+ * @see {@link SqlTypeDescriptor}
+ * @see {@link StandardBasicTypes#isStandardBasicSqlTypeDescriptor(org.hibernate.type.descriptor.sql.SqlTypeDescriptor)}
+ */
+ protected SqlTypeDescriptor getSqlTypeDescriptorOverride(int sqlCode) {
+ SqlTypeDescriptor descriptor;
+ switch ( sqlCode ) {
+ case Types.BLOB: {
+ descriptor = useInputStreamToInsertBlob() ? BlobTypeDescriptor.STREAM_BINDING : null;
+ break;
+ }
+ case Types.CLOB: {
+ descriptor = useInputStreamToInsertBlob() ? ClobTypeDescriptor.STREAM_BINDING : null;
+ break;
+ }
+ default: {
+ descriptor = null;
+ break;
+ }
+ }
+ return descriptor;
+ }
// hibernate type mapping support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/PostgreSQLDialect.java b/hibernate-core/src/main/java/org/hibernate/dialect/PostgreSQLDialect.java
index 81a3a25e4e..31402deac3 100644
--- a/hibernate-core/src/main/java/org/hibernate/dialect/PostgreSQLDialect.java
+++ b/hibernate-core/src/main/java/org/hibernate/dialect/PostgreSQLDialect.java
@@ -40,6 +40,9 @@ import org.hibernate.exception.JDBCExceptionHelper;
import org.hibernate.exception.TemplatedViolatedConstraintNameExtracter;
import org.hibernate.exception.ViolatedConstraintNameExtracter;
import org.hibernate.id.SequenceGenerator;
+import org.hibernate.type.descriptor.sql.BlobTypeDescriptor;
+import org.hibernate.type.descriptor.sql.ClobTypeDescriptor;
+import org.hibernate.type.descriptor.sql.SqlTypeDescriptor;
/**
* An SQL dialect for Postgres
@@ -144,6 +147,30 @@ public class PostgreSQLDialect extends Dialect {
registerFunction( "str", new SQLFunctionTemplate(Hibernate.STRING, "cast(?1 as varchar)") );
getDefaultProperties().setProperty(Environment.STATEMENT_BATCH_SIZE, DEFAULT_BATCH_SIZE);
+ getDefaultProperties().setProperty( Environment.NON_CONTEXTUAL_LOB_CREATION, "true" );
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public SqlTypeDescriptor getSqlTypeDescriptorOverride(int sqlCode) {
+ SqlTypeDescriptor descriptor;
+ switch ( sqlCode ) {
+ case Types.BLOB: {
+ descriptor = BlobTypeDescriptor.BLOB_BINDING;
+ break;
+ }
+ case Types.CLOB: {
+ descriptor = ClobTypeDescriptor.CLOB_BINDING;
+ break;
+ }
+ default: {
+ descriptor = super.getSqlTypeDescriptorOverride( sqlCode );
+ break;
+ }
+ }
+ return descriptor;
}
public String getAddColumnString() {
@@ -364,8 +391,18 @@ public class PostgreSQLDialect extends Dialect {
return false;
}
+ @Override
public boolean supportsExpectedLobUsagePattern() {
- // seems to have spotty LOB suppport
+ return true;
+ }
+
+ @Override
+ public boolean supportsLobValueChangePropogation() {
+ return false;
+ }
+
+ @Override
+ public boolean supportsUnboundedLobLocatorMaterialization() {
return false;
}
diff --git a/hibernate-core/src/main/java/org/hibernate/type/AbstractSingleColumnStandardBasicType.java b/hibernate-core/src/main/java/org/hibernate/type/AbstractSingleColumnStandardBasicType.java
index b23d343d94..51c6b95122 100644
--- a/hibernate-core/src/main/java/org/hibernate/type/AbstractSingleColumnStandardBasicType.java
+++ b/hibernate-core/src/main/java/org/hibernate/type/AbstractSingleColumnStandardBasicType.java
@@ -56,6 +56,10 @@ public abstract class AbstractSingleColumnStandardBasicType
public LobCreator getLobCreator() {
return NonContextualLobCreator.INSTANCE;
}
+
+ public SqlTypeDescriptor resolveSqlTypeDescriptor(SqlTypeDescriptor sqlTypeDescriptor) {
+ return sqlTypeDescriptor;
+ }
};
public final int sqlType() {
diff --git a/hibernate-core/src/main/java/org/hibernate/type/AbstractStandardBasicType.java b/hibernate-core/src/main/java/org/hibernate/type/AbstractStandardBasicType.java
index f87a891732..cd10dccbc3 100644
--- a/hibernate-core/src/main/java/org/hibernate/type/AbstractStandardBasicType.java
+++ b/hibernate-core/src/main/java/org/hibernate/type/AbstractStandardBasicType.java
@@ -244,13 +244,17 @@ public abstract class AbstractStandardBasicType
public LobCreator getLobCreator() {
return Hibernate.getLobCreator( session );
}
+
+ public SqlTypeDescriptor resolveSqlTypeDescriptor(SqlTypeDescriptor sqlTypeDescriptor) {
+ return session.getFactory().getTypeResolver().resolveSqlTypeDescriptor( sqlTypeDescriptor );
+ }
};
return nullSafeGet( rs, name, options );
}
protected final T nullSafeGet(ResultSet rs, String name, WrapperOptions options) throws SQLException {
- return sqlTypeDescriptor.getExtractor( javaTypeDescriptor ).extract( rs, name, options );
+ return resolveSqlTypeDescriptor( options ).getExtractor( javaTypeDescriptor ).extract( rs, name, options );
}
public Object get(ResultSet rs, String name, SessionImplementor session) throws HibernateException, SQLException {
@@ -272,6 +276,10 @@ public abstract class AbstractStandardBasicType
public LobCreator getLobCreator() {
return Hibernate.getLobCreator( session );
}
+
+ public SqlTypeDescriptor resolveSqlTypeDescriptor(SqlTypeDescriptor sqlTypeDescriptor) {
+ return session.getFactory().getTypeResolver().resolveSqlTypeDescriptor( sqlTypeDescriptor );
+ }
};
nullSafeSet( st, value, index, options );
@@ -279,7 +287,11 @@ public abstract class AbstractStandardBasicType
@SuppressWarnings({ "unchecked" })
protected final void nullSafeSet(PreparedStatement st, Object value, int index, WrapperOptions options) throws SQLException {
- sqlTypeDescriptor.getBinder( javaTypeDescriptor ).bind( st, (T) value, index, options );
+ resolveSqlTypeDescriptor( options ).getBinder( javaTypeDescriptor ).bind( st, ( T ) value, index, options );
+ }
+
+ private SqlTypeDescriptor resolveSqlTypeDescriptor(WrapperOptions options) {
+ return options.resolveSqlTypeDescriptor( sqlTypeDescriptor );
}
public void set(PreparedStatement st, T value, int index, SessionImplementor session) throws HibernateException, SQLException {
diff --git a/hibernate-core/src/main/java/org/hibernate/type/BlobType.java b/hibernate-core/src/main/java/org/hibernate/type/BlobType.java
index 86f9ad6012..30f37d425e 100644
--- a/hibernate-core/src/main/java/org/hibernate/type/BlobType.java
+++ b/hibernate-core/src/main/java/org/hibernate/type/BlobType.java
@@ -37,7 +37,7 @@ public class BlobType extends AbstractSingleColumnStandardBasicType {
public static final BlobType INSTANCE = new BlobType();
public BlobType() {
- super( org.hibernate.type.descriptor.sql.BlobTypeDescriptor.INSTANCE, BlobTypeDescriptor.INSTANCE );
+ super( org.hibernate.type.descriptor.sql.BlobTypeDescriptor.DEFAULT, BlobTypeDescriptor.INSTANCE );
}
/**
diff --git a/hibernate-core/src/main/java/org/hibernate/type/CharacterArrayClobType.java b/hibernate-core/src/main/java/org/hibernate/type/CharacterArrayClobType.java
index 649135dd3e..c772bc4b35 100644
--- a/hibernate-core/src/main/java/org/hibernate/type/CharacterArrayClobType.java
+++ b/hibernate-core/src/main/java/org/hibernate/type/CharacterArrayClobType.java
@@ -38,7 +38,7 @@ public class CharacterArrayClobType extends AbstractSingleColumnStandardBasicTyp
public static final CharacterArrayClobType INSTANCE = new CharacterArrayClobType();
public CharacterArrayClobType() {
- super( ClobTypeDescriptor.INSTANCE, CharacterArrayTypeDescriptor.INSTANCE );
+ super( ClobTypeDescriptor.DEFAULT, CharacterArrayTypeDescriptor.INSTANCE );
}
public String getName() {
diff --git a/hibernate-core/src/main/java/org/hibernate/type/ClobType.java b/hibernate-core/src/main/java/org/hibernate/type/ClobType.java
index d3bbdb0d2e..4bd706a8c0 100644
--- a/hibernate-core/src/main/java/org/hibernate/type/ClobType.java
+++ b/hibernate-core/src/main/java/org/hibernate/type/ClobType.java
@@ -37,7 +37,7 @@ public class ClobType extends AbstractSingleColumnStandardBasicType {
public static final ClobType INSTANCE = new ClobType();
public ClobType() {
- super( org.hibernate.type.descriptor.sql.ClobTypeDescriptor.INSTANCE, ClobTypeDescriptor.INSTANCE );
+ super( org.hibernate.type.descriptor.sql.ClobTypeDescriptor.DEFAULT, ClobTypeDescriptor.INSTANCE );
}
public String getName() {
diff --git a/hibernate-core/src/main/java/org/hibernate/type/MaterializedBlobType.java b/hibernate-core/src/main/java/org/hibernate/type/MaterializedBlobType.java
index 980dab9737..ff13815f69 100644
--- a/hibernate-core/src/main/java/org/hibernate/type/MaterializedBlobType.java
+++ b/hibernate-core/src/main/java/org/hibernate/type/MaterializedBlobType.java
@@ -38,7 +38,7 @@ public class MaterializedBlobType extends AbstractSingleColumnStandardBasicType<
public static final MaterializedBlobType INSTANCE = new MaterializedBlobType();
public MaterializedBlobType() {
- super( BlobTypeDescriptor.INSTANCE, PrimitiveByteArrayTypeDescriptor.INSTANCE );
+ super( BlobTypeDescriptor.DEFAULT, PrimitiveByteArrayTypeDescriptor.INSTANCE );
}
public String getName() {
diff --git a/hibernate-core/src/main/java/org/hibernate/type/MaterializedClobType.java b/hibernate-core/src/main/java/org/hibernate/type/MaterializedClobType.java
index 9dbce2e371..7621e49ad9 100644
--- a/hibernate-core/src/main/java/org/hibernate/type/MaterializedClobType.java
+++ b/hibernate-core/src/main/java/org/hibernate/type/MaterializedClobType.java
@@ -37,7 +37,7 @@ public class MaterializedClobType extends AbstractSingleColumnStandardBasicType<
public static final MaterializedClobType INSTANCE = new MaterializedClobType();
public MaterializedClobType() {
- super( ClobTypeDescriptor.INSTANCE, StringTypeDescriptor.INSTANCE );
+ super( ClobTypeDescriptor.DEFAULT, StringTypeDescriptor.INSTANCE );
}
public String getName() {
diff --git a/hibernate-core/src/main/java/org/hibernate/type/PrimitiveCharacterArrayClobType.java b/hibernate-core/src/main/java/org/hibernate/type/PrimitiveCharacterArrayClobType.java
index d21bb1e498..3c09a7c8f2 100644
--- a/hibernate-core/src/main/java/org/hibernate/type/PrimitiveCharacterArrayClobType.java
+++ b/hibernate-core/src/main/java/org/hibernate/type/PrimitiveCharacterArrayClobType.java
@@ -35,7 +35,7 @@ public class PrimitiveCharacterArrayClobType extends AbstractSingleColumnStandar
public static final CharacterArrayClobType INSTANCE = new CharacterArrayClobType();
public PrimitiveCharacterArrayClobType() {
- super( ClobTypeDescriptor.INSTANCE, PrimitiveCharacterArrayTypeDescriptor.INSTANCE );
+ super( ClobTypeDescriptor.DEFAULT, PrimitiveCharacterArrayTypeDescriptor.INSTANCE );
}
public String getName() {
diff --git a/hibernate-core/src/main/java/org/hibernate/type/StandardBasicTypes.java b/hibernate-core/src/main/java/org/hibernate/type/StandardBasicTypes.java
index 5933ac517b..df54e0a18e 100644
--- a/hibernate-core/src/main/java/org/hibernate/type/StandardBasicTypes.java
+++ b/hibernate-core/src/main/java/org/hibernate/type/StandardBasicTypes.java
@@ -23,6 +23,11 @@
*/
package org.hibernate.type;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.hibernate.type.descriptor.sql.SqlTypeDescriptor;
+
/**
* Centralizes access to the standard set of basic {@link Type types}.
*
@@ -37,108 +42,111 @@ package org.hibernate.type;
* @author Steve Ebersole
*/
public class StandardBasicTypes {
+
+ private static final Set sqlTypeDescriptors = new HashSet();
+
/**
* The standard Hibernate type for mapping {@link Boolean} to JDBC {@link java.sql.Types#BIT BIT}.
*
* @see BooleanType
*/
- public static final BooleanType BOOLEAN = BooleanType.INSTANCE;
+ public static final BooleanType BOOLEAN = register( BooleanType.INSTANCE );
/**
* The standard Hibernate type for mapping {@link Boolean} to JDBC {@link java.sql.Types#INTEGER INTEGER}.
*
* @see NumericBooleanType
*/
- public static final NumericBooleanType NUMERIC_BOOLEAN = NumericBooleanType.INSTANCE;
+ public static final NumericBooleanType NUMERIC_BOOLEAN = register( NumericBooleanType.INSTANCE );
/**
* The standard Hibernate type for mapping {@link Boolean} to JDBC {@link java.sql.Types#CHAR CHAR(1)} (using 'T'/'F').
*
* @see TrueFalseType
*/
- public static final TrueFalseType TRUE_FALSE = TrueFalseType.INSTANCE;
+ public static final TrueFalseType TRUE_FALSE = register( TrueFalseType.INSTANCE );
/**
* The standard Hibernate type for mapping {@link Boolean} to JDBC {@link java.sql.Types#CHAR CHAR(1)} (using 'Y'/'N').
*
* @see YesNoType
*/
- public static final YesNoType YES_NO = YesNoType.INSTANCE;
+ public static final YesNoType YES_NO = register( YesNoType.INSTANCE );
/**
* The standard Hibernate type for mapping {@link Byte} to JDBC {@link java.sql.Types#TINYINT TINYINT}.
*/
- public static final ByteType BYTE = ByteType.INSTANCE;
+ public static final ByteType BYTE = register( ByteType.INSTANCE );
/**
* The standard Hibernate type for mapping {@link Short} to JDBC {@link java.sql.Types#SMALLINT SMALLINT}.
*
* @see ShortType
*/
- public static final ShortType SHORT = ShortType.INSTANCE;
+ public static final ShortType SHORT = register( ShortType.INSTANCE );
/**
* The standard Hibernate type for mapping {@link Integer} to JDBC {@link java.sql.Types#INTEGER INTEGER}.
*
* @see IntegerType
*/
- public static final IntegerType INTEGER = IntegerType.INSTANCE;
+ public static final IntegerType INTEGER = register( IntegerType.INSTANCE );
/**
* The standard Hibernate type for mapping {@link Long} to JDBC {@link java.sql.Types#BIGINT BIGINT}.
*
* @see LongType
*/
- public static final LongType LONG = LongType.INSTANCE;
+ public static final LongType LONG = register( LongType.INSTANCE );
/**
* The standard Hibernate type for mapping {@link Float} to JDBC {@link java.sql.Types#FLOAT FLOAT}.
*
* @see FloatType
*/
- public static final FloatType FLOAT = FloatType.INSTANCE;
+ public static final FloatType FLOAT = register( FloatType.INSTANCE );
/**
* The standard Hibernate type for mapping {@link Double} to JDBC {@link java.sql.Types#DOUBLE DOUBLE}.
*
* @see DoubleType
*/
- public static final DoubleType DOUBLE = DoubleType.INSTANCE;
+ public static final DoubleType DOUBLE = register( DoubleType.INSTANCE );
/**
* The standard Hibernate type for mapping {@link java.math.BigInteger} to JDBC {@link java.sql.Types#NUMERIC NUMERIC}.
*
* @see BigIntegerType
*/
- public static final BigIntegerType BIG_INTEGER = BigIntegerType.INSTANCE;
+ public static final BigIntegerType BIG_INTEGER = register( BigIntegerType.INSTANCE );
/**
* The standard Hibernate type for mapping {@link java.math.BigDecimal} to JDBC {@link java.sql.Types#NUMERIC NUMERIC}.
*
* @see BigDecimalType
*/
- public static final BigDecimalType BIG_DECIMAL = BigDecimalType.INSTANCE;
+ public static final BigDecimalType BIG_DECIMAL = register( BigDecimalType.INSTANCE );
/**
* The standard Hibernate type for mapping {@link Character} to JDBC {@link java.sql.Types#CHAR CHAR(1)}.
*
* @see CharacterType
*/
- public static final CharacterType CHARACTER = CharacterType.INSTANCE;
+ public static final CharacterType CHARACTER = register( CharacterType.INSTANCE );
/**
* The standard Hibernate type for mapping {@link String} to JDBC {@link java.sql.Types#VARCHAR VARCHAR}.
*
* @see StringType
*/
- public static final StringType STRING = StringType.INSTANCE;
+ public static final StringType STRING = register( StringType.INSTANCE );
/**
* The standard Hibernate type for mapping {@link java.net.URL} to JDBC {@link java.sql.Types#VARCHAR VARCHAR}.
*
* @see UrlType
*/
- public static final UrlType URL = UrlType.INSTANCE;
+ public static final UrlType URL = register( UrlType.INSTANCE );
/**
* The standard Hibernate type for mapping {@link java.util.Date} ({@link java.sql.Time}) to JDBC
@@ -146,7 +154,7 @@ public class StandardBasicTypes {
*
* @see TimeType
*/
- public static final TimeType TIME = TimeType.INSTANCE;
+ public static final TimeType TIME = register( TimeType.INSTANCE );
/**
* The standard Hibernate type for mapping {@link java.util.Date} ({@link java.sql.Date}) to JDBC
@@ -154,7 +162,7 @@ public class StandardBasicTypes {
*
* @see TimeType
*/
- public static final DateType DATE = DateType.INSTANCE;
+ public static final DateType DATE = register( DateType.INSTANCE );
/**
* The standard Hibernate type for mapping {@link java.util.Date} ({@link java.sql.Timestamp}) to JDBC
@@ -162,7 +170,7 @@ public class StandardBasicTypes {
*
* @see TimeType
*/
- public static final TimestampType TIMESTAMP = TimestampType.INSTANCE;
+ public static final TimestampType TIMESTAMP = register( TimestampType.INSTANCE );
/**
* The standard Hibernate type for mapping {@link java.util.Calendar} to JDBC
@@ -170,7 +178,7 @@ public class StandardBasicTypes {
*
* @see CalendarType
*/
- public static final CalendarType CALENDAR = CalendarType.INSTANCE;
+ public static final CalendarType CALENDAR = register( CalendarType.INSTANCE );
/**
* The standard Hibernate type for mapping {@link java.util.Calendar} to JDBC
@@ -178,63 +186,63 @@ public class StandardBasicTypes {
*
* @see CalendarDateType
*/
- public static final CalendarDateType CALENDAR_DATE = CalendarDateType.INSTANCE;
+ public static final CalendarDateType CALENDAR_DATE = register( CalendarDateType.INSTANCE );
/**
* The standard Hibernate type for mapping {@link Class} to JDBC {@link java.sql.Types#VARCHAR VARCHAR}.
*
* @see ClassType
*/
- public static final ClassType CLASS = ClassType.INSTANCE;
+ public static final ClassType CLASS = register( ClassType.INSTANCE );
/**
* The standard Hibernate type for mapping {@link java.util.Locale} to JDBC {@link java.sql.Types#VARCHAR VARCHAR}.
*
* @see LocaleType
*/
- public static final LocaleType LOCALE = LocaleType.INSTANCE;
+ public static final LocaleType LOCALE = register( LocaleType.INSTANCE );
/**
* The standard Hibernate type for mapping {@link java.util.Currency} to JDBC {@link java.sql.Types#VARCHAR VARCHAR}.
*
* @see CurrencyType
*/
- public static final CurrencyType CURRENCY = CurrencyType.INSTANCE;
+ public static final CurrencyType CURRENCY = register( CurrencyType.INSTANCE );
/**
* The standard Hibernate type for mapping {@link java.util.TimeZone} to JDBC {@link java.sql.Types#VARCHAR VARCHAR}.
*
* @see TimeZoneType
*/
- public static final TimeZoneType TIMEZONE = TimeZoneType.INSTANCE;
+ public static final TimeZoneType TIMEZONE = register( TimeZoneType.INSTANCE );
/**
* The standard Hibernate type for mapping {@link java.util.UUID} to JDBC {@link java.sql.Types#BINARY BINARY}.
*
* @see UUIDBinaryType
*/
- public static final UUIDBinaryType UUID_BINARY = UUIDBinaryType.INSTANCE;
+ public static final UUIDBinaryType UUID_BINARY = register( UUIDBinaryType.INSTANCE );
/**
* The standard Hibernate type for mapping {@link java.util.UUID} to JDBC {@link java.sql.Types#CHAR CHAR}.
*
* @see UUIDCharType
*/
- public static final UUIDCharType UUID_CHAR = UUIDCharType.INSTANCE;
+ public static final UUIDCharType UUID_CHAR = register( UUIDCharType.INSTANCE );
/**
* The standard Hibernate type for mapping {@code byte[]} to JDBC {@link java.sql.Types#VARBINARY VARBINARY}.
*
* @see BinaryType
*/
- public static final BinaryType BINARY = BinaryType.INSTANCE;
+ public static final BinaryType BINARY = register( BinaryType.INSTANCE );
/**
* The standard Hibernate type for mapping {@link Byte Byte[]} to JDBC {@link java.sql.Types#VARBINARY VARBINARY}.
*
* @see WrapperBinaryType
*/
- public static final WrapperBinaryType WRAPPER_BINARY = WrapperBinaryType.INSTANCE;
+ public static final WrapperBinaryType WRAPPER_BINARY = register( WrapperBinaryType.INSTANCE );
/**
* The standard Hibernate type for mapping {@code byte[]} to JDBC {@link java.sql.Types#LONGVARBINARY LONGVARBINARY}.
@@ -242,7 +250,7 @@ public class StandardBasicTypes {
* @see ImageType
* @see #MATERIALIZED_BLOB
*/
- public static final ImageType IMAGE = ImageType.INSTANCE;
+ public static final ImageType IMAGE = register( ImageType.INSTANCE );
/**
* The standard Hibernate type for mapping {@link java.sql.Blob} to JDBC {@link java.sql.Types#BLOB BLOB}.
@@ -250,7 +258,7 @@ public class StandardBasicTypes {
* @see BlobType
* @see #MATERIALIZED_BLOB
*/
- public static final BlobType BLOB = BlobType.INSTANCE;
+ public static final BlobType BLOB = register( BlobType.INSTANCE );
/**
* The standard Hibernate type for mapping {@code byte[]} to JDBC {@link java.sql.Types#BLOB BLOB}.
@@ -259,14 +267,14 @@ public class StandardBasicTypes {
* @see #MATERIALIZED_BLOB
* @see #IMAGE
*/
- public static final MaterializedBlobType MATERIALIZED_BLOB = MaterializedBlobType.INSTANCE;
+ public static final MaterializedBlobType MATERIALIZED_BLOB = register( MaterializedBlobType.INSTANCE );
/**
* The standard Hibernate type for mapping {@code char[]} to JDBC {@link java.sql.Types#VARCHAR VARCHAR}.
*
* @see CharArrayType
*/
- public static final CharArrayType CHAR_ARRAY = CharArrayType.INSTANCE;
+ public static final CharArrayType CHAR_ARRAY = register( CharArrayType.INSTANCE );
/**
* The standard Hibernate type for mapping {@link Character Character[]} to JDBC
@@ -274,7 +282,7 @@ public class StandardBasicTypes {
*
* @see CharacterArrayType
*/
- public static final CharacterArrayType CHARACTER_ARRAY = CharacterArrayType.INSTANCE;
+ public static final CharacterArrayType CHARACTER_ARRAY = register( CharacterArrayType.INSTANCE );
/**
* The standard Hibernate type for mapping {@link String} to JDBC {@link java.sql.Types#LONGVARCHAR LONGVARCHAR}.
@@ -283,7 +291,7 @@ public class StandardBasicTypes {
*
* @see TextType
*/
- public static final TextType TEXT = TextType.INSTANCE;
+ public static final TextType TEXT = register( TextType.INSTANCE );
/**
* The standard Hibernate type for mapping {@link java.sql.Clob} to JDBC {@link java.sql.Types#CLOB CLOB}.
@@ -291,7 +299,7 @@ public class StandardBasicTypes {
* @see ClobType
* @see #MATERIALIZED_CLOB
*/
- public static final ClobType CLOB = ClobType.INSTANCE;
+ public static final ClobType CLOB = register( ClobType.INSTANCE );
/**
* The standard Hibernate type for mapping {@link String} to JDBC {@link java.sql.Types#CLOB CLOB}.
@@ -300,7 +308,7 @@ public class StandardBasicTypes {
* @see #MATERIALIZED_CLOB
* @see #TEXT
*/
- public static final MaterializedClobType MATERIALIZED_CLOB = MaterializedClobType.INSTANCE;
+ public static final MaterializedClobType MATERIALIZED_CLOB = register( MaterializedClobType.INSTANCE );
/**
* The standard Hibernate type for mapping {@link java.io.Serializable} to JDBC {@link java.sql.Types#VARBINARY VARBINARY}.
@@ -309,5 +317,14 @@ public class StandardBasicTypes {
*
* @see SerializableType
*/
- public static final SerializableType SERIALIZABLE = SerializableType.INSTANCE;
+ public static final SerializableType SERIALIZABLE = register( SerializableType.INSTANCE );
+
+ private static T register(T type) {
+ sqlTypeDescriptors.add( type.getSqlTypeDescriptor() );
+ return type;
+ }
+
+ public static final boolean isStandardBasicSqlTypeDescriptor(SqlTypeDescriptor sqlTypeDescriptor) {
+ return sqlTypeDescriptors.contains( sqlTypeDescriptor );
+ }
}
diff --git a/hibernate-core/src/main/java/org/hibernate/type/TypeFactory.java b/hibernate-core/src/main/java/org/hibernate/type/TypeFactory.java
index 5a08ec00f2..bb4db8e200 100644
--- a/hibernate-core/src/main/java/org/hibernate/type/TypeFactory.java
+++ b/hibernate-core/src/main/java/org/hibernate/type/TypeFactory.java
@@ -86,6 +86,10 @@ public final class TypeFactory implements Serializable {
typeScope.injectSessionFactory( factory );
}
+ public SessionFactoryImplementor resolveSessionFactory() {
+ return typeScope.resolveFactory();
+ }
+
public Type byClass(Class clazz, Properties parameters) {
if ( Type.class.isAssignableFrom( clazz ) ) {
return type( (Class) clazz, parameters );
diff --git a/hibernate-core/src/main/java/org/hibernate/type/TypeResolver.java b/hibernate-core/src/main/java/org/hibernate/type/TypeResolver.java
index 83231165a9..3006a643e1 100644
--- a/hibernate-core/src/main/java/org/hibernate/type/TypeResolver.java
+++ b/hibernate-core/src/main/java/org/hibernate/type/TypeResolver.java
@@ -24,11 +24,17 @@
package org.hibernate.type;
import java.io.Serializable;
+import java.util.HashMap;
+import java.util.Map;
import java.util.Properties;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
import org.hibernate.MappingException;
import org.hibernate.classic.Lifecycle;
import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.type.descriptor.sql.SqlTypeDescriptor;
import org.hibernate.usertype.CompositeUserType;
import org.hibernate.usertype.UserType;
import org.hibernate.util.ReflectHelper;
@@ -39,21 +45,31 @@ import org.hibernate.util.ReflectHelper;
* @author Steve Ebersole
*/
public class TypeResolver implements Serializable {
+ private static final Logger log = LoggerFactory.getLogger( TypeResolver.class );
+
private final BasicTypeRegistry basicTypeRegistry;
private final TypeFactory typeFactory;
+ private final Map resolvedSqlTypeDescriptors;
public TypeResolver() {
- this( new BasicTypeRegistry(), new TypeFactory() );
+ this( new BasicTypeRegistry(), new TypeFactory(), null );
}
- public TypeResolver(BasicTypeRegistry basicTypeRegistry, TypeFactory typeFactory) {
+ public TypeResolver(BasicTypeRegistry basicTypeRegistry,
+ TypeFactory typeFactory,
+ Map resolvedSqlTypeDescriptors) {
this.basicTypeRegistry = basicTypeRegistry;
this.typeFactory = typeFactory;
+ this.resolvedSqlTypeDescriptors = resolvedSqlTypeDescriptors;
}
public TypeResolver scope(SessionFactoryImplementor factory) {
typeFactory.injectSessionFactory( factory );
- return new TypeResolver( basicTypeRegistry.shallowCopy(), typeFactory );
+ return new TypeResolver(
+ basicTypeRegistry.shallowCopy(),
+ typeFactory,
+ new HashMap( 25 )
+ );
}
public void registerTypeOverride(BasicType type) {
@@ -135,4 +151,39 @@ public class TypeResolver implements Serializable {
return null;
}
+
+ public SqlTypeDescriptor resolveSqlTypeDescriptor(SqlTypeDescriptor sqlTypeDescriptor) {
+ if ( resolvedSqlTypeDescriptors == null ) {
+ throw new IllegalStateException( "cannot resolve a SqlTypeDescriptor until the TypeResolver is scoped." );
+ }
+ SqlTypeDescriptor resolvedDescriptor = resolvedSqlTypeDescriptors.get( sqlTypeDescriptor );
+ if ( resolvedDescriptor == null ) {
+ resolvedDescriptor =
+ typeFactory.resolveSessionFactory().getDialect().resolveSqlTypeDescriptor( sqlTypeDescriptor );
+ if ( resolvedDescriptor == null ) {
+ throw new IllegalStateException( "dialect returned a resolved SqlTypeDescriptor that was null." );
+ }
+ if ( sqlTypeDescriptor != resolvedDescriptor ) {
+ log.info(
+ "Adding override for {}: {}",
+ new String[] {
+ sqlTypeDescriptor.getClass().getName(),
+ resolvedDescriptor.getClass().getName(),
+ }
+ );
+ if ( sqlTypeDescriptor.getSqlType() != resolvedDescriptor.getSqlType() ) {
+ log.warn( "Resolved SqlTypeDescriptor is for a different SQL code. {} has sqlCode={}; type override {} has sqlCode={}",
+ new String[] {
+ sqlTypeDescriptor.getClass().getName(),
+ String.valueOf( sqlTypeDescriptor.getSqlType() ),
+ resolvedDescriptor.getClass().getName(),
+ String.valueOf( resolvedDescriptor.getSqlType() ),
+ }
+ );
+ }
+ }
+ resolvedSqlTypeDescriptors.put( sqlTypeDescriptor, resolvedDescriptor );
+ }
+ return resolvedDescriptor;
+ }
}
diff --git a/hibernate-core/src/main/java/org/hibernate/type/WrappedMaterializedBlobType.java b/hibernate-core/src/main/java/org/hibernate/type/WrappedMaterializedBlobType.java
index 96f340f4d1..975ffd5a43 100644
--- a/hibernate-core/src/main/java/org/hibernate/type/WrappedMaterializedBlobType.java
+++ b/hibernate-core/src/main/java/org/hibernate/type/WrappedMaterializedBlobType.java
@@ -36,7 +36,7 @@ public class WrappedMaterializedBlobType extends AbstractSingleColumnStandardBas
public static final WrappedMaterializedBlobType INSTANCE = new WrappedMaterializedBlobType();
public WrappedMaterializedBlobType() {
- super( BlobTypeDescriptor.INSTANCE, ByteArrayTypeDescriptor.INSTANCE );
+ super( BlobTypeDescriptor.DEFAULT, ByteArrayTypeDescriptor.INSTANCE );
}
public String getName() {
diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/WrapperOptions.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/WrapperOptions.java
index 339e8eb8c8..6cc8949804 100644
--- a/hibernate-core/src/main/java/org/hibernate/type/descriptor/WrapperOptions.java
+++ b/hibernate-core/src/main/java/org/hibernate/type/descriptor/WrapperOptions.java
@@ -23,7 +23,10 @@
*/
package org.hibernate.type.descriptor;
+import org.hibernate.dialect.Dialect;
import org.hibernate.engine.jdbc.LobCreator;
+import org.hibernate.type.TypeResolver;
+import org.hibernate.type.descriptor.sql.SqlTypeDescriptor;
/**
* TODO : javadoc
@@ -33,4 +36,5 @@ import org.hibernate.engine.jdbc.LobCreator;
public interface WrapperOptions {
public boolean useStreamForLobBinding();
public LobCreator getLobCreator();
+ public SqlTypeDescriptor resolveSqlTypeDescriptor(SqlTypeDescriptor sqlTypeDescriptor);
}
diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/BlobTypeDescriptor.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/BlobTypeDescriptor.java
index f834c11934..d7b104657f 100644
--- a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/BlobTypeDescriptor.java
+++ b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/BlobTypeDescriptor.java
@@ -31,6 +31,7 @@ import java.util.Comparator;
import org.hibernate.HibernateException;
import org.hibernate.engine.jdbc.BlobProxy;
import org.hibernate.engine.jdbc.WrappedBlob;
+import org.hibernate.type.descriptor.BinaryStream;
import org.hibernate.type.descriptor.WrapperOptions;
/**
@@ -107,7 +108,7 @@ public class BlobTypeDescriptor extends AbstractTypeDescriptor {
@SuppressWarnings({ "unchecked" })
public X unwrap(Blob value, Class type, WrapperOptions options) {
- if ( !Blob.class.isAssignableFrom( type ) ) {
+ if ( ! ( Blob.class.isAssignableFrom( type ) || BinaryStream.class.isAssignableFrom( type ) ) ) {
throw unknownUnwrap( type );
}
@@ -115,6 +116,15 @@ public class BlobTypeDescriptor extends AbstractTypeDescriptor {
return null;
}
+ if ( BinaryStream.class.isAssignableFrom( type ) ) {
+ try {
+ return (X) new BinaryStreamImpl( DataHelper.extractBytes( value.getBinaryStream() ) );
+ }
+ catch ( SQLException e ) {
+ throw new HibernateException( "Unable to access blob stream", e );
+ }
+ }
+
final Blob blob = WrappedBlob.class.isInstance( value )
? ( (WrappedBlob) value ).getWrappedBlob()
: value;
diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/ClobTypeDescriptor.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/ClobTypeDescriptor.java
index ec10483c49..bbe51382d0 100644
--- a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/ClobTypeDescriptor.java
+++ b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/ClobTypeDescriptor.java
@@ -23,6 +23,7 @@
*/
package org.hibernate.type.descriptor.java;
+import java.io.Reader;
import java.io.Serializable;
import java.sql.Clob;
import java.sql.SQLException;
@@ -31,6 +32,7 @@ import java.util.Comparator;
import org.hibernate.HibernateException;
import org.hibernate.engine.jdbc.ClobProxy;
import org.hibernate.engine.jdbc.WrappedClob;
+import org.hibernate.type.descriptor.CharacterStream;
import org.hibernate.type.descriptor.WrapperOptions;
/**
@@ -98,8 +100,8 @@ public class ClobTypeDescriptor extends AbstractTypeDescriptor {
}
@SuppressWarnings({ "unchecked" })
- public X unwrap(Clob value, Class type, WrapperOptions options) {
- if ( !Clob.class.isAssignableFrom( type ) ) {
+ public X unwrap(final Clob value, Class type, WrapperOptions options) {
+ if ( ! ( Clob.class.isAssignableFrom( type ) || CharacterStream.class.isAssignableFrom( type ) ) ) {
throw unknownUnwrap( type );
}
@@ -107,6 +109,15 @@ public class ClobTypeDescriptor extends AbstractTypeDescriptor {
return null;
}
+ if ( CharacterStream.class.isAssignableFrom( type ) ) {
+ try {
+ return (X) new CharacterStreamImpl( DataHelper.extractString( value.getCharacterStream() ) );
+ }
+ catch ( SQLException e ) {
+ throw new HibernateException( "Unable to access lob stream", e );
+ }
+ }
+
final Clob clob = WrappedClob.class.isInstance( value )
? ( (WrappedClob) value ).getWrappedClob()
: value;
diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/sql/BlobTypeDescriptor.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/sql/BlobTypeDescriptor.java
index c746316bfd..eec639d4a8 100644
--- a/hibernate-core/src/main/java/org/hibernate/type/descriptor/sql/BlobTypeDescriptor.java
+++ b/hibernate-core/src/main/java/org/hibernate/type/descriptor/sql/BlobTypeDescriptor.java
@@ -23,7 +23,6 @@
*/
package org.hibernate.type.descriptor.sql;
-import java.io.InputStream;
import java.sql.Blob;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
@@ -41,32 +40,72 @@ import org.hibernate.type.descriptor.WrapperOptions;
*
* @author Steve Ebersole
*/
-public class BlobTypeDescriptor implements SqlTypeDescriptor {
- public static final BlobTypeDescriptor INSTANCE = new BlobTypeDescriptor();
+public abstract class BlobTypeDescriptor implements SqlTypeDescriptor {
- public int getSqlType() {
- return Types.BLOB;
- }
+ private BlobTypeDescriptor() {}
- public ValueBinder getBinder(final JavaTypeDescriptor javaTypeDescriptor) {
- return new BasicBinder( javaTypeDescriptor, this ) {
- @Override
- protected void doBind(PreparedStatement st, X value, int index, WrapperOptions options) throws SQLException {
- if ( options.useStreamForLobBinding() ) {
- final BinaryStream binaryStream = javaTypeDescriptor.unwrap( value, BinaryStream.class, options );
- st.setBinaryStream( index, binaryStream.getInputStream(), binaryStream.getLength() );
+ public static final BlobTypeDescriptor DEFAULT =
+ new BlobTypeDescriptor() {
+ public BasicBinder getBlobBinder(final JavaTypeDescriptor javaTypeDescriptor) {
+ return new BasicBinder( javaTypeDescriptor, this ) {
+ @Override
+ protected void doBind(PreparedStatement st, X value, int index, WrapperOptions options) throws SQLException {
+ if ( options.useStreamForLobBinding() ) {
+ STREAM_BINDING.getBlobBinder( javaTypeDescriptor ).doBind( st, value, index, options );
+ }
+ else if ( byte[].class.isInstance( value ) ) {
+ // performance shortcut for binding BLOB data in byte[] format
+ PRIMITIVE_ARRAY_BINDING.getBlobBinder( javaTypeDescriptor ).doBind( st, value, index, options );
+ }
+ else {
+ BLOB_BINDING.getBlobBinder( javaTypeDescriptor ).doBind( st, value, index, options );
+ }
+ }
+ };
}
- else if ( byte[].class.isInstance( value ) ) {
- // performance shortcut for binding BLOB data in byte[] format
- final byte[] bytes = (byte[]) value;
- st.setBytes( index, bytes );
+ };
+
+ public static final BlobTypeDescriptor PRIMITIVE_ARRAY_BINDING =
+ new BlobTypeDescriptor() {
+ public BasicBinder getBlobBinder(final JavaTypeDescriptor javaTypeDescriptor) {
+ return new BasicBinder( javaTypeDescriptor, this ) {
+ @Override
+ public void doBind(PreparedStatement st, X value, int index, WrapperOptions options)
+ throws SQLException {
+ st.setBytes( index, javaTypeDescriptor.unwrap( value, byte[].class, options ) );
+ }
+ };
}
- else {
- st.setBlob( index, javaTypeDescriptor.unwrap( value, Blob.class, options ) );
+ };
+
+ public static final BlobTypeDescriptor BLOB_BINDING =
+ new BlobTypeDescriptor() {
+ public BasicBinder getBlobBinder(final JavaTypeDescriptor javaTypeDescriptor) {
+ return new BasicBinder( javaTypeDescriptor, this ) {
+ @Override
+ protected void doBind(PreparedStatement st, X value, int index, WrapperOptions options)
+ throws SQLException {
+ st.setBlob( index, javaTypeDescriptor.unwrap( value, Blob.class, options ) );
+ }
+ };
}
- }
- };
- }
+ };
+
+ public static final BlobTypeDescriptor STREAM_BINDING =
+ new BlobTypeDescriptor() {
+ public BasicBinder getBlobBinder(final JavaTypeDescriptor javaTypeDescriptor) {
+ return new BasicBinder( javaTypeDescriptor, this ) {
+ @Override
+ protected void doBind(PreparedStatement st, X value, int index, WrapperOptions options)
+ throws SQLException {
+ final BinaryStream binaryStream = javaTypeDescriptor.unwrap( value, BinaryStream.class, options );
+ st.setBinaryStream( index, binaryStream.getInputStream(), binaryStream.getLength() );
+ }
+ };
+ }
+ };
+
+ protected abstract BasicBinder getBlobBinder(final JavaTypeDescriptor javaTypeDescriptor);
public ValueExtractor getExtractor(final JavaTypeDescriptor javaTypeDescriptor) {
return new BasicExtractor( javaTypeDescriptor, this ) {
@@ -76,4 +115,12 @@ public class BlobTypeDescriptor implements SqlTypeDescriptor {
}
};
}
+
+ public int getSqlType() {
+ return Types.BLOB;
+ }
+
+ public ValueBinder getBinder(final JavaTypeDescriptor javaTypeDescriptor) {
+ return getBlobBinder( javaTypeDescriptor );
+ }
}
diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/sql/ClobTypeDescriptor.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/sql/ClobTypeDescriptor.java
index 218e9e9a99..a0913e97a0 100644
--- a/hibernate-core/src/main/java/org/hibernate/type/descriptor/sql/ClobTypeDescriptor.java
+++ b/hibernate-core/src/main/java/org/hibernate/type/descriptor/sql/ClobTypeDescriptor.java
@@ -41,28 +41,62 @@ import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
*
* @author Steve Ebersole
*/
-public class ClobTypeDescriptor implements SqlTypeDescriptor {
- public static final ClobTypeDescriptor INSTANCE = new ClobTypeDescriptor();
+public abstract class ClobTypeDescriptor implements SqlTypeDescriptor {
+
+ public static final ClobTypeDescriptor DEFAULT =
+ new ClobTypeDescriptor() {
+ public BasicBinder getClobBinder(final JavaTypeDescriptor javaTypeDescriptor) {
+ return new BasicBinder( javaTypeDescriptor, this ) {
+ @Override
+ protected void doBind(PreparedStatement st, X value, int index, WrapperOptions options) throws SQLException {
+ if ( options.useStreamForLobBinding() ) {
+ STREAM_BINDING.getClobBinder( javaTypeDescriptor ).doBind( st, value, index, options );
+ }
+ else {
+ CLOB_BINDING.getClobBinder( javaTypeDescriptor ).doBind( st, value, index, options );
+ }
+ }
+ };
+ }
+ };
+
+ public static final ClobTypeDescriptor CLOB_BINDING =
+ new ClobTypeDescriptor() {
+ public BasicBinder getClobBinder(final JavaTypeDescriptor javaTypeDescriptor) {
+ return new BasicBinder( javaTypeDescriptor, this ) {
+ @Override
+ protected void doBind(PreparedStatement st, X value, int index, WrapperOptions options)
+ throws SQLException {
+ st.setClob( index, javaTypeDescriptor.unwrap( value, Clob.class, options ) );
+ }
+ };
+ }
+ };
+
+ public static final ClobTypeDescriptor STREAM_BINDING =
+ new ClobTypeDescriptor() {
+ public BasicBinder getClobBinder(final JavaTypeDescriptor javaTypeDescriptor) {
+ return new BasicBinder( javaTypeDescriptor, this ) {
+ @Override
+ protected void doBind(PreparedStatement st, X value, int index, WrapperOptions options)
+ throws SQLException {
+ final CharacterStream characterStream = javaTypeDescriptor.unwrap( value, CharacterStream.class, options );
+ st.setCharacterStream( index, characterStream.getReader(), characterStream.getLength() );
+ }
+ };
+ }
+ };
+
+ protected abstract BasicBinder getClobBinder(final JavaTypeDescriptor javaTypeDescriptor);
+
+ public ValueBinder getBinder(final JavaTypeDescriptor javaTypeDescriptor) {
+ return getClobBinder( javaTypeDescriptor );
+ }
public int getSqlType() {
return Types.CLOB;
}
- public ValueBinder getBinder(final JavaTypeDescriptor javaTypeDescriptor) {
- return new BasicBinder( javaTypeDescriptor, this ) {
- @Override
- protected void doBind(PreparedStatement st, X value, int index, WrapperOptions options) throws SQLException {
- if ( options.useStreamForLobBinding() ) {
- final CharacterStream characterStream = javaTypeDescriptor.unwrap( value, CharacterStream.class, options );
- st.setCharacterStream( index, characterStream.getReader(), characterStream.getLength() );
- }
- else {
- st.setClob( index, javaTypeDescriptor.unwrap( value, Clob.class, options ) );
- }
- }
- };
- }
-
public ValueExtractor getExtractor(final JavaTypeDescriptor javaTypeDescriptor) {
return new BasicExtractor( javaTypeDescriptor, this ) {
@Override
diff --git a/hibernate-core/src/test/java/org/hibernate/test/annotations/lob/MaterializedBlobTest.java b/hibernate-core/src/test/java/org/hibernate/test/annotations/lob/MaterializedBlobTest.java
index dcecebd8e0..de19373961 100644
--- a/hibernate-core/src/test/java/org/hibernate/test/annotations/lob/MaterializedBlobTest.java
+++ b/hibernate-core/src/test/java/org/hibernate/test/annotations/lob/MaterializedBlobTest.java
@@ -28,7 +28,7 @@ import java.util.Arrays;
import org.hibernate.Session;
import org.hibernate.cfg.AnnotationConfiguration;
import org.hibernate.cfg.Configuration;
-import org.hibernate.cfg.Environment;
+import org.hibernate.dialect.PostgreSQLDialect;
import org.hibernate.test.annotations.TestCase;
import org.hibernate.testing.junit.DialectChecks;
import org.hibernate.testing.junit.RequiresDialectFeature;
diff --git a/hibernate-core/src/test/java/org/hibernate/test/typeoverride/Entity.hbm.xml b/hibernate-core/src/test/java/org/hibernate/test/typeoverride/Entity.hbm.xml
new file mode 100644
index 0000000000..84386ea601
--- /dev/null
+++ b/hibernate-core/src/test/java/org/hibernate/test/typeoverride/Entity.hbm.xml
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/hibernate-core/src/test/java/org/hibernate/test/typeoverride/Entity.java b/hibernate-core/src/test/java/org/hibernate/test/typeoverride/Entity.java
new file mode 100644
index 0000000000..e1f1f3e884
--- /dev/null
+++ b/hibernate-core/src/test/java/org/hibernate/test/typeoverride/Entity.java
@@ -0,0 +1,55 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2011, 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
+ */
+package org.hibernate.test.typeoverride;
+
+/**
+ * @author Gail Badner
+ */
+public class Entity {
+ private long id;
+ private String name;
+
+ public Entity() {
+ }
+
+ public Entity(String name) {
+ this.name = name;
+ }
+
+ public long getId() {
+ return id;
+ }
+
+ public void setId(long id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+}
diff --git a/hibernate-core/src/test/java/org/hibernate/test/typeoverride/H2DialectOverridePrefixedVarcharSqlTypeDesc.java b/hibernate-core/src/test/java/org/hibernate/test/typeoverride/H2DialectOverridePrefixedVarcharSqlTypeDesc.java
new file mode 100644
index 0000000000..b6ec851395
--- /dev/null
+++ b/hibernate-core/src/test/java/org/hibernate/test/typeoverride/H2DialectOverridePrefixedVarcharSqlTypeDesc.java
@@ -0,0 +1,41 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2011, 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
+ */
+package org.hibernate.test.typeoverride;
+
+import org.hibernate.dialect.H2Dialect;
+import org.hibernate.type.descriptor.sql.SqlTypeDescriptor;
+import org.hibernate.type.descriptor.sql.VarcharTypeDescriptor;
+
+/**
+ *
+ * @author Gail Badner
+ */
+public class H2DialectOverridePrefixedVarcharSqlTypeDesc extends H2Dialect {
+ public SqlTypeDescriptor resolveSqlTypeDescriptor(SqlTypeDescriptor sqlTypeDescriptor) {
+ return sqlTypeDescriptor == StoredPrefixedStringType.INSTANCE.getSqlTypeDescriptor() ?
+ VarcharTypeDescriptor.INSTANCE :
+ super.resolveSqlTypeDescriptor( sqlTypeDescriptor );
+ }
+}
+
diff --git a/hibernate-core/src/test/java/org/hibernate/test/typeoverride/H2DialectOverrideVarcharSqlCode.java b/hibernate-core/src/test/java/org/hibernate/test/typeoverride/H2DialectOverrideVarcharSqlCode.java
new file mode 100644
index 0000000000..7e2be2b90d
--- /dev/null
+++ b/hibernate-core/src/test/java/org/hibernate/test/typeoverride/H2DialectOverrideVarcharSqlCode.java
@@ -0,0 +1,42 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2011, 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
+ */
+package org.hibernate.test.typeoverride;
+
+import java.sql.Types;
+
+import org.hibernate.dialect.H2Dialect;
+import org.hibernate.type.descriptor.sql.SqlTypeDescriptor;
+
+/**
+ *
+ * @author Gail Badner
+ */
+public class H2DialectOverrideVarcharSqlCode extends H2Dialect {
+ public SqlTypeDescriptor getSqlTypeDescriptorOverride(int sqlCode) {
+ return sqlCode == Types.VARCHAR ?
+ StoredPrefixedStringType.INSTANCE.getSqlTypeDescriptor() :
+ super.getSqlTypeDescriptorOverride( sqlCode );
+ }
+}
+
diff --git a/hibernate-core/src/test/java/org/hibernate/test/typeoverride/StoredPrefixedStringType.java b/hibernate-core/src/test/java/org/hibernate/test/typeoverride/StoredPrefixedStringType.java
new file mode 100644
index 0000000000..e00fb49984
--- /dev/null
+++ b/hibernate-core/src/test/java/org/hibernate/test/typeoverride/StoredPrefixedStringType.java
@@ -0,0 +1,105 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2011, 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
+ */
+package org.hibernate.test.typeoverride;
+
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+import org.hibernate.AssertionFailure;
+import org.hibernate.dialect.Dialect;
+import org.hibernate.type.AbstractSingleColumnStandardBasicType;
+import org.hibernate.type.DiscriminatorType;
+import org.hibernate.type.StringType;
+import org.hibernate.type.descriptor.ValueBinder;
+import org.hibernate.type.descriptor.ValueExtractor;
+import org.hibernate.type.descriptor.WrapperOptions;
+import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
+import org.hibernate.type.descriptor.sql.BasicBinder;
+import org.hibernate.type.descriptor.sql.BasicExtractor;
+import org.hibernate.type.descriptor.sql.SqlTypeDescriptor;
+import org.hibernate.type.descriptor.sql.VarcharTypeDescriptor;
+
+/**
+ *
+ * @author Gail Badner
+ */
+public class StoredPrefixedStringType
+ extends AbstractSingleColumnStandardBasicType
+ implements DiscriminatorType {
+ public static final String PREFIX = "PRE:";
+ private static final SqlTypeDescriptor PREFIXED_VARCHAR_TYPE_DESCRIPTOR =
+ new VarcharTypeDescriptor() {
+ public ValueBinder getBinder(final JavaTypeDescriptor javaTypeDescriptor) {
+ return new BasicBinder( javaTypeDescriptor, this ) {
+ @Override
+ protected void doBind(PreparedStatement st, X value, int index, WrapperOptions options) throws SQLException {
+ String stringValue = javaTypeDescriptor.unwrap( value, String.class, options );
+ st.setString( index, PREFIX + stringValue );
+ }
+ };
+ }
+
+ public ValueExtractor getExtractor(final JavaTypeDescriptor javaTypeDescriptor) {
+ return new BasicExtractor( javaTypeDescriptor, this ) {
+ @Override
+ protected X doExtract(ResultSet rs, String name, WrapperOptions options) throws SQLException {
+ String stringValue = rs.getString( name );
+ if ( ! stringValue.startsWith( PREFIX ) ) {
+ throw new AssertionFailure( "Value read from resultset does not have prefix." );
+ }
+ return javaTypeDescriptor.wrap( stringValue.substring( PREFIX.length() ), options );
+ }
+ };
+ }
+ };
+
+
+ public static final StoredPrefixedStringType INSTANCE = new StoredPrefixedStringType();
+
+ public StoredPrefixedStringType() {
+ super( PREFIXED_VARCHAR_TYPE_DESCRIPTOR, StringType.INSTANCE.getJavaTypeDescriptor() );
+ }
+
+ public String getName() {
+ return StringType.INSTANCE.getName();
+ }
+
+ @Override
+ protected boolean registerUnderJavaType() {
+ return true;
+ }
+
+ public String objectToSQLString(String value, Dialect dialect) throws Exception {
+ return StringType.INSTANCE.objectToSQLString( value, dialect );
+ }
+
+ public String stringToObject(String xml) throws Exception {
+ return StringType.INSTANCE.stringToObject( xml );
+ }
+
+ public String toString(String value) {
+ return StringType.INSTANCE.toString( value );
+ }
+}
\ No newline at end of file
diff --git a/hibernate-core/src/test/java/org/hibernate/test/typeoverride/TypeOverrideTest.java b/hibernate-core/src/test/java/org/hibernate/test/typeoverride/TypeOverrideTest.java
new file mode 100644
index 0000000000..f15f158df6
--- /dev/null
+++ b/hibernate-core/src/test/java/org/hibernate/test/typeoverride/TypeOverrideTest.java
@@ -0,0 +1,208 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2011, 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
+ */
+package org.hibernate.test.typeoverride;
+
+import org.hibernate.Session;
+import org.hibernate.cfg.Configuration;
+import org.hibernate.dialect.PostgreSQLDialect;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.testing.junit.functional.FunctionalTestCase;
+import org.hibernate.type.StandardBasicTypes;
+import org.hibernate.type.descriptor.sql.BlobTypeDescriptor;
+import org.hibernate.type.descriptor.sql.ClobTypeDescriptor;
+import org.hibernate.type.descriptor.sql.IntegerTypeDescriptor;
+import org.hibernate.type.descriptor.sql.SqlTypeDescriptor;
+import org.hibernate.type.descriptor.sql.VarcharTypeDescriptor;
+
+/**
+ *
+ * @author Gail Badner
+ */
+public class TypeOverrideTest extends FunctionalTestCase {
+
+ public TypeOverrideTest(String string) {
+ super( string );
+ }
+
+ public String[] getMappings() {
+ return new String[] { "typeoverride/Entity.hbm.xml" };
+ }
+
+ @Override
+ public void configure(Configuration cfg) {
+ cfg.registerTypeOverride( StoredPrefixedStringType.INSTANCE );
+ }
+
+ public void testStandardBasicSqlTypeDescriptor() {
+ // no override
+ assertTrue( StandardBasicTypes.isStandardBasicSqlTypeDescriptor( IntegerTypeDescriptor.INSTANCE ) );
+ assertSame( IntegerTypeDescriptor.INSTANCE, getResolvedSqlTypeDescriptor( IntegerTypeDescriptor.INSTANCE ) );
+
+ // override depends on Dialect.useInputStreamToInsertBlob();
+ // Postgresql explicitly overrides BlobTypeDescriptor.DEFAULT
+ assertTrue( StandardBasicTypes.isStandardBasicSqlTypeDescriptor( BlobTypeDescriptor.DEFAULT ) );
+ if ( getDialect().useInputStreamToInsertBlob() ) {
+ assertSame(
+ BlobTypeDescriptor.STREAM_BINDING,
+ getDialect().resolveSqlTypeDescriptor( BlobTypeDescriptor.DEFAULT )
+ );
+ }
+ else if ( PostgreSQLDialect.class.isInstance( getDialect() ) ) {
+ assertSame(
+ BlobTypeDescriptor.BLOB_BINDING,
+ getDialect().resolveSqlTypeDescriptor( BlobTypeDescriptor.DEFAULT )
+ );
+ }
+ else {
+ assertSame(
+ BlobTypeDescriptor.DEFAULT,
+ getDialect().resolveSqlTypeDescriptor( BlobTypeDescriptor.DEFAULT )
+ );
+ }
+ }
+
+ public void testNonStandardSqlTypeDescriptor() {
+ // no override
+ SqlTypeDescriptor sqlTypeDescriptor = new IntegerTypeDescriptor();
+ assertFalse( StandardBasicTypes.isStandardBasicSqlTypeDescriptor( sqlTypeDescriptor ) );
+ assertSame( sqlTypeDescriptor, getResolvedSqlTypeDescriptor( sqlTypeDescriptor ) );
+
+ // no override; (ClobTypeDescriptor.DEFAULT is overridden
+ // if Dialect.useInputStreamToInsertBlob() is true)
+ assertFalse( StandardBasicTypes.isStandardBasicSqlTypeDescriptor( ClobTypeDescriptor.CLOB_BINDING ) );
+ assertSame( ClobTypeDescriptor.CLOB_BINDING, getResolvedSqlTypeDescriptor( ClobTypeDescriptor.CLOB_BINDING ) );
+ }
+
+ public void testDialectWithNonStandardSqlTypeDescriptor() {
+ assertNotSame( VarcharTypeDescriptor.INSTANCE, StoredPrefixedStringType.INSTANCE.getSqlTypeDescriptor() );
+ if ( H2DialectOverridePrefixedVarcharSqlTypeDesc.class.isInstance( getDialect() ) ) {
+ // TODO: dialect is currently a global; how can this be tested in the testsuite?
+ assertSame(
+ VarcharTypeDescriptor.INSTANCE,
+ getResolvedSqlTypeDescriptor( StoredPrefixedStringType.INSTANCE.getSqlTypeDescriptor() )
+ );
+ }
+ else {
+ assertSame(
+ StoredPrefixedStringType.INSTANCE.getSqlTypeDescriptor(),
+ getResolvedSqlTypeDescriptor( StoredPrefixedStringType.INSTANCE.getSqlTypeDescriptor() )
+ );
+ }
+
+ if ( H2DialectOverrideVarcharSqlCode.class.isInstance( getDialect() ) ) {
+ // TODO: dialect is currently a global; how can this be tested in the testsuite?
+ assertSame(
+ StoredPrefixedStringType.INSTANCE.getSqlTypeDescriptor(),
+ getResolvedSqlTypeDescriptor( VarcharTypeDescriptor.INSTANCE )
+ );
+ }
+ else {
+ assertSame(
+ VarcharTypeDescriptor.INSTANCE,
+ getResolvedSqlTypeDescriptor( VarcharTypeDescriptor.INSTANCE )
+ );
+ }
+ }
+
+ private SqlTypeDescriptor getResolvedSqlTypeDescriptor(SqlTypeDescriptor sqlTypeDescriptor) {
+ return ( ( SessionFactoryImplementor ) getSessions() )
+ .getTypeResolver()
+ .resolveSqlTypeDescriptor( sqlTypeDescriptor );
+ }
+
+ public void testInsert() {
+ Session s = openSession();
+ s.getTransaction().begin();
+ Entity e = new Entity( "name" );
+ s.save( e );
+ s.getTransaction().commit();
+ s.close();
+
+ s = openSession();
+ s.getTransaction().begin();
+ e = ( Entity ) s.get( Entity.class, e.getId() );
+ assertFalse( e.getName().startsWith( StoredPrefixedStringType.PREFIX ) );
+ assertEquals( "name", e.getName() );
+ s.delete( e );
+ s.getTransaction().commit();
+ s.close();
+ }
+
+ public void testRegisteredFunction() {
+ Session s = openSession();
+ s.getTransaction().begin();
+ Entity e = new Entity( "name " );
+ s.save( e );
+ s.getTransaction().commit();
+ s.close();
+
+ s = openSession();
+ s.getTransaction().begin();
+ e = ( Entity ) s.get( Entity.class, e.getId() );
+ assertFalse( e.getName().startsWith( StoredPrefixedStringType.PREFIX ) );
+ assertEquals( "name ", e.getName() );
+ s.getTransaction().commit();
+ s.close();
+
+ s = openSession();
+ s.getTransaction().begin();
+ String trimmedName = ( String ) s.createQuery( "select trim( TRAILING from e.name ) from Entity e" ).uniqueResult();
+ // trim(...) is a "standard" DB function returning VarcharTypeDescriptor.INSTANCE,
+ // so the prefix will not be removed unless
+ // 1) getDialect().getSqlTypeDescriptorOverride( VarcharTypeDescriptor.INSTANCE )
+ // returns StoredPrefixedStringType.INSTANCE.getSqlTypeDescriptor()
+ // (H2DialectOverrideVarcharSqlCode does this)
+ // or 2) getDialect().getSqlTypeDescriptorOverride( StoredPrefixedStringType.INSTANCE.getSqlTypeDescriptor() )
+ // returns VarcharTypeDescriptor.INSTANCE
+ // (H2DialectOverridePrefixedVarcharSqlTypeDesc does this)
+ // TODO: dialect is currently a global; how can this be tested in the testsuite?
+ assertNotSame( VarcharTypeDescriptor.INSTANCE, StoredPrefixedStringType.INSTANCE.getSqlTypeDescriptor() );
+ if ( getDialect().resolveSqlTypeDescriptor( VarcharTypeDescriptor.INSTANCE ) ==
+ StoredPrefixedStringType.INSTANCE.getSqlTypeDescriptor() ||
+ getDialect().resolveSqlTypeDescriptor( StoredPrefixedStringType.INSTANCE.getSqlTypeDescriptor() ) ==
+ VarcharTypeDescriptor.INSTANCE ) {
+ assertFalse( trimmedName.startsWith( StoredPrefixedStringType.PREFIX ) );
+ assertEquals( "name", trimmedName );
+ }
+ else {
+ assertSame(
+ VarcharTypeDescriptor.INSTANCE,
+ ( ( SessionFactoryImplementor ) getSessions() )
+ .getTypeResolver()
+ .resolveSqlTypeDescriptor( VarcharTypeDescriptor.INSTANCE )
+ );
+ assertTrue( trimmedName.startsWith( StoredPrefixedStringType.PREFIX ) );
+ assertEquals( StoredPrefixedStringType.PREFIX + "name", trimmedName );
+ }
+ s.delete( e );
+ s.getTransaction().commit();
+ s.close();
+ }
+}
+
+
+
+
+
diff --git a/hibernate-core/src/test/java/org/hibernate/type/descriptor/sql/StringValueMappingTest.java b/hibernate-core/src/test/java/org/hibernate/type/descriptor/sql/StringValueMappingTest.java
index 7e870dc8d8..3fd78a2f03 100644
--- a/hibernate-core/src/test/java/org/hibernate/type/descriptor/sql/StringValueMappingTest.java
+++ b/hibernate-core/src/test/java/org/hibernate/type/descriptor/sql/StringValueMappingTest.java
@@ -36,8 +36,6 @@ import org.hibernate.type.descriptor.ValueBinder;
import org.hibernate.type.descriptor.ValueExtractor;
import org.hibernate.type.descriptor.WrapperOptions;
import org.hibernate.type.descriptor.java.StringTypeDescriptor;
-import org.hibernate.type.descriptor.sql.ClobTypeDescriptor;
-import org.hibernate.type.descriptor.sql.VarcharTypeDescriptor;
/**
* TODO : javadoc
@@ -48,7 +46,7 @@ public class StringValueMappingTest extends TestCase {
private final StringTypeDescriptor stringJavaDescriptor = new StringTypeDescriptor();
private final VarcharTypeDescriptor varcharSqlDescriptor = new VarcharTypeDescriptor();
- private final ClobTypeDescriptor clobSqlDescriptor = new ClobTypeDescriptor();
+ private final ClobTypeDescriptor clobSqlDescriptor = ClobTypeDescriptor.DEFAULT;
private final WrapperOptions wrapperOptions = new WrapperOptions() {
public boolean useStreamForLobBinding() {
@@ -58,6 +56,10 @@ public class StringValueMappingTest extends TestCase {
public LobCreator getLobCreator() {
return NonContextualLobCreator.INSTANCE;
}
+
+ public SqlTypeDescriptor resolveSqlTypeDescriptor(SqlTypeDescriptor sqlTypeDescriptor) {
+ return sqlTypeDescriptor;
+ }
};
public static final String COLUMN_NAME = "n/a";
From 7243d04541f5bb81f409d7f1033a133fc79e90ea Mon Sep 17 00:00:00 2001
From: Gail Badner
Date: Fri, 25 Feb 2011 16:29:09 -0800
Subject: [PATCH 02/19] HHH-5941 : remove deprecated set(), nullSafeSet(),
get(), nullSafeGet() methods and add SessionImplementer argument to
UserType.nullSafeGet()/nullSafeSet()
---
...AbstractSingleColumnStandardBasicType.java | 43 -------------------
.../java/org/hibernate/type/CustomType.java | 6 +--
.../java/org/hibernate/type/EnumType.java | 5 ++-
.../org/hibernate/type/SingleColumnType.java | 30 -------------
.../org/hibernate/type/StringClobType.java | 5 ++-
.../java/org/hibernate/usertype/UserType.java | 12 ++++--
.../annotations/entity/CasterStringType.java | 5 ++-
.../entity/MonetaryAmountUserType.java | 8 ++--
.../annotations/entity/PhoneNumberType.java | 5 ++-
.../test/annotations/generics/StateType.java | 5 ++-
.../test/annotations/type/MyOidType.java | 16 +++----
.../test/cut/MonetoryAmountUserType.java | 8 ++--
.../test/hql/ClassificationType.java | 9 ++--
.../instrument/domain/CustomBlobType.java | 9 ++--
.../org/hibernate/test/rowid/RowIdType.java | 5 ++-
.../test/sql/hand/MonetaryAmountUserType.java | 5 ++-
.../DefaultValueIntegerType.java | 5 ++-
.../hibernate/type/BasicTypeRegistryTest.java | 6 +--
.../envers/entities/RevisionTypeType.java | 29 ++++++-------
.../customtype/ParametrizedTestUserType.java | 12 +++---
.../test/entities/ids/CustomEnumUserType.java | 6 ++-
21 files changed, 87 insertions(+), 147 deletions(-)
diff --git a/hibernate-core/src/main/java/org/hibernate/type/AbstractSingleColumnStandardBasicType.java b/hibernate-core/src/main/java/org/hibernate/type/AbstractSingleColumnStandardBasicType.java
index 51c6b95122..131f636fa1 100644
--- a/hibernate-core/src/main/java/org/hibernate/type/AbstractSingleColumnStandardBasicType.java
+++ b/hibernate-core/src/main/java/org/hibernate/type/AbstractSingleColumnStandardBasicType.java
@@ -48,38 +48,10 @@ public abstract class AbstractSingleColumnStandardBasicType
super( sqlTypeDescriptor, javaTypeDescriptor );
}
- private static WrapperOptions NO_OPTIONS = new WrapperOptions() {
- public boolean useStreamForLobBinding() {
- return false;
- }
-
- public LobCreator getLobCreator() {
- return NonContextualLobCreator.INSTANCE;
- }
-
- public SqlTypeDescriptor resolveSqlTypeDescriptor(SqlTypeDescriptor sqlTypeDescriptor) {
- return sqlTypeDescriptor;
- }
- };
-
public final int sqlType() {
return getSqlTypeDescriptor().getSqlType();
}
- /**
- * {@inheritDoc}
- */
- public T nullSafeGet(ResultSet rs, String name) throws HibernateException, SQLException {
- return nullSafeGet( rs, name, NO_OPTIONS );
- }
-
- /**
- * {@inheritDoc}
- */
- public Object get(ResultSet rs, String name) throws HibernateException, SQLException {
- return nullSafeGet( rs, name );
- }
-
/**
* {@inheritDoc}
*/
@@ -89,19 +61,4 @@ public abstract class AbstractSingleColumnStandardBasicType
nullSafeSet( st, value, index, session );
}
}
-
- /**
- * {@inheritDoc}
- */
- public void nullSafeSet(PreparedStatement st, T value, int index) throws HibernateException, SQLException {
- nullSafeSet( st, value, index, NO_OPTIONS );
- }
-
- /**
- * {@inheritDoc}
- */
- public void set(PreparedStatement st, T value, int index) throws HibernateException, SQLException {
- nullSafeSet( st, value, index );
- }
-
}
\ No newline at end of file
diff --git a/hibernate-core/src/main/java/org/hibernate/type/CustomType.java b/hibernate-core/src/main/java/org/hibernate/type/CustomType.java
index 123ad4e757..73834769b7 100644
--- a/hibernate-core/src/main/java/org/hibernate/type/CustomType.java
+++ b/hibernate-core/src/main/java/org/hibernate/type/CustomType.java
@@ -106,7 +106,7 @@ public class CustomType extends AbstractType implements IdentifierType, Discrimi
public Object nullSafeGet(ResultSet rs, String[] names, SessionImplementor session, Object owner)
throws HibernateException, SQLException {
- return userType.nullSafeGet(rs, names, owner);
+ return userType.nullSafeGet(rs, names, session, owner);
}
public Object nullSafeGet(ResultSet rs, String columnName, SessionImplementor session, Object owner)
@@ -137,13 +137,13 @@ public class CustomType extends AbstractType implements IdentifierType, Discrimi
public void nullSafeSet(PreparedStatement st, Object value, int index, boolean[] settable, SessionImplementor session)
throws HibernateException, SQLException {
if ( settable[0] ) {
- userType.nullSafeSet( st, value, index );
+ userType.nullSafeSet( st, value, index, session );
}
}
public void nullSafeSet(PreparedStatement st, Object value, int index, SessionImplementor session)
throws HibernateException, SQLException {
- userType.nullSafeSet( st, value, index );
+ userType.nullSafeSet( st, value, index, session );
}
@SuppressWarnings({ "UnusedDeclaration" })
diff --git a/hibernate-core/src/main/java/org/hibernate/type/EnumType.java b/hibernate-core/src/main/java/org/hibernate/type/EnumType.java
index b30571ad2a..a2afb739fb 100644
--- a/hibernate-core/src/main/java/org/hibernate/type/EnumType.java
+++ b/hibernate-core/src/main/java/org/hibernate/type/EnumType.java
@@ -34,6 +34,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.hibernate.HibernateException;
+import org.hibernate.engine.SessionImplementor;
import org.hibernate.usertype.EnhancedUserType;
import org.hibernate.usertype.ParameterizedType;
import org.hibernate.util.ReflectHelper;
@@ -97,7 +98,7 @@ public class EnumType implements EnhancedUserType, ParameterizedType, Serializab
}
- public Object nullSafeGet(ResultSet rs, String[] names, Object owner) throws HibernateException, SQLException {
+ public Object nullSafeGet(ResultSet rs, String[] names, SessionImplementor session, Object owner) throws HibernateException, SQLException {
Object object = rs.getObject( names[0] );
if ( rs.wasNull() ) {
if ( IS_VALUE_TRACING_ENABLED ) {
@@ -130,7 +131,7 @@ public class EnumType implements EnhancedUserType, ParameterizedType, Serializab
}
}
- public void nullSafeSet(PreparedStatement st, Object value, int index) throws HibernateException, SQLException {
+ public void nullSafeSet(PreparedStatement st, Object value, int index, SessionImplementor session) throws HibernateException, SQLException {
if ( value == null ) {
if ( IS_VALUE_TRACING_ENABLED ) {
log().debug( "Binding null to parameter: {}", index );
diff --git a/hibernate-core/src/main/java/org/hibernate/type/SingleColumnType.java b/hibernate-core/src/main/java/org/hibernate/type/SingleColumnType.java
index c93fdad579..247a749ca7 100644
--- a/hibernate-core/src/main/java/org/hibernate/type/SingleColumnType.java
+++ b/hibernate-core/src/main/java/org/hibernate/type/SingleColumnType.java
@@ -46,12 +46,6 @@ public interface SingleColumnType extends Type {
public T fromStringValue(String xml) throws HibernateException;
- /**
- * @deprecated Use {@link #nullSafeGet(ResultSet, String, SessionImplementor)} instead
- */
- @SuppressWarnings({ "JavaDoc" })
- public T nullSafeGet(ResultSet rs, String name) throws HibernateException, SQLException;
-
/**
* Get a column value from a result set by name.
*
@@ -66,14 +60,6 @@ public interface SingleColumnType extends Type {
*/
public T nullSafeGet(ResultSet rs, String name, SessionImplementor session) throws HibernateException, SQLException;
- /**
- * DO NOT USER THIS FORM!
- *
- * @deprecated Use {@link #get(ResultSet, String, SessionImplementor)} instead.
- */
- @SuppressWarnings({ "JavaDoc" })
- public Object get(ResultSet rs, String name) throws HibernateException, SQLException;
-
/**
* Get a column value from a result set, without worrying about the possibility of null values.
*
@@ -88,22 +74,6 @@ public interface SingleColumnType extends Type {
*/
public Object get(ResultSet rs, String name, SessionImplementor session) throws HibernateException, SQLException;
- /**
- * DO NOT USE THIS FORM!
- *
- * @deprecated Use {@link #nullSafeSet(PreparedStatement, Object, int, SessionImplementor)} instead.
- */
- @SuppressWarnings({ "JavaDoc" })
- public void nullSafeSet(PreparedStatement st, T value, int index) throws HibernateException, SQLException;
-
- /**
- * DO NOT USE THIS FORM!
- *
- * @deprecated Use {@link #set(PreparedStatement, Object, int, SessionImplementor)} instead.
- */
- @SuppressWarnings({ "JavaDoc" })
- public void set(PreparedStatement st, T value, int index) throws HibernateException, SQLException;
-
/**
* Set a parameter value without worrying about the possibility of null
* values. Called from {@link #nullSafeSet} after nullness checks have
diff --git a/hibernate-core/src/main/java/org/hibernate/type/StringClobType.java b/hibernate-core/src/main/java/org/hibernate/type/StringClobType.java
index 6926186538..a233d019b2 100644
--- a/hibernate-core/src/main/java/org/hibernate/type/StringClobType.java
+++ b/hibernate-core/src/main/java/org/hibernate/type/StringClobType.java
@@ -33,6 +33,7 @@ import java.sql.SQLException;
import java.sql.Types;
import org.hibernate.HibernateException;
+import org.hibernate.engine.SessionImplementor;
import org.hibernate.usertype.UserType;
/**
@@ -59,7 +60,7 @@ public class StringClobType implements UserType, Serializable {
return x.hashCode();
}
- public Object nullSafeGet(ResultSet rs, String[] names, Object owner) throws HibernateException, SQLException {
+ public Object nullSafeGet(ResultSet rs, String[] names, SessionImplementor session, Object owner) throws HibernateException, SQLException {
Reader reader = rs.getCharacterStream( names[0] );
if ( reader == null ) return null;
StringBuilder result = new StringBuilder( 4096 );
@@ -75,7 +76,7 @@ public class StringClobType implements UserType, Serializable {
return result.toString();
}
- public void nullSafeSet(PreparedStatement st, Object value, int index) throws HibernateException, SQLException {
+ public void nullSafeSet(PreparedStatement st, Object value, int index, SessionImplementor session) throws HibernateException, SQLException {
if ( value != null ) {
String string = (String) value;
StringReader reader = new StringReader( string );
diff --git a/hibernate-core/src/main/java/org/hibernate/usertype/UserType.java b/hibernate-core/src/main/java/org/hibernate/usertype/UserType.java
index d993bc13eb..9e538ae3c9 100644
--- a/hibernate-core/src/main/java/org/hibernate/usertype/UserType.java
+++ b/hibernate-core/src/main/java/org/hibernate/usertype/UserType.java
@@ -30,6 +30,7 @@ import java.sql.ResultSet;
import java.sql.SQLException;
import org.hibernate.HibernateException;
+import org.hibernate.engine.SessionImplementor;
/**
* This interface should be implemented by user-defined "types".
@@ -100,27 +101,30 @@ public interface UserType {
* Retrieve an instance of the mapped class from a JDBC resultset. Implementors
* should handle possibility of null values.
*
+ *
* @param rs a JDBC result set
* @param names the column names
- * @param owner the containing entity
- * @return Object
+ * @param session
+ *@param owner the containing entity @return Object
* @throws HibernateException
* @throws SQLException
*/
- public Object nullSafeGet(ResultSet rs, String[] names, Object owner) throws HibernateException, SQLException;
+ public Object nullSafeGet(ResultSet rs, String[] names, SessionImplementor session, Object owner) throws HibernateException, SQLException;
/**
* Write an instance of the mapped class to a prepared statement. Implementors
* should handle possibility of null values. A multi-column type should be written
* to parameters starting from index.
*
+ *
* @param st a JDBC prepared statement
* @param value the object to write
* @param index statement parameter index
+ * @param session
* @throws HibernateException
* @throws SQLException
*/
- public void nullSafeSet(PreparedStatement st, Object value, int index) throws HibernateException, SQLException;
+ public void nullSafeSet(PreparedStatement st, Object value, int index, SessionImplementor session) throws HibernateException, SQLException;
/**
* Return a deep copy of the persistent state, stopping at entities and at
diff --git a/hibernate-core/src/test/java/org/hibernate/test/annotations/entity/CasterStringType.java b/hibernate-core/src/test/java/org/hibernate/test/annotations/entity/CasterStringType.java
index 6c145b78eb..cdd058f35f 100644
--- a/hibernate-core/src/test/java/org/hibernate/test/annotations/entity/CasterStringType.java
+++ b/hibernate-core/src/test/java/org/hibernate/test/annotations/entity/CasterStringType.java
@@ -9,6 +9,7 @@ import java.sql.Types;
import java.util.Properties;
import org.hibernate.HibernateException;
+import org.hibernate.engine.SessionImplementor;
import org.hibernate.usertype.ParameterizedType;
import org.hibernate.usertype.UserType;
@@ -37,7 +38,7 @@ public class CasterStringType implements UserType, ParameterizedType {
return x.hashCode();
}
- public Object nullSafeGet(ResultSet rs, String[] names, Object owner) throws HibernateException, SQLException {
+ public Object nullSafeGet(ResultSet rs, String[] names, SessionImplementor session, Object owner) throws HibernateException, SQLException {
String result = rs.getString( names[0] );
if ( rs.wasNull() ) return null;
if ( parameters.getProperty( CAST ).equals( "lower" ) ) {
@@ -48,7 +49,7 @@ public class CasterStringType implements UserType, ParameterizedType {
}
}
- public void nullSafeSet(PreparedStatement st, Object value, int index) throws HibernateException, SQLException {
+ public void nullSafeSet(PreparedStatement st, Object value, int index, SessionImplementor session) throws HibernateException, SQLException {
if ( value == null ) {
st.setNull( index, sqlTypes()[0] );
}
diff --git a/hibernate-core/src/test/java/org/hibernate/test/annotations/entity/MonetaryAmountUserType.java b/hibernate-core/src/test/java/org/hibernate/test/annotations/entity/MonetaryAmountUserType.java
index 8925958438..670704a919 100644
--- a/hibernate-core/src/test/java/org/hibernate/test/annotations/entity/MonetaryAmountUserType.java
+++ b/hibernate-core/src/test/java/org/hibernate/test/annotations/entity/MonetaryAmountUserType.java
@@ -62,8 +62,8 @@ public class MonetaryAmountUserType implements CompositeUserType {
public Object nullSafeGet(ResultSet rs, String[] names, SessionImplementor session, Object owner)
throws HibernateException, SQLException {
- BigDecimal amt = (BigDecimal) Hibernate.BIG_DECIMAL.nullSafeGet( rs, names[0] );
- Currency cur = (Currency) Hibernate.CURRENCY.nullSafeGet( rs, names[1] );
+ BigDecimal amt = (BigDecimal) Hibernate.BIG_DECIMAL.nullSafeGet( rs, names[0], session);
+ Currency cur = (Currency) Hibernate.CURRENCY.nullSafeGet( rs, names[1], session );
if ( amt == null ) return null;
return new MonetaryAmount( amt, cur );
}
@@ -75,8 +75,8 @@ public class MonetaryAmountUserType implements CompositeUserType {
MonetaryAmount ma = (MonetaryAmount) value;
BigDecimal amt = ma == null ? null : ma.getAmount();
Currency cur = ma == null ? null : ma.getCurrency();
- Hibernate.BIG_DECIMAL.nullSafeSet( st, amt, index );
- Hibernate.CURRENCY.nullSafeSet( st, cur, index + 1 );
+ Hibernate.BIG_DECIMAL.nullSafeSet( st, amt, index, session );
+ Hibernate.CURRENCY.nullSafeSet( st, cur, index + 1, session );
}
public Object deepCopy(Object value) throws HibernateException {
diff --git a/hibernate-core/src/test/java/org/hibernate/test/annotations/entity/PhoneNumberType.java b/hibernate-core/src/test/java/org/hibernate/test/annotations/entity/PhoneNumberType.java
index 0c642ed694..87180b0621 100644
--- a/hibernate-core/src/test/java/org/hibernate/test/annotations/entity/PhoneNumberType.java
+++ b/hibernate-core/src/test/java/org/hibernate/test/annotations/entity/PhoneNumberType.java
@@ -29,6 +29,7 @@ import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import org.hibernate.HibernateException;
+import org.hibernate.engine.SessionImplementor;
import org.hibernate.usertype.UserType;
/**
@@ -54,7 +55,7 @@ public class PhoneNumberType implements UserType {
return x.hashCode();
}
- public Object nullSafeGet(ResultSet rs, String[] names, Object owner) throws HibernateException, SQLException {
+ public Object nullSafeGet(ResultSet rs, String[] names, SessionImplementor session, Object owner) throws HibernateException, SQLException {
String result = rs.getString( names[0] );
if ( rs.wasNull() ) return null;
@@ -66,7 +67,7 @@ public class PhoneNumberType implements UserType {
}
}
- public void nullSafeSet(PreparedStatement st, Object value, int index) throws HibernateException, SQLException {
+ public void nullSafeSet(PreparedStatement st, Object value, int index, SessionImplementor session) throws HibernateException, SQLException {
if ( value == null ) {
st.setNull( index, sqlTypes()[0] );
return;
diff --git a/hibernate-core/src/test/java/org/hibernate/test/annotations/generics/StateType.java b/hibernate-core/src/test/java/org/hibernate/test/annotations/generics/StateType.java
index 88e1d4c7db..1ac9929ad2 100644
--- a/hibernate-core/src/test/java/org/hibernate/test/annotations/generics/StateType.java
+++ b/hibernate-core/src/test/java/org/hibernate/test/annotations/generics/StateType.java
@@ -7,6 +7,7 @@ import java.sql.SQLException;
import java.sql.PreparedStatement;
import java.sql.Types;
+import org.hibernate.engine.SessionImplementor;
import org.hibernate.usertype.UserType;
import org.hibernate.HibernateException;
@@ -32,13 +33,13 @@ public class StateType implements UserType {
return x.hashCode();
}
- public Object nullSafeGet(ResultSet rs, String[] names, Object owner) throws HibernateException, SQLException {
+ public Object nullSafeGet(ResultSet rs, String[] names, SessionImplementor session, Object owner) throws HibernateException, SQLException {
int result = rs.getInt( names[0] );
if ( rs.wasNull() ) return null;
return State.values()[result];
}
- public void nullSafeSet(PreparedStatement st, Object value, int index) throws HibernateException, SQLException {
+ public void nullSafeSet(PreparedStatement st, Object value, int index, SessionImplementor session) throws HibernateException, SQLException {
if (value == null) {
st.setNull( index, Types.INTEGER );
}
diff --git a/hibernate-core/src/test/java/org/hibernate/test/annotations/type/MyOidType.java b/hibernate-core/src/test/java/org/hibernate/test/annotations/type/MyOidType.java
index 608ace2c4c..8717a91965 100644
--- a/hibernate-core/src/test/java/org/hibernate/test/annotations/type/MyOidType.java
+++ b/hibernate-core/src/test/java/org/hibernate/test/annotations/type/MyOidType.java
@@ -93,10 +93,10 @@ public class MyOidType implements CompositeUserType {
public Object nullSafeGet(
ResultSet aResultSet, String[] names, SessionImplementor aSessionImplementor, Object aObject
) throws HibernateException, SQLException {
- Integer highval = (Integer) Hibernate.INTEGER.nullSafeGet( aResultSet, names[0] );
- Integer midval = (Integer) Hibernate.INTEGER.nullSafeGet( aResultSet, names[1] );
- Integer lowval = (Integer) Hibernate.INTEGER.nullSafeGet( aResultSet, names[2] );
- Integer other = (Integer) Hibernate.INTEGER.nullSafeGet( aResultSet, names[3] );
+ Integer highval = (Integer) Hibernate.INTEGER.nullSafeGet( aResultSet, names[0], aSessionImplementor );
+ Integer midval = (Integer) Hibernate.INTEGER.nullSafeGet( aResultSet, names[1], aSessionImplementor );
+ Integer lowval = (Integer) Hibernate.INTEGER.nullSafeGet( aResultSet, names[2], aSessionImplementor );
+ Integer other = (Integer) Hibernate.INTEGER.nullSafeGet( aResultSet, names[3], aSessionImplementor );
return new MyOid( highval, midval, lowval, other );
}
@@ -113,10 +113,10 @@ public class MyOidType implements CompositeUserType {
c = (MyOid) value;
}
- Hibernate.INTEGER.nullSafeSet( aPreparedStatement, c.getHigh(), index );
- Hibernate.INTEGER.nullSafeSet( aPreparedStatement, c.getMiddle(), index + 1 );
- Hibernate.INTEGER.nullSafeSet( aPreparedStatement, c.getLow(), index + 2 );
- Hibernate.INTEGER.nullSafeSet( aPreparedStatement, c.getOther(), index + 3 );
+ Hibernate.INTEGER.nullSafeSet( aPreparedStatement, c.getHigh(), index, aSessionImplementor );
+ Hibernate.INTEGER.nullSafeSet( aPreparedStatement, c.getMiddle(), index + 1, aSessionImplementor );
+ Hibernate.INTEGER.nullSafeSet( aPreparedStatement, c.getLow(), index + 2, aSessionImplementor );
+ Hibernate.INTEGER.nullSafeSet( aPreparedStatement, c.getOther(), index + 3, aSessionImplementor );
}
public Object deepCopy(Object aObject) throws HibernateException {
diff --git a/hibernate-core/src/test/java/org/hibernate/test/cut/MonetoryAmountUserType.java b/hibernate-core/src/test/java/org/hibernate/test/cut/MonetoryAmountUserType.java
index 891544f141..220aa8252d 100755
--- a/hibernate-core/src/test/java/org/hibernate/test/cut/MonetoryAmountUserType.java
+++ b/hibernate-core/src/test/java/org/hibernate/test/cut/MonetoryAmountUserType.java
@@ -62,8 +62,8 @@ public class MonetoryAmountUserType implements CompositeUserType {
public Object nullSafeGet(ResultSet rs, String[] names, SessionImplementor session, Object owner)
throws HibernateException, SQLException {
- BigDecimal amt = (BigDecimal) Hibernate.BIG_DECIMAL.nullSafeGet( rs, names[0] );
- Currency cur = (Currency) Hibernate.CURRENCY.nullSafeGet( rs, names[1] );
+ BigDecimal amt = (BigDecimal) Hibernate.BIG_DECIMAL.nullSafeGet( rs, names[0], session );
+ Currency cur = (Currency) Hibernate.CURRENCY.nullSafeGet( rs, names[1], session );
if (amt==null) return null;
return new MonetoryAmount(amt, cur);
}
@@ -73,8 +73,8 @@ public class MonetoryAmountUserType implements CompositeUserType {
MonetoryAmount ma = (MonetoryAmount) value;
BigDecimal amt = ma == null ? null : ma.getAmount();
Currency cur = ma == null ? null : ma.getCurrency();
- Hibernate.BIG_DECIMAL.nullSafeSet(st, amt, index);
- Hibernate.CURRENCY.nullSafeSet(st, cur, index+1);
+ Hibernate.BIG_DECIMAL.nullSafeSet(st, amt, index, session);
+ Hibernate.CURRENCY.nullSafeSet(st, cur, index+1, session);
}
public Object deepCopy(Object value) throws HibernateException {
diff --git a/hibernate-core/src/test/java/org/hibernate/test/hql/ClassificationType.java b/hibernate-core/src/test/java/org/hibernate/test/hql/ClassificationType.java
index 945b14ad53..a4ee9282a7 100644
--- a/hibernate-core/src/test/java/org/hibernate/test/hql/ClassificationType.java
+++ b/hibernate-core/src/test/java/org/hibernate/test/hql/ClassificationType.java
@@ -1,5 +1,6 @@
package org.hibernate.test.hql;
+import org.hibernate.engine.SessionImplementor;
import org.hibernate.type.IntegerType;
import org.hibernate.usertype.EnhancedUserType;
import org.hibernate.HibernateException;
@@ -46,14 +47,14 @@ public class ClassificationType implements EnhancedUserType {
return x.hashCode();
}
- public Object nullSafeGet(ResultSet rs, String[] names, Object owner) throws HibernateException, SQLException {
- Integer ordinal = ( Integer ) IntegerType.INSTANCE.nullSafeGet( rs, names[0] );
+ public Object nullSafeGet(ResultSet rs, String[] names, SessionImplementor session, Object owner) throws HibernateException, SQLException {
+ Integer ordinal = ( Integer ) IntegerType.INSTANCE.nullSafeGet( rs, names[0], session );
return Classification.valueOf( ordinal );
}
- public void nullSafeSet(PreparedStatement st, Object value, int index) throws HibernateException, SQLException {
+ public void nullSafeSet(PreparedStatement st, Object value, int index, SessionImplementor session) throws HibernateException, SQLException {
Integer ordinal = value == null ? null : new Integer( ( ( Classification ) value ).ordinal() );
- Hibernate.INTEGER.nullSafeSet( st, ordinal, index );
+ Hibernate.INTEGER.nullSafeSet( st, ordinal, index, session );
}
public Object deepCopy(Object value) throws HibernateException {
diff --git a/hibernate-core/src/test/java/org/hibernate/test/instrument/domain/CustomBlobType.java b/hibernate-core/src/test/java/org/hibernate/test/instrument/domain/CustomBlobType.java
index a4ab267cd4..a16dd72c2e 100644
--- a/hibernate-core/src/test/java/org/hibernate/test/instrument/domain/CustomBlobType.java
+++ b/hibernate-core/src/test/java/org/hibernate/test/instrument/domain/CustomBlobType.java
@@ -9,6 +9,7 @@ import java.util.Arrays;
import org.hibernate.HibernateException;
import org.hibernate.Hibernate;
+import org.hibernate.engine.SessionImplementor;
import org.hibernate.usertype.UserType;
/**
@@ -18,17 +19,17 @@ public class CustomBlobType implements UserType {
/**
* {@inheritDoc}
*/
- public Object nullSafeGet(ResultSet rs, String names[], Object owner) throws SQLException {
+ public Object nullSafeGet(ResultSet rs, String names[], SessionImplementor session, Object owner) throws SQLException {
// cast just to make sure...
- return ( byte[] ) Hibernate.BINARY.nullSafeGet( rs, names[0] );
+ return ( byte[] ) Hibernate.BINARY.nullSafeGet( rs, names[0], session );
}
/**
* {@inheritDoc}
*/
- public void nullSafeSet(PreparedStatement ps, Object value, int index) throws SQLException, HibernateException {
+ public void nullSafeSet(PreparedStatement ps, Object value, int index, SessionImplementor session) throws SQLException, HibernateException {
// cast just to make sure...
- Hibernate.BINARY.nullSafeSet( ps, ( byte[] ) value, index );
+ Hibernate.BINARY.nullSafeSet( ps, ( byte[] ) value, index, session );
}
/**
diff --git a/hibernate-core/src/test/java/org/hibernate/test/rowid/RowIdType.java b/hibernate-core/src/test/java/org/hibernate/test/rowid/RowIdType.java
index dabed44826..4384a852fd 100755
--- a/hibernate-core/src/test/java/org/hibernate/test/rowid/RowIdType.java
+++ b/hibernate-core/src/test/java/org/hibernate/test/rowid/RowIdType.java
@@ -8,6 +8,7 @@ import java.sql.SQLException;
import java.sql.Types;
import org.hibernate.HibernateException;
+import org.hibernate.engine.SessionImplementor;
import org.hibernate.usertype.UserType;
/**
@@ -31,12 +32,12 @@ public class RowIdType implements UserType {
return x.hashCode();
}
- public Object nullSafeGet(ResultSet rs, String[] names, Object owner)
+ public Object nullSafeGet(ResultSet rs, String[] names, SessionImplementor session, Object owner)
throws HibernateException, SQLException {
return rs.getObject( names[0] );
}
- public void nullSafeSet(PreparedStatement st, Object value, int index)
+ public void nullSafeSet(PreparedStatement st, Object value, int index, SessionImplementor session)
throws HibernateException, SQLException {
throw new UnsupportedOperationException();
}
diff --git a/hibernate-core/src/test/java/org/hibernate/test/sql/hand/MonetaryAmountUserType.java b/hibernate-core/src/test/java/org/hibernate/test/sql/hand/MonetaryAmountUserType.java
index b548945aab..14ec4ed2f0 100644
--- a/hibernate-core/src/test/java/org/hibernate/test/sql/hand/MonetaryAmountUserType.java
+++ b/hibernate-core/src/test/java/org/hibernate/test/sql/hand/MonetaryAmountUserType.java
@@ -9,6 +9,7 @@ import java.sql.Types;
import java.util.Currency;
import org.hibernate.HibernateException;
+import org.hibernate.engine.SessionImplementor;
import org.hibernate.usertype.UserType;
/**
@@ -40,7 +41,7 @@ public class MonetaryAmountUserType
public Object nullSafeGet(ResultSet resultSet,
String[] names,
- Object owner)
+ SessionImplementor session, Object owner)
throws HibernateException, SQLException {
BigDecimal value = resultSet.getBigDecimal(names[0]);
@@ -53,7 +54,7 @@ public class MonetaryAmountUserType
public void nullSafeSet(PreparedStatement statement,
Object value,
- int index)
+ int index, SessionImplementor session)
throws HibernateException, SQLException {
if (value == null) {
diff --git a/hibernate-core/src/test/java/org/hibernate/test/typeparameters/DefaultValueIntegerType.java b/hibernate-core/src/test/java/org/hibernate/test/typeparameters/DefaultValueIntegerType.java
index 33eae97252..ad4662e610 100644
--- a/hibernate-core/src/test/java/org/hibernate/test/typeparameters/DefaultValueIntegerType.java
+++ b/hibernate-core/src/test/java/org/hibernate/test/typeparameters/DefaultValueIntegerType.java
@@ -9,6 +9,7 @@ import java.util.Properties;
import org.slf4j.LoggerFactory;
import org.hibernate.HibernateException;
+import org.hibernate.engine.SessionImplementor;
import org.hibernate.usertype.ParameterizedType;
import org.hibernate.usertype.UserType;
@@ -34,12 +35,12 @@ public class DefaultValueIntegerType implements UserType, ParameterizedType, Ser
return x.equals(y);
}
- public Object nullSafeGet(ResultSet rs, String[] names, Object owner) throws HibernateException, SQLException {
+ public Object nullSafeGet(ResultSet rs, String[] names, SessionImplementor session, Object owner) throws HibernateException, SQLException {
Number result = (Number) rs.getObject(names[0]);
return result==null ? defaultValue : new Integer(result.intValue());
}
- public void nullSafeSet(PreparedStatement st, Object value, int index) throws HibernateException, SQLException {
+ public void nullSafeSet(PreparedStatement st, Object value, int index, SessionImplementor session) throws HibernateException, SQLException {
if (value == null || defaultValue.equals(value) ) {
LoggerFactory.getLogger( getClass() ).trace("binding null to parameter: " + index);
st.setNull(index, Types.INTEGER);
diff --git a/hibernate-core/src/test/java/org/hibernate/type/BasicTypeRegistryTest.java b/hibernate-core/src/test/java/org/hibernate/type/BasicTypeRegistryTest.java
index a757dbfc6f..d43a5f049a 100644
--- a/hibernate-core/src/test/java/org/hibernate/type/BasicTypeRegistryTest.java
+++ b/hibernate-core/src/test/java/org/hibernate/type/BasicTypeRegistryTest.java
@@ -24,7 +24,6 @@
package org.hibernate.type;
import java.io.Serializable;
-import java.net.Socket;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
@@ -35,7 +34,6 @@ import junit.framework.TestCase;
import org.hibernate.HibernateException;
import org.hibernate.engine.SessionImplementor;
import org.hibernate.type.descriptor.java.StringTypeDescriptor;
-import org.hibernate.type.descriptor.java.UrlTypeDescriptor;
import org.hibernate.type.descriptor.sql.VarcharTypeDescriptor;
import org.hibernate.usertype.CompositeUserType;
import org.hibernate.usertype.UserType;
@@ -132,11 +130,11 @@ public class BasicTypeRegistryTest extends TestCase {
return 0;
}
- public Object nullSafeGet(ResultSet rs, String[] names, Object owner) throws HibernateException, SQLException {
+ public Object nullSafeGet(ResultSet rs, String[] names, SessionImplementor session, Object owner) throws HibernateException, SQLException {
return null;
}
- public void nullSafeSet(PreparedStatement st, Object value, int index) throws HibernateException, SQLException {
+ public void nullSafeSet(PreparedStatement st, Object value, int index, SessionImplementor session) throws HibernateException, SQLException {
}
public Object deepCopy(Object value) throws HibernateException {
diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/entities/RevisionTypeType.java b/hibernate-envers/src/main/java/org/hibernate/envers/entities/RevisionTypeType.java
index c97d538f6c..8829106ec7 100644
--- a/hibernate-envers/src/main/java/org/hibernate/envers/entities/RevisionTypeType.java
+++ b/hibernate-envers/src/main/java/org/hibernate/envers/entities/RevisionTypeType.java
@@ -29,9 +29,11 @@ import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
+import org.hibernate.engine.SessionImplementor;
import org.hibernate.envers.RevisionType;
import org.hibernate.HibernateException;
+import org.hibernate.type.IntegerType;
import org.hibernate.usertype.UserType;
/**
@@ -49,23 +51,20 @@ public class RevisionTypeType implements UserType {
return RevisionType.class;
}
- public RevisionType nullSafeGet(ResultSet resultSet, String[] names, Object owner) throws HibernateException, SQLException {
- byte representation = (byte) resultSet.getInt(names[0]);
- RevisionType result = null;
-
- if (!resultSet.wasNull()) {
- result = RevisionType.fromRepresentation(representation);
- }
-
- return result;
+ public RevisionType nullSafeGet(ResultSet resultSet, String[] names, SessionImplementor session, Object owner) throws HibernateException, SQLException {
+ Integer representationInt = IntegerType.INSTANCE.nullSafeGet( resultSet, names[0], session );
+ return representationInt == null ?
+ null :
+ RevisionType.fromRepresentation( representationInt.byteValue() );
}
- public void nullSafeSet(PreparedStatement preparedStatement, Object value, int index) throws HibernateException, SQLException {
- if (null == value) {
- preparedStatement.setNull(index, Types.TINYINT);
- } else {
- preparedStatement.setInt(index, ((RevisionType) value).getRepresentation());
- }
+ public void nullSafeSet(PreparedStatement preparedStatement, Object value, int index, SessionImplementor session) throws HibernateException, SQLException {
+ IntegerType.INSTANCE.nullSafeSet(
+ preparedStatement,
+ ( value == null ? null : ((RevisionType) value).getRepresentation().intValue() ),
+ index,
+ session
+ );
}
public Object deepCopy(Object value) throws HibernateException{
diff --git a/hibernate-envers/src/test/java/org/hibernate/envers/test/entities/customtype/ParametrizedTestUserType.java b/hibernate-envers/src/test/java/org/hibernate/envers/test/entities/customtype/ParametrizedTestUserType.java
index 83bc29b0e1..2a2825173c 100644
--- a/hibernate-envers/src/test/java/org/hibernate/envers/test/entities/customtype/ParametrizedTestUserType.java
+++ b/hibernate-envers/src/test/java/org/hibernate/envers/test/entities/customtype/ParametrizedTestUserType.java
@@ -30,8 +30,8 @@ import java.sql.SQLException;
import java.sql.Types;
import java.util.Properties;
-import org.hibernate.Hibernate;
import org.hibernate.HibernateException;
+import org.hibernate.engine.SessionImplementor;
import org.hibernate.type.StringType;
import org.hibernate.usertype.ParameterizedType;
import org.hibernate.usertype.UserType;
@@ -54,11 +54,11 @@ public class ParametrizedTestUserType implements UserType, ParameterizedType {
return String.class;
}
- public Object nullSafeGet(ResultSet rs, String[] names, Object owner) throws HibernateException, SQLException {
- return StringType.INSTANCE.nullSafeGet( rs, names[0] );
+ public Object nullSafeGet(ResultSet rs, String[] names, SessionImplementor session, Object owner) throws HibernateException, SQLException {
+ return StringType.INSTANCE.nullSafeGet( rs, names[0], session );
}
- public void nullSafeSet(PreparedStatement st, Object value, int index) throws HibernateException, SQLException {
+ public void nullSafeSet(PreparedStatement st, Object value, int index, SessionImplementor session) throws HibernateException, SQLException {
if (value != null) {
String v = (String) value;
if (!v.startsWith(param1)) {
@@ -67,10 +67,10 @@ public class ParametrizedTestUserType implements UserType, ParameterizedType {
if (!v.endsWith(param2)) {
v = v + param2;
}
- StringType.INSTANCE.nullSafeSet(st, v, index);
+ StringType.INSTANCE.nullSafeSet(st, v, index, session);
}
else {
- StringType.INSTANCE.nullSafeSet( st, null, index );
+ StringType.INSTANCE.nullSafeSet( st, null, index, session );
}
}
diff --git a/hibernate-envers/src/test/java/org/hibernate/envers/test/entities/ids/CustomEnumUserType.java b/hibernate-envers/src/test/java/org/hibernate/envers/test/entities/ids/CustomEnumUserType.java
index 69c590052c..2f39c24146 100644
--- a/hibernate-envers/src/test/java/org/hibernate/envers/test/entities/ids/CustomEnumUserType.java
+++ b/hibernate-envers/src/test/java/org/hibernate/envers/test/entities/ids/CustomEnumUserType.java
@@ -30,6 +30,8 @@ import java.sql.SQLException;
import java.sql.Types;
import org.hibernate.HibernateException;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.type.StringType;
import org.hibernate.usertype.UserType;
/**
@@ -60,7 +62,7 @@ public class CustomEnumUserType implements UserType {
return (x == null) ? 0 : x.hashCode();
}
- public Object nullSafeGet(ResultSet rs, String[] names, Object owner) throws HibernateException, SQLException {
+ public Object nullSafeGet(ResultSet rs, String[] names, SessionImplementor session, Object owner) throws HibernateException, SQLException {
String name = rs.getString(names[0]);
if (rs.wasNull()) {
return null;
@@ -68,7 +70,7 @@ public class CustomEnumUserType implements UserType {
return CustomEnum.fromYesNo(name);
}
- public void nullSafeSet(PreparedStatement st, Object value, int index) throws HibernateException, SQLException {
+ public void nullSafeSet(PreparedStatement st, Object value, int index, SessionImplementor session) throws HibernateException, SQLException {
CustomEnum val = (CustomEnum) value;
if (val == null) {
st.setNull(index, Types.VARCHAR);
From 08d9fe2117a1afc60ad15cb1b6124b057b6eae32 Mon Sep 17 00:00:00 2001
From: Steve Ebersole
Date: Wed, 2 Mar 2011 15:57:28 -0600
Subject: [PATCH 03/19] HHH-5949 - Migrate, complete and integrate
TransactionFactory as a service
---
build.gradle | 8 +-
.../org/hibernate/HibernateException.java | 12 +-
...okup.java => ResourceClosedException.java} | 22 +-
.../java/org/hibernate/SessionFactory.java | 3 +-
.../main/java/org/hibernate/Transaction.java | 167 +++--
.../java/org/hibernate/cfg/Configuration.java | 14 +-
.../java/org/hibernate/cfg/Environment.java | 5 +-
.../main/java/org/hibernate/cfg/Settings.java | 46 +-
.../org/hibernate/cfg/SettingsFactory.java | 52 +-
.../hibernate/context/JTASessionContext.java | 14 +-
.../context/ThreadLocalSessionContext.java | 14 +-
.../PessimisticReadSelectLockingStrategy.java | 2 +-
.../PessimisticReadUpdateLockingStrategy.java | 2 +-
...PessimisticWriteSelectLockingStrategy.java | 2 +-
...PessimisticWriteUpdateLockingStrategy.java | 2 +-
.../dialect/lock/SelectLockingStrategy.java | 2 +-
.../dialect/lock/UpdateLockingStrategy.java | 2 +-
.../org/hibernate/engine/ActionQueue.java | 2 +-
.../engine/SessionFactoryImplementor.java | 9 +-
.../hibernate/engine/SessionImplementor.java | 27 +-
.../hibernate/engine/TransactionHelper.java | 34 +-
.../batch/internal/AbstractBatchImpl.java | 134 ++--
.../jdbc/batch/internal/BasicBatchKey.java | 89 +++
...atchBuilder.java => BatchBuilderImpl.java} | 49 +-
.../batch/internal/BatchBuilderInitiator.java | 69 ++
.../jdbc/batch/internal/BatchingBatch.java | 197 ++----
.../jdbc/batch/internal/NonBatchingBatch.java | 54 +-
.../engine/jdbc/batch/spi/Batch.java | 23 +-
.../engine/jdbc/batch/spi/BatchBuilder.java | 45 ++
.../jdbc/batch/spi/BatchKey.java} | 39 +-
.../jdbc/internal/ConnectionManagerImpl.java | 611 ------------------
.../engine/jdbc/internal/JDBCContextImpl.java | 369 -----------
.../jdbc/internal/JdbcCoordinatorImpl.java | 236 +++++++
.../jdbc/internal/LogicalConnectionImpl.java | 309 ++++-----
.../jdbc/internal/StatementPreparer.java | 276 --------
.../jdbc/internal/StatementPreparerImpl.java | 223 +++++++
.../proxy/ConnectionProxyHandler.java | 36 +-
.../engine/jdbc/spi/ConnectionObserver.java | 5 +
.../jdbc/spi/ConnectionObserverAdapter.java} | 89 +--
.../engine/jdbc/spi/JDBCContext.java | 83 ---
.../jdbc/spi/JdbcContext.java} | 47 +-
.../engine/jdbc/spi/JdbcCoordinator.java | 96 +++
.../engine/jdbc/spi/JdbcResourceRegistry.java | 3 +-
.../engine/jdbc/spi/LogicalConnection.java | 21 +-
.../spi/LogicalConnectionImplementor.java | 38 +-
.../spi/NonDurableConnectionObserver.java} | 23 +-
.../engine/jdbc/spi/SQLExceptionHelper.java | 3 +-
.../engine/jdbc/spi/StatementPreparer.java | 97 +++
.../engine/query/NativeSQLQueryPlan.java | 2 +-
.../engine/transaction/Isolater.java | 307 ---------
.../NullSynchronizationException.java | 4 +-
.../SynchronizationRegistryImpl.java} | 42 +-
.../internal/TransactionCoordinatorImpl.java | 348 ++++++++++
.../internal/TransactionFactoryInitiator.java | 96 +++
.../internal/jdbc/JdbcIsolationDelegate.java | 123 ++++
.../internal/jdbc/JdbcTransaction.java | 208 ++++++
.../internal/jdbc/JdbcTransactionFactory.java | 71 ++
.../internal/jta/CMTTransaction.java | 154 +++++
.../internal/jta}/CMTTransactionFactory.java | 66 +-
.../internal/jta/JtaIsolationDelegate.java | 185 ++++++
.../internal}/jta/JtaStatusHelper.java | 25 +-
.../internal/jta/JtaTransaction.java | 276 ++++++++
.../internal/jta/JtaTransactionFactory.java | 109 ++++
.../spi/AbstractTransactionImpl.java | 237 +++++++
.../transaction/spi/IsolationDelegate.java | 44 ++
.../transaction/spi/JoinStatus.java} | 15 +-
.../engine/transaction/spi/LocalStatus.java | 52 ++
.../spi/SynchronizationRegistry.java | 57 ++
.../transaction/spi/TransactionContext.java | 105 +++
.../spi/TransactionCoordinator.java | 139 ++++
.../spi/TransactionEnvironment.java | 63 ++
.../transaction/spi/TransactionFactory.java | 93 +++
.../spi/TransactionImplementor.java | 67 ++
.../transaction/spi/TransactionObserver.java | 57 ++
.../internal/RegisteredSynchronization.java} | 26 +-
...nchronizationCallbackCoordinatorImpl.java} | 117 ++--
.../spi/AfterCompletionAction.java | 38 ++
.../synchronization/spi}/ExceptionMapper.java | 12 +-
.../spi/ManagedFlushChecker.java} | 26 +-
.../SynchronizationCallbackCoordinator.java | 35 +
.../def/AbstractFlushingEventListener.java | 4 +-
.../event/def/AbstractSaveEventListener.java | 2 +-
.../exception/SQLExceptionConverter.java | 5 +-
.../ast/exec/AbstractStatementExecutor.java | 181 +++---
.../hibernate/hql/ast/exec/BasicExecutor.java | 2 +-
.../ast/exec/MultiTableDeleteExecutor.java | 4 +-
.../ast/exec/MultiTableUpdateExecutor.java | 4 +-
.../java/org/hibernate/id/GUIDGenerator.java | 2 +-
.../org/hibernate/id/IdentityGenerator.java | 10 +-
.../org/hibernate/id/IncrementGenerator.java | 2 +-
.../org/hibernate/id/SequenceGenerator.java | 2 +-
.../id/SequenceIdentityGenerator.java | 2 +-
.../id/enhanced/SequenceStructure.java | 2 +-
.../id/insert/AbstractSelectingDelegate.java | 10 +-
.../hibernate/impl/AbstractSessionImpl.java | 9 +-
.../impl/ConnectionObserverStatsBridge.java | 59 ++
.../hibernate/impl/SessionFactoryImpl.java | 134 ++--
.../java/org/hibernate/impl/SessionImpl.java | 307 ++++-----
.../hibernate/impl/StatelessSessionImpl.java | 88 +--
.../impl/TransactionEnvironmentImpl.java | 67 ++
.../jdbc/BorrowedConnectionProxy.java | 138 ----
.../org/hibernate/jmx/HibernateService.java | 42 +-
.../hibernate/jmx/HibernateServiceMBean.java | 35 +-
.../java/org/hibernate/loader/Loader.java | 22 +-
.../AbstractCollectionPersister.java | 143 ++--
.../collection/BasicCollectionPersister.java | 26 +-
.../collection/OneToManyPersister.java | 108 ++--
.../entity/AbstractEntityPersister.java | 207 +++---
.../service/internal/ServiceInitializer.java | 20 +-
.../service/internal/ServiceRegistryImpl.java | 3 +-
.../DriverManagerConnectionProviderImpl.java | 13 +-
.../internal/AbstractJtaPlatform.java | 133 ++++
.../internal/BitronixJtaPlatform.java} | 133 ++--
.../BorlandEnterpriseServerJtaPlatform.java | 52 ++
.../internal/JBossAppServerPlatform.java | 64 +-
.../internal/JBossStandAloneJtaPlatform.java | 70 ++
.../platform/internal/JOTMJtaPlatform.java | 63 ++
.../platform/internal/JOnASJtaPlatform.java} | 50 +-
.../platform/internal/JRun4JtaPlatform.java | 55 ++
.../internal/JtaPlatformInitiator.java | 130 +++-
.../internal/JtaSynchronizationStrategy.java | 48 ++
.../jta/platform/internal/NoJtaPlatform.java} | 72 +--
.../platform/internal/OC4JJtaPlatform.java | 55 ++
.../platform/internal/OrionJtaPlatform.java | 55 ++
.../platform/internal/ResinJtaPlatform.java | 55 ++
.../platform/internal/SunOneJtaPlatform.java | 57 ++
.../SynchronizationRegistryAccess.java | 42 ++
...nRegistryBasedSynchronizationStrategy.java | 56 ++
.../internal/TransactionManagerAccess.java} | 26 +-
...onManagerBasedSynchronizationStrategy.java | 58 ++
.../TransactionManagerLookupBridge.java | 67 ++
.../WebSphereExtendedJtaPlatform.java} | 168 ++---
.../internal/WebSphereJtaPlatform.java | 103 +++
.../internal/WeblogicJtaPlatform.java | 55 ++
.../service/jta/platform/spi/JtaPlatform.java | 41 +-
.../platform/spi/JtaPlatformException.java} | 25 +-
.../org/hibernate/service/spi/Service.java | 6 +-
.../spi/StandardServiceInitiators.java | 5 +-
.../BESTransactionManagerLookup.java | 42 --
.../hibernate/transaction/CMTTransaction.java | 224 -------
.../transaction/CacheSynchronization.java | 134 ----
...sTSStandaloneTransactionManagerLookup.java | 66 --
.../transaction/JDBCTransaction.java | 275 --------
.../transaction/JDBCTransactionFactory.java | 96 ---
.../JNDITransactionManagerLookup.java | 77 ---
.../hibernate/transaction/JTATransaction.java | 359 ----------
.../transaction/JTATransactionFactory.java | 254 --------
.../SunONETransactionManagerLookup.java | 50 --
.../transaction/TransactionFactory.java | 124 ----
.../TransactionFactoryFactory.java | 88 ---
.../TransactionManagerLookupFactory.java | 97 ---
.../WebSphereTransactionManagerLookup.java | 111 ----
.../org/hibernate/type/DbTimestampType.java | 22 +-
.../java/org/hibernate/util/JTAHelper.java | 3 +-
.../manytomany/ManyToManyTest.java | 42 +-
.../polymorphism/PolymorphismTest.java | 1 -
.../annotations/subselect/SubselectTest.java | 3 +-
.../test/common/JournalingBatchObserver.java | 57 ++
.../common/JournalingConnectionObserver.java | 74 +++
.../JournalingTransactionObserver.java} | 52 +-
.../test/common/TransactionContextImpl.java | 95 +++
.../common/TransactionEnvironmentImpl.java | 63 ++
.../AtomikosDataSourceConnectionProvider.java | 82 +++
.../test/common/jta/AtomikosJtaPlatform.java | 129 ++++
.../connections/AggressiveReleaseTest.java | 81 ++-
.../CurrentSessionConnectionTest.java | 5 +
.../exception/SQLExceptionConversionTest.java | 10 +-
.../insertordering/InsertOrderingTest.java | 64 +-
.../jdbc/proxies/AggressiveReleaseTest.java | 115 ++--
.../proxies/BasicConnectionProxyTest.java | 9 +-
.../test/jdbc/proxies/BatchingTest.java | 213 ++++++
.../batchload/BatchedManyToManyTest.java | 47 +-
.../AbstractOperationTestCase.java | 2 +-
.../org/hibernate/test/ops/CreateTest.java | 2 +-
.../test/readonly/ReadOnlyProxyTest.java | 2 -
.../java/org/hibernate/test/tm/CMTTest.java | 193 +++---
.../transaction/jdbc/TestExpectedUsage.java | 139 ++++
.../transaction/jta/BasicDrivingTest.java | 162 +++++
.../transaction/jta/ManagedDrivingTest.java | 178 +++++
.../cache/BaseCacheProviderTestCase.java | 4 +-
.../src/test/resources/log4j.properties | 1 +
181 files changed, 8187 insertions(+), 5961 deletions(-)
rename hibernate-core/src/main/java/org/hibernate/{transaction/JRun4TransactionManagerLookup.java => ResourceClosedException.java} (66%)
create mode 100644 hibernate-core/src/main/java/org/hibernate/engine/jdbc/batch/internal/BasicBatchKey.java
rename hibernate-core/src/main/java/org/hibernate/engine/jdbc/batch/internal/{BatchBuilder.java => BatchBuilderImpl.java} (59%)
create mode 100644 hibernate-core/src/main/java/org/hibernate/engine/jdbc/batch/internal/BatchBuilderInitiator.java
create mode 100644 hibernate-core/src/main/java/org/hibernate/engine/jdbc/batch/spi/BatchBuilder.java
rename hibernate-core/src/main/java/org/hibernate/{transaction/ResinTransactionManagerLookup.java => engine/jdbc/batch/spi/BatchKey.java} (59%)
delete mode 100644 hibernate-core/src/main/java/org/hibernate/engine/jdbc/internal/ConnectionManagerImpl.java
delete mode 100644 hibernate-core/src/main/java/org/hibernate/engine/jdbc/internal/JDBCContextImpl.java
create mode 100644 hibernate-core/src/main/java/org/hibernate/engine/jdbc/internal/JdbcCoordinatorImpl.java
delete mode 100644 hibernate-core/src/main/java/org/hibernate/engine/jdbc/internal/StatementPreparer.java
create mode 100644 hibernate-core/src/main/java/org/hibernate/engine/jdbc/internal/StatementPreparerImpl.java
rename hibernate-core/src/main/java/org/hibernate/{jdbc/ConnectionWrapper.java => engine/jdbc/spi/ConnectionObserverAdapter.java} (66%)
delete mode 100644 hibernate-core/src/main/java/org/hibernate/engine/jdbc/spi/JDBCContext.java
rename hibernate-core/src/main/java/org/hibernate/{transaction/OrionTransactionManagerLookup.java => engine/jdbc/spi/JdbcContext.java} (55%)
create mode 100644 hibernate-core/src/main/java/org/hibernate/engine/jdbc/spi/JdbcCoordinator.java
rename hibernate-core/src/main/java/org/hibernate/{transaction/JBossTransactionManagerLookup.java => engine/jdbc/spi/NonDurableConnectionObserver.java} (65%)
create mode 100644 hibernate-core/src/main/java/org/hibernate/engine/jdbc/spi/StatementPreparer.java
delete mode 100644 hibernate-core/src/main/java/org/hibernate/engine/transaction/Isolater.java
rename hibernate-core/src/main/java/org/hibernate/engine/transaction/{ => internal}/NullSynchronizationException.java (89%)
rename hibernate-core/src/main/java/org/hibernate/engine/transaction/{SynchronizationRegistry.java => internal/SynchronizationRegistryImpl.java} (75%)
create mode 100644 hibernate-core/src/main/java/org/hibernate/engine/transaction/internal/TransactionCoordinatorImpl.java
create mode 100644 hibernate-core/src/main/java/org/hibernate/engine/transaction/internal/TransactionFactoryInitiator.java
create mode 100644 hibernate-core/src/main/java/org/hibernate/engine/transaction/internal/jdbc/JdbcIsolationDelegate.java
create mode 100644 hibernate-core/src/main/java/org/hibernate/engine/transaction/internal/jdbc/JdbcTransaction.java
create mode 100644 hibernate-core/src/main/java/org/hibernate/engine/transaction/internal/jdbc/JdbcTransactionFactory.java
create mode 100644 hibernate-core/src/main/java/org/hibernate/engine/transaction/internal/jta/CMTTransaction.java
rename hibernate-core/src/main/java/org/hibernate/{transaction => engine/transaction/internal/jta}/CMTTransactionFactory.java (50%)
mode change 100755 => 100644
create mode 100644 hibernate-core/src/main/java/org/hibernate/engine/transaction/internal/jta/JtaIsolationDelegate.java
rename hibernate-core/src/main/java/org/hibernate/{internal/util => engine/transaction/internal}/jta/JtaStatusHelper.java (89%)
create mode 100644 hibernate-core/src/main/java/org/hibernate/engine/transaction/internal/jta/JtaTransaction.java
create mode 100644 hibernate-core/src/main/java/org/hibernate/engine/transaction/internal/jta/JtaTransactionFactory.java
create mode 100644 hibernate-core/src/main/java/org/hibernate/engine/transaction/spi/AbstractTransactionImpl.java
create mode 100644 hibernate-core/src/main/java/org/hibernate/engine/transaction/spi/IsolationDelegate.java
rename hibernate-core/src/main/java/org/hibernate/{transaction/synchronization/AfterCompletionAction.java => engine/transaction/spi/JoinStatus.java} (77%)
create mode 100644 hibernate-core/src/main/java/org/hibernate/engine/transaction/spi/LocalStatus.java
create mode 100644 hibernate-core/src/main/java/org/hibernate/engine/transaction/spi/SynchronizationRegistry.java
create mode 100644 hibernate-core/src/main/java/org/hibernate/engine/transaction/spi/TransactionContext.java
create mode 100644 hibernate-core/src/main/java/org/hibernate/engine/transaction/spi/TransactionCoordinator.java
create mode 100644 hibernate-core/src/main/java/org/hibernate/engine/transaction/spi/TransactionEnvironment.java
create mode 100644 hibernate-core/src/main/java/org/hibernate/engine/transaction/spi/TransactionFactory.java
create mode 100644 hibernate-core/src/main/java/org/hibernate/engine/transaction/spi/TransactionImplementor.java
create mode 100644 hibernate-core/src/main/java/org/hibernate/engine/transaction/spi/TransactionObserver.java
rename hibernate-core/src/main/java/org/hibernate/{transaction/synchronization/HibernateSynchronizationImpl.java => engine/transaction/synchronization/internal/RegisteredSynchronization.java} (60%)
rename hibernate-core/src/main/java/org/hibernate/{transaction/synchronization/CallbackCoordinator.java => engine/transaction/synchronization/internal/SynchronizationCallbackCoordinatorImpl.java} (53%)
create mode 100644 hibernate-core/src/main/java/org/hibernate/engine/transaction/synchronization/spi/AfterCompletionAction.java
rename hibernate-core/src/main/java/org/hibernate/{transaction/synchronization => engine/transaction/synchronization/spi}/ExceptionMapper.java (79%)
rename hibernate-core/src/main/java/org/hibernate/{transaction/synchronization/BeforeCompletionManagedFlushChecker.java => engine/transaction/synchronization/spi/ManagedFlushChecker.java} (58%)
create mode 100644 hibernate-core/src/main/java/org/hibernate/engine/transaction/synchronization/spi/SynchronizationCallbackCoordinator.java
create mode 100644 hibernate-core/src/main/java/org/hibernate/impl/ConnectionObserverStatsBridge.java
create mode 100644 hibernate-core/src/main/java/org/hibernate/impl/TransactionEnvironmentImpl.java
delete mode 100644 hibernate-core/src/main/java/org/hibernate/jdbc/BorrowedConnectionProxy.java
create mode 100644 hibernate-core/src/main/java/org/hibernate/service/jta/platform/internal/AbstractJtaPlatform.java
rename hibernate-core/src/main/java/org/hibernate/{transaction/BTMTransactionManagerLookup.java => service/jta/platform/internal/BitronixJtaPlatform.java} (51%)
create mode 100644 hibernate-core/src/main/java/org/hibernate/service/jta/platform/internal/BorlandEnterpriseServerJtaPlatform.java
create mode 100644 hibernate-core/src/main/java/org/hibernate/service/jta/platform/internal/JBossStandAloneJtaPlatform.java
create mode 100644 hibernate-core/src/main/java/org/hibernate/service/jta/platform/internal/JOTMJtaPlatform.java
rename hibernate-core/src/main/java/org/hibernate/{transaction/JOnASTransactionManagerLookup.java => service/jta/platform/internal/JOnASJtaPlatform.java} (55%)
create mode 100644 hibernate-core/src/main/java/org/hibernate/service/jta/platform/internal/JRun4JtaPlatform.java
create mode 100644 hibernate-core/src/main/java/org/hibernate/service/jta/platform/internal/JtaSynchronizationStrategy.java
rename hibernate-core/src/main/java/org/hibernate/{transaction/JOTMTransactionManagerLookup.java => service/jta/platform/internal/NoJtaPlatform.java} (53%)
create mode 100644 hibernate-core/src/main/java/org/hibernate/service/jta/platform/internal/OC4JJtaPlatform.java
create mode 100644 hibernate-core/src/main/java/org/hibernate/service/jta/platform/internal/OrionJtaPlatform.java
create mode 100644 hibernate-core/src/main/java/org/hibernate/service/jta/platform/internal/ResinJtaPlatform.java
create mode 100644 hibernate-core/src/main/java/org/hibernate/service/jta/platform/internal/SunOneJtaPlatform.java
create mode 100644 hibernate-core/src/main/java/org/hibernate/service/jta/platform/internal/SynchronizationRegistryAccess.java
create mode 100644 hibernate-core/src/main/java/org/hibernate/service/jta/platform/internal/SynchronizationRegistryBasedSynchronizationStrategy.java
rename hibernate-core/src/main/java/org/hibernate/{engine/transaction/IsolatedWork.java => service/jta/platform/internal/TransactionManagerAccess.java} (61%)
create mode 100644 hibernate-core/src/main/java/org/hibernate/service/jta/platform/internal/TransactionManagerBasedSynchronizationStrategy.java
create mode 100644 hibernate-core/src/main/java/org/hibernate/service/jta/platform/internal/TransactionManagerLookupBridge.java
rename hibernate-core/src/main/java/org/hibernate/{transaction/WebSphereExtendedJTATransactionLookup.java => service/jta/platform/internal/WebSphereExtendedJtaPlatform.java} (73%)
mode change 100755 => 100644
create mode 100644 hibernate-core/src/main/java/org/hibernate/service/jta/platform/internal/WebSphereJtaPlatform.java
create mode 100644 hibernate-core/src/main/java/org/hibernate/service/jta/platform/internal/WeblogicJtaPlatform.java
rename hibernate-core/src/main/java/org/hibernate/{transaction/OC4JTransactionManagerLookup.java => service/jta/platform/spi/JtaPlatformException.java} (65%)
delete mode 100644 hibernate-core/src/main/java/org/hibernate/transaction/BESTransactionManagerLookup.java
delete mode 100755 hibernate-core/src/main/java/org/hibernate/transaction/CMTTransaction.java
delete mode 100644 hibernate-core/src/main/java/org/hibernate/transaction/CacheSynchronization.java
delete mode 100644 hibernate-core/src/main/java/org/hibernate/transaction/JBossTSStandaloneTransactionManagerLookup.java
delete mode 100644 hibernate-core/src/main/java/org/hibernate/transaction/JDBCTransaction.java
delete mode 100644 hibernate-core/src/main/java/org/hibernate/transaction/JDBCTransactionFactory.java
delete mode 100644 hibernate-core/src/main/java/org/hibernate/transaction/JNDITransactionManagerLookup.java
delete mode 100644 hibernate-core/src/main/java/org/hibernate/transaction/JTATransaction.java
delete mode 100644 hibernate-core/src/main/java/org/hibernate/transaction/JTATransactionFactory.java
delete mode 100644 hibernate-core/src/main/java/org/hibernate/transaction/SunONETransactionManagerLookup.java
delete mode 100644 hibernate-core/src/main/java/org/hibernate/transaction/TransactionFactory.java
delete mode 100644 hibernate-core/src/main/java/org/hibernate/transaction/TransactionFactoryFactory.java
delete mode 100644 hibernate-core/src/main/java/org/hibernate/transaction/TransactionManagerLookupFactory.java
delete mode 100644 hibernate-core/src/main/java/org/hibernate/transaction/WebSphereTransactionManagerLookup.java
create mode 100644 hibernate-core/src/test/java/org/hibernate/test/common/JournalingBatchObserver.java
create mode 100644 hibernate-core/src/test/java/org/hibernate/test/common/JournalingConnectionObserver.java
rename hibernate-core/src/{main/java/org/hibernate/transaction/WeblogicTransactionManagerLookup.java => test/java/org/hibernate/test/common/JournalingTransactionObserver.java} (50%)
create mode 100644 hibernate-core/src/test/java/org/hibernate/test/common/TransactionContextImpl.java
create mode 100644 hibernate-core/src/test/java/org/hibernate/test/common/TransactionEnvironmentImpl.java
create mode 100644 hibernate-core/src/test/java/org/hibernate/test/common/jta/AtomikosDataSourceConnectionProvider.java
create mode 100644 hibernate-core/src/test/java/org/hibernate/test/common/jta/AtomikosJtaPlatform.java
create mode 100644 hibernate-core/src/test/java/org/hibernate/test/jdbc/proxies/BatchingTest.java
create mode 100644 hibernate-core/src/test/java/org/hibernate/test/transaction/jdbc/TestExpectedUsage.java
create mode 100644 hibernate-core/src/test/java/org/hibernate/test/transaction/jta/BasicDrivingTest.java
create mode 100644 hibernate-core/src/test/java/org/hibernate/test/transaction/jta/ManagedDrivingTest.java
diff --git a/build.gradle b/build.gradle
index efada05429..5d250557a0 100644
--- a/build.gradle
+++ b/build.gradle
@@ -67,6 +67,7 @@ libraries = [
jcl: 'commons-logging:commons-logging:99.0-does-not-exist',
// testing
+ atomikos: 'com.atomikos:transactions-jdbc:3.6.4',
junit: 'junit:junit:3.8.2',
testng: 'org.testng:testng:5.8:jdk15',
jpa_modelgen: 'org.hibernate:hibernate-jpamodelgen:1.1.0.Final',
@@ -106,6 +107,7 @@ subprojects { subProject ->
dependencies {
compile( libraries.slf4j_api )
testCompile( libraries.junit )
+ testCompile( libraries.atomikos )
testRuntime( libraries.slf4j_simple )
testRuntime( libraries.jcl_slf4j )
testRuntime( libraries.jcl_api )
@@ -151,12 +153,8 @@ subprojects { subProject ->
sourceCompatibility = "1.6"
ideaModule {
- // treat our "provided" configuration dependencies as "Compile" scope dependencies in IntelliJ
+ // treat our "provided" configuration dependencies as "compile" scope dependencies in IntelliJ
scopes.COMPILE.plus.add( configurations.provided )
- // Use explicitly separate compilation output directories for Gradle and IntelliJ
- File baseDirectory = new File( subProject.buildDir, "idea/classes" )
- outputDir = new File( baseDirectory, "main" )
- testOutputDir = new File( baseDirectory, "test" )
whenConfigured { module ->
module.dependencies*.exported = true
}
diff --git a/hibernate-core/src/main/java/org/hibernate/HibernateException.java b/hibernate-core/src/main/java/org/hibernate/HibernateException.java
index 4699d28dc7..5e75777632 100644
--- a/hibernate-core/src/main/java/org/hibernate/HibernateException.java
+++ b/hibernate-core/src/main/java/org/hibernate/HibernateException.java
@@ -1,10 +1,10 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
- * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * Copyright (c) 2007-2011, 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 Middleware LLC.
+ * 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
@@ -20,7 +20,6 @@
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
- *
*/
package org.hibernate;
@@ -35,6 +34,9 @@ package org.hibernate;
* @author Gavin King
*/
public class HibernateException extends RuntimeException {
+ public HibernateException(String s) {
+ super(s);
+ }
public HibernateException(Throwable root) {
super(root);
@@ -43,10 +45,6 @@ public class HibernateException extends RuntimeException {
public HibernateException(String string, Throwable root) {
super(string, root);
}
-
- public HibernateException(String s) {
- super(s);
- }
}
diff --git a/hibernate-core/src/main/java/org/hibernate/transaction/JRun4TransactionManagerLookup.java b/hibernate-core/src/main/java/org/hibernate/ResourceClosedException.java
similarity index 66%
rename from hibernate-core/src/main/java/org/hibernate/transaction/JRun4TransactionManagerLookup.java
rename to hibernate-core/src/main/java/org/hibernate/ResourceClosedException.java
index 5f0bf15fd0..800d478cf0 100644
--- a/hibernate-core/src/main/java/org/hibernate/transaction/JRun4TransactionManagerLookup.java
+++ b/hibernate-core/src/main/java/org/hibernate/ResourceClosedException.java
@@ -1,10 +1,10 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
- * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * Copyright (c) 2011, 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 Middleware LLC.
+ * 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
@@ -20,22 +20,20 @@
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
- *
*/
-package org.hibernate.transaction;
+package org.hibernate;
/**
- * {@link TransactionManagerLookup} strategy for JRun4 AS
+ * Indicates an attempt was made to use a closed resource (Session, SessionFactory, etc).
*
- * @author Joseph Bissen
+ * @author Steve Ebersole
*/
-public class JRun4TransactionManagerLookup extends JNDITransactionManagerLookup {
-
- protected String getName() {
- return "java:/TransactionManager";
+public class ResourceClosedException extends HibernateException {
+ public ResourceClosedException(String s) {
+ super( s );
}
- public String getUserTransactionName() {
- return "java:comp/UserTransaction";
+ public ResourceClosedException(String string, Throwable root) {
+ super( string, root );
}
}
diff --git a/hibernate-core/src/main/java/org/hibernate/SessionFactory.java b/hibernate-core/src/main/java/org/hibernate/SessionFactory.java
index af193fc35e..c097bfb29f 100644
--- a/hibernate-core/src/main/java/org/hibernate/SessionFactory.java
+++ b/hibernate-core/src/main/java/org/hibernate/SessionFactory.java
@@ -119,8 +119,7 @@ public interface SessionFactory extends Referenceable, Serializable {
* for use.
*
* Note that for backwards compatibility, if a {@link org.hibernate.context.CurrentSessionContext}
- * is not configured but a JTA {@link org.hibernate.transaction.TransactionManagerLookup}
- * is configured this will default to the {@link org.hibernate.context.JTASessionContext}
+ * is not configured but JTA is configured this will default to the {@link org.hibernate.context.JTASessionContext}
* impl.
*
* @return The current session.
diff --git a/hibernate-core/src/main/java/org/hibernate/Transaction.java b/hibernate-core/src/main/java/org/hibernate/Transaction.java
index 38635007c1..cbed4ea957 100644
--- a/hibernate-core/src/main/java/org/hibernate/Transaction.java
+++ b/hibernate-core/src/main/java/org/hibernate/Transaction.java
@@ -1,10 +1,10 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
- * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * Copyright (c) 2007-2011, 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 Middleware LLC.
+ * 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
@@ -20,109 +20,140 @@
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
- *
*/
package org.hibernate;
+import org.hibernate.engine.transaction.spi.LocalStatus;
+
import javax.transaction.Synchronization;
/**
- * Allows the application to define units of work, while
- * maintaining abstraction from the underlying transaction
- * implementation (eg. JTA, JDBC).
- *
- * A transaction is associated with a Session and is
- * usually instantiated by a call to Session.beginTransaction().
- * A single session might span multiple transactions since
- * the notion of a session (a conversation between the application
- * and the datastore) is of coarser granularity than the notion of
- * a transaction. However, it is intended that there be at most one
- * uncommitted Transaction associated with a particular
- * Session at any time.
- *
- * Implementors are not intended to be threadsafe.
+ * Defines the contract for abstracting applications from the configured underlying means of transaction management.
+ * Allows the application to define units of work, while maintaining abstraction from the underlying transaction
+ * implementation (eg. JTA, JDBC).
+ *
+ * A transaction is associated with a {@link Session} and is usually initiated by a call to
+ * {@link org.hibernate.Session#beginTransaction()}. A single session might span multiple transactions since
+ * the notion of a session (a conversation between the application and the datastore) is of coarser granularity than
+ * the notion of a transaction. However, it is intended that there be at most one uncommitted transaction associated
+ * with a particular {@link Session} at any time.
+ *
+ * Implementers are not intended to be thread-safe.
*
- * @see Session#beginTransaction()
- * @see org.hibernate.transaction.TransactionFactory
* @author Anton van Straaten
+ * @author Steve Ebersole
*/
public interface Transaction {
-
/**
- * Begin a new transaction.
+ * Is this transaction the initiator of any underlying transaction?
+ *
+ * @return {@literal true} if this transaction initiated the underlying transaction; {@literal false} otherwise.
*/
- public void begin() throws HibernateException;
+ public boolean isInitiator();
/**
- * Flush the associated Session and end the unit of work (unless
- * we are in {@link FlushMode#MANUAL}.
- *
- * This method will commit the underlying transaction if and only
- * if the underlying transaction was initiated by this object.
+ * Begin this transaction. No-op if the transaction has already been begun. Note that this is not necessarily
+ * symmetrical since usually multiple calls to {@link #commit} or {@link #rollback} will error.
*
- * @throws HibernateException
+ * @throws HibernateException Indicates a problem beginning the transaction.
*/
- public void commit() throws HibernateException;
+ public void begin();
/**
- * Force the underlying transaction to roll back.
+ * Commit this transaction. This might entail a number of things depending on the context:
+ * -
+ * If this transaction is the {@link #isInitiator initiator}, {@link Session#flush} the {@link Session}
+ * with which it is associated (unless {@link Session} is in {@link FlushMode#MANUAL}).
+ *
+ * -
+ * If this transaction is the {@link #isInitiator initiator}, commit the underlying transaction.
+ *
+ * -
+ * Coordinate various callbacks
+ *
+ *
*
- * @throws HibernateException
+ * @throws HibernateException Indicates a problem committing the transaction.
*/
- public void rollback() throws HibernateException;
+ public void commit();
+
+ /**
+ * Rollback this transaction. Either rolls back the underlying transaction or ensures it cannot later commit
+ * (depending on the actual underlying strategy).
+ *
+ * @throws HibernateException Indicates a problem rolling back the transaction.
+ */
+ public void rollback();
+
+ /**
+ * Get the current local status of this transaction.
+ *
+ * This only accounts for the local view of the transaction status. In other words it does not check the status
+ * of the actual underlying transaction.
+ *
+ * @return The current local status.
+ */
+ public LocalStatus getLocalStatus();
+
+ /**
+ * Is this transaction still active?
+ *
+ * Answers on a best effort basis. For example, in the case of JDBC based transactions we cannot know that a
+ * transaction is active when it is initiated directly through the JDBC {@link java.sql.Connection}, only when
+ * it is initiated from here.
+ *
+ * @return {@literal true} if the transaction is still active; {@literal false} otherwise.
+ *
+ * @throws HibernateException Indicates a problem checking the transaction status.
+ */
+ public boolean isActive();
+
+ /**
+ * Was this transaction committed?
+ *
+ * Answers on a best effort basis. For example, in the case of JDBC based transactions we cannot know that a
+ * transaction was committed when the commit was performed directly through the JDBC {@link java.sql.Connection},
+ * only when the commit was done from this.
+ *
+ * @return {@literal true} if the transaction is rolled back; {@literal false} otherwise.
+ *
+ * @throws HibernateException Indicates a problem checking the transaction status.
+ */
+ public boolean wasCommitted();
/**
* Was this transaction rolled back or set to rollback only?
*
- * This only accounts for actions initiated from this local transaction.
- * If, for example, the underlying transaction is forced to rollback via
- * some other means, this method still reports false because the rollback
- * was not initiated from here.
+ * Answers on a best effort basis. For example, in the case of JDBC based transactions we cannot know that a
+ * transaction was rolled back when rollback was performed directly through the JDBC {@link java.sql.Connection},
+ * only when it was rolled back from here.
*
- * @return boolean True if the transaction was rolled back via this
- * local transaction; false otherwise.
- * @throws HibernateException
- */
- public boolean wasRolledBack() throws HibernateException;
-
- /**
- * Check if this transaction was successfully committed.
- *
- * This method could return false even after successful invocation
- * of {@link #commit}. As an example, JTA based strategies no-op on
- * {@link #commit} calls if they did not start the transaction; in that case,
- * they also report {@link #wasCommitted} as false.
+ * @return {@literal true} if the transaction is rolled back; {@literal false} otherwise.
*
- * @return boolean True if the transaction was (unequivocally) committed
- * via this local transaction; false otherwise.
- * @throws HibernateException
+ * @throws HibernateException Indicates a problem checking the transaction status.
*/
- public boolean wasCommitted() throws HibernateException;
-
- /**
- * Is this transaction still active?
- *
- * Again, this only returns information in relation to the
- * local transaction, not the actual underlying transaction.
- *
- * @return boolean Treu if this local transaction is still active.
- */
- public boolean isActive() throws HibernateException;
+ public boolean wasRolledBack();
/**
* Register a user synchronization callback for this transaction.
*
* @param synchronization The Synchronization callback to register.
- * @throws HibernateException
+ *
+ * @throws HibernateException Indicates a problem registering the synchronization.
*/
- public void registerSynchronization(Synchronization synchronization)
- throws HibernateException;
+ public void registerSynchronization(Synchronization synchronization) throws HibernateException;
/**
- * Set the transaction timeout for any transaction started by
- * a subsequent call to begin() on this instance.
+ * Set the transaction timeout for any transaction started by a subsequent call to {@link #begin} on this instance.
*
* @param seconds The number of seconds before a timeout.
*/
public void setTimeout(int seconds);
+
+ /**
+ * Retrieve the transaction timeout set for this transaction. A negative indicates no timeout has been set.
+ *
+ * @return The timeout, in seconds.
+ */
+ public int getTimeout();
}
diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/Configuration.java b/hibernate-core/src/main/java/org/hibernate/cfg/Configuration.java
index 2e71eab331..ba64ce4900 100644
--- a/hibernate-core/src/main/java/org/hibernate/cfg/Configuration.java
+++ b/hibernate-core/src/main/java/org/hibernate/cfg/Configuration.java
@@ -1842,7 +1842,7 @@ public class Configuration implements Serializable {
Properties copy = new Properties();
copy.putAll( properties );
ConfigurationHelper.resolvePlaceHolders( copy );
- Settings settings = buildSettings( copy, serviceRegistry.getService( JdbcServices.class ) );
+ Settings settings = buildSettings( copy, serviceRegistry );
return new SessionFactoryImpl(
this,
@@ -2825,18 +2825,18 @@ public class Configuration implements Serializable {
*
* @return The build settings
*/
- public Settings buildSettings(JdbcServices jdbcServices) {
+ public Settings buildSettings(ServiceRegistry serviceRegistry) {
Properties clone = ( Properties ) properties.clone();
ConfigurationHelper.resolvePlaceHolders( clone );
- return buildSettingsInternal( clone, jdbcServices );
+ return buildSettingsInternal( clone, serviceRegistry );
}
- public Settings buildSettings(Properties props, JdbcServices jdbcServices) throws HibernateException {
- return buildSettingsInternal( props, jdbcServices );
+ public Settings buildSettings(Properties props, ServiceRegistry serviceRegistry) throws HibernateException {
+ return buildSettingsInternal( props, serviceRegistry );
}
- private Settings buildSettingsInternal(Properties props, JdbcServices jdbcServices) {
- final Settings settings = settingsFactory.buildSettings( props, jdbcServices );
+ private Settings buildSettingsInternal(Properties props, ServiceRegistry serviceRegistry) {
+ final Settings settings = settingsFactory.buildSettings( props, serviceRegistry );
settings.setEntityTuplizerFactory( this.getEntityTuplizerFactory() );
// settings.setComponentTuplizerFactory( this.getComponentTuplizerFactory() );
return settings;
diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/Environment.java b/hibernate-core/src/main/java/org/hibernate/cfg/Environment.java
index e2e670501c..51a7628170 100644
--- a/hibernate-core/src/main/java/org/hibernate/cfg/Environment.java
+++ b/hibernate-core/src/main/java/org/hibernate/cfg/Environment.java
@@ -164,7 +164,7 @@ import org.hibernate.util.ConfigHelper;
*
* hibernate.transaction.factory_class |
* the factory to use for instantiating Transactions.
- * (Defaults to JDBCTransactionFactory.) |
+ * (Defaults to JdbcTransactionFactory.)
*
*
* hibernate.query.substitutions | query language token substitutions |
@@ -376,7 +376,8 @@ public final class Environment {
*/
public static final String CURRENT_SESSION_CONTEXT_CLASS = "hibernate.current_session_context_class";
/**
- * TransactionFactory implementor to use for creating Transactions
+ * Names the implementation of {@link org.hibernate.engine.transaction.spi.TransactionContext} to use for
+ * creating {@link org.hibernate.Transaction} instances
*/
public static final String TRANSACTION_STRATEGY = "hibernate.transaction.factory_class";
/**
diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/Settings.java b/hibernate-core/src/main/java/org/hibernate/cfg/Settings.java
index 5e8056a6b5..fbc5e31eac 100644
--- a/hibernate-core/src/main/java/org/hibernate/cfg/Settings.java
+++ b/hibernate-core/src/main/java/org/hibernate/cfg/Settings.java
@@ -23,20 +23,18 @@
*/
package org.hibernate.cfg;
-import java.util.Map;
-
import org.hibernate.ConnectionReleaseMode;
import org.hibernate.EntityMode;
import org.hibernate.cache.QueryCacheFactory;
import org.hibernate.cache.RegionFactory;
import org.hibernate.engine.jdbc.JdbcSupport;
-import org.hibernate.engine.jdbc.batch.internal.BatchBuilder;
import org.hibernate.hql.QueryTranslatorFactory;
import org.hibernate.jdbc.util.SQLStatementLogger;
-import org.hibernate.transaction.TransactionFactory;
-import org.hibernate.transaction.TransactionManagerLookup;
+import org.hibernate.service.jta.platform.spi.JtaPlatform;
import org.hibernate.tuple.entity.EntityTuplizerFactory;
+import java.util.Map;
+
/**
* Settings that affect the behaviour of Hibernate at runtime.
*
@@ -75,9 +73,6 @@ public final class Settings {
private ConnectionReleaseMode connectionReleaseMode;
private RegionFactory regionFactory;
private QueryCacheFactory queryCacheFactory;
- private TransactionFactory transactionFactory;
- private TransactionManagerLookup transactionManagerLookup;
- private BatchBuilder batchBuilder;
private QueryTranslatorFactory queryTranslatorFactory;
private boolean wrapResultSetsEnabled;
private boolean orderUpdatesEnabled;
@@ -94,6 +89,8 @@ public final class Settings {
private JdbcSupport jdbcSupport;
private String importFiles;
+ private JtaPlatform jtaPlatform;
+
/**
* Package protected constructor
*/
@@ -162,10 +159,6 @@ public final class Settings {
return jdbcFetchSize;
}
- public TransactionFactory getTransactionFactory() {
- return transactionFactory;
- }
-
public String getSessionFactoryName() {
return sessionFactoryName;
}
@@ -190,10 +183,6 @@ public final class Settings {
return regionFactory;
}
- public TransactionManagerLookup getTransactionManagerLookup() {
- return transactionManagerLookup;
- }
-
public boolean isQueryCacheEnabled() {
return queryCacheEnabled;
}
@@ -226,10 +215,6 @@ public final class Settings {
return flushBeforeCompletionEnabled;
}
- public BatchBuilder getBatchBuilder() {
- return batchBuilder;
- }
-
public boolean isAutoCloseSessionEnabled() {
return autoCloseSessionEnabled;
}
@@ -349,10 +334,6 @@ public final class Settings {
jdbcFetchSize = integer;
}
- void setTransactionFactory(TransactionFactory factory) {
- transactionFactory = factory;
- }
-
void setSessionFactoryName(String string) {
sessionFactoryName = string;
}
@@ -377,10 +358,6 @@ public final class Settings {
this.regionFactory = regionFactory;
}
- void setTransactionManagerLookup(TransactionManagerLookup lookup) {
- transactionManagerLookup = lookup;
- }
-
void setQueryCacheEnabled(boolean b) {
queryCacheEnabled = b;
}
@@ -413,10 +390,6 @@ public final class Settings {
this.flushBeforeCompletionEnabled = flushBeforeCompletionEnabled;
}
- void setBatcherBuilder(BatchBuilder batchBuilder) {
- this.batchBuilder = batchBuilder;
- }
-
void setAutoCloseSessionEnabled(boolean autoCloseSessionEnabled) {
this.autoCloseSessionEnabled = autoCloseSessionEnabled;
}
@@ -496,4 +469,13 @@ public final class Settings {
// void setBytecodeProvider(BytecodeProvider bytecodeProvider) {
// this.bytecodeProvider = bytecodeProvider;
// }
+
+
+ public JtaPlatform getJtaPlatform() {
+ return jtaPlatform;
+ }
+
+ void setJtaPlatform(JtaPlatform jtaPlatform) {
+ this.jtaPlatform = jtaPlatform;
+ }
}
diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/SettingsFactory.java b/hibernate-core/src/main/java/org/hibernate/cfg/SettingsFactory.java
index ca2a34f396..73801f2b98 100644
--- a/hibernate-core/src/main/java/org/hibernate/cfg/SettingsFactory.java
+++ b/hibernate-core/src/main/java/org/hibernate/cfg/SettingsFactory.java
@@ -39,16 +39,14 @@ import org.hibernate.cache.QueryCacheFactory;
import org.hibernate.cache.RegionFactory;
import org.hibernate.cache.impl.NoCachingRegionFactory;
import org.hibernate.cache.impl.bridge.RegionFactoryCacheProviderBridge;
-import org.hibernate.engine.jdbc.batch.internal.BatchBuilder;
import org.hibernate.engine.jdbc.spi.ExtractedDatabaseMetaData;
import org.hibernate.engine.jdbc.spi.JdbcServices;
+import org.hibernate.engine.transaction.spi.TransactionFactory;
import org.hibernate.hql.QueryTranslatorFactory;
import org.hibernate.internal.util.config.ConfigurationHelper;
import org.hibernate.jdbc.util.SQLStatementLogger;
-import org.hibernate.transaction.TransactionFactory;
-import org.hibernate.transaction.TransactionFactoryFactory;
-import org.hibernate.transaction.TransactionManagerLookup;
-import org.hibernate.transaction.TransactionManagerLookupFactory;
+import org.hibernate.service.jta.platform.spi.JtaPlatform;
+import org.hibernate.service.spi.ServiceRegistry;
import org.hibernate.util.ReflectHelper;
import org.hibernate.util.StringHelper;
@@ -66,7 +64,8 @@ public class SettingsFactory implements Serializable {
protected SettingsFactory() {
}
- public Settings buildSettings(Properties props, JdbcServices jdbcServices) {
+ public Settings buildSettings(Properties props, ServiceRegistry serviceRegistry) {
+ final JdbcServices jdbcServices = serviceRegistry.getService( JdbcServices.class );
Settings settings = new Settings();
//SessionFactory name:
@@ -90,10 +89,7 @@ public class SettingsFactory implements Serializable {
settings.setJdbcSupport( new JdbcSupport( ! ConfigurationHelper.getBoolean( Environment.NON_CONTEXTUAL_LOB_CREATION, properties ) ) );
// Transaction settings:
-
- TransactionFactory transactionFactory = createTransactionFactory(properties);
- settings.setTransactionFactory(transactionFactory);
- settings.setTransactionManagerLookup( createTransactionManagerLookup(properties) );
+ settings.setJtaPlatform( serviceRegistry.getService( JtaPlatform.class ) );
boolean flushBeforeCompletion = ConfigurationHelper.getBoolean(Environment.FLUSH_BEFORE_COMPLETION, properties);
log.info("Automatic flush during beforeCompletion(): " + enabledDisabled(flushBeforeCompletion) );
@@ -112,7 +108,6 @@ public class SettingsFactory implements Serializable {
boolean jdbcBatchVersionedData = ConfigurationHelper.getBoolean(Environment.BATCH_VERSIONED_DATA, properties, false);
if (batchSize>0) log.info("JDBC batch updates for versioned data: " + enabledDisabled(jdbcBatchVersionedData) );
settings.setJdbcBatchVersionedData(jdbcBatchVersionedData);
- settings.setBatcherBuilder( createBatchBuilder(properties, batchSize) );
boolean useScrollableResultSets = ConfigurationHelper.getBoolean(Environment.USE_SCROLLABLE_RESULTSET, properties, meta.supportsScrollableResults());
log.info("Scrollable result sets: " + enabledDisabled(useScrollableResultSets) );
@@ -134,7 +129,7 @@ public class SettingsFactory implements Serializable {
log.info( "Connection release mode: " + releaseModeName );
ConnectionReleaseMode releaseMode;
if ( "auto".equals(releaseModeName) ) {
- releaseMode = transactionFactory.getDefaultReleaseMode();
+ releaseMode = serviceRegistry.getService( TransactionFactory.class ).getDefaultReleaseMode();
}
else {
releaseMode = ConnectionReleaseMode.parse( releaseModeName );
@@ -301,7 +296,9 @@ public class SettingsFactory implements Serializable {
}
public static RegionFactory createRegionFactory(Properties properties, boolean cachingEnabled) {
- String regionFactoryClassName = ConfigurationHelper.getString( Environment.CACHE_REGION_FACTORY, properties, null );
+ String regionFactoryClassName = ConfigurationHelper.getString(
+ Environment.CACHE_REGION_FACTORY, properties, null
+ );
if ( regionFactoryClassName == null && cachingEnabled ) {
String providerClassName = ConfigurationHelper.getString( Environment.CACHE_PROVIDER, properties, null );
if ( providerClassName != null ) {
@@ -346,33 +343,4 @@ public class SettingsFactory implements Serializable {
}
}
- protected BatchBuilder createBatchBuilder(Properties properties, int batchSize) {
- String batchBuilderClass = properties.getProperty(Environment.BATCH_STRATEGY);
- BatchBuilder batchBuilder;
- if (batchBuilderClass==null) {
- batchBuilder = batchSize > 0
- ? new BatchBuilder( batchSize )
- : new BatchBuilder();
- }
- else {
- log.info("Batch factory: " + batchBuilderClass);
- try {
- batchBuilder = (BatchBuilder) ReflectHelper.classForName(batchBuilderClass).newInstance();
- }
- catch (Exception cnfe) {
- throw new HibernateException("could not instantiate BatchBuilder: " + batchBuilderClass, cnfe);
- }
- }
- batchBuilder.setJdbcBatchSize( batchSize );
- return batchBuilder;
- }
-
- protected TransactionFactory createTransactionFactory(Properties properties) {
- return TransactionFactoryFactory.buildTransactionFactory(properties);
- }
-
- protected TransactionManagerLookup createTransactionManagerLookup(Properties properties) {
- return TransactionManagerLookupFactory.getTransactionManagerLookup(properties);
- }
-
}
diff --git a/hibernate-core/src/main/java/org/hibernate/context/JTASessionContext.java b/hibernate-core/src/main/java/org/hibernate/context/JTASessionContext.java
index 7b7f7fc7e8..058882c5cc 100644
--- a/hibernate-core/src/main/java/org/hibernate/context/JTASessionContext.java
+++ b/hibernate-core/src/main/java/org/hibernate/context/JTASessionContext.java
@@ -28,7 +28,8 @@ import org.hibernate.HibernateException;
import org.hibernate.ConnectionReleaseMode;
import org.hibernate.classic.Session;
import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.util.JTAHelper;
+import org.hibernate.engine.transaction.internal.jta.JtaStatusHelper;
+import org.hibernate.service.jta.platform.spi.JtaPlatform;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -76,7 +77,8 @@ public class JTASessionContext implements CurrentSessionContext {
* {@inheritDoc}
*/
public Session currentSession() throws HibernateException {
- TransactionManager transactionManager = factory.getTransactionManager();
+ final JtaPlatform jtaPlatform = factory.getServiceRegistry().getService( JtaPlatform.class );
+ final TransactionManager transactionManager = jtaPlatform.retrieveTransactionManager();
if ( transactionManager == null ) {
throw new HibernateException( "No TransactionManagerLookup specified" );
}
@@ -87,9 +89,9 @@ public class JTASessionContext implements CurrentSessionContext {
if ( txn == null ) {
throw new HibernateException( "Unable to locate current JTA transaction" );
}
- if ( !JTAHelper.isInProgress( txn.getStatus() ) ) {
+ if ( !JtaStatusHelper.isActive( txn.getStatus() ) ) {
// We could register the session against the transaction even though it is
- // not started, but we'd have no guarentee of ever getting the map
+ // not started, but we'd have no guarantee of ever getting the map
// entries cleaned up (aside from spawning threads).
throw new HibernateException( "Current transaction is not in progress" );
}
@@ -101,9 +103,7 @@ public class JTASessionContext implements CurrentSessionContext {
throw new HibernateException( "Problem locating/validating JTA transaction", t );
}
- final Object txnIdentifier = factory.getSettings().getTransactionManagerLookup() == null
- ? txn
- : factory.getSettings().getTransactionManagerLookup().getTransactionIdentifier( txn );
+ final Object txnIdentifier = jtaPlatform.getTransactionIdentifier( txn );
Session currentSession = ( Session ) currentSessionMap.get( txnIdentifier );
diff --git a/hibernate-core/src/main/java/org/hibernate/context/ThreadLocalSessionContext.java b/hibernate-core/src/main/java/org/hibernate/context/ThreadLocalSessionContext.java
index a0613d8a6f..f3bbe79cd9 100644
--- a/hibernate-core/src/main/java/org/hibernate/context/ThreadLocalSessionContext.java
+++ b/hibernate-core/src/main/java/org/hibernate/context/ThreadLocalSessionContext.java
@@ -43,6 +43,10 @@ import org.hibernate.HibernateException;
import org.hibernate.SessionFactory;
import org.hibernate.classic.Session;
import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.engine.jdbc.LobCreationContext;
+import org.hibernate.engine.transaction.spi.TransactionContext;
+import org.hibernate.event.EventSource;
/**
* A {@link CurrentSessionContext} impl which scopes the notion of current
@@ -74,11 +78,11 @@ public class ThreadLocalSessionContext implements CurrentSessionContext {
private static final Logger log = LoggerFactory.getLogger( ThreadLocalSessionContext.class );
private static final Class[] SESSION_PROXY_INTERFACES = new Class[] {
- org.hibernate.classic.Session.class,
- org.hibernate.engine.SessionImplementor.class,
- org.hibernate.engine.jdbc.spi.JDBCContext.Context.class,
- org.hibernate.event.EventSource.class,
- org.hibernate.engine.jdbc.LobCreationContext.class
+ Session.class,
+ SessionImplementor.class,
+ EventSource.class,
+ TransactionContext.class,
+ LobCreationContext.class
};
/**
diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/lock/PessimisticReadSelectLockingStrategy.java b/hibernate-core/src/main/java/org/hibernate/dialect/lock/PessimisticReadSelectLockingStrategy.java
index 12e7b4c575..d8db93be62 100644
--- a/hibernate-core/src/main/java/org/hibernate/dialect/lock/PessimisticReadSelectLockingStrategy.java
+++ b/hibernate-core/src/main/java/org/hibernate/dialect/lock/PessimisticReadSelectLockingStrategy.java
@@ -78,7 +78,7 @@ public class PessimisticReadSelectLockingStrategy extends AbstractSelectLockingS
final String sql = determineSql( timeout );
SessionFactoryImplementor factory = session.getFactory();
try {
- PreparedStatement st = session.getJDBCContext().getConnectionManager().prepareSelectStatement( sql );
+ PreparedStatement st = session.getTransactionCoordinator().getJdbcCoordinator().getStatementPreparer().prepareStatement( sql );
try {
getLockable().getIdentifierType().nullSafeSet( st, id, 1, session );
if ( getLockable().isVersioned() ) {
diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/lock/PessimisticReadUpdateLockingStrategy.java b/hibernate-core/src/main/java/org/hibernate/dialect/lock/PessimisticReadUpdateLockingStrategy.java
index 9d473ca9b9..19976b0898 100644
--- a/hibernate-core/src/main/java/org/hibernate/dialect/lock/PessimisticReadUpdateLockingStrategy.java
+++ b/hibernate-core/src/main/java/org/hibernate/dialect/lock/PessimisticReadUpdateLockingStrategy.java
@@ -94,7 +94,7 @@ public class PessimisticReadUpdateLockingStrategy implements LockingStrategy {
}
SessionFactoryImplementor factory = session.getFactory();
try {
- PreparedStatement st = session.getJDBCContext().getConnectionManager().prepareSelectStatement( sql );
+ PreparedStatement st = session.getTransactionCoordinator().getJdbcCoordinator().getStatementPreparer().prepareStatement( sql );
try {
lockable.getVersionType().nullSafeSet( st, version, 1, session );
int offset = 2;
diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/lock/PessimisticWriteSelectLockingStrategy.java b/hibernate-core/src/main/java/org/hibernate/dialect/lock/PessimisticWriteSelectLockingStrategy.java
index d7cd8e96c2..a280a88526 100644
--- a/hibernate-core/src/main/java/org/hibernate/dialect/lock/PessimisticWriteSelectLockingStrategy.java
+++ b/hibernate-core/src/main/java/org/hibernate/dialect/lock/PessimisticWriteSelectLockingStrategy.java
@@ -78,7 +78,7 @@ public class PessimisticWriteSelectLockingStrategy extends AbstractSelectLocking
final String sql = determineSql( timeout );
SessionFactoryImplementor factory = session.getFactory();
try {
- PreparedStatement st = session.getJDBCContext().getConnectionManager().prepareSelectStatement( sql );
+ PreparedStatement st = session.getTransactionCoordinator().getJdbcCoordinator().getStatementPreparer().prepareStatement( sql );
try {
getLockable().getIdentifierType().nullSafeSet( st, id, 1, session );
if ( getLockable().isVersioned() ) {
diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/lock/PessimisticWriteUpdateLockingStrategy.java b/hibernate-core/src/main/java/org/hibernate/dialect/lock/PessimisticWriteUpdateLockingStrategy.java
index 47d9af492c..d59c619e24 100644
--- a/hibernate-core/src/main/java/org/hibernate/dialect/lock/PessimisticWriteUpdateLockingStrategy.java
+++ b/hibernate-core/src/main/java/org/hibernate/dialect/lock/PessimisticWriteUpdateLockingStrategy.java
@@ -94,7 +94,7 @@ public class PessimisticWriteUpdateLockingStrategy implements LockingStrategy {
}
SessionFactoryImplementor factory = session.getFactory();
try {
- PreparedStatement st = session.getJDBCContext().getConnectionManager().prepareSelectStatement( sql );
+ PreparedStatement st = session.getTransactionCoordinator().getJdbcCoordinator().getStatementPreparer().prepareStatement( sql );
try {
lockable.getVersionType().nullSafeSet( st, version, 1, session );
int offset = 2;
diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/lock/SelectLockingStrategy.java b/hibernate-core/src/main/java/org/hibernate/dialect/lock/SelectLockingStrategy.java
index 65e563f76b..dbca19411f 100644
--- a/hibernate-core/src/main/java/org/hibernate/dialect/lock/SelectLockingStrategy.java
+++ b/hibernate-core/src/main/java/org/hibernate/dialect/lock/SelectLockingStrategy.java
@@ -73,7 +73,7 @@ public class SelectLockingStrategy extends AbstractSelectLockingStrategy {
final String sql = determineSql( timeout );
SessionFactoryImplementor factory = session.getFactory();
try {
- PreparedStatement st = session.getJDBCContext().getConnectionManager().prepareSelectStatement( sql );
+ PreparedStatement st = session.getTransactionCoordinator().getJdbcCoordinator().getStatementPreparer().prepareStatement( sql );
try {
getLockable().getIdentifierType().nullSafeSet( st, id, 1, session );
if ( getLockable().isVersioned() ) {
diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/lock/UpdateLockingStrategy.java b/hibernate-core/src/main/java/org/hibernate/dialect/lock/UpdateLockingStrategy.java
index a8c7e2b47d..d68b79b0a7 100644
--- a/hibernate-core/src/main/java/org/hibernate/dialect/lock/UpdateLockingStrategy.java
+++ b/hibernate-core/src/main/java/org/hibernate/dialect/lock/UpdateLockingStrategy.java
@@ -92,7 +92,7 @@ public class UpdateLockingStrategy implements LockingStrategy {
// todo : should we additionally check the current isolation mode explicitly?
SessionFactoryImplementor factory = session.getFactory();
try {
- PreparedStatement st = session.getJDBCContext().getConnectionManager().prepareSelectStatement( sql );
+ PreparedStatement st = session.getTransactionCoordinator().getJdbcCoordinator().getStatementPreparer().prepareStatement( sql );
try {
lockable.getVersionType().nullSafeSet( st, version, 1, session );
int offset = 2;
diff --git a/hibernate-core/src/main/java/org/hibernate/engine/ActionQueue.java b/hibernate-core/src/main/java/org/hibernate/engine/ActionQueue.java
index 56b5bcb939..92c8709fa5 100644
--- a/hibernate-core/src/main/java/org/hibernate/engine/ActionQueue.java
+++ b/hibernate-core/src/main/java/org/hibernate/engine/ActionQueue.java
@@ -265,7 +265,7 @@ public class ActionQueue {
execute( ( Executable ) list.get( i ) );
}
list.clear();
- session.getJDBCContext().getConnectionManager().executeBatch();
+ session.getTransactionCoordinator().getJdbcCoordinator().executeBatch();
}
public void execute(Executable executable) {
diff --git a/hibernate-core/src/main/java/org/hibernate/engine/SessionFactoryImplementor.java b/hibernate-core/src/main/java/org/hibernate/engine/SessionFactoryImplementor.java
index 4a8eba6789..a72b2aee50 100644
--- a/hibernate-core/src/main/java/org/hibernate/engine/SessionFactoryImplementor.java
+++ b/hibernate-core/src/main/java/org/hibernate/engine/SessionFactoryImplementor.java
@@ -52,6 +52,7 @@ import org.hibernate.dialect.Dialect;
import org.hibernate.dialect.function.SQLFunctionRegistry;
import org.hibernate.exception.SQLExceptionConverter;
import org.hibernate.id.IdentifierGenerator;
+import org.hibernate.service.spi.ServiceRegistry;
import org.hibernate.stat.StatisticsImplementor;
import org.hibernate.type.Type;
import org.hibernate.type.TypeResolver;
@@ -145,13 +146,6 @@ public interface SessionFactoryImplementor extends Mapping, SessionFactory {
*/
public String getImportedClassName(String name);
-
- /**
- * Get the JTA transaction manager
- */
- public TransactionManager getTransactionManager();
-
-
/**
* Get the default query cache
*/
@@ -262,4 +256,5 @@ public interface SessionFactoryImplementor extends Mapping, SessionFactory {
*/
public FetchProfile getFetchProfile(String name);
+ public ServiceRegistry getServiceRegistry();
}
diff --git a/hibernate-core/src/main/java/org/hibernate/engine/SessionImplementor.java b/hibernate-core/src/main/java/org/hibernate/engine/SessionImplementor.java
index ca3a585439..a566ce401c 100644
--- a/hibernate-core/src/main/java/org/hibernate/engine/SessionImplementor.java
+++ b/hibernate-core/src/main/java/org/hibernate/engine/SessionImplementor.java
@@ -39,9 +39,9 @@ import org.hibernate.Query;
import org.hibernate.ScrollMode;
import org.hibernate.ScrollableResults;
import org.hibernate.Transaction;
-import org.hibernate.engine.jdbc.spi.JDBCContext;
import org.hibernate.engine.query.sql.NativeSQLQuerySpecification;
import org.hibernate.collection.PersistentCollection;
+import org.hibernate.engine.transaction.spi.TransactionCoordinator;
import org.hibernate.event.EventListeners;
import org.hibernate.impl.CriteriaImpl;
import org.hibernate.loader.custom.CustomQuery;
@@ -157,20 +157,6 @@ public interface SessionImplementor extends Serializable {
*/
public Object getEntityUsingInterceptor(EntityKey key) throws HibernateException;
- /**
- * Notify the session that the transaction completed, so we no longer
- * own the old locks. (Also we should release cache softlocks.) May
- * be called multiple times during the transaction completion process.
- * Also called after an autocommit, in which case the second argument
- * is null.
- */
- public void afterTransactionCompletion(boolean successful, Transaction tx);
-
- /**
- * Notify the session that the transaction is about to complete
- */
- public void beforeTransactionCompletion(Transaction tx);
-
/**
* Return the identifier of the persistent object, or null if
* not associated with the session
@@ -340,11 +326,16 @@ public interface SessionImplementor extends Serializable {
*/
public void setFetchProfile(String name);
- public JDBCContext getJDBCContext();
+ /**
+ * Retrieve access to the session's transaction coordinator.
+ *
+ * @return The transaction coordinator.
+ */
+ public TransactionCoordinator getTransactionCoordinator();
/**
- * Determine whether the session is closed. Provided seperately from
- * {@link #isOpen()} as this method does not attempt any JTA synch
+ * Determine whether the session is closed. Provided separately from
+ * {@link #isOpen()} as this method does not attempt any JTA synchronization
* registration, where as {@link #isOpen()} does; which makes this one
* nicer to use for most internal purposes.
*
diff --git a/hibernate-core/src/main/java/org/hibernate/engine/TransactionHelper.java b/hibernate-core/src/main/java/org/hibernate/engine/TransactionHelper.java
index 0c7df45cdc..d820594a9a 100644
--- a/hibernate-core/src/main/java/org/hibernate/engine/TransactionHelper.java
+++ b/hibernate-core/src/main/java/org/hibernate/engine/TransactionHelper.java
@@ -1,10 +1,10 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
- * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * Copyright (c) 2008-2011, 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 Middleware LLC.
+ * 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
@@ -20,19 +20,16 @@
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
- *
*/
package org.hibernate.engine;
+import org.hibernate.HibernateException;
+import org.hibernate.jdbc.Work;
+
import java.io.Serializable;
import java.sql.Connection;
import java.sql.SQLException;
-import org.hibernate.HibernateException;
-import org.hibernate.engine.transaction.IsolatedWork;
-import org.hibernate.engine.transaction.Isolater;
-import org.hibernate.exception.JDBCExceptionHelper;
-
/**
* Allows work to be done outside the current transaction, by suspending it,
* and performing work in a new transaction
@@ -41,7 +38,7 @@ import org.hibernate.exception.JDBCExceptionHelper;
*/
public abstract class TransactionHelper {
- // todo : remove this and just have subclasses use Isolater/IsolatedWork directly...
+ // todo : remove this and just have subclasses use IsolationDelegate directly...
/**
* The work to be done
@@ -51,26 +48,27 @@ public abstract class TransactionHelper {
/**
* Suspend the current transaction and perform work in a new transaction
*/
- public Serializable doWorkInNewTransaction(final SessionImplementor session)
- throws HibernateException {
- class Work implements IsolatedWork {
+ public Serializable doWorkInNewTransaction(final SessionImplementor session) throws HibernateException {
+ class WorkToDo implements Work {
Serializable generatedValue;
- public void doWork(Connection connection) throws HibernateException {
+
+ @Override
+ public void execute(Connection connection) throws SQLException {
String sql = null;
try {
generatedValue = doWorkInCurrentTransaction( connection, sql );
}
- catch( SQLException sqle ) {
+ catch( SQLException e ) {
throw session.getFactory().getSQLExceptionHelper().convert(
- sqle,
+ e,
"could not get or update next value",
sql
- );
+ );
}
}
}
- Work work = new Work();
- Isolater.doIsolatedWork( work, session );
+ WorkToDo work = new WorkToDo();
+ session.getTransactionCoordinator().getTransaction().createIsolationDelegate().delegateWork( work, true );
return work.generatedValue;
}
}
diff --git a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/batch/internal/AbstractBatchImpl.java b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/batch/internal/AbstractBatchImpl.java
index 5d171f4a38..a0c4bd2b97 100644
--- a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/batch/internal/AbstractBatchImpl.java
+++ b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/batch/internal/AbstractBatchImpl.java
@@ -23,19 +23,20 @@
*/
package org.hibernate.engine.jdbc.batch.internal;
+import org.hibernate.engine.jdbc.batch.spi.Batch;
+import org.hibernate.engine.jdbc.batch.spi.BatchKey;
+import org.hibernate.engine.jdbc.batch.spi.BatchObserver;
+import org.hibernate.engine.jdbc.spi.JdbcCoordinator;
+import org.hibernate.engine.jdbc.spi.SQLExceptionHelper;
+import org.hibernate.engine.jdbc.spi.SQLStatementLogger;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.hibernate.engine.jdbc.batch.spi.Batch;
-import org.hibernate.engine.jdbc.batch.spi.BatchObserver;
-import org.hibernate.engine.jdbc.spi.SQLExceptionHelper;
-import org.hibernate.engine.jdbc.spi.SQLStatementLogger;
-
/**
* Convenience base class for implementors of the Batch interface.
*
@@ -44,21 +45,20 @@ import org.hibernate.engine.jdbc.spi.SQLStatementLogger;
public abstract class AbstractBatchImpl implements Batch {
private static final Logger log = LoggerFactory.getLogger( AbstractBatchImpl.class );
- private final SQLStatementLogger statementLogger;
- private final SQLExceptionHelper exceptionHelper;
- private Object key;
+ private final BatchKey key;
+ private final JdbcCoordinator jdbcCoordinator;
private LinkedHashMap statements = new LinkedHashMap();
private LinkedHashSet observers = new LinkedHashSet();
- protected AbstractBatchImpl(Object key,
- SQLStatementLogger statementLogger,
- SQLExceptionHelper exceptionHelper) {
- if ( key == null || statementLogger == null || exceptionHelper == null ) {
- throw new IllegalArgumentException( "key, statementLogger, and exceptionHelper must be non-null." );
+ protected AbstractBatchImpl(BatchKey key, JdbcCoordinator jdbcCoordinator) {
+ if ( key == null ) {
+ throw new IllegalArgumentException( "batch key cannot be null" );
+ }
+ if ( jdbcCoordinator == null ) {
+ throw new IllegalArgumentException( "JDBC coordinator cannot be null" );
}
this.key = key;
- this.statementLogger = statementLogger;
- this.exceptionHelper = exceptionHelper;
+ this.jdbcCoordinator = jdbcCoordinator;
}
/**
@@ -74,8 +74,12 @@ public abstract class AbstractBatchImpl implements Batch {
*
* @return The underlying SQLException helper.
*/
- protected SQLExceptionHelper getSqlExceptionHelper() {
- return exceptionHelper;
+ protected SQLExceptionHelper sqlExceptionHelper() {
+ return jdbcCoordinator.getTransactionCoordinator()
+ .getTransactionContext()
+ .getTransactionEnvironment()
+ .getJdbcServices()
+ .getSqlExceptionHelper();
}
/**
@@ -83,8 +87,12 @@ public abstract class AbstractBatchImpl implements Batch {
*
* @return The underlying JDBC services.
*/
- protected SQLStatementLogger getSqlStatementLogger() {
- return statementLogger;
+ protected SQLStatementLogger sqlStatementLogger() {
+ return jdbcCoordinator.getTransactionCoordinator()
+ .getTransactionContext()
+ .getTransactionEnvironment()
+ .getJdbcServices()
+ .getSqlStatementLogger();
}
/**
@@ -96,62 +104,49 @@ public abstract class AbstractBatchImpl implements Batch {
return statements;
}
- /**
- * {@inheritDoc}
- */
- public final Object getKey() {
+ @Override
+ public final BatchKey getKey() {
return key;
}
- /**
- * {@inheritDoc}
- */
+ @Override
public void addObserver(BatchObserver observer) {
observers.add( observer );
}
- /**
- * {@inheritDoc}
- */
- public final PreparedStatement getBatchStatement(Object key, String sql) {
- checkConsistentBatchKey( key );
+ @Override
+ public PreparedStatement getBatchStatement(String sql, boolean callable) {
if ( sql == null ) {
throw new IllegalArgumentException( "sql must be non-null." );
}
PreparedStatement statement = statements.get( sql );
- if ( statement != null ) {
- log.debug( "reusing prepared statement" );
- statementLogger.logStatement( sql );
- }
+ if ( statement == null ) {
+ statement = buildBatchStatement( sql, callable );
+ statements.put( sql, statement );
+ }
+ else {
+ log.debug( "reusing batch statement" );
+ sqlStatementLogger().logStatement( sql );
+ }
return statement;
}
- /**
- * {@inheritDoc}
- */
- // TODO: should this be final???
+ private PreparedStatement buildBatchStatement(String sql, boolean callable) {
+ try {
+ if ( callable ) {
+ return jdbcCoordinator.getLogicalConnection().getShareableConnectionProxy().prepareCall( sql );
+ }
+ else {
+ return jdbcCoordinator.getLogicalConnection().getShareableConnectionProxy().prepareStatement( sql );
+ }
+ }
+ catch ( SQLException sqle ) {
+ log.error( "sqlexception escaped proxy", sqle );
+ throw sqlExceptionHelper().convert( sqle, "could not prepare batch statement", sql );
+ }
+ }
+
@Override
- public void addBatchStatement(Object key, String sql, PreparedStatement preparedStatement) {
- checkConsistentBatchKey( key );
- if ( sql == null ) {
- throw new IllegalArgumentException( "sql must be non-null." );
- }
- if ( statements.put( sql, preparedStatement ) != null ) {
- log.error( "PreparedStatement was already in the batch, [" + sql + "]." );
- }
- }
-
- protected void checkConsistentBatchKey(Object key) {
- if ( ! this.key.equals( key ) ) {
- throw new IllegalStateException(
- "specified key ["+ key + "] is different from internal batch key [" + this.key + "]."
- );
- }
- }
-
- /**
- * {@inheritDoc}
- */
public final void execute() {
notifyObserversExplicitExecution();
if ( statements.isEmpty() ) {
@@ -162,7 +157,7 @@ public abstract class AbstractBatchImpl implements Batch {
doExecuteBatch();
}
finally {
- release();
+ releaseStatements();
}
}
finally {
@@ -176,14 +171,16 @@ public abstract class AbstractBatchImpl implements Batch {
statement.close();
}
catch ( SQLException e ) {
- log.error( "unable to release batch statement..." );
- log.error( "sqlexception escaped proxy", e );
+ log.error( "unable to release batch statement; sqlexception escaped proxy", e );
}
}
getStatements().clear();
}
- private void notifyObserversExplicitExecution() {
+ /**
+ * Convenience method to notify registered observers of an explicit execution of this batch.
+ */
+ protected final void notifyObserversExplicitExecution() {
for ( BatchObserver observer : observers ) {
observer.batchExplicitlyExecuted();
}
@@ -192,12 +189,13 @@ public abstract class AbstractBatchImpl implements Batch {
/**
* Convenience method to notify registered observers of an implicit execution of this batch.
*/
- protected void notifyObserversImplicitExecution() {
+ protected final void notifyObserversImplicitExecution() {
for ( BatchObserver observer : observers ) {
observer.batchImplicitlyExecuted();
}
}
+ @Override
public void release() {
if ( getStatements() != null && !getStatements().isEmpty() ) {
log.info( "On release of batch it still contained JDBC statements" );
diff --git a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/batch/internal/BasicBatchKey.java b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/batch/internal/BasicBatchKey.java
new file mode 100644
index 0000000000..0cff7e330a
--- /dev/null
+++ b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/batch/internal/BasicBatchKey.java
@@ -0,0 +1,89 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2011, 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
+ */
+package org.hibernate.engine.jdbc.batch.internal;
+
+import org.hibernate.engine.jdbc.batch.spi.BatchKey;
+import org.hibernate.jdbc.Expectation;
+
+/**
+ * @author Steve Ebersole
+ */
+public class BasicBatchKey implements BatchKey {
+ private final String comparison;
+ private final int statementCount;
+ private final Expectation expectation;
+
+// public BasicBatchKey(String comparison, int statementCount, Expectation expectation) {
+// this.comparison = comparison;
+// this.statementCount = statementCount;
+// this.expectations = new Expectation[statementCount];
+// Arrays.fill( this.expectations, expectation );
+// }
+//
+// public BasicBatchKey(String comparison, Expectation... expectations) {
+// this.comparison = comparison;
+// this.statementCount = expectations.length;
+// this.expectations = expectations;
+// }
+
+ public BasicBatchKey(String comparison, Expectation expectation) {
+ this.comparison = comparison;
+ this.statementCount = 1;
+ this.expectation = expectation;
+ }
+
+ @Override
+ public Expectation getExpectation() {
+ return expectation;
+ }
+
+ @Override
+ public int getBatchedStatementCount() {
+ return statementCount;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if ( this == o ) {
+ return true;
+ }
+ if ( o == null || getClass() != o.getClass() ) {
+ return false;
+ }
+
+ BasicBatchKey that = (BasicBatchKey) o;
+
+ if ( !comparison.equals( that.comparison ) ) {
+ return false;
+ }
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ return comparison.hashCode();
+ }
+
+}
diff --git a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/batch/internal/BatchBuilder.java b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/batch/internal/BatchBuilderImpl.java
similarity index 59%
rename from hibernate-core/src/main/java/org/hibernate/engine/jdbc/batch/internal/BatchBuilder.java
rename to hibernate-core/src/main/java/org/hibernate/engine/jdbc/batch/internal/BatchBuilderImpl.java
index e01a7047b3..71157a798f 100644
--- a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/batch/internal/BatchBuilder.java
+++ b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/batch/internal/BatchBuilderImpl.java
@@ -23,28 +23,37 @@
*/
package org.hibernate.engine.jdbc.batch.internal;
+import org.hibernate.cfg.Environment;
+import org.hibernate.engine.jdbc.batch.spi.Batch;
+import org.hibernate.engine.jdbc.batch.spi.BatchBuilder;
+import org.hibernate.engine.jdbc.batch.spi.BatchKey;
+import org.hibernate.engine.jdbc.spi.JdbcCoordinator;
+import org.hibernate.internal.util.config.ConfigurationHelper;
+import org.hibernate.service.spi.Configurable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.hibernate.engine.jdbc.batch.spi.Batch;
-import org.hibernate.engine.jdbc.spi.LogicalConnectionImplementor;
-import org.hibernate.engine.jdbc.spi.SQLExceptionHelper;
-import org.hibernate.engine.jdbc.spi.SQLStatementLogger;
+import java.util.Map;
/**
* A builder for {@link Batch} instances.
*
* @author Steve Ebersole
*/
-public class BatchBuilder {
- private static final Logger log = LoggerFactory.getLogger( BatchBuilder.class );
+public class BatchBuilderImpl implements BatchBuilder, Configurable {
+ private static final Logger log = LoggerFactory.getLogger( BatchBuilderImpl.class );
private int size;
- public BatchBuilder() {
+ public BatchBuilderImpl() {
}
- public BatchBuilder(int size) {
+ @Override
+ public void configure(Map configurationValues) {
+ size = ConfigurationHelper.getInt( Environment.STATEMENT_BATCH_SIZE, configurationValues, size );
+ }
+
+ public BatchBuilderImpl(int size) {
this.size = size;
}
@@ -52,13 +61,27 @@ public class BatchBuilder {
this.size = size;
}
- public Batch buildBatch(Object key,
- SQLStatementLogger statementLogger,
- SQLExceptionHelper exceptionHelper) {
+ @Override
+ public Batch buildBatch(BatchKey key, JdbcCoordinator jdbcCoordinator) {
log.trace( "building batch [size={}]", size );
return size > 1
- ? new BatchingBatch( key, statementLogger, exceptionHelper, size )
- : new NonBatchingBatch( key, statementLogger, exceptionHelper );
+ ? new BatchingBatch( key, jdbcCoordinator, size )
+ : new NonBatchingBatch( key, jdbcCoordinator );
+ }
+
+ @Override
+ public String getManagementDomain() {
+ return null; // use Hibernate default domain
+ }
+
+ @Override
+ public String getManagementServiceType() {
+ return null; // use Hibernate default scheme
+ }
+
+ @Override
+ public Object getManagementBean() {
+ return this;
}
}
diff --git a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/batch/internal/BatchBuilderInitiator.java b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/batch/internal/BatchBuilderInitiator.java
new file mode 100644
index 0000000000..26b5c4f3bd
--- /dev/null
+++ b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/batch/internal/BatchBuilderInitiator.java
@@ -0,0 +1,69 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2011, 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
+ */
+package org.hibernate.engine.jdbc.batch.internal;
+
+import org.hibernate.cfg.Environment;
+import org.hibernate.engine.jdbc.batch.spi.BatchBuilder;
+import org.hibernate.internal.util.config.ConfigurationHelper;
+import org.hibernate.service.classloading.spi.ClassLoaderService;
+import org.hibernate.service.spi.ServiceException;
+import org.hibernate.service.spi.ServiceInitiator;
+import org.hibernate.service.spi.ServiceRegistry;
+
+import java.util.Map;
+
+/**
+ * @author Steve Ebersole
+ */
+public class BatchBuilderInitiator implements ServiceInitiator {
+ public static final BatchBuilderInitiator INSTANCE = new BatchBuilderInitiator();
+ public static final String BUILDER = "hibernate.jdbc.batch.builder";
+
+ @Override
+ public Class getServiceInitiated() {
+ return BatchBuilder.class;
+ }
+
+ @Override
+ public BatchBuilder initiateService(Map configurationValues, ServiceRegistry registry) {
+ final Object builder = configurationValues.get( BUILDER );
+ if ( builder == null ) {
+ return new BatchBuilderImpl(
+ ConfigurationHelper.getInt( Environment.STATEMENT_BATCH_SIZE, configurationValues, 1 )
+ );
+ }
+
+ if ( BatchBuilder.class.isInstance( builder ) ) {
+ return (BatchBuilder) builder;
+ }
+
+ final String builderClassName = builder.toString();
+ try {
+ return (BatchBuilder) registry.getService( ClassLoaderService.class ).classForName( builderClassName ).newInstance();
+ }
+ catch (Exception e) {
+ throw new ServiceException( "Could not build explicit BatchBuilder [" + builderClassName + "]", e );
+ }
+ }
+}
diff --git a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/batch/internal/BatchingBatch.java b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/batch/internal/BatchingBatch.java
index 9dc1b27020..1b91a78b0a 100644
--- a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/batch/internal/BatchingBatch.java
+++ b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/batch/internal/BatchingBatch.java
@@ -23,173 +23,116 @@
*/
package org.hibernate.engine.jdbc.batch.internal;
-import java.sql.PreparedStatement;
-import java.sql.SQLException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
+import org.hibernate.HibernateException;
+import org.hibernate.engine.jdbc.batch.spi.BatchKey;
+import org.hibernate.engine.jdbc.spi.JdbcCoordinator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.hibernate.AssertionFailure;
-import org.hibernate.HibernateException;
-import org.hibernate.engine.jdbc.spi.SQLExceptionHelper;
-import org.hibernate.engine.jdbc.spi.SQLStatementLogger;
-import org.hibernate.jdbc.Expectation;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.util.Map;
/**
- * A {@link org.hibernate.engine.jdbc.batch.spi.Batch} implementation which does
- * batching based on a given size. Once the batch size is reached for a statement
- * in the batch, the entire batch is implicitly executed.
+ * A {@link org.hibernate.engine.jdbc.batch.spi.Batch} implementation which does bathing based on a given size. Once
+ * the batch size is reached for a statement in the batch, the entire batch is implicitly executed.
*
* @author Steve Ebersole
*/
public class BatchingBatch extends AbstractBatchImpl {
private static final Logger log = LoggerFactory.getLogger( BatchingBatch.class );
+ // IMPL NOTE : Until HHH-5797 is fixed, there will only be 1 statement in a batch
+
private final int batchSize;
+ private int batchPosition;
+ private int statementPosition;
- // TODO: A Map is used for expectations so it is possible to track when a batch
- // is full (i.e., when the batch for a particular statement exceeds batchSize)
- // Until HHH-5797 is fixed, there will only be 1 statement in a batch, so it won't
- // be necessary to track expectations by statement.
- private Map> expectationsBySql;
- private int maxBatchPosition;
-
- public BatchingBatch(Object key,
- SQLStatementLogger statementLogger,
- SQLExceptionHelper exceptionHelper,
- int batchSize) {
- super( key, statementLogger, exceptionHelper );
- this.batchSize = batchSize;
- this.expectationsBySql = new HashMap>();
- }
-
- /**
- * {@inheritDoc}
- */
- public void addToBatch(Object key, String sql, Expectation expectation) {
- checkConsistentBatchKey( key );
- if ( sql == null || expectation == null ) {
- throw new AssertionFailure( "sql or expection was null." );
- }
- if ( ! expectation.canBeBatched() ) {
+ public BatchingBatch(
+ BatchKey key,
+ JdbcCoordinator jdbcCoordinator,
+ int batchSize) {
+ super( key, jdbcCoordinator );
+ if ( ! key.getExpectation().canBeBatched() ) {
throw new HibernateException( "attempting to batch an operation which cannot be batched" );
}
- final PreparedStatement statement = getStatements().get( sql );
+ this.batchSize = batchSize;
+ }
+
+ private String currentStatementSql;
+ private PreparedStatement currentStatement;
+
+ @Override
+ public PreparedStatement getBatchStatement(String sql, boolean callable) {
+ currentStatementSql = sql;
+ currentStatement = super.getBatchStatement( sql, callable );
+ return currentStatement;
+ }
+
+ @Override
+ public void addToBatch() {
try {
- statement.addBatch();
+ currentStatement.addBatch();
}
catch ( SQLException e ) {
- log.error( "sqlexception escaped proxy", e );
- throw getSqlExceptionHelper().convert( e, "could not perform addBatch", sql );
+ log.debug( "sqlexception escaped proxy", e );
+ throw sqlExceptionHelper().convert( e, "could not perform addBatch", currentStatementSql );
}
- List expectations = expectationsBySql.get( sql );
- if ( expectations == null ) {
- expectations = new ArrayList( batchSize );
- expectationsBySql.put( sql, expectations );
- }
- expectations.add( expectation );
- maxBatchPosition = Math.max( maxBatchPosition, expectations.size() );
-
- // TODO: When HHH-5797 is fixed the following if-block should probably be moved before
- // adding the batch to the current statement (to detect that we have finished
- // with the previous entity).
- if ( maxBatchPosition == batchSize ) {
- notifyObserversImplicitExecution();
- doExecuteBatch();
+ statementPosition++;
+ if ( statementPosition >= getKey().getBatchedStatementCount() ) {
+ batchPosition++;
+ if ( batchPosition == batchSize ) {
+ notifyObserversImplicitExecution();
+ performExecution();
+ batchPosition = 0;
+ }
+ statementPosition = 0;
}
}
- /**
- * {@inheritDoc}
- */
+ @Override
protected void doExecuteBatch() {
- if ( maxBatchPosition == 0 ) {
+ if ( batchPosition == 0 ) {
log.debug( "no batched statements to execute" );
}
else {
if ( log.isDebugEnabled() ) {
- log.debug( "Executing {} statements with maximum batch size {} ",
- getStatements().size(), maxBatchPosition
- );
- }
- try {
- executeStatements();
- }
- catch ( RuntimeException re ) {
- log.error( "Exception executing batch [{}]", re.getMessage() );
- throw re;
- }
- finally {
- for ( List expectations : expectationsBySql.values() ) {
- expectations.clear();
- }
- maxBatchPosition = 0;
+ log.debug( "Executing batch size: " + batchPosition );
}
+ performExecution();
}
}
- private void executeStatements() {
- for ( Map.Entry entry : getStatements().entrySet() ) {
- final String sql = entry.getKey();
- final PreparedStatement statement = entry.getValue();
- final List expectations = expectationsBySql.get( sql );
- if ( batchSize < expectations.size() ) {
- throw new IllegalStateException(
- "Number of expectations [" + expectations.size() +
- "] is greater than batch size [" + batchSize +
- "] for statement [" + sql +
- "]"
- );
- }
- if ( expectations.size() > 0 ) {
- if ( log.isDebugEnabled() ) {
- log.debug( "Executing with batch of size {}: {}", expectations.size(), sql );
- }
- executeStatement( sql, statement, expectations );
- expectations.clear();
- }
- else {
- if ( log.isDebugEnabled() ) {
- log.debug( "Skipped executing because batch size is 0: ", sql );
- }
- }
- }
- }
-
- private void executeStatement(String sql, PreparedStatement ps, List expectations) {
+ private void performExecution() {
try {
- checkRowCounts( sql, ps.executeBatch(), ps, expectations );
+ for ( Map.Entry entry : getStatements().entrySet() ) {
+ try {
+ final PreparedStatement statement = entry.getValue();
+ checkRowCounts( statement.executeBatch(), statement );
+ }
+ catch ( SQLException e ) {
+ log.debug( "sqlexception escaped proxy", e );
+ throw sqlExceptionHelper().convert( e, "could not perform addBatch", entry.getKey() );
+ }
+ }
}
- catch ( SQLException e ) {
- log.error( "sqlexception escaped proxy", e );
- throw getSqlExceptionHelper()
- .convert( e, "could not execute statement: " + sql );
+ catch ( RuntimeException re ) {
+ log.error( "Exception executing batch [{}]", re.getMessage() );
+ throw re;
+ }
+ finally {
+ batchPosition = 0;
}
}
- private void checkRowCounts(String sql, int[] rowCounts, PreparedStatement ps, List expectations) {
+ private void checkRowCounts(int[] rowCounts, PreparedStatement ps) throws SQLException, HibernateException {
int numberOfRowCounts = rowCounts.length;
- if ( numberOfRowCounts != expectations.size() ) {
+ if ( numberOfRowCounts != batchPosition ) {
log.warn( "JDBC driver did not return the expected number of row counts" );
}
- try {
- for ( int i = 0; i < numberOfRowCounts; i++ ) {
- expectations.get( i ).verifyOutcome( rowCounts[i], ps, i );
- }
- }
- catch ( SQLException e ) {
- log.error( "sqlexception escaped proxy", e );
- throw getSqlExceptionHelper()
- .convert( e, "row count verification failed for statement: ", sql );
+ for ( int i = 0; i < numberOfRowCounts; i++ ) {
+ getKey().getExpectation().verifyOutcome( rowCounts[i], ps, i );
}
}
- public void release() {
- expectationsBySql.clear();
- maxBatchPosition = 0;
- }
}
\ No newline at end of file
diff --git a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/batch/internal/NonBatchingBatch.java b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/batch/internal/NonBatchingBatch.java
index 64eb6b116a..9b2e280096 100644
--- a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/batch/internal/NonBatchingBatch.java
+++ b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/batch/internal/NonBatchingBatch.java
@@ -23,48 +23,52 @@
*/
package org.hibernate.engine.jdbc.batch.internal;
-import java.sql.PreparedStatement;
-import java.sql.SQLException;
-
+import org.hibernate.engine.jdbc.batch.spi.BatchKey;
+import org.hibernate.engine.jdbc.spi.JdbcCoordinator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.hibernate.engine.jdbc.spi.SQLExceptionHelper;
-import org.hibernate.engine.jdbc.spi.SQLStatementLogger;
-import org.hibernate.jdbc.Expectation;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.util.Map;
/**
- * An implementation of {@link org.hibernate.engine.jdbc.batch.spi.Batch} which does not perform batching. It simply executes each statement as it is
- * encountered.
+ * An implementation of {@link org.hibernate.engine.jdbc.batch.spi.Batch} which does not perform batching. It simply
+ * executes each statement as it is encountered.
*
* @author Steve Ebersole
*/
public class NonBatchingBatch extends AbstractBatchImpl {
private static final Logger log = LoggerFactory.getLogger( NonBatchingBatch.class );
- protected NonBatchingBatch(Object key,
- SQLStatementLogger statementLogger,
- SQLExceptionHelper exceptionHelper) {
- super( key, statementLogger, exceptionHelper );
+ protected NonBatchingBatch(BatchKey key, JdbcCoordinator jdbcCoordinator) {
+ super( key, jdbcCoordinator );
}
- public void addToBatch(Object key, String sql, Expectation expectation) {
- checkConsistentBatchKey( key );
- if ( sql == null ) {
- throw new IllegalArgumentException( "sql must be non-null." );
- }
+ @Override
+ public void addToBatch() {
notifyObserversImplicitExecution();
- try {
- final PreparedStatement statement = getStatements().get( sql );
- final int rowCount = statement.executeUpdate();
- expectation.verifyOutcome( rowCount, statement, 0 );
- }
- catch ( SQLException e ) {
- log.error( "sqlexception escaped proxy", e );
- throw getSqlExceptionHelper().convert( e, "could not execute batch statement", sql );
+ for ( Map.Entry entry : getStatements().entrySet() ) {
+ try {
+ final PreparedStatement statement = entry.getValue();
+ final int rowCount = statement.executeUpdate();
+ getKey().getExpectation().verifyOutcome( rowCount, statement, 0 );
+ try {
+ statement.close();
+ }
+ catch (SQLException e) {
+ log.debug( "Unable to close non-batched batch statement", e );
+ }
+ }
+ catch ( SQLException e ) {
+ log.debug( "sqlexception escaped proxy", e );
+ throw sqlExceptionHelper().convert( e, "could not execute batch statement", entry.getKey() );
+ }
}
+ getStatements().clear();
}
+ @Override
protected void doExecuteBatch() {
// nothing to do
}
diff --git a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/batch/spi/Batch.java b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/batch/spi/Batch.java
index 7c99332100..3a3ee658bb 100644
--- a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/batch/spi/Batch.java
+++ b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/batch/spi/Batch.java
@@ -42,7 +42,7 @@ public interface Batch {
*
* @return The batch key.
*/
- public Object getKey();
+ public BatchKey getKey();
/**
* Adds an observer to this batch.
@@ -52,30 +52,19 @@ public interface Batch {
public void addObserver(BatchObserver observer);
/**
- * Get a statement which is part of the batch.
+ * Get a statement which is part of the batch, creating if necessary (and storing for next time).
*
* @param sql The SQL statement.
- * @return the prepared statement representing the SQL statement, if the batch contained it;
- * null, otherwise.
- */
- public PreparedStatement getBatchStatement(Object key, String sql);
-
- /**
- * Add a prepared statement to the batch.
+ * @param callable Is the SQL statement callable?
*
- * @param sql The SQL statement.
+ * @return The prepared statement instance, representing the SQL statement.
*/
- public void addBatchStatement(Object key, String sql, PreparedStatement preparedStatement);
-
+ public PreparedStatement getBatchStatement(String sql, boolean callable);
/**
* Indicates completion of the current part of the batch.
- *
- * @param key
- * @param sql
- * @param expectation The expectation for the part's result.
*/
- public void addToBatch(Object key, String sql, Expectation expectation);
+ public void addToBatch();
/**
* Execute this batch.
diff --git a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/batch/spi/BatchBuilder.java b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/batch/spi/BatchBuilder.java
new file mode 100644
index 0000000000..4715c13faa
--- /dev/null
+++ b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/batch/spi/BatchBuilder.java
@@ -0,0 +1,45 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2011, 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
+ */
+package org.hibernate.engine.jdbc.batch.spi;
+
+import org.hibernate.engine.jdbc.spi.JdbcCoordinator;
+import org.hibernate.service.spi.Manageable;
+import org.hibernate.service.spi.Service;
+
+/**
+ * A builder for {@link Batch} instances
+ *
+ * @author Steve Ebersole
+ */
+public interface BatchBuilder extends Service, Manageable {
+ /**
+ * Build a batch.
+ *
+ * @param key Value to uniquely identify a batch
+ * @param jdbcCoordinator The JDBC coordinator with which to coordinate efforts
+ *
+ * @return The built batch
+ */
+ public Batch buildBatch(BatchKey key, JdbcCoordinator jdbcCoordinator);
+}
diff --git a/hibernate-core/src/main/java/org/hibernate/transaction/ResinTransactionManagerLookup.java b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/batch/spi/BatchKey.java
similarity index 59%
rename from hibernate-core/src/main/java/org/hibernate/transaction/ResinTransactionManagerLookup.java
rename to hibernate-core/src/main/java/org/hibernate/engine/jdbc/batch/spi/BatchKey.java
index c1c157c761..86e8338cc0 100644
--- a/hibernate-core/src/main/java/org/hibernate/transaction/ResinTransactionManagerLookup.java
+++ b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/batch/spi/BatchKey.java
@@ -1,10 +1,10 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
- * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * Copyright (c) 2011, 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 Middleware LLC.
+ * 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
@@ -20,29 +20,30 @@
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
- *
*/
-package org.hibernate.transaction;
+package org.hibernate.engine.jdbc.batch.spi;
+
+import org.hibernate.jdbc.Expectation;
/**
- * {@link TransactionManagerLookup} strategy for Resin
+ * Unique key for batch identification.
*
- * @author Aapo Laakkonen
+ * @author Steve Ebersole
*/
-public class ResinTransactionManagerLookup extends JNDITransactionManagerLookup {
+public interface BatchKey {
+ /**
+ * How many statements will be in this batch?
+ *
+ * Note that this is distinctly different than the size of the batch.
+ *
+ * @return The number of statements.
+ */
+ public int getBatchedStatementCount();
/**
- * {@inheritDoc}
+ * Get the expectation pertaining to the outcome of the {@link Batch} associated with this key.
+ *
+ * @return The expectations
*/
- protected String getName() {
- return "java:comp/TransactionManager";
- }
-
- /**
- * {@inheritDoc}
- */
- public String getUserTransactionName() {
- return "java:comp/UserTransaction";
- }
-
+ public Expectation getExpectation();
}
diff --git a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/internal/ConnectionManagerImpl.java b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/internal/ConnectionManagerImpl.java
deleted file mode 100644
index dddaa20eca..0000000000
--- a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/internal/ConnectionManagerImpl.java
+++ /dev/null
@@ -1,611 +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.engine.jdbc.internal;
-
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.sql.CallableStatement;
-import java.sql.Connection;
-import java.sql.PreparedStatement;
-import java.sql.SQLException;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.hibernate.AssertionFailure;
-import org.hibernate.ConnectionReleaseMode;
-import org.hibernate.HibernateException;
-import org.hibernate.Interceptor;
-import org.hibernate.ScrollMode;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.engine.jdbc.batch.internal.BatchBuilder;
-import org.hibernate.engine.jdbc.batch.spi.Batch;
-import org.hibernate.engine.jdbc.spi.ConnectionManager;
-import org.hibernate.engine.jdbc.spi.ConnectionObserver;
-import org.hibernate.jdbc.Expectation;
-
-/**
- * Encapsulates JDBC Connection management logic needed by Hibernate.
- *
- * The lifecycle is intended to span a logical series of interactions with the
- * database. Internally, this means the the lifecycle of the Session.
- *
- * @author Steve Ebersole
- */
-public class ConnectionManagerImpl implements ConnectionManager {
-
- private static final Logger log = LoggerFactory.getLogger( ConnectionManagerImpl.class );
-
- public static interface Callback extends ConnectionObserver {
- public boolean isTransactionInProgress();
- }
-
- // TODO: check if it's ok to change the method names in Callback
-
- private transient Interceptor interceptor;
-
- private final Callback callback;
- private transient LogicalConnectionImpl logicalConnection;
- private transient StatementPreparer statementPreparer;
- private final transient BatchBuilder batchBuilder;
- private Batch batch;
-
- /**
- * Constructs a ConnectionManager.
- *
- * This is the form used internally.
- *
- * @param callback An observer for internal state change.
- * @param releaseMode The mode by which to release JDBC connections.
- * @param suppliedConnection An externally supplied connection.
- */
- public ConnectionManagerImpl(
- SessionFactoryImplementor factory,
- Callback callback,
- ConnectionReleaseMode releaseMode,
- Connection suppliedConnection,
- Interceptor interceptor) {
- this( factory,
- callback,
- interceptor,
- new LogicalConnectionImpl(
- suppliedConnection,
- releaseMode,
- factory.getJdbcServices(),
- factory.getStatistics() != null ? factory.getStatisticsImplementor() : null
- )
- );
- }
-
- /**
- * Private constructor used exclusively from custom serialization
- */
- private ConnectionManagerImpl(
- SessionFactoryImplementor factory,
- Callback callback,
- Interceptor interceptor,
- LogicalConnectionImpl logicalConnection
- ) {
- this.callback = callback;
- this.interceptor = interceptor;
- this.logicalConnection = logicalConnection;
- this.logicalConnection.addObserver( callback );
- this.statementPreparer = new StatementPreparer( logicalConnection, factory.getSettings() );
- this.batchBuilder = factory.getSettings().getBatchBuilder();
- }
-
- /**
- * Retrieves the connection currently managed by this ConnectionManager.
- *
- * Note, that we may need to obtain a connection to return here if a
- * connection has either not yet been obtained (non-UserSuppliedConnectionProvider)
- * or has previously been aggressively released (if supported in this environment).
- *
- * @return The current Connection.
- *
- * @throws HibernateException Indicates a connection is currently not
- * available (we are currently manually disconnected).
- */
- @Override
- public Connection getConnection() throws HibernateException {
- return logicalConnection.getConnection();
- }
-
- @Override
- public boolean hasBorrowedConnection() {
- // used from testsuite
- return logicalConnection.hasBorrowedConnection();
- }
-
- public Connection borrowConnection() {
- return logicalConnection.borrowConnection();
- }
-
- @Override
- public void releaseBorrowedConnection() {
- logicalConnection.releaseBorrowedConnection();
- }
-
- /**
- * Is the connection considered "auto-commit"?
- *
- * @return True if we either do not have a connection, or the connection
- * really is in auto-commit mode.
- *
- * @throws SQLException Can be thrown by the Connection.isAutoCommit() check.
- */
- public boolean isAutoCommit() throws SQLException {
- return logicalConnection == null ||
- ! logicalConnection.isOpen() ||
- ! logicalConnection.isPhysicallyConnected() ||
- logicalConnection.getConnection().getAutoCommit();
- }
-
- /**
- * Will connections be released after each statement execution?
- *
- * Connections will be released after each statement if either:
- * - the defined release-mode is {@link ConnectionReleaseMode#AFTER_STATEMENT}; or
- *
- the defined release-mode is {@link ConnectionReleaseMode#AFTER_TRANSACTION} but
- * we are in auto-commit mode.
- *
- * release-mode = {@link ConnectionReleaseMode#ON_CLOSE} should [b]never[/b] release
- * a connection.
- *
- * @return True if the connections will be released after each statement; false otherwise.
- */
- public boolean isAggressiveRelease() {
- if ( logicalConnection.getConnectionReleaseMode() == ConnectionReleaseMode.AFTER_STATEMENT ) {
- return true;
- }
- else if ( logicalConnection.getConnectionReleaseMode() == ConnectionReleaseMode.AFTER_TRANSACTION ) {
- boolean inAutoCommitState;
- try {
- inAutoCommitState = isAutoCommit() && ! callback.isTransactionInProgress();
- }
- catch( SQLException e ) {
- // assume we are in an auto-commit state
- inAutoCommitState = true;
- }
- return inAutoCommitState;
- }
- return false;
- }
-
- /**
- * Modified version of {@link #isAggressiveRelease} which does not force a
- * transaction check. This is solely used from our {@link #afterTransaction}
- * callback, so no need to do the check; plus it seems to cause problems on
- * websphere (god i love websphere ;)
- *
- * It uses this information to decide if an aggressive release was skipped
- * do to open resources, and if so forces a release.
- *
- * @return True if the connections will be released after each statement; false otherwise.
- */
- private boolean isAggressiveReleaseNoTransactionCheck() {
- if ( logicalConnection.getConnectionReleaseMode() == ConnectionReleaseMode.AFTER_STATEMENT ) {
- return true;
- }
- else {
- boolean inAutoCommitState;
- try {
- inAutoCommitState = isAutoCommit();
- }
- catch( SQLException e ) {
- // assume we are in an auto-commit state
- inAutoCommitState = true;
- }
- return logicalConnection.getConnectionReleaseMode() == ConnectionReleaseMode.AFTER_TRANSACTION && inAutoCommitState;
- }
- }
-
- /**
- * Is this ConnectionManager instance "logically" connected. Meaning
- * do we either have a cached connection available or do we have the
- * ability to obtain a connection on demand.
- *
- * @return True if logically connected; false otherwise.
- */
- @Override
- public boolean isCurrentlyConnected() {
- return logicalConnection != null && logicalConnection.isLogicallyConnected();
- }
-
- /**
- * To be called after execution of each JDBC statement. Used to
- * conditionally release the JDBC connection aggressively if
- * the configured release mode indicates.
- */
- @Override
- public void afterStatement() {
- if ( isAggressiveRelease() ) {
- logicalConnection.afterStatementExecution();
- }
- }
-
- /**
- * To be called after local transaction completion. Used to conditionally
- * release the JDBC connection aggressively if the configured release mode
- * indicates.
- */
- public void afterTransaction() {
- if ( logicalConnection != null ) {
- if ( isAfterTransactionRelease() || isAggressiveReleaseNoTransactionCheck() ) {
- logicalConnection.afterTransaction();
- }
- else if ( isOnCloseRelease() ) {
- // log a message about potential connection leaks
- log.debug( "transaction completed on session with on_close connection release mode; be sure to close the session to release JDBC resources!" );
- }
- }
- if ( statementPreparer != null ) {
- statementPreparer.unsetTransactionTimeout();
- }
- }
-
- private boolean isAfterTransactionRelease() {
- return logicalConnection.getConnectionReleaseMode() == ConnectionReleaseMode.AFTER_TRANSACTION;
- }
-
- private boolean isOnCloseRelease() {
- return logicalConnection.getConnectionReleaseMode() == ConnectionReleaseMode.ON_CLOSE;
- }
-
- private boolean isLogicallyConnected() {
- return logicalConnection != null && logicalConnection.isOpen();
- }
-
- @Override
- public void setTransactionTimeout(int seconds) {
- statementPreparer.setTransactionTimeout( seconds );
- }
-
- /**
- * To be called after Session completion. Used to release the JDBC
- * connection.
- *
- * @return The connection mantained here at time of close. Null if
- * there was no connection cached internally.
- */
- @Override
- public Connection close() {
- return cleanup();
- }
-
- /**
- * Manually disconnect the underlying JDBC Connection. The assumption here
- * is that the manager will be reconnected at a later point in time.
- *
- * @return The connection mantained here at time of disconnect. Null if
- * there was no connection cached internally.
- */
- @Override
- public Connection manualDisconnect() {
- if ( ! isLogicallyConnected() ) {
- throw new IllegalStateException( "cannot manually disconnect because not logically connected." );
- }
- releaseBatch();
- return logicalConnection.manualDisconnect();
- }
-
- /**
- * Manually reconnect the underlying JDBC Connection. Should be called at
- * some point after manualDisconnect().
- *
- * This form is used for ConnectionProvider-supplied connections.
- */
- @Override
- public void manualReconnect() {
- manualReconnect( null );
- }
-
- /**
- * Manually reconnect the underlying JDBC Connection. Should be called at
- * some point after manualDisconnect().
- *
- * This form is used for user-supplied connections.
- */
- @Override
- public void manualReconnect(Connection suppliedConnection) {
- if ( ! isLogicallyConnected() ) {
- throw new IllegalStateException( "cannot manually disconnect because not logically connected." );
- }
- logicalConnection.reconnect( suppliedConnection );
- }
-
- /**
- * Releases the Connection and cleans up any resources associated with
- * that Connection. This is intended for use:
- * 1) at the end of the session
- * 2) on a manual disconnect of the session
- * 3) from afterTransaction(), in the case of skipped aggressive releasing
- *
- * @return The released connection.
- * @throws HibernateException
- */
- private Connection cleanup() throws HibernateException {
- if ( logicalConnection == null ) {
- log.trace( "connection already null in cleanup : no action");
- return null;
- }
- try {
- log.trace( "performing cleanup" );
- releaseBatch();
- statementPreparer.close();
- Connection c = logicalConnection.close();
- return c;
- }
- finally {
- batch = null;
- statementPreparer = null;
- logicalConnection = null;
- }
- }
-
- /**
- * Callback to let us know that a flush is beginning. We use this fact
- * to temporarily circumvent aggressive connection releasing until after
- * the flush cycle is complete {@link #flushEnding()}
- */
- @Override
- public void flushBeginning() {
- log.trace( "registering flush begin" );
- logicalConnection.disableReleases();
- }
-
- /**
- * Callback to let us know that a flush is ending. We use this fact to
- * stop circumventing aggressive releasing connections.
- */
- @Override
- public void flushEnding() {
- log.trace( "registering flush end" );
- logicalConnection.enableReleases();
- afterStatement();
- }
-
- /**
- * Get a non-batchable prepared statement to use for inserting / deleting / updating,
- * using JDBC3 getGeneratedKeys ({@link java.sql.Connection#prepareStatement(String, int)}).
- *
- * If not explicitly closed via {@link java.sql.PreparedStatement#close()}, it will be
- * released when the session is closed or disconnected.
- */
- @Override
- public PreparedStatement prepareStatement(String sql, final int autoGeneratedKeys)
- throws HibernateException {
- executeBatch();
- return statementPreparer.prepareStatement( getSQL( sql ), autoGeneratedKeys );
- }
-
- /**
- * Get a non-batchable prepared statement to use for inserting / deleting / updating.
- * using JDBC3 getGeneratedKeys ({@link java.sql.Connection#prepareStatement(String, String[])}).
- *
- * If not explicitly closed via {@link java.sql.PreparedStatement#close()}, it will be
- * released when the session is closed or disconnected.
- */
- @Override
- public PreparedStatement prepareStatement(String sql, final String[] columnNames) {
- executeBatch();
- return statementPreparer.prepareStatement( getSQL( sql ), columnNames );
- }
-
- /**
- * Get a non-batchable prepared statement to use for selecting. Does not
- * result in execution of the current batch.
- *
- * If not explicitly closed via {@link java.sql.PreparedStatement#close()},
- * it will be released when the session is closed or disconnected.
- */
- @Override
- public PreparedStatement prepareSelectStatement(String sql) {
- return statementPreparer.prepareStatement( getSQL( sql ), false );
- }
-
- /**
- * Get a non-batchable prepared statement to use for inserting / deleting / updating.
- *
- * If not explicitly closed via {@link java.sql.PreparedStatement#close()}, it will be
- * released when the session is closed or disconnected.
- */
- @Override
- public PreparedStatement prepareStatement(String sql, final boolean isCallable) {
- executeBatch();
- return statementPreparer.prepareStatement( getSQL( sql ), isCallable );
- }
-
- /**
- * Get a non-batchable callable statement to use for inserting / deleting / updating.
- *
- * If not explicitly closed via {@link java.sql.PreparedStatement#close()}, it will be
- * released when the session is closed or disconnected.
- */
- @Override
- public CallableStatement prepareCallableStatement(String sql) {
- executeBatch();
- log.trace("preparing callable statement");
- return CallableStatement.class.cast( statementPreparer.prepareStatement( getSQL( sql ), true ) );
- }
-
- /**
- * Get a batchable prepared statement to use for inserting / deleting / updating
- * (might be called many times before a single call to executeBatch()).
- * After setting parameters, call addToBatch - do not execute the
- * statement explicitly.
- * @see org.hibernate.engine.jdbc.batch.spi.Batch#addToBatch
- *
- * If not explicitly closed via {@link java.sql.PreparedStatement#close()}, it will be
- * released when the session is closed or disconnected.
- */
- @Override
- public PreparedStatement prepareBatchStatement(Object key, String sql, boolean isCallable) {
- if ( key == null ) {
- throw new IllegalArgumentException( "batch key must be non-null." );
- }
- String actualSQL = getSQL( sql );
- PreparedStatement batchUpdate = null;
- if ( batch != null ) {
- if ( key.equals( batch.getKey() ) ) {
- batchUpdate = batch.getBatchStatement( key, actualSQL );
- }
- else {
- batch.execute();
- batch = null;
- }
- }
- if ( batch == null ) {
- batch = batchBuilder.buildBatch(
- key,
- logicalConnection.getJdbcServices().getSqlStatementLogger(),
- logicalConnection.getJdbcServices().getSqlExceptionHelper()
- );
- }
- if ( batchUpdate == null ) {
- batchUpdate = statementPreparer.prepareStatement( actualSQL, isCallable );
- batch.addBatchStatement( key, actualSQL, batchUpdate );
- }
- return batchUpdate;
- }
-
- /**
- * Get a prepared statement for use in loading / querying. Does not
- * result in execution of the current batch.
- *
- * If not explicitly closed via {@link java.sql.PreparedStatement#close()},
- * it will be released when the session is closed or disconnected.
- */
- @Override
- public PreparedStatement prepareQueryStatement(
- String sql,
- final boolean isScrollable,
- final ScrollMode scrollMode,
- final boolean isCallable) {
- PreparedStatement ps = (
- isScrollable ?
- statementPreparer.prepareScrollableQueryStatement(
- getSQL( sql ), scrollMode, isCallable
- ) :
- statementPreparer.prepareQueryStatement(
- getSQL( sql ), isCallable
- )
- );
- logicalConnection.getResourceRegistry().registerLastQuery( ps );
- return ps;
- }
-
- /**
- * Cancel the current query statement
- */
- @Override
- public void cancelLastQuery() throws HibernateException {
- logicalConnection.getResourceRegistry().cancelLastQuery();
- }
-
- @Override
- public void addToBatch(Object batchKey, String sql, Expectation expectation) {
- batch.addToBatch( batchKey, sql, expectation );
- }
-
- @Override
- public void executeBatch() throws HibernateException {
- if ( batch != null ) {
- batch.execute();
- batch.release(); // needed?
- }
- }
-
- @Override
- public void abortBatch() {
- releaseBatch();
- }
-
- private void releaseBatch() {
- if ( batch != null ) {
- batch.release();
- }
- }
-
- private String getSQL(String sql) {
- sql = interceptor.onPrepareStatement( sql );
- if ( sql==null || sql.length() == 0 ) {
- throw new AssertionFailure( "Interceptor.onPrepareStatement() returned null or empty string." );
- }
- return sql;
- }
-
- public boolean isReadyForSerialization() {
- return logicalConnection == null ? true : logicalConnection.isReadyForSerialization();
- }
-
- /**
- * Used during serialization.
- *
- * @param oos The stream to which we are being written.
- * @throws IOException Indicates an I/O error writing to the stream
- */
- private void writeObject(ObjectOutputStream oos) throws IOException {
- if ( !isReadyForSerialization() ) {
- throw new IllegalStateException( "Cannot serialize a ConnectionManager while connected" );
- }
- oos.defaultWriteObject();
- }
-
- /**
- * Used during deserialization.
- *
- * @param ois The stream from which we are being read.
- * @throws IOException Indicates an I/O error reading the stream
- * @throws ClassNotFoundException Indicates resource class resolution.
- */
- private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
- ois.defaultReadObject();
- }
-
- public void serialize(ObjectOutputStream oos) throws IOException {
- logicalConnection.serialize( oos );
- }
-
- public static ConnectionManagerImpl deserialize(
- ObjectInputStream ois,
- SessionFactoryImplementor factory,
- Interceptor interceptor,
- ConnectionReleaseMode connectionReleaseMode,
- Callback callback) throws IOException {
- return new ConnectionManagerImpl(
- factory,
- callback,
- interceptor,
- LogicalConnectionImpl.deserialize(
- ois,
- factory.getJdbcServices(),
- factory.getStatistics() != null ? factory.getStatisticsImplementor() : null,
- connectionReleaseMode
- )
- );
- }
-}
diff --git a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/internal/JDBCContextImpl.java b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/internal/JDBCContextImpl.java
deleted file mode 100644
index bc3e7fb75a..0000000000
--- a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/internal/JDBCContextImpl.java
+++ /dev/null
@@ -1,369 +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.engine.jdbc.internal;
-
-import java.io.ObjectOutputStream;
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.sql.Connection;
-import java.sql.SQLException;
-
-import javax.transaction.TransactionManager;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.hibernate.ConnectionReleaseMode;
-import org.hibernate.HibernateException;
-import org.hibernate.Interceptor;
-import org.hibernate.SessionException;
-import org.hibernate.Transaction;
-import org.hibernate.TransactionException;
-import org.hibernate.engine.jdbc.spi.ConnectionManager;
-import org.hibernate.engine.jdbc.spi.JDBCContext;
-import org.hibernate.transaction.synchronization.CallbackCoordinator;
-import org.hibernate.transaction.synchronization.HibernateSynchronizationImpl;
-import org.hibernate.util.JTAHelper;
-import org.hibernate.engine.SessionFactoryImplementor;
-
-/**
- * Acts as the mediary between "entity-mode related" sessions in terms of
- * their interaction with the JDBC data store.
- *
- * @author Steve Ebersole
- */
-public class JDBCContextImpl implements ConnectionManagerImpl.Callback, JDBCContext {
-
- // TODO : make this the factory for "entity mode related" sessions;
- // also means making this the target of transaction-synch and the
- // thing that knows how to cascade things between related sessions
- //
- // At that point, perhaps this thing is a "SessionContext", and
- // ConnectionManager is a "JDBCContext"? A "SessionContext" should
- // live in the impl package...
-
- private static final Logger log = LoggerFactory.getLogger( JDBCContextImpl.class );
-
- private Context owner;
- private ConnectionManagerImpl connectionManager;
- private transient boolean isTransactionCallbackRegistered;
- private transient Transaction hibernateTransaction;
-
- private CallbackCoordinator jtaSynchronizationCallbackCoordinator;
-
- public JDBCContextImpl(Context owner, Connection connection, Interceptor interceptor) {
- this.owner = owner;
- this.connectionManager = new ConnectionManagerImpl(
- owner.getFactory(),
- this,
- owner.getConnectionReleaseMode(),
- connection,
- interceptor
- );
-
- final boolean registerSynchronization = owner.isAutoCloseSessionEnabled()
- || owner.isFlushBeforeCompletionEnabled()
- || owner.getConnectionReleaseMode() == ConnectionReleaseMode.AFTER_TRANSACTION;
- if ( registerSynchronization ) {
- registerSynchronizationIfPossible();
- }
- }
-
- /**
- * Private constructor used exclusively for custom serialization...
- *
- */
- private JDBCContextImpl() {
- }
-
- @Override
- public CallbackCoordinator getJtaSynchronizationCallbackCoordinator() {
- return jtaSynchronizationCallbackCoordinator;
- }
-
- private CallbackCoordinator getJtaSynchronizationCallbackCoordinator(javax.transaction.Transaction jtaTransaction) {
- jtaSynchronizationCallbackCoordinator = new CallbackCoordinator( owner, this, jtaTransaction, hibernateTransaction );
- return jtaSynchronizationCallbackCoordinator;
- }
-
- @Override
- public void cleanUpJtaSynchronizationCallbackCoordinator() {
- jtaSynchronizationCallbackCoordinator = null;
- }
-
-
- // ConnectionManager.Callback implementation ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- @Override
- public void physicalConnectionObtained(Connection connection) {
- if ( owner.getFactory().getStatistics().isStatisticsEnabled() ) {
- owner.getFactory().getStatisticsImplementor().connect();
- }
- }
-
- @Override
- public void physicalConnectionReleased() {
- if ( !isTransactionCallbackRegistered ) {
- afterTransactionCompletion( false, null );
- // Note : success = false, because we don't know the outcome of the transaction
- }
- }
-
- @Override
- public void logicalConnectionClosed() {
- // TODO: anything need to be done?
- }
-
- @Override
- public SessionFactoryImplementor getFactory() {
- return owner.getFactory();
- }
-
- @Override
- public ConnectionManager getConnectionManager() {
- return connectionManager;
- }
-
- public Connection borrowConnection() {
- return connectionManager.borrowConnection();
- }
-
- @Override
- public Connection connection() throws HibernateException {
- if ( owner.isClosed() ) {
- throw new SessionException( "Session is closed" );
- }
-
- return connectionManager.getConnection();
- }
-
- @Override
- public boolean registerCallbackIfNecessary() {
- if ( isTransactionCallbackRegistered ) {
- return false;
- }
- else {
- isTransactionCallbackRegistered = true;
- return true;
- }
-
- }
-
- @Override
- public boolean registerSynchronizationIfPossible() {
- if ( isTransactionCallbackRegistered ) {
- // we already have a callback registered; either a local
- // (org.hibernate.Transaction) transaction has accepted
- // callback responsibilities, or we have previously
- // registered a transaction synch.
- return true;
- }
- boolean localCallbacksOnly = owner.getFactory().getSettings()
- .getTransactionFactory()
- .areCallbacksLocalToHibernateTransactions();
- if ( localCallbacksOnly ) {
- // the configured transaction-factory says it only supports
- // local callback mode, so no sense attempting to register a
- // JTA Synchronization
- return false;
- }
- TransactionManager tm = owner.getFactory().getTransactionManager();
- if ( tm == null ) {
- // if there is no TM configured, we will not be able to access
- // the javax.transaction.Transaction object in order to
- // register a synch anyway.
- return false;
- }
- else {
- try {
- if ( !isTransactionInProgress() ) {
- log.trace( "TransactionFactory reported no active transaction; Synchronization not registered" );
- return false;
- }
- else {
- javax.transaction.Transaction tx = tm.getTransaction();
- if ( JTAHelper.isMarkedForRollback( tx ) ) {
- // transactions marked for rollback-only cause some TM impls to throw exceptions
- log.debug( "Transaction is marked for rollback; skipping Synchronization registration" );
- return false;
- }
- else {
- if ( hibernateTransaction == null ) {
- hibernateTransaction = owner.getFactory().getSettings().getTransactionFactory().createTransaction( this, owner );
- }
- tx.registerSynchronization(
- new HibernateSynchronizationImpl( getJtaSynchronizationCallbackCoordinator( tx ) )
- );
-// tx.registerSynchronization( new CacheSynchronization(owner, this, tx, hibernateTransaction) );
- isTransactionCallbackRegistered = true;
- log.debug("successfully registered Synchronization");
- return true;
- }
- }
- }
- catch( HibernateException e ) {
- throw e;
- }
- catch (Exception e) {
- throw new TransactionException( "could not register synchronization with JTA TransactionManager", e );
- }
- }
- }
-
- @Override
- public boolean isTransactionInProgress() {
- return owner.getFactory().getSettings().getTransactionFactory()
- .isTransactionInProgress( this, owner, hibernateTransaction );
- }
-
- @Override
- public Transaction getTransaction() throws HibernateException {
- if (hibernateTransaction==null) {
- hibernateTransaction = owner.getFactory().getSettings()
- .getTransactionFactory()
- .createTransaction( this, owner );
- }
- return hibernateTransaction;
- }
-
- @Override
- public void beforeTransactionCompletion(Transaction tx) {
- log.trace( "before transaction completion" );
- owner.beforeTransactionCompletion(tx);
- }
-
- /**
- * We cannot rely upon this method being called! It is only
- * called if we are using Hibernate Transaction API.
- */
- @Override
- public void afterTransactionBegin(Transaction tx) {
- log.trace( "after transaction begin" );
- owner.afterTransactionBegin(tx);
- }
-
- @Override
- public void afterTransactionCompletion(boolean success, Transaction tx) {
- log.trace( "after transaction completion" );
-
- if ( getFactory().getStatistics().isStatisticsEnabled() ) {
- getFactory().getStatisticsImplementor().endTransaction(success);
- }
-
- connectionManager.afterTransaction();
-
- isTransactionCallbackRegistered = false;
- hibernateTransaction = null;
- owner.afterTransactionCompletion(success, tx);
- }
-
- /**
- * Called after executing a query outside the scope of
- * a Hibernate or JTA transaction
- */
- @Override
- public void afterNontransactionalQuery(boolean success) {
- log.trace( "after autocommit" );
- try {
- // check to see if the connection is in auto-commit
- // mode (no connection means aggressive connection
- // release outside a JTA transaction context, so MUST
- // be autocommit mode)
- boolean isAutocommit = connectionManager.isAutoCommit();
-
- connectionManager.afterTransaction();
-
- if ( isAutocommit ) {
- owner.afterTransactionCompletion(success, null);
- }
- }
- catch (SQLException sqle) {
- throw owner.getFactory().getSQLExceptionHelper().convert(
- sqle,
- "could not inspect JDBC autocommit mode"
- );
- }
- }
-
-
- // serialization ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
- public boolean isReadyForSerialization() {
- return connectionManager.isReadyForSerialization();
- }
-
- private void writeObject(ObjectOutputStream oos) throws IOException {
- // isTransactionCallbackRegistered denotes whether any Hibernate
- // Transaction has registered as a callback against this
- // JDBCContext; only one such callback is allowed. Directly
- // serializing this value causes problems with JDBCTransaction,
- // or really any Transaction impl where the callback is local
- // to the Transaction instance itself, since that Transaction
- // is not serialized along with the JDBCContext. Thus we
- // handle that fact here explicitly...
- oos.defaultWriteObject();
- boolean deserHasCallbackRegistered = isTransactionCallbackRegistered
- && ! owner.getFactory().getSettings().getTransactionFactory()
- .areCallbacksLocalToHibernateTransactions();
- oos.writeBoolean( deserHasCallbackRegistered );
- }
-
- private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
- ois.defaultReadObject();
- isTransactionCallbackRegistered = ois.readBoolean();
- }
-
- /**
- * Custom serialization routine used during serialization of a
- * Session/PersistenceContext for increased performance.
- *
- * @param oos The stream to which we should write the serial data.
- * @throws IOException
- */
- public void serialize(ObjectOutputStream oos) throws IOException {
- connectionManager.serialize( oos );
- }
-
- /**
- * Custom deserialization routine used during deserialization of a
- * Session/PersistenceContext for increased performance.
- *
- * @param ois The stream from which to read the entry.
- * @throws IOException
- */
- public static JDBCContextImpl deserialize(
- ObjectInputStream ois,
- Context context,
- Interceptor interceptor) throws IOException, ClassNotFoundException {
- JDBCContextImpl jdbcContext = new JDBCContextImpl();
- jdbcContext.owner = context;
- jdbcContext.connectionManager = ConnectionManagerImpl.deserialize(
- ois,
- context.getFactory(),
- interceptor,
- context.getConnectionReleaseMode(),
- jdbcContext
- );
- return jdbcContext;
- }
-}
diff --git a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/internal/JdbcCoordinatorImpl.java b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/internal/JdbcCoordinatorImpl.java
new file mode 100644
index 0000000000..241530c1a6
--- /dev/null
+++ b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/internal/JdbcCoordinatorImpl.java
@@ -0,0 +1,236 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2011, 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
+ */
+package org.hibernate.engine.jdbc.internal;
+
+import org.hibernate.HibernateException;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.engine.jdbc.batch.spi.Batch;
+import org.hibernate.engine.jdbc.batch.spi.BatchBuilder;
+import org.hibernate.engine.jdbc.batch.spi.BatchKey;
+import org.hibernate.engine.jdbc.spi.JdbcCoordinator;
+import org.hibernate.engine.jdbc.spi.LogicalConnectionImplementor;
+import org.hibernate.engine.jdbc.spi.SQLExceptionHelper;
+import org.hibernate.engine.jdbc.spi.StatementPreparer;
+import org.hibernate.engine.transaction.internal.TransactionCoordinatorImpl;
+import org.hibernate.engine.transaction.spi.TransactionContext;
+import org.hibernate.engine.transaction.spi.TransactionCoordinator;
+import org.hibernate.engine.transaction.spi.TransactionEnvironment;
+import org.hibernate.jdbc.Work;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.sql.Connection;
+import java.sql.SQLException;
+
+/**
+ * Standard Hibernate implementation of {@link JdbcCoordinator}
+ *
+ * IMPL NOTE : Custom serialization handling!
+ *
+ * @author Steve Ebersole
+ */
+public class JdbcCoordinatorImpl implements JdbcCoordinator {
+ private static final Logger log = LoggerFactory.getLogger( JdbcCoordinatorImpl.class );
+
+ private transient TransactionCoordinatorImpl transactionCoordinator;
+
+ private final transient LogicalConnectionImpl logicalConnection;
+
+ private transient Batch currentBatch;
+
+ public JdbcCoordinatorImpl(
+ Connection userSuppliedConnection,
+ TransactionCoordinatorImpl transactionCoordinator) {
+ this.transactionCoordinator = transactionCoordinator;
+ this.logicalConnection = new LogicalConnectionImpl(
+ userSuppliedConnection,
+ transactionCoordinator.getTransactionContext().getConnectionReleaseMode(),
+ transactionCoordinator.getTransactionContext().getTransactionEnvironment().getJdbcServices()
+ );
+ }
+
+ private JdbcCoordinatorImpl(LogicalConnectionImpl logicalConnection) {
+ this.logicalConnection = logicalConnection;
+ }
+
+ @Override
+ public TransactionCoordinator getTransactionCoordinator() {
+ return transactionCoordinator;
+ }
+
+ @Override
+ public LogicalConnectionImplementor getLogicalConnection() {
+ return logicalConnection;
+ }
+
+ protected TransactionEnvironment transactionEnvironment() {
+ return getTransactionCoordinator().getTransactionContext().getTransactionEnvironment();
+ }
+
+ protected SessionFactoryImplementor sessionFactory() {
+ return transactionEnvironment().getSessionFactory();
+ }
+
+ protected BatchBuilder batchBuilder() {
+ return sessionFactory().getServiceRegistry().getService( BatchBuilder.class );
+ }
+
+ private SQLExceptionHelper sqlExceptionHelper() {
+ return transactionEnvironment().getJdbcServices().getSqlExceptionHelper();
+ }
+
+
+ private int flushDepth = 0;
+
+ @Override
+ public void flushBeginning() {
+ if ( flushDepth == 0 ) {
+ logicalConnection.disableReleases();
+ }
+ flushDepth++;
+ }
+
+ @Override
+ public void flushEnding() {
+ flushDepth--;
+ if ( flushDepth < 0 ) {
+ throw new HibernateException( "Mismatched flush handling" );
+ }
+ if ( flushDepth == 0 ) {
+ logicalConnection.enableReleases();
+ }
+ }
+
+ @Override
+ public Connection close() {
+ if ( currentBatch != null ) {
+ log.warn( "Closing un-released batch" );
+ currentBatch.release();
+ }
+ return logicalConnection.close();
+ }
+
+ @Override
+ public Batch getBatch(BatchKey key) {
+ if ( currentBatch != null ) {
+ if ( currentBatch.getKey().equals( key ) ) {
+ return currentBatch;
+ }
+ else {
+ currentBatch.execute();
+ currentBatch.release();
+ }
+ }
+ currentBatch = batchBuilder().buildBatch( key, this );
+ return currentBatch;
+ }
+
+ @Override
+ public void abortBatch() {
+ if ( currentBatch != null ) {
+ currentBatch.release();
+ }
+ }
+
+ private transient StatementPreparer statementPreparer;
+
+ @Override
+ public StatementPreparer getStatementPreparer() {
+ if ( statementPreparer == null ) {
+ statementPreparer = new StatementPreparerImpl( this );
+ }
+ return statementPreparer;
+ }
+
+ @Override
+ public void setTransactionTimeOut(int timeOut) {
+ getStatementPreparer().setTransactionTimeOut( timeOut );
+ }
+
+ /**
+ * To be called after local transaction completion. Used to conditionally
+ * release the JDBC connection aggressively if the configured release mode
+ * indicates.
+ */
+ public void afterTransaction() {
+ logicalConnection.afterTransaction();
+ if ( statementPreparer != null ) {
+ statementPreparer.unsetTransactionTimeOut();
+ }
+ }
+
+ public void coordinateWork(Work work) {
+ Connection connection = getLogicalConnection().getDistinctConnectionProxy();
+ try {
+ work.execute( connection );
+ getLogicalConnection().afterStatementExecution();
+ }
+ catch ( SQLException e ) {
+ throw sqlExceptionHelper().convert( e, "error executing work" );
+ }
+ finally {
+ try {
+ if ( ! connection.isClosed() ) {
+ connection.close();
+ }
+ }
+ catch (SQLException e) {
+ log.debug( "Error closing connection proxy", e );
+ }
+ }
+ }
+
+ public void executeBatch() {
+ if ( currentBatch != null ) {
+ currentBatch.execute();
+ currentBatch.release(); // needed?
+ }
+ }
+
+ @Override
+ public void cancelLastQuery() {
+ logicalConnection.getResourceRegistry().cancelLastQuery();
+ }
+
+
+ public void serialize(ObjectOutputStream oos) throws IOException {
+ if ( ! logicalConnection.isReadyForSerialization() ) {
+ throw new HibernateException( "Cannot serialize Session while connected" );
+ }
+ logicalConnection.serialize( oos );
+ }
+
+ public static JdbcCoordinatorImpl deserialize(
+ ObjectInputStream ois,
+ TransactionContext transactionContext) throws IOException, ClassNotFoundException {
+ return new JdbcCoordinatorImpl( LogicalConnectionImpl.deserialize( ois, transactionContext ) );
+ }
+
+ public void afterDeserialize(TransactionCoordinatorImpl transactionCoordinator) {
+ this.transactionCoordinator = transactionCoordinator;
+ }
+}
diff --git a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/internal/LogicalConnectionImpl.java b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/internal/LogicalConnectionImpl.java
index 8191d94162..25a5c208f2 100644
--- a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/internal/LogicalConnectionImpl.java
+++ b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/internal/LogicalConnectionImpl.java
@@ -23,43 +23,46 @@
*/
package org.hibernate.engine.jdbc.internal;
+import org.hibernate.ConnectionReleaseMode;
+import org.hibernate.HibernateException;
+import org.hibernate.JDBCException;
+import org.hibernate.engine.jdbc.internal.proxy.ProxyBuilder;
+import org.hibernate.engine.jdbc.spi.ConnectionObserver;
+import org.hibernate.engine.jdbc.spi.JdbcResourceRegistry;
+import org.hibernate.engine.jdbc.spi.JdbcServices;
+import org.hibernate.engine.jdbc.spi.LogicalConnectionImplementor;
+import org.hibernate.engine.jdbc.spi.NonDurableConnectionObserver;
+import org.hibernate.engine.transaction.spi.TransactionContext;
+import org.hibernate.util.CollectionHelper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.ArrayList;
+import java.util.Iterator;
import java.util.List;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.hibernate.ConnectionReleaseMode;
-import org.hibernate.HibernateException;
-import org.hibernate.JDBCException;
-import org.hibernate.engine.jdbc.spi.JdbcResourceRegistry;
-import org.hibernate.engine.jdbc.spi.JdbcServices;
-import org.hibernate.engine.jdbc.spi.ConnectionObserver;
-import org.hibernate.engine.jdbc.spi.LogicalConnectionImplementor;
-import org.hibernate.jdbc.BorrowedConnectionProxy;
-import org.hibernate.stat.StatisticsImplementor;
-
/**
- * LogicalConnectionImpl implementation
+ * Standard Hibernate {@link org.hibernate.engine.jdbc.spi.LogicalConnection} implementation
+ *
+ * IMPL NOTE : Custom serialization handling!
*
* @author Steve Ebersole
*/
public class LogicalConnectionImpl implements LogicalConnectionImplementor {
private static final Logger log = LoggerFactory.getLogger( LogicalConnectionImpl.class );
- private Connection physicalConnection;
- private Connection borrowedConnection;
+ private transient Connection physicalConnection;
+ private transient Connection shareableConnectionProxy;
- private final ConnectionReleaseMode connectionReleaseMode;
- private final JdbcServices jdbcServices;
- private final StatisticsImplementor statisticsImplementor;
- private final JdbcResourceRegistry jdbcResourceRegistry;
- private final List observers = new ArrayList();
+ private final transient ConnectionReleaseMode connectionReleaseMode;
+ private final transient JdbcServices jdbcServices;
+ private final transient JdbcResourceRegistry jdbcResourceRegistry;
+ private final transient List observers;
private boolean releasesEnabled = true;
@@ -67,40 +70,41 @@ public class LogicalConnectionImpl implements LogicalConnectionImplementor {
private boolean isClosed;
- public LogicalConnectionImpl(Connection userSuppliedConnection,
- ConnectionReleaseMode connectionReleaseMode,
- JdbcServices jdbcServices,
- StatisticsImplementor statisticsImplementor
- ) {
- this( connectionReleaseMode,
+ public LogicalConnectionImpl(
+ Connection userSuppliedConnection,
+ ConnectionReleaseMode connectionReleaseMode,
+ JdbcServices jdbcServices) {
+ this(
+ connectionReleaseMode,
jdbcServices,
- statisticsImplementor,
- userSuppliedConnection != null,
- false
+ (userSuppliedConnection != null),
+ false,
+ new ArrayList()
);
this.physicalConnection = userSuppliedConnection;
}
- private LogicalConnectionImpl(ConnectionReleaseMode connectionReleaseMode,
- JdbcServices jdbcServices,
- StatisticsImplementor statisticsImplementor,
- boolean isUserSuppliedConnection,
- boolean isClosed) {
+ private LogicalConnectionImpl(
+ ConnectionReleaseMode connectionReleaseMode,
+ JdbcServices jdbcServices,
+ boolean isUserSuppliedConnection,
+ boolean isClosed,
+ List observers) {
this.connectionReleaseMode = determineConnectionReleaseMode(
jdbcServices, isUserSuppliedConnection, connectionReleaseMode
);
this.jdbcServices = jdbcServices;
- this.statisticsImplementor = statisticsImplementor;
- this.jdbcResourceRegistry =
- new JdbcResourceRegistryImpl( getJdbcServices().getSqlExceptionHelper() );
+ this.jdbcResourceRegistry = new JdbcResourceRegistryImpl( getJdbcServices().getSqlExceptionHelper() );
+ this.observers = observers;
this.isUserSuppliedConnection = isUserSuppliedConnection;
this.isClosed = isClosed;
}
- private static ConnectionReleaseMode determineConnectionReleaseMode(JdbcServices jdbcServices,
- boolean isUserSuppliedConnection,
- ConnectionReleaseMode connectionReleaseMode) {
+ private static ConnectionReleaseMode determineConnectionReleaseMode(
+ JdbcServices jdbcServices,
+ boolean isUserSuppliedConnection,
+ ConnectionReleaseMode connectionReleaseMode) {
if ( isUserSuppliedConnection ) {
return ConnectionReleaseMode.ON_CLOSE;
}
@@ -114,60 +118,37 @@ public class LogicalConnectionImpl implements LogicalConnectionImplementor {
}
}
- /**
- * {@inheritDoc}
- */
+ @Override
public JdbcServices getJdbcServices() {
return jdbcServices;
}
- /**
- * {@inheritDoc}
- */
- public StatisticsImplementor getStatisticsImplementor() {
- return statisticsImplementor;
- }
-
- /**
- * {@inheritDoc}
- */
+ @Override
public JdbcResourceRegistry getResourceRegistry() {
return jdbcResourceRegistry;
}
- /**
- * {@inheritDoc}
- */
+ @Override
public void addObserver(ConnectionObserver observer) {
observers.add( observer );
}
- /**
- * {@inheritDoc}
- */
+ @Override
+ public void removeObserver(ConnectionObserver connectionObserver) {
+ observers.remove( connectionObserver );
+ }
+
+ @Override
public boolean isOpen() {
return !isClosed;
}
- /**
- * {@inheritDoc}
- */
- public boolean isLogicallyConnected() {
- return isUserSuppliedConnection ?
- isPhysicallyConnected() :
- isOpen();
- }
-
- /**
- * {@inheritDoc}
- */
+ @Override
public boolean isPhysicallyConnected() {
return physicalConnection != null;
}
- /**
- * {@inheritDoc}
- */
+ @Override
public Connection getConnection() throws HibernateException {
if ( isClosed ) {
throw new HibernateException( "Logical connection is closed" );
@@ -182,16 +163,33 @@ public class LogicalConnectionImpl implements LogicalConnectionImplementor {
return physicalConnection;
}
+ @Override
+ public Connection getShareableConnectionProxy() {
+ if ( shareableConnectionProxy == null ) {
+ shareableConnectionProxy = buildConnectionProxy();
+ }
+ return shareableConnectionProxy;
+ }
+
+ private Connection buildConnectionProxy() {
+ return ProxyBuilder.buildConnection( this );
+ }
+
+ @Override
+ public Connection getDistinctConnectionProxy() {
+ return buildConnectionProxy();
+ }
+
/**
* {@inheritDoc}
*/
public Connection close() {
- Connection c = physicalConnection;
+ log.trace( "closing logical connection" );
+ Connection c = isUserSuppliedConnection ? physicalConnection : null;
try {
- releaseBorrowedConnection();
- log.trace( "closing logical connection" );
+ releaseProxies();
+ jdbcResourceRegistry.close();
if ( !isUserSuppliedConnection && physicalConnection != null ) {
- jdbcResourceRegistry.close();
releaseConnection();
}
return c;
@@ -204,46 +202,28 @@ public class LogicalConnectionImpl implements LogicalConnectionImplementor {
for ( ConnectionObserver observer : observers ) {
observer.logicalConnectionClosed();
}
+ observers.clear();
}
}
- /**
- * {@inheritDoc}
- */
+ private void releaseProxies() {
+ if ( shareableConnectionProxy != null ) {
+ try {
+ shareableConnectionProxy.close();
+ }
+ catch (SQLException e) {
+ log.debug( "Error releasing shared connection proxy", e );
+ }
+ }
+ shareableConnectionProxy = null;
+ }
+
+ @Override
public ConnectionReleaseMode getConnectionReleaseMode() {
return connectionReleaseMode;
}
- public boolean hasBorrowedConnection() {
- return borrowedConnection != null;
- }
-
- public Connection borrowConnection() {
- if ( isClosed ) {
- throw new HibernateException( "connection has been closed" );
- }
- if ( isUserSuppliedConnection ) {
- return physicalConnection;
- }
- else {
- if ( borrowedConnection == null ) {
- borrowedConnection = BorrowedConnectionProxy.generateProxy( this );
- }
- return borrowedConnection;
- }
- }
-
- public void releaseBorrowedConnection() {
- if ( borrowedConnection != null ) {
- try {
- BorrowedConnectionProxy.renderUnuseable( borrowedConnection );
- }
- finally {
- borrowedConnection = null;
- }
- }
- }
-
+ @Override
public void afterStatementExecution() {
log.trace( "starting after statement execution processing [{}]", connectionReleaseMode );
if ( connectionReleaseMode == ConnectionReleaseMode.AFTER_STATEMENT ) {
@@ -255,13 +235,11 @@ public class LogicalConnectionImpl implements LogicalConnectionImplementor {
log.debug( "skipping aggressive release due to registered resources" );
return;
}
- else if ( borrowedConnection != null ) {
- log.debug( "skipping aggresive-release due to borrowed connection" );
- }
releaseConnection();
}
}
+ @Override
public void afterTransaction() {
if ( connectionReleaseMode == ConnectionReleaseMode.AFTER_STATEMENT ||
connectionReleaseMode == ConnectionReleaseMode.AFTER_TRANSACTION ) {
@@ -273,20 +251,21 @@ public class LogicalConnectionImpl implements LogicalConnectionImplementor {
}
}
+ @Override
public void disableReleases() {
log.trace( "disabling releases" );
releasesEnabled = false;
}
+ @Override
public void enableReleases() {
log.trace( "(re)enabling releases" );
releasesEnabled = true;
- //FIXME: uncomment after new batch stuff is integrated!!!
- //afterStatementExecution();
+ afterStatementExecution();
}
/**
- * Force aggresive release of the underlying connection.
+ * Force aggressive release of the underlying connection.
*/
public void aggressiveRelease() {
if ( isUserSuppliedConnection ) {
@@ -302,7 +281,7 @@ public class LogicalConnectionImpl implements LogicalConnectionImplementor {
/**
- * Pysically opens a JDBC Connection.
+ * Physically opens a JDBC Connection.
*
* @throws org.hibernate.JDBCException Indicates problem opening a connection
*/
@@ -349,32 +328,32 @@ public class LogicalConnectionImpl implements LogicalConnectionImplementor {
for ( ConnectionObserver observer : observers ) {
observer.physicalConnectionReleased();
}
+ releaseNonDurableObservers();
}
- /**
- * Manually disconnect the underlying JDBC Connection. The assumption here
- * is that the manager will be reconnected at a later point in time.
- *
- * @return The connection mantained here at time of disconnect. Null if
- * there was no connection cached internally.
- */
+ @Override
public Connection manualDisconnect() {
if ( isClosed ) {
throw new IllegalStateException( "cannot manually disconnect because logical connection is already closed" );
}
+ releaseProxies();
Connection c = physicalConnection;
jdbcResourceRegistry.releaseResources();
releaseConnection();
return c;
}
- /**
- * Manually reconnect the underlying JDBC Connection. Should be called at
- * some point after manualDisconnect().
- *
- * This form is used for user-supplied connections.
- */
- public void reconnect(Connection suppliedConnection) {
+ private void releaseNonDurableObservers() {
+ Iterator observers = this.observers.iterator();
+ while ( observers.hasNext() ) {
+ if ( NonDurableConnectionObserver.class.isInstance( observers.next() ) ) {
+ observers.remove();
+ }
+ }
+ }
+
+ @Override
+ public void manualReconnect(Connection suppliedConnection) {
if ( isClosed ) {
throw new IllegalStateException( "cannot manually reconnect because logical connection is already closed" );
}
@@ -401,29 +380,65 @@ public class LogicalConnectionImpl implements LogicalConnectionImplementor {
}
}
+ @Override
+ public boolean isAutoCommit() {
+ if ( !isOpen() || ! isPhysicallyConnected() ) {
+ return true;
+ }
+
+ try {
+ return getConnection().getAutoCommit();
+ }
+ catch (SQLException e) {
+ throw jdbcServices.getSqlExceptionHelper().convert( e, "could not inspect JDBC autocommit mode" );
+ }
+ }
+
+ @Override
+ public void notifyObserversStatementPrepared() {
+ for ( ConnectionObserver observer : observers ) {
+ observer.statementPrepared();
+ }
+ }
+
+ @Override
public boolean isReadyForSerialization() {
- return isUserSuppliedConnection ?
- ! isPhysicallyConnected() :
- ! getResourceRegistry().hasRegisteredResources()
- ;
+ return isUserSuppliedConnection
+ ? ! isPhysicallyConnected()
+ : ! getResourceRegistry().hasRegisteredResources();
}
public void serialize(ObjectOutputStream oos) throws IOException {
oos.writeBoolean( isUserSuppliedConnection );
oos.writeBoolean( isClosed );
+ List durableConnectionObservers = new ArrayList();
+ for ( ConnectionObserver observer : observers ) {
+ if ( ! NonDurableConnectionObserver.class.isInstance( observer ) ) {
+ durableConnectionObservers.add( observer );
+ }
+ }
+ oos.writeInt( durableConnectionObservers.size() );
+ for ( ConnectionObserver observer : durableConnectionObservers ) {
+ oos.writeObject( observer );
+ }
}
- public static LogicalConnectionImpl deserialize(ObjectInputStream ois,
- JdbcServices jdbcServices,
- StatisticsImplementor statisticsImplementor,
- ConnectionReleaseMode connectionReleaseMode
- ) throws IOException {
+ public static LogicalConnectionImpl deserialize(
+ ObjectInputStream ois,
+ TransactionContext transactionContext) throws IOException, ClassNotFoundException {
+ boolean isUserSuppliedConnection = ois.readBoolean();
+ boolean isClosed = ois.readBoolean();
+ int observerCount = ois.readInt();
+ List observers = CollectionHelper.arrayList( observerCount );
+ for ( int i = 0; i < observerCount; i++ ) {
+ observers.add( (ConnectionObserver) ois.readObject() );
+ }
return new LogicalConnectionImpl(
- connectionReleaseMode,
- jdbcServices,
- statisticsImplementor,
- ois.readBoolean(),
- ois.readBoolean()
+ transactionContext.getConnectionReleaseMode(),
+ transactionContext.getTransactionEnvironment().getJdbcServices(),
+ isUserSuppliedConnection,
+ isClosed,
+ observers
);
}
diff --git a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/internal/StatementPreparer.java b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/internal/StatementPreparer.java
deleted file mode 100644
index 2500f328f9..0000000000
--- a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/internal/StatementPreparer.java
+++ /dev/null
@@ -1,276 +0,0 @@
-/*
- * 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
- */
-package org.hibernate.engine.jdbc.internal;
-
-import java.sql.Connection;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Statement;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.hibernate.AssertionFailure;
-import org.hibernate.HibernateException;
-import org.hibernate.ScrollMode;
-import org.hibernate.TransactionException;
-import org.hibernate.cfg.Settings;
-import org.hibernate.engine.jdbc.internal.proxy.ProxyBuilder;
-import org.hibernate.engine.jdbc.spi.LogicalConnectionImplementor;
-import org.hibernate.engine.jdbc.spi.SQLExceptionHelper;
-
-/**
- * Prepares statements.
- *
- * @author Gail Badner
- */
-public class StatementPreparer {
-
- private static final Logger log = LoggerFactory.getLogger( StatementPreparer.class );
-
- // TODO: Move JDBC settings into a different object...
- private final Settings settings;
- private final Connection proxiedConnection;
- private final SQLExceptionHelper sqlExceptionHelper;
-
- private long transactionTimeout = -1;
- boolean isTransactionTimeoutSet;
-
- /**
- * Constructs a StatementPreparer object
- * @param logicalConnection - the logical connection
- * @param settings - contains settings configured for preparing statements
- */
- public StatementPreparer(LogicalConnectionImplementor logicalConnection, Settings settings) {
- this.settings = settings;
- proxiedConnection = ProxyBuilder.buildConnection( logicalConnection );
- sqlExceptionHelper = logicalConnection.getJdbcServices().getSqlExceptionHelper();
- }
-
- private abstract class StatementPreparation {
- private final String sql;
- protected abstract PreparedStatement doPrepare() throws SQLException;
- public StatementPreparation(String sql) {
- this.sql = sql;
- }
- public String getSql() {
- return sql;
- }
- public void postProcess(PreparedStatement preparedStatement) throws SQLException {
- setStatementTimeout( preparedStatement );
- }
- public PreparedStatement prepareAndPostProcess() {
- try {
- PreparedStatement ps = doPrepare();
- postProcess( ps );
- return ps;
- }
- catch ( SQLException sqle ) {
- log.error( "sqlexception escaped proxy", sqle );
- throw sqlExceptionHelper.convert(
- sqle, "could not prepare statement", sql
- );
- }
- }
- }
-
- private abstract class QueryStatementPreparation extends StatementPreparation {
- QueryStatementPreparation(String sql) {
- super( sql );
- }
- public void postProcess(PreparedStatement preparedStatement) throws SQLException {
- super.postProcess( preparedStatement );
- setStatementFetchSize( preparedStatement );
- }
- }
-
- public void close() {
- try {
- proxiedConnection.close();
- }
- catch (SQLException sqle) {
- log.error( "sqlexception escaped proxy", sqle );
- throw sqlExceptionHelper.convert( sqle, "could not close connection proxy" );
- }
- }
-
- /**
- * Prepare a statement. If configured, the query timeout is set.
- *
- * If not explicitly closed via {@link java.sql.PreparedStatement#close()},
- * it will be released when the session is closed or disconnected.
- *
- * @param sql - the SQL for the statement to be prepared
- * @param isCallable - true, if a callable statement is to be prepared
- * @return the prepared statement
- */
- public PreparedStatement prepareStatement(String sql, final boolean isCallable) {
- StatementPreparation statementPreparation = new StatementPreparation( sql ) {
- public PreparedStatement doPrepare() throws SQLException {
- return isCallable ?
- proxiedConnection.prepareCall( getSql() ) :
- proxiedConnection.prepareStatement( getSql() );
- }
- };
- return statementPreparation.prepareAndPostProcess();
- }
-
- /**
- * Get a prepared statement to use for inserting / deleting / updating,
- * using JDBC3 getGeneratedKeys ({@link java.sql.Connection#prepareStatement(String, int)}).
- * If configured, the query timeout is set.
- *
- * If not explicitly closed via {@link java.sql.PreparedStatement#close()},
- * it will be released when the session is closed or disconnected.
-
- * @param sql - the SQL for the statement to be prepared
- * @param autoGeneratedKeys - a flag indicating whether auto-generated
- * keys should be returned; one of
- *
PreparedStatement.RETURN_GENERATED_KEYS
or
- * Statement.NO_GENERATED_KEYS
- * @return the prepared statement
- */
- public PreparedStatement prepareStatement(String sql, final int autoGeneratedKeys)
- throws HibernateException {
- if ( autoGeneratedKeys == PreparedStatement.RETURN_GENERATED_KEYS ) {
- checkAutoGeneratedKeysSupportEnabled();
- }
- StatementPreparation statementPreparation = new StatementPreparation( sql ) {
- public PreparedStatement doPrepare() throws SQLException {
- return proxiedConnection.prepareStatement( getSql(), autoGeneratedKeys );
- }
- };
- return statementPreparation.prepareAndPostProcess();
- }
-
- /**
- * Get a prepared statement to use for inserting / deleting / updating.
- * using JDBC3 getGeneratedKeys ({@link java.sql.Connection#prepareStatement(String, String[])}).
- * If configured, the query timeout is set.
- *
- * If not explicitly closed via {@link java.sql.PreparedStatement#close()},
- * it will be released when the session is closed or disconnected.
- */
- public PreparedStatement prepareStatement(String sql, final String[] columnNames) {
- checkAutoGeneratedKeysSupportEnabled();
- StatementPreparation preparation = new StatementPreparation( sql ) {
- public PreparedStatement doPrepare() throws SQLException {
- return proxiedConnection.prepareStatement( getSql(), columnNames );
- }
- };
- return preparation.prepareAndPostProcess();
- }
-
- private void checkAutoGeneratedKeysSupportEnabled() {
- if ( ! settings.isGetGeneratedKeysEnabled() ) {
- throw new AssertionFailure("getGeneratedKeys() support is not enabled");
- }
- }
-
- /**
- * Get a prepared statement for use in loading / querying.
- * If configured, the query timeout and statement fetch size are set.
- *
- * If not explicitly closed via {@link java.sql.PreparedStatement#close()},
- * it will be released when the session is closed or disconnected.
- */
- public PreparedStatement prepareQueryStatement(
- String sql,
- final boolean isCallable
- ) {
- StatementPreparation prep = new QueryStatementPreparation( sql ) {
- public PreparedStatement doPrepare() throws SQLException {
- return isCallable ?
- proxiedConnection.prepareCall( getSql() ) :
- proxiedConnection.prepareStatement( getSql() );
- }
- };
- return prep.prepareAndPostProcess();
- }
-
- /**
- * Get a scrollable prepared statement for use in loading / querying.
- * If configured, the query timeout and statement fetch size are set.
- *
- * If not explicitly closed via {@link java.sql.PreparedStatement#close()},
- * it will be released when the session is closed or disconnected.
- */
- public PreparedStatement prepareScrollableQueryStatement(
- String sql,
- final ScrollMode scrollMode,
- final boolean isCallable
- ) {
- if ( ! settings.isScrollableResultSetsEnabled() ) {
- throw new AssertionFailure("scrollable result sets are not enabled");
- }
- StatementPreparation prep = new QueryStatementPreparation( sql ) {
- public PreparedStatement doPrepare() throws SQLException {
- return isCallable ?
- proxiedConnection.prepareCall(
- getSql(), scrollMode.toResultSetType(), ResultSet.CONCUR_READ_ONLY
- ) :
- proxiedConnection.prepareStatement(
- getSql(), scrollMode.toResultSetType(), ResultSet.CONCUR_READ_ONLY
- );
- }
- };
- return prep.prepareAndPostProcess();
- }
-
- /**
- * Sets the transaction timeout.
- * @param seconds - number of seconds until the the transaction times out.
- */
- public void setTransactionTimeout(int seconds) {
- isTransactionTimeoutSet = true;
- transactionTimeout = System.currentTimeMillis() / 1000 + seconds;
- }
-
- /**
- * Unset the transaction timeout, called after the end of a
- * transaction.
- */
- public void unsetTransactionTimeout() {
- isTransactionTimeoutSet = false;
- }
-
- private void setStatementTimeout(PreparedStatement preparedStatement) throws SQLException {
- if ( isTransactionTimeoutSet ) {
- int timeout = (int) ( transactionTimeout - ( System.currentTimeMillis() / 1000 ) );
- if ( timeout <= 0) {
- throw new TransactionException("transaction timeout expired");
- }
- else {
- preparedStatement.setQueryTimeout(timeout);
- }
- }
- }
-
- private void setStatementFetchSize(PreparedStatement statement) throws SQLException {
- if ( settings.getJdbcFetchSize() != null ) {
- statement.setFetchSize( settings.getJdbcFetchSize() );
- }
- }
-}
diff --git a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/internal/StatementPreparerImpl.java b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/internal/StatementPreparerImpl.java
new file mode 100644
index 0000000000..ed4fa259b0
--- /dev/null
+++ b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/internal/StatementPreparerImpl.java
@@ -0,0 +1,223 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2011, 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
+ */
+package org.hibernate.engine.jdbc.internal;
+
+import org.hibernate.AssertionFailure;
+import org.hibernate.ScrollMode;
+import org.hibernate.TransactionException;
+import org.hibernate.cfg.Settings;
+import org.hibernate.engine.jdbc.spi.LogicalConnectionImplementor;
+import org.hibernate.engine.jdbc.spi.SQLExceptionHelper;
+import org.hibernate.engine.jdbc.spi.StatementPreparer;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+/**
+* @author Steve Ebersole
+*/
+class StatementPreparerImpl implements StatementPreparer {
+ private long transactionTimeOut = -1;
+ private JdbcCoordinatorImpl jdbcCoordinator;
+
+ StatementPreparerImpl(JdbcCoordinatorImpl jdbcCoordinator) {
+ this.jdbcCoordinator = jdbcCoordinator;
+ }
+
+ protected final Settings settings() {
+ return jdbcCoordinator.sessionFactory().getSettings();
+ }
+
+ protected final Connection connectionProxy() {
+ return logicalConnection().getShareableConnectionProxy();
+ }
+
+ protected final LogicalConnectionImplementor logicalConnection() {
+ return jdbcCoordinator.getLogicalConnection();
+ }
+
+ protected final SQLExceptionHelper sqlExceptionHelper() {
+ return jdbcCoordinator.getTransactionCoordinator()
+ .getTransactionContext()
+ .getTransactionEnvironment()
+ .getJdbcServices()
+ .getSqlExceptionHelper();
+ }
+
+ @Override
+ public PreparedStatement prepareStatement(String sql) {
+ return buildPreparedStatementPreparationTemplate( sql, false ).prepareStatement();
+ }
+
+ @Override
+ public PreparedStatement prepareStatement(String sql, final boolean isCallable) {
+ jdbcCoordinator.executeBatch();
+ return buildPreparedStatementPreparationTemplate( sql, isCallable ).prepareStatement();
+ }
+
+ private StatementPreparationTemplate buildPreparedStatementPreparationTemplate(String sql, final boolean isCallable) {
+ return new StatementPreparationTemplate( sql ) {
+ @Override
+ protected PreparedStatement doPrepare() throws SQLException {
+ return isCallable
+ ? connectionProxy().prepareCall( sql )
+ : connectionProxy().prepareStatement( sql );
+ }
+ };
+ }
+
+ private void checkAutoGeneratedKeysSupportEnabled() {
+ if ( ! settings().isGetGeneratedKeysEnabled() ) {
+ throw new AssertionFailure( "getGeneratedKeys() support is not enabled" );
+ }
+ }
+
+ @Override
+ public PreparedStatement prepareStatement(String sql, final int autoGeneratedKeys) {
+ if ( autoGeneratedKeys == PreparedStatement.RETURN_GENERATED_KEYS ) {
+ checkAutoGeneratedKeysSupportEnabled();
+ }
+ jdbcCoordinator.executeBatch();
+ return new StatementPreparationTemplate( sql ) {
+ public PreparedStatement doPrepare() throws SQLException {
+ return connectionProxy().prepareStatement( sql, autoGeneratedKeys );
+ }
+ }.prepareStatement();
+ }
+
+ @Override
+ public PreparedStatement prepareStatement(String sql, final String[] columnNames) {
+ checkAutoGeneratedKeysSupportEnabled();
+ jdbcCoordinator.executeBatch();
+ return new StatementPreparationTemplate( sql ) {
+ public PreparedStatement doPrepare() throws SQLException {
+ return connectionProxy().prepareStatement( sql, columnNames );
+ }
+ }.prepareStatement();
+ }
+
+ @Override
+ public PreparedStatement prepareQueryStatement(
+ String sql,
+ final boolean isCallable,
+ final ScrollMode scrollMode) {
+ if ( scrollMode != null && !scrollMode.equals( ScrollMode.FORWARD_ONLY ) ) {
+ if ( ! settings().isScrollableResultSetsEnabled() ) {
+ throw new AssertionFailure("scrollable result sets are not enabled");
+ }
+ PreparedStatement ps = new QueryStatementPreparationTemplate( sql ) {
+ public PreparedStatement doPrepare() throws SQLException {
+ return isCallable
+ ? connectionProxy().prepareCall(
+ sql, scrollMode.toResultSetType(), ResultSet.CONCUR_READ_ONLY
+ )
+ : connectionProxy().prepareStatement(
+ sql, scrollMode.toResultSetType(), ResultSet.CONCUR_READ_ONLY
+ );
+ }
+ }.prepareStatement();
+ logicalConnection().getResourceRegistry().registerLastQuery( ps );
+ return ps;
+ }
+ else {
+ PreparedStatement ps = new QueryStatementPreparationTemplate( sql ) {
+ public PreparedStatement doPrepare() throws SQLException {
+ return isCallable
+ ? connectionProxy().prepareCall( sql )
+ : connectionProxy().prepareStatement( sql );
+ }
+ }.prepareStatement();
+ logicalConnection().getResourceRegistry().registerLastQuery( ps );
+ return ps;
+ }
+ }
+
+ @Override
+ public void setTransactionTimeOut(int timeOut) {
+ transactionTimeOut = timeOut;
+ }
+
+ @Override
+ public void unsetTransactionTimeOut() {
+ transactionTimeOut = -1;
+ }
+
+ private abstract class StatementPreparationTemplate {
+ protected final String sql;
+
+ protected StatementPreparationTemplate(String sql) {
+ this.sql = sql;
+ }
+
+ public PreparedStatement prepareStatement() {
+ try {
+ PreparedStatement preparedStatement = doPrepare();
+ setStatementTimeout( preparedStatement );
+ postProcess( preparedStatement );
+ return preparedStatement;
+ }
+ catch ( SQLException e ) {
+ throw sqlExceptionHelper().convert( e, "could not prepare statement", sql );
+ }
+ }
+
+ protected abstract PreparedStatement doPrepare() throws SQLException;
+
+ public void postProcess(PreparedStatement preparedStatement) throws SQLException {
+ }
+
+ private void setStatementTimeout(PreparedStatement preparedStatement) throws SQLException {
+ if ( transactionTimeOut > 0 ) {
+ int timeout = (int) ( transactionTimeOut - ( System.currentTimeMillis() / 1000 ) );
+ if ( timeout <= 0 ) {
+ throw new TransactionException( "transaction timeout expired" );
+ }
+ else {
+ preparedStatement.setQueryTimeout( timeout );
+ }
+ }
+ }
+
+ }
+
+ private abstract class QueryStatementPreparationTemplate extends StatementPreparationTemplate {
+ protected QueryStatementPreparationTemplate(String sql) {
+ super( sql );
+ }
+
+ public void postProcess(PreparedStatement preparedStatement) throws SQLException {
+ super.postProcess( preparedStatement );
+ setStatementFetchSize( preparedStatement );
+ }
+ }
+
+ private void setStatementFetchSize(PreparedStatement statement) throws SQLException {
+ if ( settings().getJdbcFetchSize() != null ) {
+ statement.setFetchSize( settings().getJdbcFetchSize() );
+ }
+ }
+
+}
diff --git a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/internal/proxy/ConnectionProxyHandler.java b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/internal/proxy/ConnectionProxyHandler.java
index ef5e0fcf47..206ae0b2e7 100644
--- a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/internal/proxy/ConnectionProxyHandler.java
+++ b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/internal/proxy/ConnectionProxyHandler.java
@@ -36,19 +36,19 @@ import java.sql.Statement;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.hibernate.TransactionException;
import org.hibernate.engine.jdbc.spi.JdbcResourceRegistry;
import org.hibernate.engine.jdbc.spi.JdbcServices;
-import org.hibernate.engine.jdbc.spi.ConnectionObserver;
import org.hibernate.engine.jdbc.spi.LogicalConnectionImplementor;
-import org.hibernate.stat.StatisticsImplementor;
+import org.hibernate.engine.jdbc.spi.NonDurableConnectionObserver;
/**
* The {@link InvocationHandler} for intercepting messages to {@link java.sql.Connection} proxies.
*
* @author Steve Ebersole
*/
-public class ConnectionProxyHandler extends AbstractProxyHandler implements InvocationHandler, ConnectionObserver {
+public class ConnectionProxyHandler
+ extends AbstractProxyHandler
+ implements InvocationHandler, NonDurableConnectionObserver {
private static final Logger log = LoggerFactory.getLogger( ConnectionProxyHandler.class );
private LogicalConnectionImplementor logicalConnection;
@@ -112,6 +112,10 @@ public class ConnectionProxyHandler extends AbstractProxyHandler implements Invo
return null;
}
+ if ( "isClosed".equals( methodName ) ) {
+ return ! isValid();
+ }
+
errorIfInvalid();
// handle the JDBC 4 Wrapper#isWrapperFor and Wrapper#unwrap calls
@@ -185,9 +189,7 @@ public class ConnectionProxyHandler extends AbstractProxyHandler implements Invo
}
private void postProcessPreparedStatement(Statement statement) throws SQLException {
- if ( getStatisticsImplementorOrNull() != null ) {
- getStatisticsImplementorOrNull().prepareStatement();
- }
+ logicalConnection.notifyObserversStatementPrepared();
postProcessStatement( statement );
}
@@ -203,29 +205,25 @@ public class ConnectionProxyHandler extends AbstractProxyHandler implements Invo
invalidate();
}
- /**
- * {@inheritDoc}
- */
+ // ConnectionObserver ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ @Override
public void physicalConnectionObtained(Connection connection) {
}
- /**
- * {@inheritDoc}
- */
+ @Override
public void physicalConnectionReleased() {
log.info( "logical connection releasing its physical connection");
}
- /**
- * {@inheritDoc}
- */
+ @Override
public void logicalConnectionClosed() {
log.info( "*** logical connection closed ***" );
invalidateHandle();
}
- /* package-protected */
- StatisticsImplementor getStatisticsImplementorOrNull() {
- return getLogicalConnection().getStatisticsImplementor();
+ @Override
+ public void statementPrepared() {
+ // N/A
}
}
diff --git a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/spi/ConnectionObserver.java b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/spi/ConnectionObserver.java
index 20abcbf038..27072979d7 100644
--- a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/spi/ConnectionObserver.java
+++ b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/spi/ConnectionObserver.java
@@ -47,4 +47,9 @@ public interface ConnectionObserver {
* The logical connection was closed.
*/
public void logicalConnectionClosed();
+
+ /**
+ * Notification of a statement being prepared
+ */
+ public void statementPrepared();
}
diff --git a/hibernate-core/src/main/java/org/hibernate/jdbc/ConnectionWrapper.java b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/spi/ConnectionObserverAdapter.java
similarity index 66%
rename from hibernate-core/src/main/java/org/hibernate/jdbc/ConnectionWrapper.java
rename to hibernate-core/src/main/java/org/hibernate/engine/jdbc/spi/ConnectionObserverAdapter.java
index 1515245d79..32408525b2 100644
--- a/hibernate-core/src/main/java/org/hibernate/jdbc/ConnectionWrapper.java
+++ b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/spi/ConnectionObserverAdapter.java
@@ -1,42 +1,47 @@
-/*
- * Hibernate, Relational Persistence for Idiomatic Java
- *
- * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
- * indicated by the @author tags or express copyright attribution
- * statements applied by the authors. All third-party contributions are
- * distributed under license by Red Hat Middleware LLC.
- *
- * This copyrighted material is made available to anyone wishing to use, modify,
- * copy, or redistribute it subject to the terms and conditions of the GNU
- * Lesser General Public License, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
- * for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this distribution; if not, write to:
- * Free Software Foundation, Inc.
- * 51 Franklin Street, Fifth Floor
- * Boston, MA 02110-1301 USA
- *
- */
-package org.hibernate.jdbc;
-
-import java.sql.Connection;
-
-/**
- * Interface implemented by JDBC connection wrappers in order to give
- * access to the underlying wrapped connection.
- *
- * @author Steve Ebersole
- */
-public interface ConnectionWrapper {
- /**
- * Get a reference to the wrapped connection.
- *
- * @return The wrapped connection.
- */
- public Connection getWrappedConnection();
-}
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2011, 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
+ */
+package org.hibernate.engine.jdbc.spi;
+
+import java.sql.Connection;
+
+/**
+ * @author Steve Ebersole
+ */
+public class ConnectionObserverAdapter implements ConnectionObserver {
+ @Override
+ public void physicalConnectionObtained(Connection connection) {
+ }
+
+ @Override
+ public void physicalConnectionReleased() {
+ }
+
+ @Override
+ public void logicalConnectionClosed() {
+ }
+
+ @Override
+ public void statementPrepared() {
+ }
+}
diff --git a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/spi/JDBCContext.java b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/spi/JDBCContext.java
deleted file mode 100644
index 4e177d44a0..0000000000
--- a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/spi/JDBCContext.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * 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
- */
-package org.hibernate.engine.jdbc.spi;
-
-import java.io.Serializable;
-import java.sql.Connection;
-
-import org.hibernate.ConnectionReleaseMode;
-import org.hibernate.HibernateException;
-import org.hibernate.Transaction;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.transaction.TransactionFactory;
-import org.hibernate.transaction.synchronization.CallbackCoordinator;
-
-/**
- * Acts as the SPI for the mediary between "entity-mode related" sessions in terms of
- * their interaction with the JDBC data store.
- *
- * @author Gail Badner
- */
-public interface JDBCContext extends Serializable {
-
- // TODO: Document these methods...
-
- CallbackCoordinator getJtaSynchronizationCallbackCoordinator();
-
- void cleanUpJtaSynchronizationCallbackCoordinator();
-
- SessionFactoryImplementor getFactory();
-
- ConnectionManager getConnectionManager();
-
- Connection connection() throws HibernateException;
-
- boolean registerCallbackIfNecessary();
-
- boolean registerSynchronizationIfPossible();
-
- boolean isTransactionInProgress();
-
- Transaction getTransaction() throws HibernateException;
-
- void beforeTransactionCompletion(Transaction tx);
-
- void afterTransactionBegin(Transaction tx);
-
- void afterTransactionCompletion(boolean success, Transaction tx);
-
- void afterNontransactionalQuery(boolean success);
-
- public static interface Context extends TransactionFactory.Context {
- /**
- * We cannot rely upon this method being called! It is only
- * called if we are using Hibernate Transaction API.
- */
- public void afterTransactionBegin(Transaction tx);
- public void beforeTransactionCompletion(Transaction tx);
- public void afterTransactionCompletion(boolean success, Transaction tx);
- public ConnectionReleaseMode getConnectionReleaseMode();
- public boolean isAutoCloseSessionEnabled();
- }
-}
diff --git a/hibernate-core/src/main/java/org/hibernate/transaction/OrionTransactionManagerLookup.java b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/spi/JdbcContext.java
similarity index 55%
rename from hibernate-core/src/main/java/org/hibernate/transaction/OrionTransactionManagerLookup.java
rename to hibernate-core/src/main/java/org/hibernate/engine/jdbc/spi/JdbcContext.java
index 6960405c77..a3c8ad8998 100644
--- a/hibernate-core/src/main/java/org/hibernate/transaction/OrionTransactionManagerLookup.java
+++ b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/spi/JdbcContext.java
@@ -1,10 +1,10 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
- * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * Copyright (c) 2011, 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 Middleware LLC.
+ * 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
@@ -20,35 +20,32 @@
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
- *
*/
-package org.hibernate.transaction;
+package org.hibernate.engine.jdbc.spi;
+
+import org.hibernate.ConnectionReleaseMode;
+import org.hibernate.engine.SessionFactoryImplementor;
+
+import java.io.Serializable;
/**
- * {@link TransactionManagerLookup} strategy for Orion
+ * Access to services needed in the context of processing JDBC requests.
*
- * @author Gavin King
+ * @author Steve Ebersole
*/
-public class OrionTransactionManagerLookup extends JNDITransactionManagerLookup {
+public interface JdbcContext extends Serializable {
+ public SessionFactoryImplementor getSessionFactory();
+ public ConnectionReleaseMode getConnectionReleaseMode();
- /**
- * {@inheritDoc}
- */
- protected String getName() {
- return "java:comp/UserTransaction";
- }
+ public boolean isClosed();
- /**
- * {@inheritDoc}
- */
- public String getUserTransactionName() {
- return "java:comp/UserTransaction";
- }
+ public boolean isFlushModeNever();
+ public boolean isFlushBeforeCompletionEnabled();
+
+ public void managedFlush();
+
+ public boolean shouldAutoClose();
+
+ public void managedClose();
}
-
-
-
-
-
-
diff --git a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/spi/JdbcCoordinator.java b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/spi/JdbcCoordinator.java
new file mode 100644
index 0000000000..d1d9a143de
--- /dev/null
+++ b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/spi/JdbcCoordinator.java
@@ -0,0 +1,96 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2011, 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
+ */
+package org.hibernate.engine.jdbc.spi;
+
+import org.hibernate.engine.jdbc.batch.spi.Batch;
+import org.hibernate.engine.jdbc.batch.spi.BatchKey;
+import org.hibernate.engine.transaction.spi.TransactionCoordinator;
+import org.hibernate.jdbc.Work;
+
+import java.io.Serializable;
+import java.sql.Connection;
+
+/**
+ * Coordinates JDBC-related activities.
+ *
+ * @author Steve Ebersole
+ */
+public interface JdbcCoordinator extends Serializable {
+ /**
+ * Retrieve the transaction coordinator associated with this JDBC coordinator.
+ *
+ * @return The transaction coordinator
+ */
+ public TransactionCoordinator getTransactionCoordinator();
+
+ /**
+ * Retrieves the logical connection associated with this JDBC coordinator.
+ *
+ * @return The logical connection
+ */
+ public LogicalConnectionImplementor getLogicalConnection();
+
+ /**
+ * Get a batch instance.
+ *
+ * @param key The unique batch key.
+ *
+ * @return The batch
+ */
+ public Batch getBatch(BatchKey key);
+
+ public void abortBatch();
+
+ /**
+ * Obtain the statement preparer associated with this JDBC coordinator.
+ *
+ * @return This coordinator's statement preparer
+ */
+ public StatementPreparer getStatementPreparer();
+
+ /**
+ * Callback to let us know that a flush is beginning. We use this fact
+ * to temporarily circumvent aggressive connection releasing until after
+ * the flush cycle is complete {@link #flushEnding()}
+ */
+ public void flushBeginning();
+
+ /**
+ * Callback to let us know that a flush is ending. We use this fact to
+ * stop circumventing aggressive releasing connections.
+ */
+ public void flushEnding();
+
+ public Connection close();
+
+ public void afterTransaction();
+
+ public void coordinateWork(Work work);
+
+ public void executeBatch();
+
+ public void cancelLastQuery();
+
+ public void setTransactionTimeOut(int timeout);
+}
diff --git a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/spi/JdbcResourceRegistry.java b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/spi/JdbcResourceRegistry.java
index 078c6d48ec..4ec5c57ee3 100644
--- a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/spi/JdbcResourceRegistry.java
+++ b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/spi/JdbcResourceRegistry.java
@@ -23,6 +23,7 @@
*/
package org.hibernate.engine.jdbc.spi;
+import java.io.Serializable;
import java.sql.ResultSet;
import java.sql.Statement;
@@ -31,7 +32,7 @@ import java.sql.Statement;
*
* @author Steve Ebersole
*/
-public interface JdbcResourceRegistry {
+public interface JdbcResourceRegistry extends Serializable {
/**
* Register a JDBC statement.
*
diff --git a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/spi/LogicalConnection.java b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/spi/LogicalConnection.java
index 1c54e3f6aa..0a237d0860 100644
--- a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/spi/LogicalConnection.java
+++ b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/spi/LogicalConnection.java
@@ -31,7 +31,7 @@ import java.sql.Connection;
*
* @author Steve Ebersole
*/
-public interface LogicalConnection {
+public interface LogicalConnection extends Serializable {
/**
* Is this logical connection open? Another phraseology sometimes used is: "are we
* logically connected"?
@@ -55,10 +55,27 @@ public interface LogicalConnection {
* connection has either not yet been obtained (non-UserSuppliedConnectionProvider)
* or has previously been aggressively released.
*
+ * @todo ?? Move this to {@link LogicalConnectionImplementor} in lieu of {@link #getShareableConnectionProxy} and {@link #getDistinctConnectionProxy} ??
+ *
* @return The current Connection.
*/
public Connection getConnection();
+ /**
+ * Retrieves the shareable connection proxy (see {@link org.hibernate.engine.jdbc.internal.proxy} for details).
+ *
+ * @return The shareable connection proxy.
+ */
+ public Connection getShareableConnectionProxy();
+
+ /**
+ * Retrieves a distinct connection proxy (see {@link org.hibernate.engine.jdbc.internal.proxy} for details). It
+ * is distinct in that it is not shared with others unless the caller explicitly shares it.
+ *
+ * @return The distinct connection proxy.
+ */
+ public Connection getDistinctConnectionProxy();
+
/**
* Release the underlying connection and clean up any other resources associated
* with this logical connection.
@@ -68,4 +85,6 @@ public interface LogicalConnection {
* @return The physical connection which was being used.
*/
public Connection close();
+
+ public void afterTransaction();
}
diff --git a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/spi/LogicalConnectionImplementor.java b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/spi/LogicalConnectionImplementor.java
index 288554ff35..4c505836bd 100644
--- a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/spi/LogicalConnectionImplementor.java
+++ b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/spi/LogicalConnectionImplementor.java
@@ -24,8 +24,11 @@
package org.hibernate.engine.jdbc.spi;
import org.hibernate.ConnectionReleaseMode;
+import org.hibernate.engine.jdbc.internal.proxy.ConnectionProxyHandler;
import org.hibernate.stat.StatisticsImplementor;
+import java.sql.Connection;
+
/**
* The "internal" contract for LogicalConnection
*
@@ -39,13 +42,6 @@ public interface LogicalConnectionImplementor extends LogicalConnection {
*/
public JdbcServices getJdbcServices();
- /**
- * Obtains the statistics implementor.
- *
- * @return the statistics implementor
- */
- public StatisticsImplementor getStatisticsImplementor();
-
/**
* Obtains the JDBC resource registry associated with this logical connection.
*
@@ -60,6 +56,13 @@ public interface LogicalConnectionImplementor extends LogicalConnection {
*/
public void addObserver(ConnectionObserver observer);
+ /**
+ * Remove an observer
+ *
+ * @param connectionObserver The observer to remove.
+ */
+ public void removeObserver(ConnectionObserver connectionObserver);
+
/**
* The release mode under which this logical connection is operating.
*
@@ -91,5 +94,26 @@ public interface LogicalConnectionImplementor extends LogicalConnection {
*/
public void enableReleases();
+ /**
+ * Manually disconnect the underlying JDBC Connection. The assumption here
+ * is that the manager will be reconnected at a later point in time.
+ *
+ * @return The connection maintained here at time of disconnect. Null if
+ * there was no connection cached internally.
+ */
+ public Connection manualDisconnect();
+ /**
+ * Manually reconnect the underlying JDBC Connection. Should be called at some point after manualDisconnect().
+ *
+ * @param suppliedConnection For user supplied connection strategy the user needs to hand us the connection
+ * with which to reconnect. It is an error to pass a connection in the other strategies.
+ */
+ public void manualReconnect(Connection suppliedConnection);
+
+ public boolean isAutoCommit();
+
+ public boolean isReadyForSerialization();
+
+ public void notifyObserversStatementPrepared();
}
diff --git a/hibernate-core/src/main/java/org/hibernate/transaction/JBossTransactionManagerLookup.java b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/spi/NonDurableConnectionObserver.java
similarity index 65%
rename from hibernate-core/src/main/java/org/hibernate/transaction/JBossTransactionManagerLookup.java
rename to hibernate-core/src/main/java/org/hibernate/engine/jdbc/spi/NonDurableConnectionObserver.java
index cdfd63390a..7a84ded4f9 100644
--- a/hibernate-core/src/main/java/org/hibernate/transaction/JBossTransactionManagerLookup.java
+++ b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/spi/NonDurableConnectionObserver.java
@@ -1,10 +1,10 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
- * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * Copyright (c) 2011, 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 Middleware LLC.
+ * 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
@@ -20,23 +20,14 @@
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
- *
*/
-package org.hibernate.transaction;
+package org.hibernate.engine.jdbc.spi;
/**
- * A {@link TransactionManagerLookup} lookup strategy for JBoss AS.
+ * Additional optional contract for connection observers to indicate that they should be released when the physical
+ * connection is released.
*
- * @author Gavin King
+ * @author Steve Ebersole
*/
-public final class JBossTransactionManagerLookup extends JNDITransactionManagerLookup {
-
- protected String getName() {
- return "java:/TransactionManager";
- }
-
- public String getUserTransactionName() {
- return "UserTransaction";
- }
-
+public interface NonDurableConnectionObserver extends ConnectionObserver {
}
diff --git a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/spi/SQLExceptionHelper.java b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/spi/SQLExceptionHelper.java
index bb70a938cf..0db12c826b 100644
--- a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/spi/SQLExceptionHelper.java
+++ b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/spi/SQLExceptionHelper.java
@@ -23,6 +23,7 @@
*/
package org.hibernate.engine.jdbc.spi;
+import java.io.Serializable;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.SQLWarning;
@@ -41,7 +42,7 @@ import org.hibernate.util.StringHelper;
*
* @author Steve Ebersole
*/
-public class SQLExceptionHelper {
+public class SQLExceptionHelper implements Serializable {
private static final Logger log = LoggerFactory.getLogger( SQLExceptionHelper.class );
public static final String DEFAULT_EXCEPTION_MSG = "SQL Exception";
diff --git a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/spi/StatementPreparer.java b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/spi/StatementPreparer.java
new file mode 100644
index 0000000000..56c02e6653
--- /dev/null
+++ b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/spi/StatementPreparer.java
@@ -0,0 +1,97 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2011, 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
+ */
+package org.hibernate.engine.jdbc.spi;
+
+import org.hibernate.ScrollMode;
+
+import java.sql.PreparedStatement;
+
+/**
+ * @author Steve Ebersole
+ */
+public interface StatementPreparer {
+ /**
+ * Prepare a statement.
+ *
+ * @param sql The SQL the statement to be prepared
+ *
+ * @return the prepared statement
+ */
+ public PreparedStatement prepareStatement(String sql);
+
+ /**
+ * Prepare a statement.
+ *
+ * @param sql The SQL the statement to be prepared
+ * @param isCallable Whether to prepare as a callable statement.
+ *
+ * @return the prepared statement
+ */
+ public PreparedStatement prepareStatement(String sql, boolean isCallable);
+
+ /**
+ * Get a prepared statement to use for inserting using JDBC3
+ * {@link java.sql.PreparedStatement#getGeneratedKeys getGeneratedKeys} processing.
+ *
+ * @param sql - the SQL for the statement to be prepared
+ * @param autoGeneratedKeys - a flag indicating whether auto-generated keys should be returned; one of
+ * - {@link PreparedStatement#RETURN_GENERATED_KEYS}
+ * - {@link PreparedStatement#NO_GENERATED_KEYS}
+ *
+ *
+ * @return the prepared statement
+ *
+ * @see java.sql.Connection#prepareStatement(String, int)
+ */
+ public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys);
+
+
+ /**
+ * Get a prepared statement to use for inserting using JDBC3
+ * {@link java.sql.PreparedStatement#getGeneratedKeys getGeneratedKeys} processing.
+ *
+ * @param sql - the SQL for the statement to be prepared
+ * @param columnNames The name of the columns to be returned in the generated keys result set.
+ *
+ * @return the prepared statement
+ *
+ * @see java.sql.Connection#prepareStatement(String, String[])
+ */
+ public PreparedStatement prepareStatement(String sql, String[] columnNames);
+
+ /**
+ * Get a prepared statement for use in loading / querying.
+ *
+ * @param sql The SQL the statement to be prepared
+ * @param isCallable Whether to prepare as a callable statement.
+ * @param scrollMode (optional) scroll mode to be applied to the resulting result set; may be null to indicate
+ * no scrolling should be applied.
+ *
+ * @return the prepared statement
+ */
+ public PreparedStatement prepareQueryStatement(String sql, boolean isCallable, ScrollMode scrollMode);
+
+ public void setTransactionTimeOut(int timeout);
+ public void unsetTransactionTimeOut();
+}
diff --git a/hibernate-core/src/main/java/org/hibernate/engine/query/NativeSQLQueryPlan.java b/hibernate-core/src/main/java/org/hibernate/engine/query/NativeSQLQueryPlan.java
index e930ef4ff4..dfa7d3c94f 100644
--- a/hibernate-core/src/main/java/org/hibernate/engine/query/NativeSQLQueryPlan.java
+++ b/hibernate-core/src/main/java/org/hibernate/engine/query/NativeSQLQueryPlan.java
@@ -198,7 +198,7 @@ public class NativeSQLQueryPlan implements Serializable {
session );
String sql = queryParameters.getFilteredSQL();
- ps = session.getJDBCContext().getConnectionManager().prepareStatement( sql, false );
+ ps = session.getTransactionCoordinator().getJdbcCoordinator().getStatementPreparer().prepareStatement( sql, false );
try {
int col = 1;
diff --git a/hibernate-core/src/main/java/org/hibernate/engine/transaction/Isolater.java b/hibernate-core/src/main/java/org/hibernate/engine/transaction/Isolater.java
deleted file mode 100644
index ba2c75f799..0000000000
--- a/hibernate-core/src/main/java/org/hibernate/engine/transaction/Isolater.java
+++ /dev/null
@@ -1,307 +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.engine.transaction;
-
-import java.sql.Connection;
-import java.sql.SQLException;
-import javax.transaction.Transaction;
-import javax.transaction.TransactionManager;
-import javax.transaction.SystemException;
-import javax.transaction.NotSupportedException;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.hibernate.HibernateException;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.engine.jdbc.spi.SQLExceptionHelper;
-import org.hibernate.exception.JDBCExceptionHelper;
-import org.hibernate.exception.SQLExceptionConverter;
-
-/**
- * Class which provides the isolation semantics required by
- * an {@link IsolatedWork}. Processing comes in two flavors:
- * - {@link #doIsolatedWork} : makes sure the work to be done is
- * performed in a seperate, distinct transaction
- * - {@link #doNonTransactedWork} : makes sure the work to be
- * done is performed outside the scope of any transaction
- *
- *
- * @author Steve Ebersole
- */
-public class Isolater {
-
- private static final Logger log = LoggerFactory.getLogger( Isolater.class );
-
- /**
- * Ensures that all processing actually performed by the given work will
- * occur on a seperate transaction.
- *
- * @param work The work to be performed.
- * @param session The session from which this request is originating.
- * @throws HibernateException
- */
- public static void doIsolatedWork(IsolatedWork work, SessionImplementor session) throws HibernateException {
- boolean isJta = session.getFactory().getTransactionManager() != null;
- if ( isJta ) {
- new JtaDelegate( session ).delegateWork( work, true );
- }
- else {
- new JdbcDelegate( session ).delegateWork( work, true );
- }
- }
-
- /**
- * Ensures that all processing actually performed by the given work will
- * occur outside of a transaction.
- *
- * @param work The work to be performed.
- * @param session The session from which this request is originating.
- * @throws HibernateException
- */
- public static void doNonTransactedWork(IsolatedWork work, SessionImplementor session) throws HibernateException {
- boolean isJta = session.getFactory().getTransactionManager() != null;
- if ( isJta ) {
- new JtaDelegate( session ).delegateWork( work, false );
- }
- else {
- new JdbcDelegate( session ).delegateWork( work, false );
- }
- }
-
- // should be ok performance-wise to generate new delegate instances for each
- // request since these are locally stack-scoped. Besides, it makes the code
- // much easier to read than the old TransactionHelper stuff...
-
- private static interface Delegate {
- public void delegateWork(IsolatedWork work, boolean transacted) throws HibernateException;
- }
-
- /**
- * An isolation delegate for JTA-based transactions. Essentially susepnds
- * any current transaction, does the work in a new transaction, and then
- * resumes the initial transaction (if there was one).
- */
- public static class JtaDelegate implements Delegate {
- private final SessionImplementor session;
-
- public JtaDelegate(SessionImplementor session) {
- this.session = session;
- }
-
- public void delegateWork(IsolatedWork work, boolean transacted) throws HibernateException {
- TransactionManager transactionManager = session.getFactory().getTransactionManager();
-
- try {
- // First we suspend any current JTA transaction
- Transaction surroundingTransaction = transactionManager.suspend();
- if ( log.isDebugEnabled() ) {
- log.debug( "surrounding JTA transaction suspended [" + surroundingTransaction + "]" );
- }
-
- boolean hadProblems = false;
- try {
- // then peform the requested work
- if ( transacted ) {
- doTheWorkInNewTransaction( work, transactionManager );
- }
- else {
- doTheWorkInNoTransaction( work );
- }
- }
- catch ( HibernateException e ) {
- hadProblems = true;
- throw e;
- }
- finally {
- try {
- transactionManager.resume( surroundingTransaction );
- if ( log.isDebugEnabled() ) {
- log.debug( "surrounding JTA transaction resumed [" + surroundingTransaction + "]" );
- }
- }
- catch( Throwable t ) {
- // if the actually work had an error use that, otherwise error based on t
- if ( !hadProblems ) {
- //noinspection ThrowFromFinallyBlock
- throw new HibernateException( "Unable to resume previously suspended transaction", t );
- }
- }
- }
- }
- catch ( SystemException e ) {
- throw new HibernateException( "Unable to suspend current JTA transaction", e );
- }
- }
-
- private void doTheWorkInNewTransaction(IsolatedWork work, TransactionManager transactionManager) {
- try {
- // start the new isolated transaction
- transactionManager.begin();
-
- try {
- doTheWork( work );
- // if everythign went ok, commit the isolated transaction
- transactionManager.commit();
- }
- catch ( Exception e ) {
- try {
- transactionManager.rollback();
- }
- catch ( Exception ignore ) {
- log.info( "Unable to rollback isolated transaction on error [" + e + "] : [" + ignore + "]" );
- }
- }
- }
- catch ( SystemException e ) {
- throw new HibernateException( "Unable to start isolated transaction", e );
- }
- catch ( NotSupportedException e ) {
- throw new HibernateException( "Unable to start isolated transaction", e );
- }
- }
-
- private void doTheWorkInNoTransaction(IsolatedWork work) {
- doTheWork( work );
- }
-
- private void doTheWork(IsolatedWork work) {
- try {
- // obtain our isolated connection
- Connection connection = session.getFactory().getConnectionProvider().getConnection();
- try {
- // do the actual work
- work.doWork( connection );
- }
- catch ( HibernateException e ) {
- throw e;
- }
- catch ( Exception e ) {
- throw new HibernateException( "Unable to perform isolated work", e );
- }
- finally {
- try {
- // no matter what, release the connection (handle)
- session.getFactory().getConnectionProvider().closeConnection( connection );
- }
- catch ( Throwable ignore ) {
- log.info( "Unable to release isolated connection [" + ignore + "]" );
- }
- }
- }
- catch ( SQLException sqle ) {
- throw sqlExceptionHelper().convert(
- sqle,
- "unable to obtain isolated JDBC connection"
- );
- }
- }
-
- private SQLExceptionHelper sqlExceptionHelper() {
- return session.getFactory().getSQLExceptionHelper();
- }
- }
-
- /**
- * An isolation delegate for JDBC-based transactions. Basically just
- * grabs a new connection and does the work on that.
- */
- public static class JdbcDelegate implements Delegate {
- private final SessionImplementor session;
-
- public JdbcDelegate(SessionImplementor session) {
- this.session = session;
- }
-
- public void delegateWork(IsolatedWork work, boolean transacted) throws HibernateException {
- boolean wasAutoCommit = false;
- try {
- Connection connection = session.getFactory().getConnectionProvider().getConnection();
- try {
- if ( transacted ) {
- if ( connection.getAutoCommit() ) {
- wasAutoCommit = true;
- connection.setAutoCommit( false );
- }
- }
-
- work.doWork( connection );
-
- if ( transacted ) {
- connection.commit();
- }
- }
- catch( Exception e ) {
- try {
- if ( transacted && !connection.isClosed() ) {
- connection.rollback();
- }
- }
- catch( Exception ignore ) {
- log.info( "unable to rollback connection on exception [" + ignore + "]" );
- }
-
- if ( e instanceof HibernateException ) {
- throw ( HibernateException ) e;
- }
- else if ( e instanceof SQLException ) {
- throw sqlExceptionHelper().convert(
- ( SQLException ) e,
- "error performing isolated work"
- );
- }
- else {
- throw new HibernateException( "error performing isolated work", e );
- }
- }
- finally {
- if ( transacted && wasAutoCommit ) {
- try {
- connection.setAutoCommit( true );
- }
- catch( Exception ignore ) {
- log.trace( "was unable to reset connection back to auto-commit" );
- }
- }
- try {
- session.getFactory().getConnectionProvider().closeConnection( connection );
- }
- catch ( Exception ignore ) {
- log.info( "Unable to release isolated connection [" + ignore + "]" );
- }
- }
- }
- catch ( SQLException sqle ) {
- throw sqlExceptionHelper().convert(
- sqle,
- "unable to obtain isolated JDBC connection"
- );
- }
- }
-
- private SQLExceptionHelper sqlExceptionHelper() {
- return session.getFactory().getSQLExceptionHelper();
- }
- }
-}
diff --git a/hibernate-core/src/main/java/org/hibernate/engine/transaction/NullSynchronizationException.java b/hibernate-core/src/main/java/org/hibernate/engine/transaction/internal/NullSynchronizationException.java
similarity index 89%
rename from hibernate-core/src/main/java/org/hibernate/engine/transaction/NullSynchronizationException.java
rename to hibernate-core/src/main/java/org/hibernate/engine/transaction/internal/NullSynchronizationException.java
index 083ba68072..e4080b7b62 100644
--- a/hibernate-core/src/main/java/org/hibernate/engine/transaction/NullSynchronizationException.java
+++ b/hibernate-core/src/main/java/org/hibernate/engine/transaction/internal/NullSynchronizationException.java
@@ -21,12 +21,12 @@
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
-package org.hibernate.engine.transaction;
+package org.hibernate.engine.transaction.internal;
import org.hibernate.HibernateException;
/**
- * TODO : javadoc
+ * Indicates an attempt to register a null synchronization. Basically a glorified {@link NullPointerException}
*
* @author Steve Ebersole
*/
diff --git a/hibernate-core/src/main/java/org/hibernate/engine/transaction/SynchronizationRegistry.java b/hibernate-core/src/main/java/org/hibernate/engine/transaction/internal/SynchronizationRegistryImpl.java
similarity index 75%
rename from hibernate-core/src/main/java/org/hibernate/engine/transaction/SynchronizationRegistry.java
rename to hibernate-core/src/main/java/org/hibernate/engine/transaction/internal/SynchronizationRegistryImpl.java
index c0a3ad9e68..ca504aac1b 100644
--- a/hibernate-core/src/main/java/org/hibernate/engine/transaction/SynchronizationRegistry.java
+++ b/hibernate-core/src/main/java/org/hibernate/engine/transaction/internal/SynchronizationRegistryImpl.java
@@ -1,7 +1,7 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
- * Copyright (c) 2010, Red Hat Inc. or third-party contributors as
+ * Copyright (c) 2011, 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.
@@ -21,7 +21,9 @@
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
-package org.hibernate.engine.transaction;
+package org.hibernate.engine.transaction.internal;
+
+import org.hibernate.engine.transaction.spi.SynchronizationRegistry;
import java.util.LinkedHashSet;
import javax.transaction.Synchronization;
@@ -29,25 +31,17 @@ import javax.transaction.Synchronization;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.hibernate.HibernateException;
-
/**
* Manages a registry of {@link Synchronization Synchronizations}.
*
* @author Steve Ebersole
*/
-public class SynchronizationRegistry {
- private static final Logger log = LoggerFactory.getLogger( SynchronizationRegistry.class );
+public class SynchronizationRegistryImpl implements SynchronizationRegistry {
+ private static final Logger log = LoggerFactory.getLogger( SynchronizationRegistryImpl.class );
private LinkedHashSet synchronizations;
- /**
- * Register a user {@link Synchronization} callback for this transaction.
- *
- * @param synchronization The synchronization callback to register.
- *
- * @throws HibernateException
- */
+ @Override
public void registerSynchronization(Synchronization synchronization) {
if ( synchronization == null ) {
throw new NullSynchronizationException();
@@ -63,10 +57,7 @@ public class SynchronizationRegistry {
}
}
- /**
- * Delegate {@link Synchronization#beforeCompletion} calls to {@link #registerSynchronization registered}
- * {@link Synchronization Synchronizations}
- */
+ @Override
public void notifySynchronizationsBeforeTransactionCompletion() {
if ( synchronizations != null ) {
for ( Synchronization synchronization : synchronizations ) {
@@ -80,12 +71,7 @@ public class SynchronizationRegistry {
}
}
- /**
- * Delegate {@link Synchronization#afterCompletion} calls to {@link #registerSynchronization registered}
- * {@link Synchronization Synchronizations}
- *
- * @param status The transaction status (if known) per {@link javax.transaction.Status}
- */
+ @Override
public void notifySynchronizationsAfterTransactionCompletion(int status) {
if ( synchronizations != null ) {
for ( Synchronization synchronization : synchronizations ) {
@@ -98,4 +84,14 @@ public class SynchronizationRegistry {
}
}
}
+
+ /**
+ * Package-protected access to clear registered synchronizations.
+ */
+ void clearSynchronizations() {
+ if ( synchronizations != null ) {
+ synchronizations.clear();
+ synchronizations = null;
+ }
+ }
}
diff --git a/hibernate-core/src/main/java/org/hibernate/engine/transaction/internal/TransactionCoordinatorImpl.java b/hibernate-core/src/main/java/org/hibernate/engine/transaction/internal/TransactionCoordinatorImpl.java
new file mode 100644
index 0000000000..b9d4fc59ff
--- /dev/null
+++ b/hibernate-core/src/main/java/org/hibernate/engine/transaction/internal/TransactionCoordinatorImpl.java
@@ -0,0 +1,348 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2011, 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
+ */
+package org.hibernate.engine.transaction.internal;
+
+import org.hibernate.ConnectionReleaseMode;
+import org.hibernate.ResourceClosedException;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl;
+import org.hibernate.engine.jdbc.spi.JdbcCoordinator;
+import org.hibernate.engine.transaction.internal.jta.JtaStatusHelper;
+import org.hibernate.engine.transaction.spi.JoinStatus;
+import org.hibernate.engine.transaction.spi.SynchronizationRegistry;
+import org.hibernate.engine.transaction.spi.TransactionContext;
+import org.hibernate.engine.transaction.spi.TransactionCoordinator;
+import org.hibernate.engine.transaction.spi.TransactionEnvironment;
+import org.hibernate.engine.transaction.spi.TransactionFactory;
+import org.hibernate.engine.transaction.spi.TransactionImplementor;
+import org.hibernate.engine.transaction.spi.TransactionObserver;
+import org.hibernate.engine.transaction.synchronization.internal.RegisteredSynchronization;
+import org.hibernate.engine.transaction.synchronization.internal.SynchronizationCallbackCoordinatorImpl;
+import org.hibernate.engine.transaction.synchronization.spi.SynchronizationCallbackCoordinator;
+import org.hibernate.service.jta.platform.spi.JtaPlatform;
+import org.hibernate.util.CollectionHelper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.sql.Connection;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Standard implementation of the Hibernate {@link TransactionCoordinator}
+ *
+ * IMPL NOTE : Custom serialization handling!
+ *
+ * @author Steve Ebersole
+ */
+public class TransactionCoordinatorImpl implements TransactionCoordinator {
+ private static final Logger log = LoggerFactory.getLogger( TransactionCoordinatorImpl.class );
+
+ private final transient TransactionContext transactionContext;
+ private final transient JdbcCoordinatorImpl jdbcCoordinator;
+
+ private final transient List observers;
+ private final transient SynchronizationRegistryImpl synchronizationRegistry;
+
+ private transient TransactionImplementor currentHibernateTransaction;
+
+ private transient SynchronizationCallbackCoordinatorImpl callbackCoordinator;
+
+ private transient boolean open = true;
+ private transient boolean synchronizationRegistered;
+ private transient boolean ownershipTaken;
+
+ public TransactionCoordinatorImpl(
+ Connection userSuppliedConnection,
+ TransactionContext transactionContext) {
+ this.transactionContext = transactionContext;
+ this.jdbcCoordinator = new JdbcCoordinatorImpl( userSuppliedConnection, this );
+ this.observers = new ArrayList();
+ this.synchronizationRegistry = new SynchronizationRegistryImpl();
+ reset();
+
+ final boolean registerSynchronization = transactionContext.isAutoCloseSessionEnabled()
+ || transactionContext.isFlushBeforeCompletionEnabled()
+ || transactionContext.getConnectionReleaseMode() == ConnectionReleaseMode.AFTER_TRANSACTION;
+ if ( registerSynchronization ) {
+ pulse();
+ }
+ }
+
+ public TransactionCoordinatorImpl(
+ TransactionContext transactionContext,
+ JdbcCoordinatorImpl jdbcCoordinator,
+ List observers) {
+ this.transactionContext = transactionContext;
+ this.jdbcCoordinator = jdbcCoordinator;
+ this.observers = observers;
+ this.synchronizationRegistry = new SynchronizationRegistryImpl();
+ reset();
+ }
+
+ /**
+ * Reset the internal state.
+ */
+ public void reset() {
+ synchronizationRegistered = false;
+ ownershipTaken = false;
+
+ if ( currentHibernateTransaction != null ) {
+ currentHibernateTransaction.invalidate();
+ }
+ currentHibernateTransaction = transactionFactory().createTransaction( this );
+
+ // IMPL NOTE : reset clears synchronizations (following jta spec), but not observers!
+ synchronizationRegistry.clearSynchronizations();
+ }
+
+ public void afterTransaction(TransactionImplementor hibernateTransaction, int status) {
+ log.trace( "after transaction completion" );
+
+ final boolean success = JtaStatusHelper.isCommitted( status );
+
+ // todo : handle stats as observer?
+ // as is this messes up unit tests which do not build a sf
+// if ( sessionFactory().getStatistics().isStatisticsEnabled() ) {
+// sessionFactory().getStatisticsImplementor().endTransaction( success );
+// }
+
+ getJdbcCoordinator().afterTransaction();
+
+ getTransactionContext().afterTransactionCompletion( hibernateTransaction, success );
+ sendAfterTransactionCompletionNotifications( hibernateTransaction, status );
+ reset();
+ }
+
+ private SessionFactoryImplementor sessionFactory() {
+ return transactionContext.getTransactionEnvironment().getSessionFactory();
+ }
+
+ public boolean isSynchronizationRegistered() {
+ return synchronizationRegistered;
+ }
+
+ @Override
+ @SuppressWarnings( {"unchecked"})
+ public boolean isTransactionInProgress() {
+ return getTransaction().isActive() &&
+ transactionFactory().getJoinStatus( this, getTransaction() ) == JoinStatus.JOINED;
+ }
+
+ @Override
+ public TransactionContext getTransactionContext() {
+ return transactionContext;
+ }
+
+ @Override
+ public JdbcCoordinator getJdbcCoordinator() {
+ return jdbcCoordinator;
+ }
+
+ private TransactionFactory transactionFactory() {
+ return getTransactionEnvironment().getTransactionFactory();
+ }
+
+ private TransactionEnvironment getTransactionEnvironment() {
+ return getTransactionContext().getTransactionEnvironment();
+ }
+
+ @Override
+ public TransactionImplementor getTransaction() {
+ if ( ! open ) {
+ throw new ResourceClosedException( "This TransactionCoordinator has been closed" );
+ }
+ pulse();
+ return currentHibernateTransaction;
+ }
+
+ public void afterNonTransactionalQuery(boolean success) {
+ // check to see if the connection is in auto-commit mode (no connection means aggressive connection
+ // release outside a JTA transaction context, so MUST be autocommit mode)
+ boolean isAutocommit = getJdbcCoordinator().getLogicalConnection().isAutoCommit();
+ getJdbcCoordinator().getLogicalConnection().afterTransaction();
+
+ if ( isAutocommit ) {
+ for ( TransactionObserver observer : observers ) {
+ observer.afterCompletion( success, this.getTransaction() );
+ }
+ }
+ }
+
+ @Override
+ public void resetJoinStatus() {
+ getTransaction().resetJoinStatus();
+ }
+
+ @SuppressWarnings({ "unchecked" })
+ private void attemptToRegisterJtaSync() {
+ if ( synchronizationRegistered ) {
+ return;
+ }
+
+ // Has the local transaction (Hibernate facade) taken on the responsibility of driving the transaction inflow?
+ if ( currentHibernateTransaction.isInitiator() ) {
+ return;
+ }
+
+ // IMPL NOTE : At this point the local callback is the "maybe" one. The only time that needs to change is if
+ // we are able to successfully register the transaction synchronization in which case the local callback would become
+ // non driving. To that end, the following checks are simply opt outs where we are unable to register the
+ // synchronization
+
+ JtaPlatform jtaPlatform = getTransactionEnvironment().getJtaPlatform();
+ if ( jtaPlatform == null ) {
+ // if no jta platform was registered we wont be able to register a jta synchronization
+ return;
+ }
+
+ // Can we resister a synchronization
+ if ( ! jtaPlatform.canRegisterSynchronization() ) {
+ log.trace( "registered JTA platform says we cannot currently resister synchronization; skipping" );
+ return;
+ }
+
+ // Should we resister a synchronization
+ if ( ! transactionFactory().isJoinableJtaTransaction( this, currentHibernateTransaction ) ) {
+ log.trace( "TransactionFactory reported no JTA transaction to join; skipping Synchronization registration" );
+ return;
+ }
+
+ jtaPlatform.registerSynchronization( new RegisteredSynchronization( getSynchronizationCallbackCoordinator() ) );
+ synchronizationRegistered = true;
+ log.debug( "successfully registered Synchronization" );
+ }
+
+ @Override
+ public SynchronizationCallbackCoordinator getSynchronizationCallbackCoordinator() {
+ if ( callbackCoordinator == null ) {
+ callbackCoordinator = new SynchronizationCallbackCoordinatorImpl( this );
+ }
+ return callbackCoordinator;
+ }
+
+ public void pulse() {
+ log.trace( "Starting transaction coordinator pulse" );
+ if ( transactionFactory().compatibleWithJtaSynchronization() ) {
+ // the configured transaction strategy says it supports callbacks via JTA synchronization, so attempt to
+ // register JTA synchronization if possible
+ attemptToRegisterJtaSync();
+ }
+ }
+
+ public Connection close() {
+ open = false;
+ reset();
+ observers.clear();
+ return jdbcCoordinator.close();
+ }
+
+ public SynchronizationRegistry getSynchronizationRegistry() {
+ return synchronizationRegistry;
+ }
+
+ public void addObserver(TransactionObserver observer) {
+ observers.add( observer );
+ }
+
+ @Override
+ @SuppressWarnings( {"unchecked"})
+ public boolean isTransactionJoinable() {
+ return transactionFactory().isJoinableJtaTransaction( this, currentHibernateTransaction );
+ }
+
+ @Override
+ @SuppressWarnings( {"unchecked"})
+ public boolean isTransactionJoined() {
+ return transactionFactory().getJoinStatus( this, currentHibernateTransaction ) == JoinStatus.JOINED;
+ }
+
+ public void setRollbackOnly() {
+ getTransaction().markRollbackOnly();
+ }
+
+ @Override
+ public boolean takeOwnership() {
+ if ( ownershipTaken ) {
+ return false;
+ }
+ else {
+ ownershipTaken = true;
+ return true;
+ }
+ }
+
+ @Override
+ public void sendAfterTransactionBeginNotifications(TransactionImplementor hibernateTransaction) {
+ for ( TransactionObserver observer : observers ) {
+ observer.afterBegin( currentHibernateTransaction );
+ }
+ }
+
+ @Override
+ public void sendBeforeTransactionCompletionNotifications(TransactionImplementor hibernateTransaction) {
+ synchronizationRegistry.notifySynchronizationsBeforeTransactionCompletion();
+ for ( TransactionObserver observer : observers ) {
+ observer.beforeCompletion( hibernateTransaction );
+ }
+ }
+
+ @Override
+ public void sendAfterTransactionCompletionNotifications(TransactionImplementor hibernateTransaction, int status) {
+ final boolean successful = JtaStatusHelper.isCommitted( status );
+ for ( TransactionObserver observer : observers ) {
+ observer.afterCompletion( successful, hibernateTransaction );
+ }
+ synchronizationRegistry.notifySynchronizationsAfterTransactionCompletion( status );
+ }
+
+
+ // serialization ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ public void serialize(ObjectOutputStream oos) throws IOException {
+ jdbcCoordinator.serialize( oos );
+ oos.writeInt( observers.size() );
+ for ( TransactionObserver observer : observers ) {
+ oos.writeObject( observer );
+ }
+ }
+
+ public static TransactionCoordinatorImpl deserialize(
+ ObjectInputStream ois,
+ TransactionContext transactionContext) throws ClassNotFoundException, IOException {
+ final JdbcCoordinatorImpl jdbcCoordinator = JdbcCoordinatorImpl.deserialize( ois, transactionContext );
+ final int observerCount = ois.readInt();
+ final List observers = CollectionHelper.arrayList( observerCount );
+ for ( int i = 0; i < observerCount; i++ ) {
+ observers.add( (TransactionObserver) ois.readObject() );
+ }
+ final TransactionCoordinatorImpl transactionCoordinator = new TransactionCoordinatorImpl( transactionContext, jdbcCoordinator, observers );
+ jdbcCoordinator.afterDeserialize( transactionCoordinator );
+ return transactionCoordinator;
+ }
+
+}
diff --git a/hibernate-core/src/main/java/org/hibernate/engine/transaction/internal/TransactionFactoryInitiator.java b/hibernate-core/src/main/java/org/hibernate/engine/transaction/internal/TransactionFactoryInitiator.java
new file mode 100644
index 0000000000..a72526ff98
--- /dev/null
+++ b/hibernate-core/src/main/java/org/hibernate/engine/transaction/internal/TransactionFactoryInitiator.java
@@ -0,0 +1,96 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2011, 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
+ */
+package org.hibernate.engine.transaction.internal;
+
+import java.util.Map;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.hibernate.HibernateException;
+import org.hibernate.cfg.Environment;
+import org.hibernate.engine.transaction.internal.jdbc.JdbcTransactionFactory;
+import org.hibernate.engine.transaction.internal.jta.CMTTransactionFactory;
+import org.hibernate.engine.transaction.internal.jta.JtaTransactionFactory;
+import org.hibernate.engine.transaction.spi.TransactionFactory;
+import org.hibernate.service.classloading.spi.ClassLoaderService;
+import org.hibernate.service.spi.ServiceInitiator;
+import org.hibernate.service.spi.ServiceRegistry;
+
+/**
+ * Standard instantiator for the standard {@link TransactionFactory} service.
+ *
+ * @author Steve Ebersole
+ */
+public class TransactionFactoryInitiator implements ServiceInitiator {
+ private static final Logger log = LoggerFactory.getLogger( TransactionFactoryInitiator.class );
+
+ public static final TransactionFactoryInitiator INSTANCE = new TransactionFactoryInitiator();
+
+ @Override
+ public Class getServiceInitiated() {
+ return TransactionFactory.class;
+ }
+
+ @Override
+ public TransactionFactory initiateService(Map configVales, ServiceRegistry registry) {
+ final Object strategy = configVales.get( Environment.TRANSACTION_STRATEGY );
+ if ( TransactionFactory.class.isInstance( strategy ) ) {
+ return (TransactionFactory) strategy;
+ }
+
+ if ( strategy == null ) {
+ log.info( "Using default transaction strategy (direct JDBC transactions)" );
+ return new JdbcTransactionFactory();
+ }
+
+ final String strategyClassName = mapLegacyNames( strategy.toString() );
+ log.info( "Transaction strategy: " + strategyClassName );
+
+ ClassLoaderService classLoaderService = registry.getService( ClassLoaderService.class );
+ try {
+ return (TransactionFactory) classLoaderService.classForName( strategyClassName ).newInstance();
+ }
+ catch ( Exception e ) {
+ throw new HibernateException( "Unable to instantiate specified TransactionFactory class [" + strategyClassName + "]", e );
+ }
+ }
+
+ private String mapLegacyNames(String name) {
+ if ( "org.hibernate.transaction.JDBCTransactionFactory".equals( name ) ) {
+ return JdbcTransactionFactory.class.getName();
+ }
+
+ if ( "org.hibernate.transaction.JTATransactionFactory".equals( name ) ) {
+ return JtaTransactionFactory.class.getName();
+ }
+
+ if ( "org.hibernate.transaction.CMTTransactionFactory".equals( name ) ) {
+ return CMTTransactionFactory.class.getName();
+ }
+
+ return name;
+ }
+}
+
diff --git a/hibernate-core/src/main/java/org/hibernate/engine/transaction/internal/jdbc/JdbcIsolationDelegate.java b/hibernate-core/src/main/java/org/hibernate/engine/transaction/internal/jdbc/JdbcIsolationDelegate.java
new file mode 100644
index 0000000000..01a4e611d2
--- /dev/null
+++ b/hibernate-core/src/main/java/org/hibernate/engine/transaction/internal/jdbc/JdbcIsolationDelegate.java
@@ -0,0 +1,123 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2011, 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
+ */
+package org.hibernate.engine.transaction.internal.jdbc;
+
+
+import java.sql.Connection;
+import java.sql.SQLException;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.hibernate.HibernateException;
+import org.hibernate.engine.jdbc.spi.SQLExceptionHelper;
+import org.hibernate.engine.transaction.spi.IsolationDelegate;
+import org.hibernate.engine.transaction.spi.TransactionCoordinator;
+import org.hibernate.jdbc.Work;
+import org.hibernate.service.jdbc.connections.spi.ConnectionProvider;
+
+/**
+ * The isolation delegate for JDBC {@link Connection} based transactions
+ *
+ * @author Steve Ebersole
+ */
+public class JdbcIsolationDelegate implements IsolationDelegate {
+ private static final Logger log = LoggerFactory.getLogger( JdbcIsolationDelegate.class );
+
+ private final TransactionCoordinator transactionCoordinator;
+
+ public JdbcIsolationDelegate(TransactionCoordinator transactionCoordinator) {
+ this.transactionCoordinator = transactionCoordinator;
+ }
+
+ protected ConnectionProvider connectionProvider() {
+ return transactionCoordinator.getJdbcCoordinator().getLogicalConnection().getJdbcServices().getConnectionProvider();
+ }
+
+ protected SQLExceptionHelper sqlExceptionHelper() {
+ return transactionCoordinator.getJdbcCoordinator().getLogicalConnection().getJdbcServices().getSqlExceptionHelper();
+ }
+
+ @Override
+ public void delegateWork(Work work, boolean transacted) throws HibernateException {
+ boolean wasAutoCommit = false;
+ try {
+ // todo : should we use a connection proxy here?
+ Connection connection = connectionProvider().getConnection();
+ try {
+ if ( transacted ) {
+ if ( connection.getAutoCommit() ) {
+ wasAutoCommit = true;
+ connection.setAutoCommit( false );
+ }
+ }
+
+ work.execute( connection );
+
+ if ( transacted ) {
+ connection.commit();
+ }
+ }
+ catch ( Exception e ) {
+ try {
+ if ( transacted && !connection.isClosed() ) {
+ connection.rollback();
+ }
+ }
+ catch ( Exception ignore ) {
+ log.info( "unable to rollback connection on exception [" + ignore + "]" );
+ }
+
+ if ( e instanceof HibernateException ) {
+ throw (HibernateException) e;
+ }
+ else if ( e instanceof SQLException ) {
+ throw sqlExceptionHelper().convert( (SQLException) e, "error performing isolated work" );
+ }
+ else {
+ throw new HibernateException( "error performing isolated work", e );
+ }
+ }
+ finally {
+ if ( transacted && wasAutoCommit ) {
+ try {
+ connection.setAutoCommit( true );
+ }
+ catch ( Exception ignore ) {
+ log.trace( "was unable to reset connection back to auto-commit" );
+ }
+ }
+ try {
+ connectionProvider().closeConnection( connection );
+ }
+ catch ( Exception ignore ) {
+ log.info( "Unable to release isolated connection [" + ignore + "]" );
+ }
+ }
+ }
+ catch ( SQLException sqle ) {
+ throw sqlExceptionHelper().convert( sqle, "unable to obtain isolated JDBC connection" );
+ }
+ }
+}
diff --git a/hibernate-core/src/main/java/org/hibernate/engine/transaction/internal/jdbc/JdbcTransaction.java b/hibernate-core/src/main/java/org/hibernate/engine/transaction/internal/jdbc/JdbcTransaction.java
new file mode 100644
index 0000000000..9896ffe917
--- /dev/null
+++ b/hibernate-core/src/main/java/org/hibernate/engine/transaction/internal/jdbc/JdbcTransaction.java
@@ -0,0 +1,208 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2007-2011, 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
+ */
+package org.hibernate.engine.transaction.internal.jdbc;
+
+import org.hibernate.HibernateException;
+import org.hibernate.TransactionException;
+import org.hibernate.engine.transaction.spi.AbstractTransactionImpl;
+import org.hibernate.engine.transaction.spi.IsolationDelegate;
+import org.hibernate.engine.transaction.spi.JoinStatus;
+import org.hibernate.engine.transaction.spi.LocalStatus;
+import org.hibernate.engine.transaction.spi.TransactionCoordinator;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+
+/**
+ * {@link org.hibernate.Transaction} implementation based on transaction management through a JDBC {@link java.sql.Connection}.
+ *
+ * This the default transaction strategy.
+ *
+ * @author Anton van Straaten
+ * @author Gavin King
+ * @author Steve Ebersole
+ */
+public class JdbcTransaction extends AbstractTransactionImpl {
+ private static final Logger log = LoggerFactory.getLogger( JdbcTransaction.class );
+
+ private Connection managedConnection;
+ private boolean wasInitiallyAutoCommit;
+ private boolean isDriver;
+
+ protected JdbcTransaction(TransactionCoordinator transactionCoordinator) {
+ super( transactionCoordinator );
+ }
+
+ @Override
+ protected void doBegin() {
+ try {
+ if ( managedConnection != null ) {
+ throw new TransactionException( "Already have an associated managed connection" );
+ }
+ managedConnection = transactionCoordinator().getJdbcCoordinator().getLogicalConnection().getConnection();
+ wasInitiallyAutoCommit = managedConnection.getAutoCommit();
+ if ( log.isDebugEnabled() ) {
+ log.debug( "initial autocommit status: " + wasInitiallyAutoCommit );
+ }
+ if ( wasInitiallyAutoCommit ) {
+ log.debug( "disabling autocommit" );
+ managedConnection.setAutoCommit( false );
+ }
+ }
+ catch( SQLException e ) {
+ throw new TransactionException( "JDBC begin transaction failed: ", e );
+ }
+
+ isDriver = transactionCoordinator().takeOwnership();
+ }
+
+ @Override
+ protected void afterTransactionBegin() {
+ if ( getTimeout() > 0 ) {
+ transactionCoordinator().getJdbcCoordinator().setTransactionTimeOut( getTimeout() );
+ }
+ transactionCoordinator().sendAfterTransactionBeginNotifications( this );
+ if ( isDriver ) {
+ transactionCoordinator().getTransactionContext().afterTransactionBegin( this );
+ }
+ }
+
+ @Override
+ protected void beforeTransactionCommit() {
+ transactionCoordinator().sendBeforeTransactionCompletionNotifications( this );
+
+ // basically, if we are the driver of the transaction perform a managed flush prior to
+ // physically committing the transaction
+ if ( isDriver && !transactionCoordinator().getTransactionContext().isFlushModeNever() ) {
+ // if an exception occurs during flush, user must call rollback()
+ transactionCoordinator().getTransactionContext().managedFlush();
+ }
+
+ if ( isDriver ) {
+ transactionCoordinator().getTransactionContext().beforeTransactionCompletion( this );
+ }
+ }
+
+ @Override
+ protected void doCommit() throws TransactionException {
+ try {
+ managedConnection.commit();
+ log.debug( "committed JDBC Connection" );
+ }
+ catch( SQLException e ) {
+ throw new TransactionException( "unable to commit against JDBC connection", e );
+ }
+ finally {
+ releaseManagedConnection();
+ }
+ }
+
+ private void releaseManagedConnection() {
+ try {
+ if ( wasInitiallyAutoCommit ) {
+ log.debug( "re-enabling autocommit" );
+ managedConnection.setAutoCommit( true );
+ }
+ managedConnection = null;
+ }
+ catch ( Exception e ) {
+ log.debug( "Could not toggle autocommit", e );
+ }
+ }
+
+ @Override
+ protected void afterTransactionCompletion(int status) {
+ transactionCoordinator().afterTransaction( this, status );
+ }
+
+ @Override
+ protected void afterAfterCompletion() {
+ if ( isDriver
+ && transactionCoordinator().getTransactionContext().shouldAutoClose()
+ && !transactionCoordinator().getTransactionContext().isClosed() ) {
+ try {
+ transactionCoordinator().getTransactionContext().managedClose();
+ }
+ catch (HibernateException e) {
+ log.info( "Could not close session; swallowing exception as transaction completed", e );
+ }
+ }
+ }
+
+ @Override
+ protected void beforeTransactionRollBack() {
+ // nothing to do here
+ }
+
+ @Override
+ protected void doRollback() throws TransactionException {
+ try {
+ managedConnection.rollback();
+ log.debug( "rolled JDBC Connection" );
+ }
+ catch( SQLException e ) {
+ throw new TransactionException( "unable to rollback against JDBC connection", e );
+ }
+ finally {
+ releaseManagedConnection();
+ }
+ }
+
+ @Override
+ public boolean isInitiator() {
+ return isActive();
+ }
+
+ @Override
+ public IsolationDelegate createIsolationDelegate() {
+ return new JdbcIsolationDelegate( transactionCoordinator() );
+ }
+
+ @Override
+ public JoinStatus getJoinStatus() {
+ return isActive() ? JoinStatus.JOINED : JoinStatus.NOT_JOINED;
+ }
+
+ @Override
+ public void markRollbackOnly() {
+ // nothing to do here
+ }
+
+ @Override
+ public void join() {
+ // nothing to do
+ }
+
+ @Override
+ public void resetJoinStatus() {
+ // nothing to do
+ }
+
+ @Override
+ public boolean isActive() throws HibernateException {
+ return getLocalStatus() == LocalStatus.ACTIVE;
+ }
+}
\ No newline at end of file
diff --git a/hibernate-core/src/main/java/org/hibernate/engine/transaction/internal/jdbc/JdbcTransactionFactory.java b/hibernate-core/src/main/java/org/hibernate/engine/transaction/internal/jdbc/JdbcTransactionFactory.java
new file mode 100644
index 0000000000..494d886dcf
--- /dev/null
+++ b/hibernate-core/src/main/java/org/hibernate/engine/transaction/internal/jdbc/JdbcTransactionFactory.java
@@ -0,0 +1,71 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2007-2011, 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
+ */
+package org.hibernate.engine.transaction.internal.jdbc;
+
+import org.hibernate.ConnectionReleaseMode;
+import org.hibernate.engine.transaction.spi.JoinStatus;
+import org.hibernate.engine.transaction.spi.TransactionCoordinator;
+import org.hibernate.engine.transaction.spi.TransactionFactory;
+
+/**
+ * Factory for {@link org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction} instances.
+ *
+ * @author Anton van Straaten
+ * @author Steve Ebersole
+ */
+public final class JdbcTransactionFactory implements TransactionFactory {
+ @Override
+ public JdbcTransaction createTransaction(TransactionCoordinator transactionCoordinator) {
+ return new JdbcTransaction( transactionCoordinator );
+ }
+
+ @Override
+ public boolean canBeDriver() {
+ return true;
+ }
+
+ @Override
+ public ConnectionReleaseMode getDefaultReleaseMode() {
+ return ConnectionReleaseMode.ON_CLOSE;
+ }
+
+ @Override
+ public boolean compatibleWithJtaSynchronization() {
+ return false;
+ }
+
+
+
+
+
+ @Override
+ public boolean isJoinableJtaTransaction(TransactionCoordinator transactionCoordinator, JdbcTransaction transaction) {
+ return false;
+ }
+
+ @Override
+ public JoinStatus getJoinStatus(TransactionCoordinator transactionCoordinator, JdbcTransaction transaction) {
+ return transaction.getJoinStatus();
+ }
+}
\ No newline at end of file
diff --git a/hibernate-core/src/main/java/org/hibernate/engine/transaction/internal/jta/CMTTransaction.java b/hibernate-core/src/main/java/org/hibernate/engine/transaction/internal/jta/CMTTransaction.java
new file mode 100644
index 0000000000..1600f20930
--- /dev/null
+++ b/hibernate-core/src/main/java/org/hibernate/engine/transaction/internal/jta/CMTTransaction.java
@@ -0,0 +1,154 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2007-2011, 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
+ */
+package org.hibernate.engine.transaction.internal.jta;
+
+import org.hibernate.TransactionException;
+import org.hibernate.engine.transaction.spi.AbstractTransactionImpl;
+import org.hibernate.engine.transaction.spi.IsolationDelegate;
+import org.hibernate.engine.transaction.spi.JoinStatus;
+import org.hibernate.engine.transaction.spi.TransactionCoordinator;
+
+import javax.transaction.SystemException;
+import javax.transaction.TransactionManager;
+
+/**
+ * Implements a transaction strategy for Container Managed Transaction (CMT) scenarios. All work is done in
+ * the context of the container managed transaction.
+ *
+ * The term 'CMT' is potentially misleading; the pertinent point simply being that the transactions are being
+ * managed by something other than the Hibernate transaction mechanism.
+ *
+ * Additionally, this strategy does *not* attempt to access or use the {@link javax.transaction.UserTransaction} since
+ * in the actual case CMT access to the {@link javax.transaction.UserTransaction} is explicitly disallowed. Instead
+ * we use the JTA {@link javax.transaction.Transaction} object obtained from the {@link TransactionManager}
+ *
+ * @author Gavin King
+ * @author Steve Ebersole
+ */
+public class CMTTransaction extends AbstractTransactionImpl {
+ protected CMTTransaction(TransactionCoordinator transactionCoordinator) {
+ super( transactionCoordinator );
+ }
+
+ protected TransactionManager transactionManager() {
+ return jtaPlatform().retrieveTransactionManager();
+ }
+
+ private TransactionManager getTransactionManager() {
+ return transactionManager();
+ }
+
+ @Override
+ protected void doBegin() {
+ transactionCoordinator().pulse();
+ }
+
+ @Override
+ protected void afterTransactionBegin() {
+ if ( ! transactionCoordinator().isSynchronizationRegistered() ) {
+ throw new TransactionException("Could not register synchronization for container transaction");
+ }
+ transactionCoordinator().sendAfterTransactionBeginNotifications( this );
+ transactionCoordinator().getTransactionContext().afterTransactionBegin( this );
+ }
+
+ @Override
+ protected void beforeTransactionCommit() {
+ boolean flush = ! transactionCoordinator().getTransactionContext().isFlushModeNever() &&
+ ! transactionCoordinator().getTransactionContext().isFlushBeforeCompletionEnabled();
+ if ( flush ) {
+ // if an exception occurs during flush, user must call rollback()
+ transactionCoordinator().getTransactionContext().managedFlush();
+ }
+ }
+
+ @Override
+ protected void doCommit() {
+ // nothing to do
+ }
+
+ @Override
+ protected void beforeTransactionRollBack() {
+ // nothing to do
+ }
+
+ @Override
+ protected void doRollback() {
+ markRollbackOnly();
+ }
+
+ @Override
+ protected void afterTransactionCompletion(int status) {
+ // nothing to do
+ }
+
+ @Override
+ protected void afterAfterCompletion() {
+ // nothing to do
+ }
+
+ @Override
+ public boolean isActive() throws TransactionException {
+ return JtaStatusHelper.isActive( getTransactionManager() );
+ }
+
+ @Override
+ public IsolationDelegate createIsolationDelegate() {
+ return new JtaIsolationDelegate( transactionCoordinator() );
+ }
+
+ @Override
+ public boolean isInitiator() {
+ return false; // cannot be
+ }
+
+ @Override
+ public void markRollbackOnly() {
+ try {
+ getTransactionManager().setRollbackOnly();
+ }
+ catch ( SystemException se ) {
+ throw new TransactionException("Could not set transaction to rollback only", se);
+ }
+ }
+
+ @Override
+ public void join() {
+ // todo : implement method body
+ }
+
+ @Override
+ public void resetJoinStatus() {
+ // todo : implement method body
+ }
+
+ boolean isJoinable() {
+ return JtaStatusHelper.isActive( transactionManager() );
+ }
+
+ @Override
+ public JoinStatus getJoinStatus() {
+ return isJoinable() ? JoinStatus.JOINED : JoinStatus.NOT_JOINED;
+ }
+}
diff --git a/hibernate-core/src/main/java/org/hibernate/transaction/CMTTransactionFactory.java b/hibernate-core/src/main/java/org/hibernate/engine/transaction/internal/jta/CMTTransactionFactory.java
old mode 100755
new mode 100644
similarity index 50%
rename from hibernate-core/src/main/java/org/hibernate/transaction/CMTTransactionFactory.java
rename to hibernate-core/src/main/java/org/hibernate/engine/transaction/internal/jta/CMTTransactionFactory.java
index fac6e191d1..42a79256ce
--- a/hibernate-core/src/main/java/org/hibernate/transaction/CMTTransactionFactory.java
+++ b/hibernate-core/src/main/java/org/hibernate/engine/transaction/internal/jta/CMTTransactionFactory.java
@@ -1,10 +1,10 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
- * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * Copyright (c) 2007-2011, 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 Middleware LLC.
+ * 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
@@ -20,60 +20,64 @@
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
- *
*/
-package org.hibernate.transaction;
-
-import java.util.Properties;
+package org.hibernate.engine.transaction.internal.jta;
import org.hibernate.ConnectionReleaseMode;
-import org.hibernate.HibernateException;
-import org.hibernate.Transaction;
import org.hibernate.TransactionException;
-import org.hibernate.engine.jdbc.spi.JDBCContext;
-import org.hibernate.util.JTAHelper;
+import org.hibernate.engine.transaction.spi.JoinStatus;
+import org.hibernate.engine.transaction.spi.TransactionCoordinator;
+import org.hibernate.engine.transaction.spi.TransactionFactory;
import javax.transaction.SystemException;
/**
- * Factory for {@link CMTTransaction} instances.
+ * Factory for Container Managed Transaction (CMT) based transaction facades.
*
+ * @author Steve Ebersole
* @author Gavin King
*/
-public class CMTTransactionFactory implements TransactionFactory {
+public class CMTTransactionFactory implements TransactionFactory {
+ @Override
+ public CMTTransaction createTransaction(TransactionCoordinator transactionCoordinator) {
+ return new CMTTransaction( transactionCoordinator );
+ }
+ @Override
+ public boolean canBeDriver() {
+ return false;
+ }
+
+ @Override
public ConnectionReleaseMode getDefaultReleaseMode() {
return ConnectionReleaseMode.AFTER_STATEMENT;
}
- public void configure(Properties props) throws HibernateException {}
-
- public Transaction createTransaction(JDBCContext jdbcContext, Context transactionContext)
- throws HibernateException {
- return new CMTTransaction(jdbcContext, transactionContext);
- }
-
- public boolean isTransactionManagerRequired() {
+ @Override
+ public boolean compatibleWithJtaSynchronization() {
return true;
}
- public boolean areCallbacksLocalToHibernateTransactions() {
- return false;
- }
-
- public boolean isTransactionInProgress(
- JDBCContext jdbcContext,
- Context transactionContext,
- Transaction transaction) {
+ @Override
+ public boolean isJoinableJtaTransaction(TransactionCoordinator transactionCoordinator, CMTTransaction transaction) {
try {
- return JTAHelper.isTransactionInProgress(
- transactionContext.getFactory().getTransactionManager().getTransaction()
- );
+ final int status = transactionCoordinator
+ .getTransactionContext()
+ .getTransactionEnvironment()
+ .getJtaPlatform()
+ .retrieveTransactionManager()
+ .getStatus();
+ return JtaStatusHelper.isActive( status );
}
catch( SystemException se ) {
throw new TransactionException( "Unable to check transaction status", se );
}
+ }
+
+ @Override
+ public JoinStatus getJoinStatus(TransactionCoordinator transactionCoordinator, CMTTransaction transaction) {
+ return null; // todo : implement method body
}
}
diff --git a/hibernate-core/src/main/java/org/hibernate/engine/transaction/internal/jta/JtaIsolationDelegate.java b/hibernate-core/src/main/java/org/hibernate/engine/transaction/internal/jta/JtaIsolationDelegate.java
new file mode 100644
index 0000000000..7e071428fe
--- /dev/null
+++ b/hibernate-core/src/main/java/org/hibernate/engine/transaction/internal/jta/JtaIsolationDelegate.java
@@ -0,0 +1,185 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2011, 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
+ */
+package org.hibernate.engine.transaction.internal.jta;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+import javax.transaction.NotSupportedException;
+import javax.transaction.SystemException;
+import javax.transaction.Transaction;
+import javax.transaction.TransactionManager;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.hibernate.HibernateException;
+import org.hibernate.engine.jdbc.spi.SQLExceptionHelper;
+import org.hibernate.engine.transaction.spi.IsolationDelegate;
+import org.hibernate.engine.transaction.spi.TransactionCoordinator;
+import org.hibernate.jdbc.Work;
+import org.hibernate.service.jdbc.connections.spi.ConnectionProvider;
+
+/**
+ * An isolation delegate for JTA environments.
+ *
+ * @author Steve Ebersole
+ */
+public class JtaIsolationDelegate implements IsolationDelegate {
+ private static final Logger log = LoggerFactory.getLogger( JtaIsolationDelegate.class );
+
+ private final TransactionCoordinator transactionCoordinator;
+
+ public JtaIsolationDelegate(TransactionCoordinator transactionCoordinator) {
+ this.transactionCoordinator = transactionCoordinator;
+ }
+
+ protected TransactionManager transactionManager() {
+ return transactionCoordinator.getTransactionContext()
+ .getTransactionEnvironment()
+ .getJtaPlatform()
+ .retrieveTransactionManager();
+ }
+
+ protected ConnectionProvider connectionProvider() {
+ return transactionCoordinator.getTransactionContext()
+ .getTransactionEnvironment()
+ .getJdbcServices()
+ .getConnectionProvider();
+ }
+
+ protected SQLExceptionHelper sqlExceptionHelper() {
+ return transactionCoordinator.getTransactionContext()
+ .getTransactionEnvironment()
+ .getJdbcServices()
+ .getSqlExceptionHelper();
+ }
+
+ @Override
+ public void delegateWork(Work work, boolean transacted) throws HibernateException {
+ TransactionManager transactionManager = transactionManager();
+
+ try {
+ // First we suspend any current JTA transaction
+ Transaction surroundingTransaction = transactionManager.suspend();
+ if ( log.isDebugEnabled() ) {
+ log.debug( "surrounding JTA transaction suspended [" + surroundingTransaction + "]" );
+ }
+
+ boolean hadProblems = false;
+ try {
+ // then perform the requested work
+ if ( transacted ) {
+ doTheWorkInNewTransaction( work, transactionManager );
+ }
+ else {
+ doTheWorkInNoTransaction( work );
+ }
+ }
+ catch ( HibernateException e ) {
+ hadProblems = true;
+ throw e;
+ }
+ finally {
+ try {
+ transactionManager.resume( surroundingTransaction );
+ if ( log.isDebugEnabled() ) {
+ log.debug( "surrounding JTA transaction resumed [" + surroundingTransaction + "]" );
+ }
+ }
+ catch( Throwable t ) {
+ // if the actually work had an error use that, otherwise error based on t
+ if ( !hadProblems ) {
+ //noinspection ThrowFromFinallyBlock
+ throw new HibernateException( "Unable to resume previously suspended transaction", t );
+ }
+ }
+ }
+ }
+ catch ( SystemException e ) {
+ throw new HibernateException( "Unable to suspend current JTA transaction", e );
+ }
+ }
+
+ private void doTheWorkInNewTransaction(Work work, TransactionManager transactionManager) {
+ try {
+ // start the new isolated transaction
+ transactionManager.begin();
+
+ try {
+ doTheWork( work );
+ // if everythign went ok, commit the isolated transaction
+ transactionManager.commit();
+ }
+ catch ( Exception e ) {
+ try {
+ transactionManager.rollback();
+ }
+ catch ( Exception ignore ) {
+ log.info( "Unable to rollback isolated transaction on error [" + e + "] : [" + ignore + "]" );
+ }
+ }
+ }
+ catch ( SystemException e ) {
+ throw new HibernateException( "Unable to start isolated transaction", e );
+ }
+ catch ( NotSupportedException e ) {
+ throw new HibernateException( "Unable to start isolated transaction", e );
+ }
+ }
+
+ private void doTheWorkInNoTransaction(Work work) {
+ doTheWork( work );
+ }
+
+ private void doTheWork(Work work) {
+ try {
+ // obtain our isolated connection
+ Connection connection = connectionProvider().getConnection();
+ try {
+ // do the actual work
+ work.execute( connection );
+ }
+ catch ( HibernateException e ) {
+ throw e;
+ }
+ catch ( Exception e ) {
+ throw new HibernateException( "Unable to perform isolated work", e );
+ }
+ finally {
+ try {
+ // no matter what, release the connection (handle)
+ connectionProvider().closeConnection( connection );
+ }
+ catch ( Throwable ignore ) {
+ log.info( "Unable to release isolated connection [" + ignore + "]" );
+ }
+ }
+ }
+ catch ( SQLException sqle ) {
+ throw sqlExceptionHelper().convert( sqle, "unable to obtain isolated JDBC connection" );
+ }
+ }
+
+}
+
diff --git a/hibernate-core/src/main/java/org/hibernate/internal/util/jta/JtaStatusHelper.java b/hibernate-core/src/main/java/org/hibernate/engine/transaction/internal/jta/JtaStatusHelper.java
similarity index 89%
rename from hibernate-core/src/main/java/org/hibernate/internal/util/jta/JtaStatusHelper.java
rename to hibernate-core/src/main/java/org/hibernate/engine/transaction/internal/jta/JtaStatusHelper.java
index d9c2c05e45..639dea75c7 100644
--- a/hibernate-core/src/main/java/org/hibernate/internal/util/jta/JtaStatusHelper.java
+++ b/hibernate-core/src/main/java/org/hibernate/engine/transaction/internal/jta/JtaStatusHelper.java
@@ -1,7 +1,7 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
- * Copyright (c) 2010, Red Hat Inc. or third-party contributors as
+ * Copyright (c) 2011, 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.
@@ -21,7 +21,7 @@
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
-package org.hibernate.internal.util.jta;
+package org.hibernate.engine.transaction.internal.jta;
import javax.transaction.Status;
import javax.transaction.SystemException;
@@ -31,7 +31,7 @@ import javax.transaction.UserTransaction;
import org.hibernate.TransactionException;
/**
- * Utility for dealing with JTA statses.
+ * Utility for dealing with JTA statuses.
*
* @author Steve Ebersole
*/
@@ -49,7 +49,7 @@ public class JtaStatusHelper {
try {
final int status = userTransaction.getStatus();
if ( status == Status.STATUS_UNKNOWN ) {
- throw new TransactionException( "UserTransaction reported transaction status as unknwon" );
+ throw new TransactionException( "UserTransaction reported transaction status as unknown" );
}
return status;
}
@@ -97,7 +97,7 @@ public class JtaStatusHelper {
*
* @param userTransaction The {@link UserTransaction} whose status is to be checked
*
- * @return True if the transactiion is active; false otherwise.
+ * @return True if the transaction is active; false otherwise.
*/
public static boolean isActive(UserTransaction userTransaction) {
final int status = getStatus( userTransaction );
@@ -109,7 +109,7 @@ public class JtaStatusHelper {
*
* @param transactionManager The {@link TransactionManager} whose status is to be checked
*
- * @return True if the transactiion is active; false otherwise.
+ * @return True if the transaction is active; false otherwise.
*/
public static boolean isActive(TransactionManager transactionManager) {
return isActive( getStatus( transactionManager ) );
@@ -133,7 +133,7 @@ public class JtaStatusHelper {
*
* @param userTransaction The {@link UserTransaction} whose status is to be checked
*
- * @return True if the transactiion indicates roll back; false otherwise.
+ * @return True if the transaction indicates roll back; false otherwise.
*/
public static boolean isRollback(UserTransaction userTransaction) {
return isRollback( getStatus( userTransaction ) );
@@ -144,7 +144,7 @@ public class JtaStatusHelper {
*
* @param transactionManager The {@link TransactionManager} whose status is to be checked
*
- * @return True if the transactiion indicates roll back; false otherwise.
+ * @return True if the transaction indicates roll back; false otherwise.
*/
public static boolean isRollback(TransactionManager transactionManager) {
return isRollback( getStatus( transactionManager ) );
@@ -158,9 +158,7 @@ public class JtaStatusHelper {
* @return True if the code indicates a roll back; false otherwise.
*/
public static boolean isCommitted(int status) {
- return status == Status.STATUS_MARKED_ROLLBACK ||
- status == Status.STATUS_ROLLING_BACK ||
- status == Status.STATUS_ROLLEDBACK;
+ return status == Status.STATUS_COMMITTED;
}
/**
@@ -168,7 +166,7 @@ public class JtaStatusHelper {
*
* @param userTransaction The {@link UserTransaction} whose status is to be checked
*
- * @return True if the transactiion indicates commit; false otherwise.
+ * @return True if the transaction indicates commit; false otherwise.
*/
public static boolean isCommitted(UserTransaction userTransaction) {
return isCommitted( getStatus( userTransaction ) );
@@ -179,7 +177,7 @@ public class JtaStatusHelper {
*
* @param transactionManager The {@link TransactionManager} whose status is to be checked
*
- * @return True if the transactiion indicates commit; false otherwise.
+ * @return True if the transaction indicates commit; false otherwise.
*/
public static boolean isCommitted(TransactionManager transactionManager) {
return isCommitted( getStatus( transactionManager ) );
@@ -192,6 +190,7 @@ public class JtaStatusHelper {
*
* @return True if the code indicates a roll back; false otherwise.
*/
+ @SuppressWarnings( {"UnusedDeclaration"})
public static boolean isMarkedForRollback(int status) {
return status == Status.STATUS_MARKED_ROLLBACK;
}
diff --git a/hibernate-core/src/main/java/org/hibernate/engine/transaction/internal/jta/JtaTransaction.java b/hibernate-core/src/main/java/org/hibernate/engine/transaction/internal/jta/JtaTransaction.java
new file mode 100644
index 0000000000..1c06032bf5
--- /dev/null
+++ b/hibernate-core/src/main/java/org/hibernate/engine/transaction/internal/jta/JtaTransaction.java
@@ -0,0 +1,276 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2007-2011, 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
+ */
+package org.hibernate.engine.transaction.internal.jta;
+
+import org.hibernate.HibernateException;
+import org.hibernate.TransactionException;
+import org.hibernate.engine.transaction.spi.AbstractTransactionImpl;
+import org.hibernate.engine.transaction.spi.IsolationDelegate;
+import org.hibernate.engine.transaction.spi.JoinStatus;
+import org.hibernate.engine.transaction.spi.LocalStatus;
+import org.hibernate.engine.transaction.spi.TransactionCoordinator;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.transaction.Status;
+import javax.transaction.SystemException;
+import javax.transaction.TransactionManager;
+import javax.transaction.UserTransaction;
+
+/**
+ * Implements a transaction strategy based on transaction management through a JTA {@link UserTransaction}.
+ *
+ * @author Gavin King
+ * @author Steve Ebersole
+ * @author Les Hazlewood
+ */
+public class JtaTransaction extends AbstractTransactionImpl {
+ private static final Logger log = LoggerFactory.getLogger( JtaTransaction.class );
+
+ private UserTransaction userTransaction;
+
+ private boolean isInitiator;
+ private boolean isDriver;
+
+ protected JtaTransaction(TransactionCoordinator transactionCoordinator) {
+ super( transactionCoordinator );
+ }
+
+ @SuppressWarnings( {"UnusedDeclaration"})
+ public UserTransaction getUserTransaction() {
+ return userTransaction;
+ }
+
+ @Override
+ protected void doBegin() {
+ log.debug( "begin" );
+
+ userTransaction = jtaPlatform().retrieveUserTransaction();
+ if ( userTransaction == null ) {
+ throw new TransactionException( "Unable to locate JTA UserTransaction" );
+ }
+
+ try {
+ if ( userTransaction.getStatus() == Status.STATUS_NO_TRANSACTION ) {
+ userTransaction.begin();
+ isInitiator = true;
+ log.debug( "Began a new JTA transaction" );
+ }
+ }
+ catch ( Exception e ) {
+ throw new TransactionException( "JTA transaction begin failed", e );
+ }
+
+ }
+
+ @Override
+ protected void afterTransactionBegin() {
+ transactionCoordinator().pulse();
+
+ if ( !transactionCoordinator().isSynchronizationRegistered() ) {
+ isDriver = transactionCoordinator().takeOwnership();
+ }
+
+ applyTimeout();
+ transactionCoordinator().sendAfterTransactionBeginNotifications( this );
+ transactionCoordinator().getTransactionContext().afterTransactionBegin( this );
+ }
+
+ private void applyTimeout() {
+ if ( getTimeout() > 0 ) {
+ if ( userTransaction != null ) {
+ try {
+ userTransaction.setTransactionTimeout( getTimeout() );
+ }
+ catch ( SystemException e ) {
+ throw new TransactionException( "Unable to apply requested transaction timeout", e );
+ }
+ }
+ else {
+ log.debug( "Unable to apply requested transaction timeout; no UserTransaction. Will try later" );
+ }
+ }
+ }
+
+ @Override
+ protected void beforeTransactionCommit() {
+ transactionCoordinator().sendBeforeTransactionCompletionNotifications( this );
+
+ final boolean flush = ! transactionCoordinator().getTransactionContext().isFlushModeNever() &&
+ ( isDriver || ! transactionCoordinator().getTransactionContext().isFlushBeforeCompletionEnabled() );
+
+ if ( flush ) {
+ // if an exception occurs during flush, user must call rollback()
+ transactionCoordinator().getTransactionContext().managedFlush();
+ }
+
+ if ( isDriver && isInitiator ) {
+ transactionCoordinator().getTransactionContext().beforeTransactionCompletion( this );
+ }
+
+ closeIfRequired();
+ }
+
+ private void closeIfRequired() throws HibernateException {
+ final boolean close = isDriver &&
+ transactionCoordinator().getTransactionContext().shouldAutoClose() &&
+ ! transactionCoordinator().getTransactionContext().isClosed();
+ if ( close ) {
+ transactionCoordinator().getTransactionContext().managedClose();
+ }
+ }
+
+ @Override
+ protected void doCommit() {
+ try {
+ if ( isInitiator ) {
+ userTransaction.commit();
+ log.debug( "Committed JTA UserTransaction" );
+ }
+ }
+ catch ( Exception e ) {
+ throw new TransactionException( "JTA commit failed: ", e );
+ }
+ finally {
+ isInitiator = false;
+ }
+ }
+
+ @Override
+ protected void afterTransactionCompletion(int status) {
+ // nothing to do
+ }
+
+ @Override
+ protected void afterAfterCompletion() {
+ // this method is a noop if there is a Synchronization!
+ if ( isDriver ) {
+ if ( !isInitiator ) {
+ log.warn( "You should set hibernate.transaction.manager_lookup_class if cache is enabled" );
+ }
+ try {
+ transactionCoordinator().afterTransaction( this, userTransaction.getStatus() );
+ }
+ catch (SystemException e) {
+ throw new TransactionException( "Unable to determine UserTransaction status", e );
+ }
+ }
+ }
+
+ @Override
+ protected void beforeTransactionRollBack() {
+ // nothing to do
+ }
+
+ @Override
+ protected void doRollback() {
+ try {
+ if ( isInitiator ) {
+ // failed commits automatically rollback the transaction per JTA spec
+ if ( getLocalStatus() != LocalStatus.FAILED_COMMIT ) {
+ userTransaction.rollback();
+ log.debug( "Rolled back JTA UserTransaction" );
+ }
+ }
+ else {
+ markRollbackOnly();
+ }
+ }
+ catch ( Exception e ) {
+ throw new TransactionException( "JTA rollback failed", e );
+ }
+ }
+
+ @Override
+ public void markRollbackOnly() {
+ log.trace( "Marking transaction for rollback only" );
+ try {
+ userTransaction.setRollbackOnly();
+ log.debug( "set JTA UserTransaction to rollback only" );
+ }
+ catch (SystemException e) {
+ log.debug( "Unable to mark transaction for rollback only", e );
+ }
+ }
+
+ @Override
+ public IsolationDelegate createIsolationDelegate() {
+ return new JtaIsolationDelegate( transactionCoordinator() );
+ }
+
+ @Override
+ public boolean isInitiator() {
+ return isInitiator;
+ }
+
+ @Override
+ public boolean isActive() throws HibernateException {
+ if ( getLocalStatus() != LocalStatus.ACTIVE ) {
+ return false;
+ }
+
+ final int status;
+ try {
+ status = userTransaction.getStatus();
+ }
+ catch ( SystemException se ) {
+ throw new TransactionException( "Could not determine transaction status: ", se );
+ }
+ return JtaStatusHelper.isActive( status );
+ }
+
+ @Override
+ public void setTimeout(int seconds) {
+ super.setTimeout( seconds );
+ applyTimeout();
+ }
+
+ @Override
+ public void join() {
+ }
+
+ @Override
+ public void resetJoinStatus() {
+ }
+
+ @Override
+ public JoinStatus getJoinStatus() {
+ // if we already have the UserTransaction cached locally, use it to avoid JNDI look ups
+ if ( this.userTransaction != null ) {
+ return JtaStatusHelper.isActive( this.userTransaction ) ? JoinStatus.JOINED : JoinStatus.NOT_JOINED;
+ }
+
+ // Otherwise, try to use the TransactionManager since it is generally cached
+ TransactionManager transactionManager = jtaPlatform().retrieveTransactionManager();
+ if ( transactionManager != null ) {
+ return JtaStatusHelper.isActive( transactionManager ) ? JoinStatus.JOINED : JoinStatus.NOT_JOINED;
+ }
+
+ // Finally, look up the UserTransaction
+ UserTransaction userTransaction = jtaPlatform().retrieveUserTransaction();
+ return userTransaction != null && JtaStatusHelper.isActive( userTransaction )
+ ? JoinStatus.JOINED
+ : JoinStatus.NOT_JOINED;
+ }
+}
diff --git a/hibernate-core/src/main/java/org/hibernate/engine/transaction/internal/jta/JtaTransactionFactory.java b/hibernate-core/src/main/java/org/hibernate/engine/transaction/internal/jta/JtaTransactionFactory.java
new file mode 100644
index 0000000000..3c258bdcbd
--- /dev/null
+++ b/hibernate-core/src/main/java/org/hibernate/engine/transaction/internal/jta/JtaTransactionFactory.java
@@ -0,0 +1,109 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2007-2011, 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
+ */
+package org.hibernate.engine.transaction.internal.jta;
+
+import org.hibernate.ConnectionReleaseMode;
+import org.hibernate.TransactionException;
+import org.hibernate.engine.transaction.spi.JoinStatus;
+import org.hibernate.engine.transaction.spi.TransactionCoordinator;
+import org.hibernate.engine.transaction.spi.TransactionFactory;
+import org.hibernate.service.jta.platform.spi.JtaPlatform;
+import org.hibernate.util.JTAHelper;
+
+import javax.transaction.SystemException;
+import javax.transaction.UserTransaction;
+
+/**
+ * Factory for {@link JtaTransaction} instances.
+ *
+ * @author Gavin King
+ * @author Steve Ebersole
+ * @author Les Hazlewood
+ */
+public class JtaTransactionFactory implements TransactionFactory {
+ @Override
+ public JtaTransaction createTransaction(TransactionCoordinator transactionCoordinator) {
+ return new JtaTransaction( transactionCoordinator );
+ }
+
+ @Override
+ public boolean canBeDriver() {
+ return true;
+ }
+
+ @Override
+ public ConnectionReleaseMode getDefaultReleaseMode() {
+ return ConnectionReleaseMode.AFTER_STATEMENT;
+ }
+
+ @Override
+ public boolean compatibleWithJtaSynchronization() {
+ return true;
+ }
+
+ @Override
+ public boolean isJoinableJtaTransaction(TransactionCoordinator transactionCoordinator, JtaTransaction transaction) {
+ try {
+ // Essentially:
+ // 1) If we have a local (Hibernate) transaction in progress
+ // and it already has the UserTransaction cached, use that
+ // UserTransaction to determine the status.
+ // 2) If a transaction manager has been located, use
+ // that transaction manager to determine the status.
+ // 3) Finally, as the last resort, try to lookup the
+ // UserTransaction via JNDI and use that to determine the
+ // status.
+ if ( transaction != null ) {
+ UserTransaction ut = transaction.getUserTransaction();
+ if ( ut != null ) {
+ return JTAHelper.isInProgress( ut.getStatus() );
+ }
+ }
+
+ final JtaPlatform jtaPlatform = transactionCoordinator
+ .getTransactionContext()
+ .getTransactionEnvironment()
+ .getJtaPlatform();
+ if ( jtaPlatform == null ) {
+ throw new TransactionException( "Unable to check transaction status" );
+ }
+ if ( jtaPlatform.retrieveTransactionManager() != null ) {
+ return JtaStatusHelper.isActive( jtaPlatform.retrieveTransactionManager().getStatus() );
+ }
+ else {
+ final UserTransaction ut = jtaPlatform.retrieveUserTransaction();
+ return ut != null && JTAHelper.isInProgress( ut.getStatus() );
+ }
+ }
+ catch ( SystemException se ) {
+ throw new TransactionException( "Unable to check transaction status", se );
+ }
+ }
+
+ @Override
+ public JoinStatus getJoinStatus(TransactionCoordinator transactionCoordinator, JtaTransaction transaction) {
+ return null; // todo : implement method body
+ }
+
+}
\ No newline at end of file
diff --git a/hibernate-core/src/main/java/org/hibernate/engine/transaction/spi/AbstractTransactionImpl.java b/hibernate-core/src/main/java/org/hibernate/engine/transaction/spi/AbstractTransactionImpl.java
new file mode 100644
index 0000000000..e8b41ae045
--- /dev/null
+++ b/hibernate-core/src/main/java/org/hibernate/engine/transaction/spi/AbstractTransactionImpl.java
@@ -0,0 +1,237 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2011, 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
+ */
+package org.hibernate.engine.transaction.spi;
+
+import org.hibernate.HibernateException;
+import org.hibernate.TransactionException;
+import org.hibernate.service.jta.platform.spi.JtaPlatform;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.transaction.Status;
+import javax.transaction.Synchronization;
+
+/**
+ * Abstract support for creating {@link TransactionImplementor transaction} implementations
+ *
+ * @author Steve Ebersole
+ */
+public abstract class AbstractTransactionImpl implements TransactionImplementor {
+ private static final Logger log = LoggerFactory.getLogger( AbstractTransactionImpl.class );
+
+ private final TransactionCoordinator transactionCoordinator;
+
+ private boolean valid = true;
+
+ private LocalStatus localStatus = LocalStatus.NOT_ACTIVE;
+ private int timeout = -1;
+
+ protected AbstractTransactionImpl(TransactionCoordinator transactionCoordinator) {
+ this.transactionCoordinator = transactionCoordinator;
+ }
+
+ @Override
+ public void invalidate() {
+ valid = false;
+ }
+
+ /**
+ * Perform the actual steps of beginning a transaction according to the strategy.
+ *
+ * @throws org.hibernate.TransactionException Indicates a problem beginning the transaction
+ */
+ protected abstract void doBegin();
+
+ /**
+ * Perform the actual steps of committing a transaction according to the strategy.
+ *
+ * @throws org.hibernate.TransactionException Indicates a problem committing the transaction
+ */
+ protected abstract void doCommit();
+
+ /**
+ * Perform the actual steps of rolling back a transaction according to the strategy.
+ *
+ * @throws org.hibernate.TransactionException Indicates a problem rolling back the transaction
+ */
+ protected abstract void doRollback();
+
+ protected abstract void afterTransactionBegin();
+ protected abstract void beforeTransactionCommit();
+ protected abstract void beforeTransactionRollBack();
+ protected abstract void afterTransactionCompletion(int status);
+ protected abstract void afterAfterCompletion();
+
+ /**
+ * Provide subclasses with access to the transaction coordinator.
+ *
+ * @return This transaction's context.
+ */
+ protected TransactionCoordinator transactionCoordinator() {
+ return transactionCoordinator;
+ }
+
+ /**
+ * Provide subclasses with convenient access to the configured {@link JtaPlatform}
+ *
+ * @return The {@link org.hibernate.service.jta.platform.spi.JtaPlatform}
+ */
+ protected JtaPlatform jtaPlatform() {
+ return transactionCoordinator().getTransactionContext().getTransactionEnvironment().getJtaPlatform();
+ }
+
+ @Override
+ public void registerSynchronization(Synchronization synchronization) {
+ transactionCoordinator().getSynchronizationRegistry().registerSynchronization( synchronization );
+ }
+
+ @Override
+ public LocalStatus getLocalStatus() {
+ return localStatus;
+ }
+
+ @Override
+ public boolean isActive() {
+ return localStatus == LocalStatus.ACTIVE && doExtendedActiveCheck();
+ }
+
+ @Override
+ public boolean wasCommitted() {
+ return localStatus == LocalStatus.COMMITTED;
+ }
+
+ @Override
+ public boolean wasRolledBack() throws HibernateException {
+ return localStatus == LocalStatus.ROLLED_BACK;
+ }
+
+ /**
+ * Active has been checked against local state. Perform any needed checks against resource transactions.
+ *
+ * @return {@code true} if the extended active check checks out as well; false otherwise.
+ */
+ protected boolean doExtendedActiveCheck() {
+ return true;
+ }
+
+ @Override
+ public void begin() throws HibernateException {
+ if ( ! valid ) {
+ throw new TransactionException( "Transaction instance is no longer valid" );
+ }
+ if ( localStatus == LocalStatus.ACTIVE ) {
+ throw new TransactionException( "nested transactions not supported" );
+ }
+ if ( localStatus != LocalStatus.NOT_ACTIVE ) {
+ throw new TransactionException( "reuse of Transaction instances not supported" );
+ }
+
+ log.debug( "begin" );
+
+ doBegin();
+
+ localStatus = LocalStatus.ACTIVE;
+
+ afterTransactionBegin();
+ }
+
+ @Override
+ public void commit() throws HibernateException {
+ if ( localStatus != LocalStatus.ACTIVE ) {
+ throw new TransactionException( "Transaction not successfully started" );
+ }
+
+ log.debug( "committing" );
+
+ beforeTransactionCommit();
+
+ try {
+ doCommit();
+ localStatus = LocalStatus.COMMITTED;
+ afterTransactionCompletion( Status.STATUS_COMMITTED );
+ }
+ catch ( Exception e ) {
+ localStatus = LocalStatus.FAILED_COMMIT;
+ afterTransactionCompletion( Status.STATUS_UNKNOWN );
+ throw new TransactionException( "commit failed", e );
+ }
+ finally {
+ invalidate();
+ afterAfterCompletion();
+ }
+ }
+
+ protected boolean allowFailedCommitToPhysicallyRollback() {
+ return false;
+ }
+
+ @Override
+ public void rollback() throws HibernateException {
+ if ( localStatus != LocalStatus.ACTIVE && localStatus != LocalStatus.FAILED_COMMIT ) {
+ throw new TransactionException( "Transaction not successfully started" );
+ }
+
+ log.debug( "rolling back" );
+
+ beforeTransactionRollBack();
+
+ if ( localStatus != LocalStatus.FAILED_COMMIT || allowFailedCommitToPhysicallyRollback() ) {
+ try {
+ doRollback();
+ localStatus = LocalStatus.ROLLED_BACK;
+ afterTransactionCompletion( Status.STATUS_ROLLEDBACK );
+ }
+ catch ( Exception e ) {
+ afterTransactionCompletion( Status.STATUS_UNKNOWN );
+ throw new TransactionException( "rollback failed", e );
+ }
+ finally {
+ invalidate();
+ afterAfterCompletion();
+ }
+ }
+
+ }
+
+ @Override
+ public void setTimeout(int seconds) {
+ timeout = seconds;
+ }
+
+ @Override
+ public int getTimeout() {
+ return timeout;
+ }
+
+ @Override
+ public void resetJoinStatus() {
+ // generally speaking this is no-op
+ }
+
+ @Override
+ public void join() {
+ // generally speaking this is no-op
+ }
+
+}
diff --git a/hibernate-core/src/main/java/org/hibernate/engine/transaction/spi/IsolationDelegate.java b/hibernate-core/src/main/java/org/hibernate/engine/transaction/spi/IsolationDelegate.java
new file mode 100644
index 0000000000..68935e95f4
--- /dev/null
+++ b/hibernate-core/src/main/java/org/hibernate/engine/transaction/spi/IsolationDelegate.java
@@ -0,0 +1,44 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2011, 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
+ */
+package org.hibernate.engine.transaction.spi;
+
+import org.hibernate.HibernateException;
+import org.hibernate.jdbc.Work;
+
+/**
+ * Contract for performing work in a manner that isolates it from any current transaction.
+ *
+ * @author Steve Ebersole
+ */
+public interface IsolationDelegate {
+ /**
+ * Perform the given work in isolation from current transaction.
+ *
+ * @param work The work to be performed.
+ * @param transacted Should the work itself be done in a (isolated) transaction?
+ *
+ * @throws HibernateException Indicates a problem performing the work.
+ */
+ public void delegateWork(Work work, boolean transacted) throws HibernateException;
+}
diff --git a/hibernate-core/src/main/java/org/hibernate/transaction/synchronization/AfterCompletionAction.java b/hibernate-core/src/main/java/org/hibernate/engine/transaction/spi/JoinStatus.java
similarity index 77%
rename from hibernate-core/src/main/java/org/hibernate/transaction/synchronization/AfterCompletionAction.java
rename to hibernate-core/src/main/java/org/hibernate/engine/transaction/spi/JoinStatus.java
index 29a6d14ffb..f81c71d4ab 100644
--- a/hibernate-core/src/main/java/org/hibernate/transaction/synchronization/AfterCompletionAction.java
+++ b/hibernate-core/src/main/java/org/hibernate/engine/transaction/spi/JoinStatus.java
@@ -1,7 +1,7 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
- * Copyright (c) 2010, Red Hat Inc. or third-party contributors as
+ * Copyright (c) 2011, 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.
@@ -21,15 +21,16 @@
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
-package org.hibernate.transaction.synchronization;
-
-import org.hibernate.transaction.TransactionFactory;
+package org.hibernate.engine.transaction.spi;
/**
- * TODO : javadoc
+ * See the JPA notion of joining a transaction for details.
*
+ * @author Emmanuel Bernard
* @author Steve Ebersole
*/
-public interface AfterCompletionAction {
- public void doAction(TransactionFactory.Context ctx, int status);
+public enum JoinStatus {
+ NOT_JOINED,
+ MARKED_FOR_JOINED,
+ JOINED
}
diff --git a/hibernate-core/src/main/java/org/hibernate/engine/transaction/spi/LocalStatus.java b/hibernate-core/src/main/java/org/hibernate/engine/transaction/spi/LocalStatus.java
new file mode 100644
index 0000000000..ef9343c825
--- /dev/null
+++ b/hibernate-core/src/main/java/org/hibernate/engine/transaction/spi/LocalStatus.java
@@ -0,0 +1,52 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2011, 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
+ */
+package org.hibernate.engine.transaction.spi;
+
+/**
+ * Enumeration of statuses in which a local transaction facade ({@link org.hibernate.Transaction}) might be.
+ *
+ * @author Steve Ebersole
+ */
+public enum LocalStatus {
+ /**
+ * The local transaction has not yet been begun
+ */
+ NOT_ACTIVE,
+ /**
+ * The local transaction has been begun, but not yet completed.
+ */
+ ACTIVE,
+ /**
+ * The local transaction has been competed successfully.
+ */
+ COMMITTED,
+ /**
+ * The local transaction has been rolled back.
+ */
+ ROLLED_BACK,
+ /**
+ * The local transaction attempted to commit, but failed.
+ */
+ FAILED_COMMIT
+}
diff --git a/hibernate-core/src/main/java/org/hibernate/engine/transaction/spi/SynchronizationRegistry.java b/hibernate-core/src/main/java/org/hibernate/engine/transaction/spi/SynchronizationRegistry.java
new file mode 100644
index 0000000000..bad7582a6f
--- /dev/null
+++ b/hibernate-core/src/main/java/org/hibernate/engine/transaction/spi/SynchronizationRegistry.java
@@ -0,0 +1,57 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2011, 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
+ */
+package org.hibernate.engine.transaction.spi;
+
+import javax.transaction.Synchronization;
+import java.io.Serializable;
+
+/**
+ * Manages a registry of {@link Synchronization Synchronizations}.
+ *
+ * @author Steve Ebersole
+ */
+public interface SynchronizationRegistry extends Serializable {
+ /**
+ * Register a user {@link Synchronization} callback for this transaction.
+ *
+ * @param synchronization The synchronization callback to register.
+ *
+ * @throws org.hibernate.HibernateException
+ */
+ public void registerSynchronization(Synchronization synchronization);
+
+ /**
+ * Delegate {@link Synchronization#beforeCompletion} calls to the {@link #registerSynchronization registered}
+ * {@link Synchronization Synchronizations}
+ */
+ void notifySynchronizationsBeforeTransactionCompletion();
+
+ /**
+ * Delegate {@link Synchronization#afterCompletion} calls to {@link #registerSynchronization registered}
+ * {@link Synchronization Synchronizations}
+ *
+ * @param status The transaction status (if known) per {@link javax.transaction.Status}
+ */
+ void notifySynchronizationsAfterTransactionCompletion(int status);
+}
diff --git a/hibernate-core/src/main/java/org/hibernate/engine/transaction/spi/TransactionContext.java b/hibernate-core/src/main/java/org/hibernate/engine/transaction/spi/TransactionContext.java
new file mode 100644
index 0000000000..7737980758
--- /dev/null
+++ b/hibernate-core/src/main/java/org/hibernate/engine/transaction/spi/TransactionContext.java
@@ -0,0 +1,105 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2011, 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
+ */
+package org.hibernate.engine.transaction.spi;
+
+import org.hibernate.ConnectionReleaseMode;
+
+import java.io.Serializable;
+
+/**
+ * Access to services needed in the context of processing transaction requests.
+ *
+ * The context is roughly speaking equivalent to the Hibernate session, as opposed to the {@link TransactionEnvironment}
+ * which is roughly equivalent to the Hibernate session factory
+ *
+ * @author Steve Ebersole
+ */
+public interface TransactionContext extends Serializable {
+ /**
+ * Obtain the {@link TransactionEnvironment} associated with this context.
+ *
+ * @return The transaction environment.
+ */
+ public TransactionEnvironment getTransactionEnvironment();
+
+ /**
+ * Get the mode for releasing JDBC connection in effect for ths context.
+ *
+ * @return The connection release mode.
+ */
+ public ConnectionReleaseMode getConnectionReleaseMode();
+
+ /**
+ * Should session automatically be closed after transaction completion in this context?
+ *
+ * @return {@literal true}/{@literal false} appropriately.
+ */
+ public boolean isAutoCloseSessionEnabled();
+
+ /**
+ * Is this context already closed?
+ *
+ * @return {@literal true}/{@literal false} appropriately.
+ */
+ public boolean isClosed();
+
+ /**
+ * Should flushes only happen manually for this context?
+ *
+ * @return {@literal true}/{@literal false} appropriately.
+ */
+ public boolean isFlushModeNever();
+
+ /**
+ * Should before transaction completion processing perform a flush when initiated from JTA synchronization for this
+ * context?
+ *
+ * @return {@literal true}/{@literal false} appropriately.
+ */
+ public boolean isFlushBeforeCompletionEnabled();
+
+ /**
+ * Perform a managed flush.
+ */
+ public void managedFlush();
+
+ /**
+ * Should JTA synchronization processing perform a automatic close (call to {@link #managedClose} for this
+ * context?
+ *
+ * @return {@literal true}/{@literal false} appropriately.
+ */
+ public boolean shouldAutoClose();
+
+ /**
+ * Perform a managed close.
+ */
+ public void managedClose();
+
+ public void afterTransactionBegin(TransactionImplementor hibernateTransaction);
+
+ public void beforeTransactionCompletion(TransactionImplementor hibernateTransaction);
+
+ public void afterTransactionCompletion(TransactionImplementor hibernateTransaction, boolean successful);
+}
diff --git a/hibernate-core/src/main/java/org/hibernate/engine/transaction/spi/TransactionCoordinator.java b/hibernate-core/src/main/java/org/hibernate/engine/transaction/spi/TransactionCoordinator.java
new file mode 100644
index 0000000000..05ad71ab67
--- /dev/null
+++ b/hibernate-core/src/main/java/org/hibernate/engine/transaction/spi/TransactionCoordinator.java
@@ -0,0 +1,139 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2011, 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
+ */
+package org.hibernate.engine.transaction.spi;
+
+import org.hibernate.engine.jdbc.spi.JdbcCoordinator;
+import org.hibernate.engine.transaction.synchronization.spi.SynchronizationCallbackCoordinator;
+
+import java.io.Serializable;
+import java.sql.Connection;
+
+/**
+ * Acts as the coordinator between the Hibernate engine and physical transactions.
+ *
+ * @author Steve Ebersole
+ */
+public interface TransactionCoordinator extends Serializable {
+ /**
+ * Retrieves the context in which this coordinator operates.
+ *
+ * @return The context of the coordinator
+ */
+ public TransactionContext getTransactionContext();
+
+ /**
+ * Retrieves the JDBC coordinator currently operating within this transaction coordinator.
+ *
+ * @return The JDBC coordinator.
+ */
+ public JdbcCoordinator getJdbcCoordinator();
+
+ /**
+ * Get the Hibernate transaction facade object currently associated with this coordinator.
+ *
+ * @return The current Hibernate transaction.
+ */
+ public TransactionImplementor getTransaction();
+
+ /**
+ * Obtain the {@link javax.transaction.Synchronization} registry associated with this coordinator.
+ *
+ * @return The registry
+ */
+ public SynchronizationRegistry getSynchronizationRegistry();
+
+ /**
+ * Adds an observer to the coordinator.
+ *
+ * Unlike synchronizations added to the {@link #getSynchronizationRegistry() registry}, observers are not to be
+ * cleared on transaction completion.
+ *
+ * @param observer The observer to add.
+ */
+ public void addObserver(TransactionObserver observer);
+
+ /**
+ * Can we join to the underlying transaction?
+ *
+ * @return {@literal true} if the underlying transaction can be joined or is already joined; {@literal false}
+ * otherwise.
+ *
+ * @see TransactionFactory#isJoinableJtaTransaction(TransactionCoordinator, TransactionImplementor)
+ */
+ public boolean isTransactionJoinable();
+
+ /**
+ * Is the underlying transaction already joined?
+ *
+ * @return {@literal true} if the underlying transaction is already joined; {@literal false} otherwise.
+ *
+ * @see TransactionFactory#getJoinStatus(TransactionCoordinator, TransactionImplementor)
+ */
+ public boolean isTransactionJoined();
+
+ /**
+ * Reset the transaction's join status.
+ */
+ public void resetJoinStatus();
+
+ /**
+ * Are we "in" an active and joined transaction
+ *
+ * @return {@literal true} if there is currently a transaction in progress; {@literal false} otherwise.
+ */
+ public boolean isTransactionInProgress();
+
+ /**
+ * Attempts to register JTA synchronization if possible and needed.
+ */
+ public void pulse();
+
+ /**
+ * Close the transaction context, returning any user supplied connection from the underlying JDBC coordinator.
+ *
+ * @return The user supplied connection (if one).
+ */
+ public Connection close();
+
+ /**
+ * Performs actions needed after execution of a non-transactional query.
+ *
+ * @param success Was the query successfully performed
+ */
+ public void afterNonTransactionalQuery(boolean success);
+
+ public void setRollbackOnly();
+
+ public SynchronizationCallbackCoordinator getSynchronizationCallbackCoordinator();
+
+ public boolean isSynchronizationRegistered();
+ public boolean takeOwnership();
+
+ public void afterTransaction(TransactionImplementor hibernateTransaction, int status);
+
+ public void sendAfterTransactionBeginNotifications(TransactionImplementor hibernateTransaction);
+ public void sendBeforeTransactionCompletionNotifications(TransactionImplementor hibernateTransaction);
+ public void sendAfterTransactionCompletionNotifications(TransactionImplementor hibernateTransaction, int status);
+
+}
\ No newline at end of file
diff --git a/hibernate-core/src/main/java/org/hibernate/engine/transaction/spi/TransactionEnvironment.java b/hibernate-core/src/main/java/org/hibernate/engine/transaction/spi/TransactionEnvironment.java
new file mode 100644
index 0000000000..b916a41b99
--- /dev/null
+++ b/hibernate-core/src/main/java/org/hibernate/engine/transaction/spi/TransactionEnvironment.java
@@ -0,0 +1,63 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2011, 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
+ */
+package org.hibernate.engine.transaction.spi;
+
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.engine.jdbc.spi.JdbcServices;
+import org.hibernate.service.jta.platform.spi.JtaPlatform;
+
+/**
+ * Provides access to transactional services.
+ *
+ * @author Steve Ebersole
+ */
+public interface TransactionEnvironment {
+ /**
+ * Retrieve the session factory for this environment.
+ *
+ * @return The session factory
+ */
+ public SessionFactoryImplementor getSessionFactory();
+
+ /**
+ * Retrieve the JDBC services for this environment.
+ *
+ * @return The JDBC services
+ */
+ public JdbcServices getJdbcServices();
+
+ /**
+ * Retrieve the JTA platform for this environment.
+ *
+ * @return The JTA platform
+ */
+ public JtaPlatform getJtaPlatform();
+
+ /**
+ * Retrieve the transaction factory for this environment.
+ *
+ * @return The transaction factory
+ */
+ public TransactionFactory getTransactionFactory();
+}
diff --git a/hibernate-core/src/main/java/org/hibernate/engine/transaction/spi/TransactionFactory.java b/hibernate-core/src/main/java/org/hibernate/engine/transaction/spi/TransactionFactory.java
new file mode 100644
index 0000000000..3688dd8fe3
--- /dev/null
+++ b/hibernate-core/src/main/java/org/hibernate/engine/transaction/spi/TransactionFactory.java
@@ -0,0 +1,93 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2011, 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
+ */
+package org.hibernate.engine.transaction.spi;
+
+import org.hibernate.ConnectionReleaseMode;
+import org.hibernate.service.spi.Service;
+
+/**
+ * Contract for transaction creation, as well as providing metadata and contextual information about that creation.
+ *
+ * @author Steve Ebersole
+ */
+public interface TransactionFactory extends Service {
+ /**
+ * Construct a transaction instance compatible with this strategy.
+ *
+ * @param coordinator The coordinator for this transaction
+ *
+ * @return The appropriate transaction instance.
+ *
+ * @throws org.hibernate.HibernateException Indicates a problem constructing the transaction.
+ */
+ public T createTransaction(TransactionCoordinator coordinator);
+
+ /**
+ * Can the transactions created from this strategy act as the driver? In other words can the user actually manage
+ * transactions with this strategy?
+ *
+ * @return {@literal true} if the transaction strategy represented by this factory can act as the driver callback;
+ * {@literal false} otherwise.
+ */
+ public boolean canBeDriver();
+
+ /**
+ * Should we attempt to register JTA transaction {@link javax.transaction.Synchronization synchronizations}.
+ *
+ * In other words, is this strategy JTA-based?
+ *
+ * @return {@literal true} if the transaction strategy represented by this factory is compatible with registering
+ * {@link javax.transaction.Synchronization synchronizations}; {@literal false} otherwise.
+ */
+ public boolean compatibleWithJtaSynchronization();
+
+ /**
+ * Can the underlying transaction represented by the passed Hibernate {@link TransactionImplementor} be joined?
+ *
+ * @param transactionCoordinator The transaction coordinator
+ * @param transaction The current Hibernate transaction
+ *
+ * @return {@literal true} is the transaction can be joined; {@literal false} otherwise.
+ */
+ public boolean isJoinableJtaTransaction(TransactionCoordinator transactionCoordinator, T transaction);
+
+ /**
+ * Retrieve the current join status of the Hibernate transaction
+ *
+ * @param transactionCoordinator The transaction coordinator
+ * @param transaction The current Hibernate transaction
+ *
+ * @return The join status.
+ */
+ public JoinStatus getJoinStatus(TransactionCoordinator transactionCoordinator, T transaction);
+
+ /**
+ * Get the default connection release mode.
+ *
+ * @return The default release mode associated with this strategy
+ */
+ public ConnectionReleaseMode getDefaultReleaseMode();
+
+}
+
diff --git a/hibernate-core/src/main/java/org/hibernate/engine/transaction/spi/TransactionImplementor.java b/hibernate-core/src/main/java/org/hibernate/engine/transaction/spi/TransactionImplementor.java
new file mode 100644
index 0000000000..57de1d3dfd
--- /dev/null
+++ b/hibernate-core/src/main/java/org/hibernate/engine/transaction/spi/TransactionImplementor.java
@@ -0,0 +1,67 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2011, 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
+ */
+package org.hibernate.engine.transaction.spi;
+
+import org.hibernate.Transaction;
+
+/**
+ * Additional contract for implementors of the Hibernate {@link Transaction} API.
+ *
+ * @author Steve Ebersole
+ */
+public interface TransactionImplementor extends Transaction {
+ /**
+ * Retrieve an isolation delegate appropriate for this transaction strategy.
+ *
+ * @return An isolation delegate.
+ */
+ public IsolationDelegate createIsolationDelegate();
+
+ /**
+ * Get the current state of this transaction's join status.
+ *
+ * @return The current join status
+ */
+ public JoinStatus getJoinStatus();
+
+ /**
+ * Perform a join to the underlying transaction
+ */
+ public void join();
+
+ /**
+ * Reset this transaction's join status.
+ */
+ public void resetJoinStatus();
+
+ /**
+ * Make a best effort to mark the underlying transaction for rollback only.
+ */
+ public void markRollbackOnly();
+
+ /**
+ * Called after completion of the underlying transaction to signify the facade is no longer valid.
+ */
+ public void invalidate();
+}
diff --git a/hibernate-core/src/main/java/org/hibernate/engine/transaction/spi/TransactionObserver.java b/hibernate-core/src/main/java/org/hibernate/engine/transaction/spi/TransactionObserver.java
new file mode 100644
index 0000000000..5a3472f046
--- /dev/null
+++ b/hibernate-core/src/main/java/org/hibernate/engine/transaction/spi/TransactionObserver.java
@@ -0,0 +1,57 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2011, 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
+ */
+package org.hibernate.engine.transaction.spi;
+
+/**
+ * Observer of internal transaction events.
+ *
+ * @author Steve Ebersole
+ */
+public interface TransactionObserver {
+ /**
+ * Callback for processing the beginning of a transaction.
+ *
+ * Do not rely on this being called as the transaction mat be started in a manner other than through the
+ * {@link org.hibernate.Transaction} API.
+ *
+ * @param transaction The Hibernate transaction
+ */
+ public void afterBegin(TransactionImplementor transaction);
+
+ /**
+ * Callback for processing the initial phase of transaction completion.
+ *
+ * @param transaction The Hibernate transaction
+ */
+ public void beforeCompletion(TransactionImplementor transaction);
+
+ /**
+ * Callback for processing the last phase of transaction completion.
+ *
+ * @param successful Was the transaction successful?
+ * @param transaction The Hibernate transaction
+ */
+ public void afterCompletion(boolean successful, TransactionImplementor transaction);
+}
+
diff --git a/hibernate-core/src/main/java/org/hibernate/transaction/synchronization/HibernateSynchronizationImpl.java b/hibernate-core/src/main/java/org/hibernate/engine/transaction/synchronization/internal/RegisteredSynchronization.java
similarity index 60%
rename from hibernate-core/src/main/java/org/hibernate/transaction/synchronization/HibernateSynchronizationImpl.java
rename to hibernate-core/src/main/java/org/hibernate/engine/transaction/synchronization/internal/RegisteredSynchronization.java
index 5cd3c5ba48..c8651d8217 100644
--- a/hibernate-core/src/main/java/org/hibernate/transaction/synchronization/HibernateSynchronizationImpl.java
+++ b/hibernate-core/src/main/java/org/hibernate/engine/transaction/synchronization/internal/RegisteredSynchronization.java
@@ -1,7 +1,7 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
- * Copyright (c) 2010, Red Hat Inc. or third-party contributors as
+ * Copyright (c) 2011, 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.
@@ -21,26 +21,26 @@
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
-package org.hibernate.transaction.synchronization;
-
-import javax.transaction.Synchronization;
+package org.hibernate.engine.transaction.synchronization.internal;
+import org.hibernate.engine.transaction.synchronization.spi.SynchronizationCallbackCoordinator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import javax.transaction.Synchronization;
+
/**
- * The {@link Synchronization} implementation Hibernate registers with the JTA {@link javax.transaction.Transaction}
+ * The JTA {@link javax.transaction.Synchronization} Hibernate registers when needed for JTA callbacks
*
- * @author Gavin King
* @author Steve Ebersole
*/
-public class HibernateSynchronizationImpl implements Synchronization {
- private static final Logger log = LoggerFactory.getLogger( HibernateSynchronizationImpl.class );
+public class RegisteredSynchronization implements Synchronization {
+ private static final Logger log = LoggerFactory.getLogger( RegisteredSynchronization.class );
- private final CallbackCoordinator coordinator;
+ private final SynchronizationCallbackCoordinator synchronizationCallbackCoordinator;
- public HibernateSynchronizationImpl(CallbackCoordinator coordinator) {
- this.coordinator = coordinator;
+ public RegisteredSynchronization(SynchronizationCallbackCoordinator synchronizationCallbackCoordinator) {
+ this.synchronizationCallbackCoordinator = synchronizationCallbackCoordinator;
}
/**
@@ -48,7 +48,7 @@ public class HibernateSynchronizationImpl implements Synchronization {
*/
public void beforeCompletion() {
log.trace( "JTA sync : beforeCompletion()" );
- coordinator.beforeCompletion();
+ synchronizationCallbackCoordinator.beforeCompletion();
}
/**
@@ -56,6 +56,6 @@ public class HibernateSynchronizationImpl implements Synchronization {
*/
public void afterCompletion(int status) {
log.trace( "JTA sync : afterCompletion({})", status );
- coordinator.afterCompletion( status );
+ synchronizationCallbackCoordinator.afterCompletion( status );
}
}
diff --git a/hibernate-core/src/main/java/org/hibernate/transaction/synchronization/CallbackCoordinator.java b/hibernate-core/src/main/java/org/hibernate/engine/transaction/synchronization/internal/SynchronizationCallbackCoordinatorImpl.java
similarity index 53%
rename from hibernate-core/src/main/java/org/hibernate/transaction/synchronization/CallbackCoordinator.java
rename to hibernate-core/src/main/java/org/hibernate/engine/transaction/synchronization/internal/SynchronizationCallbackCoordinatorImpl.java
index 3f42cc2d8c..ff0ba26775 100644
--- a/hibernate-core/src/main/java/org/hibernate/transaction/synchronization/CallbackCoordinator.java
+++ b/hibernate-core/src/main/java/org/hibernate/engine/transaction/synchronization/internal/SynchronizationCallbackCoordinatorImpl.java
@@ -1,7 +1,7 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
- * Copyright (c) 2010, Red Hat Inc. or third-party contributors as
+ * Copyright (c) 2011, 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.
@@ -21,75 +21,57 @@
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
-package org.hibernate.transaction.synchronization;
-
-import javax.transaction.Status;
-import javax.transaction.SystemException;
-import javax.transaction.Transaction;
+package org.hibernate.engine.transaction.synchronization.internal;
+import org.hibernate.TransactionException;
+import org.hibernate.engine.transaction.internal.jta.JtaStatusHelper;
+import org.hibernate.engine.transaction.spi.TransactionContext;
+import org.hibernate.engine.transaction.spi.TransactionCoordinator;
+import org.hibernate.engine.transaction.synchronization.spi.AfterCompletionAction;
+import org.hibernate.engine.transaction.synchronization.spi.SynchronizationCallbackCoordinator;
+import org.hibernate.engine.transaction.synchronization.spi.ExceptionMapper;
+import org.hibernate.engine.transaction.synchronization.spi.ManagedFlushChecker;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.hibernate.TransactionException;
-import org.hibernate.engine.jdbc.spi.JDBCContext;
-import org.hibernate.transaction.TransactionFactory;
-import org.hibernate.util.JTAHelper;
+import javax.transaction.SystemException;
/**
* Manages callbacks from the {@link javax.transaction.Synchronization} registered by Hibernate.
*
* @author Steve Ebersole
*/
-public class CallbackCoordinator {
- private static final Logger log = LoggerFactory.getLogger( CallbackCoordinator.class );
+public class SynchronizationCallbackCoordinatorImpl implements SynchronizationCallbackCoordinator {
+ private static final Logger log = LoggerFactory.getLogger( SynchronizationCallbackCoordinatorImpl.class );
- private final TransactionFactory.Context ctx;
- private JDBCContext jdbcContext;
- private final Transaction jtaTransaction;
- private final org.hibernate.Transaction hibernateTransaction;
+ private final TransactionCoordinator transactionCoordinator;
- private BeforeCompletionManagedFlushChecker beforeCompletionManagedFlushChecker;
+ private ManagedFlushChecker managedFlushChecker;
private AfterCompletionAction afterCompletionAction;
private ExceptionMapper exceptionMapper;
- public CallbackCoordinator(
- TransactionFactory.Context ctx,
- JDBCContext jdbcContext,
- Transaction jtaTransaction,
- org.hibernate.Transaction hibernateTransaction) {
- this.ctx = ctx;
- this.jdbcContext = jdbcContext;
- this.jtaTransaction = jtaTransaction;
- this.hibernateTransaction = hibernateTransaction;
+ public SynchronizationCallbackCoordinatorImpl(TransactionCoordinator transactionCoordinator) {
+ this.transactionCoordinator = transactionCoordinator;
reset();
}
public void reset() {
- beforeCompletionManagedFlushChecker = STANDARD_MANAGED_FLUSH_CHECKER;
+ managedFlushChecker = STANDARD_MANAGED_FLUSH_CHECKER;
exceptionMapper = STANDARD_EXCEPTION_MAPPER;
afterCompletionAction = STANDARD_AFTER_COMPLETION_ACTION;
}
- public BeforeCompletionManagedFlushChecker getBeforeCompletionManagedFlushChecker() {
- return beforeCompletionManagedFlushChecker;
- }
-
- public void setBeforeCompletionManagedFlushChecker(BeforeCompletionManagedFlushChecker beforeCompletionManagedFlushChecker) {
- this.beforeCompletionManagedFlushChecker = beforeCompletionManagedFlushChecker;
- }
-
- public ExceptionMapper getExceptionMapper() {
- return exceptionMapper;
+ @Override
+ public void setManagedFlushChecker(ManagedFlushChecker managedFlushChecker) {
+ this.managedFlushChecker = managedFlushChecker;
}
+ @Override
public void setExceptionMapper(ExceptionMapper exceptionMapper) {
this.exceptionMapper = exceptionMapper;
}
- public AfterCompletionAction getAfterCompletionAction() {
- return afterCompletionAction;
- }
-
+ @Override
public void setAfterCompletionAction(AfterCompletionAction afterCompletionAction) {
this.afterCompletionAction = afterCompletionAction;
}
@@ -102,7 +84,12 @@ public class CallbackCoordinator {
boolean flush;
try {
- flush = beforeCompletionManagedFlushChecker.shouldDoManagedFlush( ctx, jtaTransaction );
+ final int status = transactionCoordinator
+ .getTransactionContext()
+ .getTransactionEnvironment()
+ .getJtaPlatform()
+ .getCurrentStatus();
+ flush = managedFlushChecker.shouldDoManagedFlush( transactionCoordinator, status );
}
catch ( SystemException se ) {
setRollbackOnly();
@@ -112,7 +99,7 @@ public class CallbackCoordinator {
try {
if ( flush ) {
log.trace( "automatically flushing session" );
- ctx.managedFlush();
+ transactionCoordinator.getTransactionContext().managedFlush();
}
}
catch ( RuntimeException re ) {
@@ -120,48 +107,41 @@ public class CallbackCoordinator {
throw exceptionMapper.mapManagedFlushFailure( "error during managed flush", re );
}
finally {
- jdbcContext.beforeTransactionCompletion( hibernateTransaction );
+ transactionCoordinator.sendBeforeTransactionCompletionNotifications( null );
+ transactionCoordinator.getTransactionContext().beforeTransactionCompletion( null );
}
}
private void setRollbackOnly() {
- try {
- jtaTransaction.setRollbackOnly();
- }
- catch ( SystemException se ) {
- // best effort
- log.error( "could not set transaction to rollback only", se );
- }
+ transactionCoordinator.setRollbackOnly();
}
public void afterCompletion(int status) {
log.trace( "transaction after completion callback [status={}]", status );
try {
- afterCompletionAction.doAction( ctx, status );
-
- final boolean wasSuccessful = ( status == Status.STATUS_COMMITTED );
- jdbcContext.afterTransactionCompletion( wasSuccessful, hibernateTransaction );
+ afterCompletionAction.doAction( transactionCoordinator, status );
+ transactionCoordinator.afterTransaction( null, status );
}
finally {
reset();
- jdbcContext.cleanUpJtaSynchronizationCallbackCoordinator();
- if ( ctx.shouldAutoClose() && !ctx.isClosed() ) {
+ if ( transactionContext().shouldAutoClose() && ! transactionContext().isClosed() ) {
log.trace( "automatically closing session" );
- ctx.managedClose();
+ transactionContext().managedClose();
}
}
}
- private static final BeforeCompletionManagedFlushChecker STANDARD_MANAGED_FLUSH_CHECKER = new BeforeCompletionManagedFlushChecker() {
- public boolean shouldDoManagedFlush(TransactionFactory.Context ctx, Transaction jtaTransaction)
- throws SystemException {
- return !ctx.isClosed() &&
- !ctx.isFlushModeNever() &&
- ctx.isFlushBeforeCompletionEnabled() &&
- !JTAHelper.isRollback( jtaTransaction.getStatus() );
- //actually, this last test is probably unnecessary, since
- //beforeCompletion() doesn't get called during rollback
+ private TransactionContext transactionContext() {
+ return transactionCoordinator.getTransactionContext();
+ }
+
+ private static final ManagedFlushChecker STANDARD_MANAGED_FLUSH_CHECKER = new ManagedFlushChecker() {
+ @Override
+ public boolean shouldDoManagedFlush(TransactionCoordinator coordinator, int jtaStatus) {
+ return coordinator.getTransactionContext().isFlushModeNever() &&
+ coordinator.getTransactionContext().isFlushBeforeCompletionEnabled() &&
+ !JtaStatusHelper.isRollback( jtaStatus );
}
};
@@ -178,7 +158,8 @@ public class CallbackCoordinator {
};
private static final AfterCompletionAction STANDARD_AFTER_COMPLETION_ACTION = new AfterCompletionAction() {
- public void doAction(TransactionFactory.Context ctx, int status) {
+ @Override
+ public void doAction(TransactionCoordinator transactionCoordinator, int status) {
// nothing to do by default.
}
};
diff --git a/hibernate-core/src/main/java/org/hibernate/engine/transaction/synchronization/spi/AfterCompletionAction.java b/hibernate-core/src/main/java/org/hibernate/engine/transaction/synchronization/spi/AfterCompletionAction.java
new file mode 100644
index 0000000000..c4e0298451
--- /dev/null
+++ b/hibernate-core/src/main/java/org/hibernate/engine/transaction/synchronization/spi/AfterCompletionAction.java
@@ -0,0 +1,38 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2011, 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
+ */
+package org.hibernate.engine.transaction.synchronization.spi;
+
+
+import org.hibernate.engine.transaction.spi.TransactionCoordinator;
+
+/**
+ * A pluggable strategy for defining any actions to be performed during
+ * {@link javax.transaction.Synchronization#afterCompletion} processing from the the
+ * {@link javax.transaction.Synchronization} registered by Hibernate with the underlying JTA platform.
+ *
+ * @author Steve Ebersole
+ */
+public interface AfterCompletionAction {
+ public void doAction(TransactionCoordinator transactionCoordinator, int status);
+}
diff --git a/hibernate-core/src/main/java/org/hibernate/transaction/synchronization/ExceptionMapper.java b/hibernate-core/src/main/java/org/hibernate/engine/transaction/synchronization/spi/ExceptionMapper.java
similarity index 79%
rename from hibernate-core/src/main/java/org/hibernate/transaction/synchronization/ExceptionMapper.java
rename to hibernate-core/src/main/java/org/hibernate/engine/transaction/synchronization/spi/ExceptionMapper.java
index 403c558dca..1a0182a050 100644
--- a/hibernate-core/src/main/java/org/hibernate/transaction/synchronization/ExceptionMapper.java
+++ b/hibernate-core/src/main/java/org/hibernate/engine/transaction/synchronization/spi/ExceptionMapper.java
@@ -1,7 +1,7 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
- * Copyright (c) 2010, Red Hat Inc. or third-party contributors as
+ * Copyright (c) 2011, 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.
@@ -21,18 +21,20 @@
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
-package org.hibernate.transaction.synchronization;
+package org.hibernate.engine.transaction.synchronization.spi;
import javax.transaction.SystemException;
+import java.io.Serializable;
/**
- * TODO : javadoc
+ * A pluggable strategy for defining how the {@link javax.transaction.Synchronization} registered by Hibernate handles
+ * exceptions.
*
* @author Steve Ebersole
*/
-public interface ExceptionMapper {
+public interface ExceptionMapper extends Serializable {
/**
- * Map a JTA {@link SystemException} to the appropriate runtime-based exception.
+ * Map a JTA {@link javax.transaction.SystemException} to the appropriate runtime-based exception.
*
* @param message The message to use for the returned exception
* @param systemException The causal exception
diff --git a/hibernate-core/src/main/java/org/hibernate/transaction/synchronization/BeforeCompletionManagedFlushChecker.java b/hibernate-core/src/main/java/org/hibernate/engine/transaction/synchronization/spi/ManagedFlushChecker.java
similarity index 58%
rename from hibernate-core/src/main/java/org/hibernate/transaction/synchronization/BeforeCompletionManagedFlushChecker.java
rename to hibernate-core/src/main/java/org/hibernate/engine/transaction/synchronization/spi/ManagedFlushChecker.java
index 90994fcc41..5734b11d3d 100644
--- a/hibernate-core/src/main/java/org/hibernate/transaction/synchronization/BeforeCompletionManagedFlushChecker.java
+++ b/hibernate-core/src/main/java/org/hibernate/engine/transaction/synchronization/spi/ManagedFlushChecker.java
@@ -1,7 +1,7 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
- * Copyright (c) 2010, Red Hat Inc. or third-party contributors as
+ * Copyright (c) 2011, 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.
@@ -21,31 +21,27 @@
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
-package org.hibernate.transaction.synchronization;
+package org.hibernate.engine.transaction.synchronization.spi;
-import javax.transaction.SystemException;
-import javax.transaction.Transaction;
+import org.hibernate.engine.transaction.spi.TransactionCoordinator;
-import org.hibernate.transaction.TransactionFactory;
+import java.io.Serializable;
/**
- * Contract for checking whether to perform a managed flush in a
- * {@link javax.transaction.Synchronization#beforeCompletion()} callback
+ * A pluggable strategy for defining how the {@link javax.transaction.Synchronization} registered by Hibernate determines
+ * whether to perform a managed flush. An exceptions from either this delegate or the subsequent flush are routed
+ * through the sister strategy {@link ExceptionMapper}.
*
* @author Steve Ebersole
*/
-public interface BeforeCompletionManagedFlushChecker {
+public interface ManagedFlushChecker extends Serializable {
/**
* Check whether we should perform the managed flush
*
- * @param ctx The Hibernate "transaction context"
- * @param jtaTransaction The JTA transaction
+ * @param coordinator The transaction coordinator
+ * @param jtaStatus The status of the current JTA transaction.
*
* @return True to indicate to perform the managed flush; false otherwise.
- *
- * @throws SystemException Can be thrown while accessing the JTA transaction; will result in transaction being
- * marked for rollback (best effort).
*/
- public boolean shouldDoManagedFlush(TransactionFactory.Context ctx, Transaction jtaTransaction)
- throws SystemException;
+ public boolean shouldDoManagedFlush(TransactionCoordinator coordinator, int jtaStatus);
}
diff --git a/hibernate-core/src/main/java/org/hibernate/engine/transaction/synchronization/spi/SynchronizationCallbackCoordinator.java b/hibernate-core/src/main/java/org/hibernate/engine/transaction/synchronization/spi/SynchronizationCallbackCoordinator.java
new file mode 100644
index 0000000000..d96a62b0f9
--- /dev/null
+++ b/hibernate-core/src/main/java/org/hibernate/engine/transaction/synchronization/spi/SynchronizationCallbackCoordinator.java
@@ -0,0 +1,35 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2011, 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
+ */
+package org.hibernate.engine.transaction.synchronization.spi;
+
+import javax.transaction.Synchronization;
+
+/**
+ * @author Steve Ebersole
+ */
+public interface SynchronizationCallbackCoordinator extends Synchronization{
+ public void setManagedFlushChecker(ManagedFlushChecker managedFlushChecker);
+ public void setAfterCompletionAction(AfterCompletionAction afterCompletionAction);
+ public void setExceptionMapper(ExceptionMapper exceptionMapper);
+}
diff --git a/hibernate-core/src/main/java/org/hibernate/event/def/AbstractFlushingEventListener.java b/hibernate-core/src/main/java/org/hibernate/event/def/AbstractFlushingEventListener.java
index d252b091f1..15aa516d8c 100644
--- a/hibernate-core/src/main/java/org/hibernate/event/def/AbstractFlushingEventListener.java
+++ b/hibernate-core/src/main/java/org/hibernate/event/def/AbstractFlushingEventListener.java
@@ -313,7 +313,7 @@ public abstract class AbstractFlushingEventListener implements Serializable {
log.trace("executing flush");
try {
- session.getJDBCContext().getConnectionManager().flushBeginning();
+ session.getTransactionCoordinator().getJdbcCoordinator().flushBeginning();
// we need to lock the collection caches before
// executing entity inserts/updates in order to
// account for bidi associations
@@ -325,7 +325,7 @@ public abstract class AbstractFlushingEventListener implements Serializable {
throw he;
}
finally {
- session.getJDBCContext().getConnectionManager().flushEnding();
+ session.getTransactionCoordinator().getJdbcCoordinator().flushEnding();
}
}
diff --git a/hibernate-core/src/main/java/org/hibernate/event/def/AbstractSaveEventListener.java b/hibernate-core/src/main/java/org/hibernate/event/def/AbstractSaveEventListener.java
index 9bf1ad0950..7cc8bfa059 100644
--- a/hibernate-core/src/main/java/org/hibernate/event/def/AbstractSaveEventListener.java
+++ b/hibernate-core/src/main/java/org/hibernate/event/def/AbstractSaveEventListener.java
@@ -259,7 +259,7 @@ public abstract class AbstractSaveEventListener extends AbstractReassociateEvent
Serializable id = key == null ? null : key.getIdentifier();
- boolean inTxn = source.getJDBCContext().isTransactionInProgress();
+ boolean inTxn = source.getTransactionCoordinator().isTransactionInProgress();
boolean shouldDelayIdentityInserts = !inTxn && !requiresImmediateIdAccess;
// Put a placeholder in entries, so we don't recurse back and try to save() the
diff --git a/hibernate-core/src/main/java/org/hibernate/exception/SQLExceptionConverter.java b/hibernate-core/src/main/java/org/hibernate/exception/SQLExceptionConverter.java
index 1a0e1df965..630db0ab6b 100644
--- a/hibernate-core/src/main/java/org/hibernate/exception/SQLExceptionConverter.java
+++ b/hibernate-core/src/main/java/org/hibernate/exception/SQLExceptionConverter.java
@@ -26,6 +26,7 @@ package org.hibernate.exception;
import org.hibernate.JDBCException;
+import java.io.Serializable;
import java.sql.SQLException;
/**
@@ -42,9 +43,9 @@ import java.sql.SQLException;
* @author Steve Ebersole
* @see SQLExceptionConverterFactory
*/
-public interface SQLExceptionConverter {
+public interface SQLExceptionConverter extends Serializable {
/**
- * Convert the given SQLException into Hibernate's JDBCException hierarchy.
+ * Convert the given SQLException into the Hibernate {@link JDBCException} hierarchy.
*
* @param sqlException The SQLException to be converted.
* @param message An optional error message.
diff --git a/hibernate-core/src/main/java/org/hibernate/hql/ast/exec/AbstractStatementExecutor.java b/hibernate-core/src/main/java/org/hibernate/hql/ast/exec/AbstractStatementExecutor.java
index 50f486cd0d..efb94d6869 100644
--- a/hibernate-core/src/main/java/org/hibernate/hql/ast/exec/AbstractStatementExecutor.java
+++ b/hibernate-core/src/main/java/org/hibernate/hql/ast/exec/AbstractStatementExecutor.java
@@ -23,35 +23,33 @@
*/
package org.hibernate.hql.ast.exec;
-import java.sql.PreparedStatement;
-import java.sql.Connection;
-import java.sql.SQLWarning;
-import java.sql.Statement;
-import java.util.List;
-import java.util.Collections;
+import antlr.RecognitionException;
+import antlr.collections.AST;
import org.hibernate.HibernateException;
import org.hibernate.action.BulkOperationCleanupAction;
import org.hibernate.engine.SessionFactoryImplementor;
import org.hibernate.engine.SessionImplementor;
-import org.hibernate.engine.transaction.Isolater;
-import org.hibernate.engine.transaction.IsolatedWork;
import org.hibernate.event.EventSource;
import org.hibernate.hql.ast.HqlSqlWalker;
import org.hibernate.hql.ast.SqlGenerator;
+import org.hibernate.jdbc.Work;
import org.hibernate.persister.entity.Queryable;
import org.hibernate.sql.InsertSelect;
import org.hibernate.sql.Select;
import org.hibernate.sql.SelectFragment;
import org.hibernate.util.JDBCExceptionReporter;
import org.hibernate.util.StringHelper;
-
-import antlr.RecognitionException;
-import antlr.collections.AST;
-
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.SQLWarning;
+import java.sql.Statement;
+import java.util.Collections;
+import java.util.List;
+
/**
* Implementation of AbstractStatementExecutor.
*
@@ -139,42 +137,55 @@ public abstract class AbstractStatementExecutor implements StatementExecutor {
" from " + persister.getTemporaryIdTableName();
}
+ private static class TemporaryTableCreationWork implements Work {
+ private final Queryable persister;
+
+ private TemporaryTableCreationWork(Queryable persister) {
+ this.persister = persister;
+ }
+
+ @Override
+ public void execute(Connection connection) {
+ try {
+ Statement statement = connection.createStatement();
+ try {
+ statement.executeUpdate( persister.getTemporaryIdTableDDL() );
+ JDBCExceptionReporter.handleAndClearWarnings( statement, CREATION_WARNING_HANDLER );
+ }
+ finally {
+ try {
+ statement.close();
+ }
+ catch( Throwable ignore ) {
+ // ignore
+ }
+ }
+ }
+ catch( Exception e ) {
+ LOG.debug( "unable to create temporary id table [" + e.getMessage() + "]" );
+ }
+ }
+ }
protected void createTemporaryTableIfNecessary(final Queryable persister, final SessionImplementor session) {
// Don't really know all the codes required to adequately decipher returned jdbc exceptions here.
// simply allow the failure to be eaten and the subsequent insert-selects/deletes should fail
- IsolatedWork work = new IsolatedWork() {
- public void doWork(Connection connection) throws HibernateException {
- try {
- Statement statement = connection.createStatement();
- try {
- statement.executeUpdate( persister.getTemporaryIdTableDDL() );
- JDBCExceptionReporter.handleAndClearWarnings( statement, CREATION_WARNING_HANDLER );
- }
- finally {
- try {
- statement.close();
- }
- catch( Throwable ignore ) {
- // ignore
- }
- }
- }
- catch( Exception e ) {
- log.debug( "unable to create temporary id table [" + e.getMessage() + "]" );
- }
- }
- };
+ TemporaryTableCreationWork work = new TemporaryTableCreationWork( persister );
if ( shouldIsolateTemporaryTableDDL() ) {
- if ( getFactory().getSettings().isDataDefinitionInTransactionSupported() ) {
- Isolater.doIsolatedWork( work, session );
- }
- else {
- Isolater.doNonTransactedWork( work, session );
- }
+ session.getTransactionCoordinator()
+ .getTransaction()
+ .createIsolationDelegate()
+ .delegateWork( work, getFactory().getSettings().isDataDefinitionInTransactionSupported() );
}
else {
- work.doWork( session.getJDBCContext().getConnectionManager().getConnection() );
- session.getJDBCContext().getConnectionManager().afterStatement();
+ final Connection connection = session.getTransactionCoordinator()
+ .getJdbcCoordinator()
+ .getLogicalConnection()
+ .getShareableConnectionProxy();
+ work.execute( connection );
+ session.getTransactionCoordinator()
+ .getJdbcCoordinator()
+ .getLogicalConnection()
+ .afterStatementExecution();
}
}
@@ -194,53 +205,67 @@ public abstract class AbstractStatementExecutor implements StatementExecutor {
}
};
- protected void dropTemporaryTableIfNecessary(final Queryable persister, final SessionImplementor session) {
- if ( getFactory().getDialect().dropTemporaryTableAfterUse() ) {
- IsolatedWork work = new IsolatedWork() {
- public void doWork(Connection connection) throws HibernateException {
- final String command = session.getFactory().getDialect().getDropTemporaryTableString()
- + ' ' + persister.getTemporaryIdTableName();
- try {
- Statement statement = connection.createStatement();
- try {
- statement = connection.createStatement();
- statement.executeUpdate( command );
- }
- finally {
- try {
- statement.close();
- }
- catch( Throwable ignore ) {
- // ignore
- }
- }
- }
- catch( Exception e ) {
- log.warn( "unable to drop temporary id table after use [" + e.getMessage() + "]" );
- }
- }
- };
+ private static class TemporaryTableDropWork implements Work {
+ private final Queryable persister;
+ private final SessionImplementor session;
- if ( shouldIsolateTemporaryTableDDL() ) {
- if ( getFactory().getSettings().isDataDefinitionInTransactionSupported() ) {
- Isolater.doIsolatedWork( work, session );
+ private TemporaryTableDropWork(Queryable persister, SessionImplementor session) {
+ this.persister = persister;
+ this.session = session;
+ }
+
+ @Override
+ public void execute(Connection connection) {
+ final String command = session.getFactory().getDialect().getDropTemporaryTableString()
+ + ' ' + persister.getTemporaryIdTableName();
+ try {
+ Statement statement = connection.createStatement();
+ try {
+ statement = connection.createStatement();
+ statement.executeUpdate( command );
}
- else {
- Isolater.doNonTransactedWork( work, session );
+ finally {
+ try {
+ statement.close();
+ }
+ catch( Throwable ignore ) {
+ // ignore
+ }
}
}
+ catch( Exception e ) {
+ LOG.warn( "unable to drop temporary id table after use [" + e.getMessage() + "]" );
+ }
+ }
+ }
+
+ protected void dropTemporaryTableIfNecessary(final Queryable persister, final SessionImplementor session) {
+ if ( getFactory().getDialect().dropTemporaryTableAfterUse() ) {
+ TemporaryTableDropWork work = new TemporaryTableDropWork( persister, session );
+ if ( shouldIsolateTemporaryTableDDL() ) {
+ session.getTransactionCoordinator()
+ .getTransaction()
+ .createIsolationDelegate()
+ .delegateWork( work, getFactory().getSettings().isDataDefinitionInTransactionSupported() );
+ }
else {
- work.doWork( session.getJDBCContext().getConnectionManager().getConnection() );
- session.getJDBCContext().getConnectionManager().afterStatement();
+ final Connection connection = session.getTransactionCoordinator()
+ .getJdbcCoordinator()
+ .getLogicalConnection()
+ .getShareableConnectionProxy();
+ work.execute( connection );
+ session.getTransactionCoordinator()
+ .getJdbcCoordinator()
+ .getLogicalConnection()
+ .afterStatementExecution();
}
}
else {
// at the very least cleanup the data :)
PreparedStatement ps = null;
try {
- ps = session.getJDBCContext().getConnectionManager().prepareStatement( "delete from " + persister.getTemporaryIdTableName(),
- false
- );
+ final String sql = "delete from " + persister.getTemporaryIdTableName();
+ ps = session.getTransactionCoordinator().getJdbcCoordinator().getStatementPreparer().prepareStatement( sql, false );
ps.executeUpdate();
}
catch( Throwable t ) {
diff --git a/hibernate-core/src/main/java/org/hibernate/hql/ast/exec/BasicExecutor.java b/hibernate-core/src/main/java/org/hibernate/hql/ast/exec/BasicExecutor.java
index 53c0aeee67..6aebc128dd 100644
--- a/hibernate-core/src/main/java/org/hibernate/hql/ast/exec/BasicExecutor.java
+++ b/hibernate-core/src/main/java/org/hibernate/hql/ast/exec/BasicExecutor.java
@@ -84,7 +84,7 @@ public class BasicExecutor extends AbstractStatementExecutor {
try {
try {
- st = session.getJDBCContext().getConnectionManager().prepareStatement( sql, false );
+ st = session.getTransactionCoordinator().getJdbcCoordinator().getStatementPreparer().prepareStatement( sql, false );
Iterator parameterSpecifications = this.parameterSpecifications.iterator();
int pos = 1;
while ( parameterSpecifications.hasNext() ) {
diff --git a/hibernate-core/src/main/java/org/hibernate/hql/ast/exec/MultiTableDeleteExecutor.java b/hibernate-core/src/main/java/org/hibernate/hql/ast/exec/MultiTableDeleteExecutor.java
index 4290cb2ef4..4c40bc3aa5 100644
--- a/hibernate-core/src/main/java/org/hibernate/hql/ast/exec/MultiTableDeleteExecutor.java
+++ b/hibernate-core/src/main/java/org/hibernate/hql/ast/exec/MultiTableDeleteExecutor.java
@@ -105,7 +105,7 @@ public class MultiTableDeleteExecutor extends AbstractStatementExecutor {
int resultCount = 0;
try {
try {
- ps = session.getJDBCContext().getConnectionManager().prepareStatement( idInsertSelect, false );
+ ps = session.getTransactionCoordinator().getJdbcCoordinator().getStatementPreparer().prepareStatement( idInsertSelect, false );
Iterator paramSpecifications = getIdSelectParameterSpecifications().iterator();
int pos = 1;
while ( paramSpecifications.hasNext() ) {
@@ -132,7 +132,7 @@ public class MultiTableDeleteExecutor extends AbstractStatementExecutor {
for ( int i = 0; i < deletes.length; i++ ) {
try {
try {
- ps = session.getJDBCContext().getConnectionManager().prepareStatement( deletes[i], false );
+ ps = session.getTransactionCoordinator().getJdbcCoordinator().getStatementPreparer().prepareStatement( deletes[i], false );
ps.executeUpdate();
}
finally {
diff --git a/hibernate-core/src/main/java/org/hibernate/hql/ast/exec/MultiTableUpdateExecutor.java b/hibernate-core/src/main/java/org/hibernate/hql/ast/exec/MultiTableUpdateExecutor.java
index 17f4cfc2a0..d183f29498 100644
--- a/hibernate-core/src/main/java/org/hibernate/hql/ast/exec/MultiTableUpdateExecutor.java
+++ b/hibernate-core/src/main/java/org/hibernate/hql/ast/exec/MultiTableUpdateExecutor.java
@@ -129,7 +129,7 @@ public class MultiTableUpdateExecutor extends AbstractStatementExecutor {
int resultCount = 0;
try {
try {
- ps = session.getJDBCContext().getConnectionManager().prepareStatement( idInsertSelect, false );
+ ps = session.getTransactionCoordinator().getJdbcCoordinator().getStatementPreparer().prepareStatement( idInsertSelect, false );
// int parameterStart = getWalker().getNumberOfParametersInSetClause();
// List allParams = getIdSelectParameterSpecifications();
// Iterator whereParams = allParams.subList( parameterStart, allParams.size() ).iterator();
@@ -161,7 +161,7 @@ public class MultiTableUpdateExecutor extends AbstractStatementExecutor {
}
try {
try {
- ps = session.getJDBCContext().getConnectionManager().prepareStatement( updates[i], false );
+ ps = session.getTransactionCoordinator().getJdbcCoordinator().getStatementPreparer().prepareStatement( updates[i], false );
if ( hqlParameters[i] != null ) {
int position = 1; // jdbc params are 1-based
for ( int x = 0; x < hqlParameters[i].length; x++ ) {
diff --git a/hibernate-core/src/main/java/org/hibernate/id/GUIDGenerator.java b/hibernate-core/src/main/java/org/hibernate/id/GUIDGenerator.java
index d183b1a592..3f24e37b12 100644
--- a/hibernate-core/src/main/java/org/hibernate/id/GUIDGenerator.java
+++ b/hibernate-core/src/main/java/org/hibernate/id/GUIDGenerator.java
@@ -58,7 +58,7 @@ public class GUIDGenerator implements IdentifierGenerator {
final String sql = session.getFactory().getDialect().getSelectGUIDString();
try {
- PreparedStatement st = session.getJDBCContext().getConnectionManager().prepareSelectStatement(sql);
+ PreparedStatement st = session.getTransactionCoordinator().getJdbcCoordinator().getStatementPreparer().prepareStatement( sql );
try {
ResultSet rs = st.executeQuery();
final String result;
diff --git a/hibernate-core/src/main/java/org/hibernate/id/IdentityGenerator.java b/hibernate-core/src/main/java/org/hibernate/id/IdentityGenerator.java
index 65aa1e4b5f..72318efff4 100644
--- a/hibernate-core/src/main/java/org/hibernate/id/IdentityGenerator.java
+++ b/hibernate-core/src/main/java/org/hibernate/id/IdentityGenerator.java
@@ -87,7 +87,10 @@ public class IdentityGenerator extends AbstractPostInsertGenerator {
}
protected PreparedStatement prepare(String insertSQL, SessionImplementor session) throws SQLException {
- return session.getJDBCContext().getConnectionManager().prepareStatement( insertSQL, PreparedStatement.RETURN_GENERATED_KEYS );
+ return session.getTransactionCoordinator()
+ .getJdbcCoordinator()
+ .getStatementPreparer()
+ .prepareStatement( insertSQL, PreparedStatement.RETURN_GENERATED_KEYS );
}
public Serializable executeAndExtract(PreparedStatement insert) throws SQLException {
@@ -131,7 +134,10 @@ public class IdentityGenerator extends AbstractPostInsertGenerator {
}
protected PreparedStatement prepare(String insertSQL, SessionImplementor session) throws SQLException {
- return session.getJDBCContext().getConnectionManager().prepareStatement( insertSQL, PreparedStatement.NO_GENERATED_KEYS );
+ return session.getTransactionCoordinator()
+ .getJdbcCoordinator()
+ .getStatementPreparer()
+ .prepareStatement( insertSQL, PreparedStatement.NO_GENERATED_KEYS );
}
public Serializable executeAndExtract(PreparedStatement insert) throws SQLException {
diff --git a/hibernate-core/src/main/java/org/hibernate/id/IncrementGenerator.java b/hibernate-core/src/main/java/org/hibernate/id/IncrementGenerator.java
index 7cdd9bf16e..45b93f297b 100644
--- a/hibernate-core/src/main/java/org/hibernate/id/IncrementGenerator.java
+++ b/hibernate-core/src/main/java/org/hibernate/id/IncrementGenerator.java
@@ -121,7 +121,7 @@ public class IncrementGenerator implements IdentifierGenerator, Configurable {
log.debug( "fetching initial value: " + sql );
try {
- PreparedStatement st = session.getJDBCContext().getConnectionManager().prepareSelectStatement( sql );
+ PreparedStatement st = session.getTransactionCoordinator().getJdbcCoordinator().getStatementPreparer().prepareStatement( sql );
try {
ResultSet rs = st.executeQuery();
try {
diff --git a/hibernate-core/src/main/java/org/hibernate/id/SequenceGenerator.java b/hibernate-core/src/main/java/org/hibernate/id/SequenceGenerator.java
index 87f37e08a7..d3da145438 100644
--- a/hibernate-core/src/main/java/org/hibernate/id/SequenceGenerator.java
+++ b/hibernate-core/src/main/java/org/hibernate/id/SequenceGenerator.java
@@ -106,7 +106,7 @@ public class SequenceGenerator implements PersistentIdentifierGenerator, Configu
protected IntegralDataTypeHolder generateHolder(SessionImplementor session) {
try {
- PreparedStatement st = session.getJDBCContext().getConnectionManager().prepareSelectStatement( sql );
+ PreparedStatement st = session.getTransactionCoordinator().getJdbcCoordinator().getStatementPreparer().prepareStatement( sql );
try {
ResultSet rs = st.executeQuery();
try {
diff --git a/hibernate-core/src/main/java/org/hibernate/id/SequenceIdentityGenerator.java b/hibernate-core/src/main/java/org/hibernate/id/SequenceIdentityGenerator.java
index 5382fbeda2..d61e23aac0 100644
--- a/hibernate-core/src/main/java/org/hibernate/id/SequenceIdentityGenerator.java
+++ b/hibernate-core/src/main/java/org/hibernate/id/SequenceIdentityGenerator.java
@@ -96,7 +96,7 @@ public class SequenceIdentityGenerator extends SequenceGenerator
}
protected PreparedStatement prepare(String insertSQL, SessionImplementor session) throws SQLException {
- return session.getJDBCContext().getConnectionManager().prepareStatement( insertSQL, keyColumns );
+ return session.getTransactionCoordinator().getJdbcCoordinator().getStatementPreparer().prepareStatement( insertSQL, keyColumns );
}
protected Serializable executeAndExtract(PreparedStatement insert) throws SQLException {
diff --git a/hibernate-core/src/main/java/org/hibernate/id/enhanced/SequenceStructure.java b/hibernate-core/src/main/java/org/hibernate/id/enhanced/SequenceStructure.java
index d946d2cf1e..5b2ac14c9c 100644
--- a/hibernate-core/src/main/java/org/hibernate/id/enhanced/SequenceStructure.java
+++ b/hibernate-core/src/main/java/org/hibernate/id/enhanced/SequenceStructure.java
@@ -102,7 +102,7 @@ public class SequenceStructure implements DatabaseStructure {
public IntegralDataTypeHolder getNextValue() {
accessCounter++;
try {
- PreparedStatement st = session.getJDBCContext().getConnectionManager().prepareSelectStatement( sql );
+ PreparedStatement st = session.getTransactionCoordinator().getJdbcCoordinator().getStatementPreparer().prepareStatement( sql );
try {
ResultSet rs = st.executeQuery();
try {
diff --git a/hibernate-core/src/main/java/org/hibernate/id/insert/AbstractSelectingDelegate.java b/hibernate-core/src/main/java/org/hibernate/id/insert/AbstractSelectingDelegate.java
index 9b93eab5d7..ca9c3a978c 100644
--- a/hibernate-core/src/main/java/org/hibernate/id/insert/AbstractSelectingDelegate.java
+++ b/hibernate-core/src/main/java/org/hibernate/id/insert/AbstractSelectingDelegate.java
@@ -50,7 +50,10 @@ public abstract class AbstractSelectingDelegate implements InsertGeneratedIdenti
public final Serializable performInsert(String insertSQL, SessionImplementor session, Binder binder) {
try {
// prepare and execute the insert
- PreparedStatement insert = session.getJDBCContext().getConnectionManager().prepareStatement( insertSQL, PreparedStatement.NO_GENERATED_KEYS );
+ PreparedStatement insert = session.getTransactionCoordinator()
+ .getJdbcCoordinator()
+ .getStatementPreparer()
+ .prepareStatement( insertSQL, PreparedStatement.NO_GENERATED_KEYS );
try {
binder.bindValues( insert );
insert.executeUpdate();
@@ -71,7 +74,10 @@ public abstract class AbstractSelectingDelegate implements InsertGeneratedIdenti
try {
//fetch the generated id in a separate query
- PreparedStatement idSelect = session.getJDBCContext().getConnectionManager().prepareStatement( selectSQL, false );
+ PreparedStatement idSelect = session.getTransactionCoordinator()
+ .getJdbcCoordinator()
+ .getStatementPreparer()
+ .prepareStatement( selectSQL, false );
try {
bindParameters( session, idSelect, binder.getEntity() );
ResultSet rs = idSelect.executeQuery();
diff --git a/hibernate-core/src/main/java/org/hibernate/impl/AbstractSessionImpl.java b/hibernate-core/src/main/java/org/hibernate/impl/AbstractSessionImpl.java
index ea7e1cbdbe..bc017b1a27 100755
--- a/hibernate-core/src/main/java/org/hibernate/impl/AbstractSessionImpl.java
+++ b/hibernate-core/src/main/java/org/hibernate/impl/AbstractSessionImpl.java
@@ -38,6 +38,8 @@ import org.hibernate.engine.QueryParameters;
import org.hibernate.engine.SessionFactoryImplementor;
import org.hibernate.engine.query.HQLQueryPlan;
import org.hibernate.engine.query.NativeSQLQueryPlan;
+import org.hibernate.engine.transaction.spi.TransactionContext;
+import org.hibernate.engine.transaction.spi.TransactionEnvironment;
import java.util.List;
@@ -46,7 +48,7 @@ import java.util.List;
*
* @author Gavin King
*/
-public abstract class AbstractSessionImpl implements SessionImplementor {
+public abstract class AbstractSessionImpl implements SessionImplementor, TransactionContext {
protected transient SessionFactoryImpl factory;
private boolean closed = false;
@@ -59,6 +61,11 @@ public abstract class AbstractSessionImpl implements SessionImplementor {
return factory;
}
+ @Override
+ public TransactionEnvironment getTransactionEnvironment() {
+ return factory.getTransactionEnvironment();
+ }
+
public boolean isClosed() {
return closed;
}
diff --git a/hibernate-core/src/main/java/org/hibernate/impl/ConnectionObserverStatsBridge.java b/hibernate-core/src/main/java/org/hibernate/impl/ConnectionObserverStatsBridge.java
new file mode 100644
index 0000000000..cbfb318576
--- /dev/null
+++ b/hibernate-core/src/main/java/org/hibernate/impl/ConnectionObserverStatsBridge.java
@@ -0,0 +1,59 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2011, 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
+ */
+package org.hibernate.impl;
+
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.engine.jdbc.spi.ConnectionObserver;
+
+import java.io.Serializable;
+import java.sql.Connection;
+
+/**
+ * @author Steve Ebersole
+ */
+public class ConnectionObserverStatsBridge implements ConnectionObserver, Serializable {
+ private final SessionFactoryImplementor sessionFactory;
+
+ public ConnectionObserverStatsBridge(SessionFactoryImplementor sessionFactory) {
+ this.sessionFactory = sessionFactory;
+ }
+
+ @Override
+ public void physicalConnectionObtained(Connection connection) {
+ sessionFactory.getStatisticsImplementor().connect();
+ }
+
+ @Override
+ public void physicalConnectionReleased() {
+ }
+
+ @Override
+ public void logicalConnectionClosed() {
+ }
+
+ @Override
+ public void statementPrepared() {
+ sessionFactory.getStatisticsImplementor().prepareStatement();
+ }
+}
diff --git a/hibernate-core/src/main/java/org/hibernate/impl/SessionFactoryImpl.java b/hibernate-core/src/main/java/org/hibernate/impl/SessionFactoryImpl.java
index 6a004835ca..3a7dedf62d 100644
--- a/hibernate-core/src/main/java/org/hibernate/impl/SessionFactoryImpl.java
+++ b/hibernate-core/src/main/java/org/hibernate/impl/SessionFactoryImpl.java
@@ -23,32 +23,6 @@
*/
package org.hibernate.impl;
-import java.io.IOException;
-import java.io.InvalidObjectException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.io.ObjectStreamException;
-import java.io.Serializable;
-import java.sql.Connection;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.LinkedHashSet;
-import java.util.Map;
-import java.util.Properties;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-import javax.naming.NamingException;
-import javax.naming.Reference;
-import javax.naming.StringRefAddr;
-import javax.transaction.TransactionManager;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
import org.hibernate.AssertionFailure;
import org.hibernate.Cache;
import org.hibernate.ConnectionReleaseMode;
@@ -76,10 +50,6 @@ import org.hibernate.cache.impl.CacheDataDescriptionImpl;
import org.hibernate.cfg.Configuration;
import org.hibernate.cfg.Environment;
import org.hibernate.cfg.Settings;
-import org.hibernate.engine.jdbc.spi.JdbcServices;
-import org.hibernate.engine.jdbc.spi.SQLExceptionHelper;
-import org.hibernate.exception.SQLExceptionConverter;
-import org.hibernate.service.jdbc.connections.spi.ConnectionProvider;
import org.hibernate.context.CurrentSessionContext;
import org.hibernate.context.JTASessionContext;
import org.hibernate.context.ManagedSessionContext;
@@ -92,12 +62,16 @@ import org.hibernate.engine.NamedQueryDefinition;
import org.hibernate.engine.NamedSQLQueryDefinition;
import org.hibernate.engine.ResultSetMappingDefinition;
import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.engine.jdbc.spi.JdbcServices;
+import org.hibernate.engine.jdbc.spi.SQLExceptionHelper;
import org.hibernate.engine.profile.Association;
import org.hibernate.engine.profile.Fetch;
import org.hibernate.engine.profile.FetchProfile;
import org.hibernate.engine.query.QueryPlanCache;
import org.hibernate.engine.query.sql.NativeSQLQuerySpecification;
+import org.hibernate.engine.transaction.spi.TransactionEnvironment;
import org.hibernate.event.EventListeners;
+import org.hibernate.exception.SQLExceptionConverter;
import org.hibernate.id.IdentifierGenerator;
import org.hibernate.id.UUIDGenerator;
import org.hibernate.id.factory.IdentifierGeneratorFactory;
@@ -113,6 +87,8 @@ import org.hibernate.persister.entity.Loadable;
import org.hibernate.persister.entity.Queryable;
import org.hibernate.pretty.MessageHelper;
import org.hibernate.proxy.EntityNotFoundDelegate;
+import org.hibernate.service.jdbc.connections.spi.ConnectionProvider;
+import org.hibernate.service.jta.platform.spi.JtaPlatform;
import org.hibernate.service.spi.ServiceRegistry;
import org.hibernate.stat.ConcurrentStatisticsImpl;
import org.hibernate.stat.Statistics;
@@ -120,7 +96,6 @@ import org.hibernate.stat.StatisticsImplementor;
import org.hibernate.tool.hbm2ddl.SchemaExport;
import org.hibernate.tool.hbm2ddl.SchemaUpdate;
import org.hibernate.tool.hbm2ddl.SchemaValidator;
-import org.hibernate.transaction.TransactionFactory;
import org.hibernate.tuple.entity.EntityTuplizer;
import org.hibernate.type.AssociationType;
import org.hibernate.type.Type;
@@ -128,6 +103,31 @@ import org.hibernate.type.TypeResolver;
import org.hibernate.util.CollectionHelper;
import org.hibernate.util.EmptyIterator;
import org.hibernate.util.ReflectHelper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.naming.NamingException;
+import javax.naming.Reference;
+import javax.naming.StringRefAddr;
+import javax.transaction.TransactionManager;
+import java.io.IOException;
+import java.io.InvalidObjectException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.ObjectStreamException;
+import java.io.Serializable;
+import java.sql.Connection;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
/**
@@ -153,7 +153,8 @@ import org.hibernate.util.ReflectHelper;
* @see org.hibernate.persister.collection.CollectionPersister
* @author Gavin King
*/
-public final class SessionFactoryImpl implements SessionFactory, SessionFactoryImplementor {
+public final class SessionFactoryImpl
+ implements SessionFactory, SessionFactoryImplementor {
private static final Logger log = LoggerFactory.getLogger(SessionFactoryImpl.class);
private static final IdentifierGenerator UUID_GENERATOR = UUIDGenerator.buildSessionFactoryUniqueIdentifierGenerator();
@@ -178,7 +179,6 @@ public final class SessionFactoryImpl implements SessionFactory, SessionFactoryI
private final transient Settings settings;
private final transient Properties properties;
private transient SchemaExport schemaExport;
- private final transient TransactionManager transactionManager;
private final transient QueryCache queryCache;
private final transient UpdateTimestampsCache updateTimestampsCache;
private final transient Map queryCaches;
@@ -195,6 +195,7 @@ public final class SessionFactoryImpl implements SessionFactory, SessionFactoryI
private transient boolean isClosed = false;
private final transient TypeResolver typeResolver;
private final transient TypeHelper typeHelper;
+ private final transient TransactionEnvironment transactionEnvironment;
public SessionFactoryImpl(
Configuration cfg,
@@ -386,17 +387,6 @@ public final class SessionFactoryImpl implements SessionFactory, SessionFactoryI
schemaExport = new SchemaExport( getJdbcServices(), cfg );
}
- if ( settings.getTransactionManagerLookup()!=null ) {
- log.debug("obtaining JTA TransactionManager");
- transactionManager = settings.getTransactionManagerLookup().getTransactionManager(properties);
- }
- else {
- if ( settings.getTransactionFactory().isTransactionManagerRequired() ) {
- throw new HibernateException("The chosen transaction strategy requires access to the JTA TransactionManager");
- }
- transactionManager = null;
- }
-
currentSessionContext = buildCurrentSessionContext();
if ( settings.isQueryCacheEnabled() ) {
@@ -480,9 +470,14 @@ public final class SessionFactoryImpl implements SessionFactory, SessionFactoryI
fetchProfiles.put( fetchProfile.getName(), fetchProfile );
}
+ this.transactionEnvironment = new TransactionEnvironmentImpl( this );
this.observer.sessionFactoryCreated( this );
}
+ public TransactionEnvironment getTransactionEnvironment() {
+ return transactionEnvironment;
+ }
+
public Properties getProperties() {
return properties;
}
@@ -728,14 +723,6 @@ public final class SessionFactoryImpl implements SessionFactory, SessionFactoryI
return interceptor;
}
- public TransactionFactory getTransactionFactory() {
- return settings.getTransactionFactory();
- }
-
- public TransactionManager getTransactionManager() {
- return transactionManager;
- }
-
public SQLExceptionConverter getSQLExceptionConverter() {
return getSQLExceptionHelper().getSqlExceptionConverter();
}
@@ -1229,19 +1216,34 @@ public final class SessionFactoryImpl implements SessionFactory, SessionFactoryI
return (IdentifierGenerator) identifierGenerators.get(rootEntityName);
}
+ private org.hibernate.engine.transaction.spi.TransactionFactory transactionFactory() {
+ return serviceRegistry.getService( org.hibernate.engine.transaction.spi.TransactionFactory.class );
+ }
+
+ private boolean canAccessTransactionManager() {
+ try {
+ return serviceRegistry.getService( JtaPlatform.class ).retrieveTransactionManager() != null;
+ }
+ catch (Exception e) {
+ return false;
+ }
+ }
+
private CurrentSessionContext buildCurrentSessionContext() {
String impl = properties.getProperty( Environment.CURRENT_SESSION_CONTEXT_CLASS );
- // for backward-compatability
- if ( impl == null && transactionManager != null ) {
- impl = "jta";
+ // for backward-compatibility
+ if ( impl == null ) {
+ if ( canAccessTransactionManager() ) {
+ impl = "jta";
+ }
+ else {
+ return null;
+ }
}
- if ( impl == null ) {
- return null;
- }
- else if ( "jta".equals( impl ) ) {
- if ( settings.getTransactionFactory().areCallbacksLocalToHibernateTransactions() ) {
- log.warn( "JTASessionContext being used with JDBCTransactionFactory; auto-flush will not operate correctly with getCurrentSession()" );
+ if ( "jta".equals( impl ) ) {
+ if ( ! transactionFactory().compatibleWithJtaSynchronization() ) {
+ log.warn( "JTASessionContext being used with JdbcTransactionFactory; auto-flush will not operate correctly with getCurrentSession()" );
}
return new JTASessionContext( this );
}
@@ -1256,7 +1258,7 @@ public final class SessionFactoryImpl implements SessionFactory, SessionFactoryI
Class implClass = ReflectHelper.classForName( impl );
return ( CurrentSessionContext ) implClass
.getConstructor( new Class[] { SessionFactoryImplementor.class } )
- .newInstance( new Object[] { this } );
+ .newInstance( this );
}
catch( Throwable t ) {
log.error( "Unable to construct current session context [" + impl + "]", t );
@@ -1265,11 +1267,15 @@ public final class SessionFactoryImpl implements SessionFactory, SessionFactoryI
}
}
- public EventListeners getEventListeners()
- {
+ public EventListeners getEventListeners() {
return eventListeners;
}
+ @Override
+ public ServiceRegistry getServiceRegistry() {
+ return serviceRegistry;
+ }
+
public EntityNotFoundDelegate getEntityNotFoundDelegate() {
return entityNotFoundDelegate;
}
diff --git a/hibernate-core/src/main/java/org/hibernate/impl/SessionImpl.java b/hibernate-core/src/main/java/org/hibernate/impl/SessionImpl.java
index 25b99c52b2..32749877d2 100644
--- a/hibernate-core/src/main/java/org/hibernate/impl/SessionImpl.java
+++ b/hibernate-core/src/main/java/org/hibernate/impl/SessionImpl.java
@@ -1,10 +1,10 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
- * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * Copyright (c) 2005-2011, 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 Middleware LLC.
+ * 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
@@ -20,44 +20,21 @@
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
- *
*/
package org.hibernate.impl;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.io.Reader;
-import java.io.Serializable;
-import java.io.ByteArrayOutputStream;
-import java.io.ByteArrayInputStream;
-import java.sql.Blob;
-import java.sql.Clob;
-import java.sql.Connection;
-import java.sql.SQLException;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
import org.hibernate.CacheMode;
import org.hibernate.ConnectionReleaseMode;
import org.hibernate.Criteria;
import org.hibernate.EntityMode;
+import org.hibernate.EntityNameResolver;
import org.hibernate.Filter;
import org.hibernate.FlushMode;
import org.hibernate.HibernateException;
import org.hibernate.Interceptor;
import org.hibernate.LobHelper;
import org.hibernate.LockMode;
+import org.hibernate.LockOptions;
import org.hibernate.MappingException;
import org.hibernate.ObjectDeletedException;
import org.hibernate.Query;
@@ -68,33 +45,34 @@ import org.hibernate.ScrollMode;
import org.hibernate.ScrollableResults;
import org.hibernate.Session;
import org.hibernate.SessionException;
-import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.TransientObjectException;
import org.hibernate.TypeHelper;
-import org.hibernate.UnresolvableObjectException;
import org.hibernate.UnknownProfileException;
-import org.hibernate.EntityNameResolver;
-import org.hibernate.LockOptions;
+import org.hibernate.UnresolvableObjectException;
import org.hibernate.collection.PersistentCollection;
import org.hibernate.engine.ActionQueue;
import org.hibernate.engine.CollectionEntry;
import org.hibernate.engine.EntityEntry;
import org.hibernate.engine.EntityKey;
+import org.hibernate.engine.LoadQueryInfluencers;
import org.hibernate.engine.NonFlushedChanges;
import org.hibernate.engine.PersistenceContext;
import org.hibernate.engine.QueryParameters;
+import org.hibernate.engine.SessionFactoryImplementor;
import org.hibernate.engine.StatefulPersistenceContext;
import org.hibernate.engine.Status;
-import org.hibernate.engine.LoadQueryInfluencers;
import org.hibernate.engine.jdbc.LobCreationContext;
import org.hibernate.engine.jdbc.LobCreator;
-import org.hibernate.engine.jdbc.internal.JDBCContextImpl;
-import org.hibernate.engine.jdbc.spi.JDBCContext;
import org.hibernate.engine.query.FilterQueryPlan;
import org.hibernate.engine.query.HQLQueryPlan;
import org.hibernate.engine.query.NativeSQLQueryPlan;
import org.hibernate.engine.query.sql.NativeSQLQuerySpecification;
+import org.hibernate.engine.transaction.internal.TransactionCoordinatorImpl;
+import org.hibernate.engine.transaction.spi.TransactionContext;
+import org.hibernate.engine.transaction.spi.TransactionCoordinator;
+import org.hibernate.engine.transaction.spi.TransactionImplementor;
+import org.hibernate.engine.transaction.spi.TransactionObserver;
import org.hibernate.event.AutoFlushEvent;
import org.hibernate.event.AutoFlushEventListener;
import org.hibernate.event.DeleteEvent;
@@ -136,57 +114,84 @@ import org.hibernate.proxy.HibernateProxy;
import org.hibernate.proxy.LazyInitializer;
import org.hibernate.stat.SessionStatistics;
import org.hibernate.stat.SessionStatisticsImpl;
-import org.hibernate.type.Type;
import org.hibernate.type.SerializationException;
+import org.hibernate.type.Type;
import org.hibernate.util.ArrayHelper;
import org.hibernate.util.CollectionHelper;
import org.hibernate.util.StringHelper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Reader;
+import java.io.Serializable;
+import java.sql.Blob;
+import java.sql.Clob;
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
/**
- * Concrete implementation of a Session, and also the central, organizing component
- * of Hibernate's internal implementation. As such, this class exposes two interfaces;
- * Session itself, to the application, and SessionImplementor, to other components
- * of Hibernate. This class is not threadsafe.
+ * Concrete implementation of a Session.
+ *
+ * Exposes two interfaces:
+ * - {@link Session} to the application
+ * - {@link org.hibernate.engine.SessionImplementor} to other Hibernate components (SPI)
+ *
+ *
+ * This class is not thread-safe.
*
* @author Gavin King
*/
-public final class SessionImpl extends AbstractSessionImpl
- implements EventSource, org.hibernate.classic.Session, JDBCContext.Context, LobCreationContext {
+public final class SessionImpl
+ extends AbstractSessionImpl
+ implements EventSource,
+ org.hibernate.classic.Session,
+ TransactionContext,
+ LobCreationContext {
// todo : need to find a clean way to handle the "event source" role
- // a seperate classs responsible for generating/dispatching events just duplicates most of the Session methods...
- // passing around seperate reto interceptor, factory, actionQueue, and persistentContext is not manageable...
+ // a separate class responsible for generating/dispatching events just duplicates most of the Session methods...
+ // passing around separate interceptor, factory, actionQueue, and persistentContext is not manageable...
private static final Logger log = LoggerFactory.getLogger(SessionImpl.class);
- private transient EntityMode entityMode = EntityMode.POJO;
- private transient boolean autoClear; //for EJB3
-
private transient long timestamp;
- private transient FlushMode flushMode = FlushMode.AUTO;
- private transient CacheMode cacheMode = CacheMode.NORMAL;
-
- private transient Interceptor interceptor;
-
- private transient int dontFlushFromFind = 0;
private transient ActionQueue actionQueue;
private transient StatefulPersistenceContext persistenceContext;
- private transient JDBCContextImpl jdbcContext;
+ private transient TransactionCoordinatorImpl transactionCoordinator;
private transient EventListeners listeners;
+ private transient Interceptor interceptor;
+ private transient EntityNameResolver entityNameResolver = new CoordinatingEntityNameResolver();
+ private transient ConnectionReleaseMode connectionReleaseMode;
+ private transient FlushMode flushMode = FlushMode.AUTO;
+ private transient CacheMode cacheMode = CacheMode.NORMAL;
+ private transient EntityMode entityMode = EntityMode.POJO;
+ private transient boolean autoClear; //for EJB3
+
+ private transient int dontFlushFromFind = 0;
private transient boolean flushBeforeCompletionEnabled;
private transient boolean autoCloseSessionEnabled;
- private transient ConnectionReleaseMode connectionReleaseMode;
private transient LoadQueryInfluencers loadQueryInfluencers;
private transient Session rootSession;
private transient Map childSessionsByEntityMode;
- private transient EntityNameResolver entityNameResolver = new CoordinatingEntityNameResolver();
-
/**
* Constructor used in building "child sessions".
*
@@ -197,7 +202,7 @@ public final class SessionImpl extends AbstractSessionImpl
super( parent.factory );
this.rootSession = parent;
this.timestamp = parent.timestamp;
- this.jdbcContext = parent.jdbcContext;
+ this.transactionCoordinator = parent.transactionCoordinator;
this.interceptor = parent.interceptor;
this.listeners = parent.listeners;
this.actionQueue = new ActionQueue( this );
@@ -251,7 +256,11 @@ public final class SessionImpl extends AbstractSessionImpl
this.flushBeforeCompletionEnabled = flushBeforeCompletionEnabled;
this.autoCloseSessionEnabled = autoCloseSessionEnabled;
this.connectionReleaseMode = connectionReleaseMode;
- this.jdbcContext = new JDBCContextImpl( this, connection, interceptor );
+
+ this.transactionCoordinator = new TransactionCoordinatorImpl( connection, this );
+ this.transactionCoordinator.getJdbcCoordinator().getLogicalConnection().addObserver(
+ new ConnectionObserverStatsBridge( factory )
+ );
loadQueryInfluencers = new LoadQueryInfluencers( factory );
@@ -330,7 +339,7 @@ public final class SessionImpl extends AbstractSessionImpl
}
if ( rootSession == null ) {
- return jdbcContext.getConnectionManager().close();
+ return transactionCoordinator.close();
}
else {
return null;
@@ -343,7 +352,6 @@ public final class SessionImpl extends AbstractSessionImpl
}
public ConnectionReleaseMode getConnectionReleaseMode() {
- checkTransactionSynchStatus();
return connectionReleaseMode;
}
@@ -523,76 +531,84 @@ public final class SessionImpl extends AbstractSessionImpl
public Connection connection() throws HibernateException {
errorIfClosed();
- return jdbcContext.borrowConnection();
+ return transactionCoordinator.getJdbcCoordinator().getLogicalConnection().getDistinctConnectionProxy();
}
public boolean isConnected() {
checkTransactionSynchStatus();
- return !isClosed() && jdbcContext.getConnectionManager().isCurrentlyConnected();
+ return !isClosed() && transactionCoordinator.getJdbcCoordinator().getLogicalConnection().isOpen();
}
-
+
public boolean isTransactionInProgress() {
checkTransactionSynchStatus();
- return !isClosed() && jdbcContext.isTransactionInProgress();
+ return !isClosed() && transactionCoordinator.isTransactionInProgress();
}
public Connection disconnect() throws HibernateException {
errorIfClosed();
log.debug( "disconnecting session" );
- return jdbcContext.getConnectionManager().manualDisconnect();
+ return transactionCoordinator.getJdbcCoordinator().getLogicalConnection().manualDisconnect();
}
public void reconnect() throws HibernateException {
errorIfClosed();
log.debug( "reconnecting session" );
checkTransactionSynchStatus();
- jdbcContext.getConnectionManager().manualReconnect();
+ transactionCoordinator.getJdbcCoordinator().getLogicalConnection().manualReconnect( null );
}
public void reconnect(Connection conn) throws HibernateException {
errorIfClosed();
log.debug( "reconnecting session" );
checkTransactionSynchStatus();
- jdbcContext.getConnectionManager().manualReconnect( conn );
+ transactionCoordinator.getJdbcCoordinator().getLogicalConnection().manualReconnect( conn );
}
- public void beforeTransactionCompletion(Transaction tx) {
- log.trace( "before transaction completion" );
- actionQueue.beforeTransactionCompletion();
- if ( rootSession == null ) {
- try {
- interceptor.beforeTransactionCompletion(tx);
- }
- catch (Throwable t) {
- log.error("exception in interceptor beforeTransactionCompletion()", t);
- }
- }
- }
-
public void setAutoClear(boolean enabled) {
errorIfClosed();
autoClear = enabled;
}
-
+
/**
- * Check if there is a Hibernate or JTA transaction in progress and,
- * if there is not, flush if necessary, make sure the connection has
- * been committed (if it is not in autocommit mode) and run the after
+ * Check if there is a Hibernate or JTA transaction in progress and,
+ * if there is not, flush if necessary, make sure the connection has
+ * been committed (if it is not in autocommit mode) and run the after
* completion processing
*/
public void afterOperation(boolean success) {
- if ( !jdbcContext.isTransactionInProgress() ) {
- jdbcContext.afterNontransactionalQuery( success );
+ if ( ! transactionCoordinator.isTransactionInProgress() ) {
+ transactionCoordinator.afterNonTransactionalQuery( success );
}
}
- public void afterTransactionCompletion(boolean success, Transaction tx) {
+ @Override
+ public void afterTransactionBegin(TransactionImplementor hibernateTransaction) {
+ errorIfClosed();
+ interceptor.afterTransactionBegin( hibernateTransaction );
+ }
+
+ @Override
+ public void beforeTransactionCompletion(TransactionImplementor hibernateTransaction) {
+ log.trace( "before transaction completion" );
+ actionQueue.beforeTransactionCompletion();
+ if ( rootSession == null ) {
+ try {
+ interceptor.beforeTransactionCompletion( hibernateTransaction );
+ }
+ catch (Throwable t) {
+ log.error( "exception in interceptor beforeTransactionCompletion()", t );
+ }
+ }
+ }
+
+ @Override
+ public void afterTransactionCompletion(TransactionImplementor hibernateTransaction, boolean successful) {
log.trace( "after transaction completion" );
persistenceContext.afterTransactionCompletion();
- actionQueue.afterTransactionCompletion(success);
- if ( rootSession == null && tx != null ) {
+ actionQueue.afterTransactionCompletion( successful );
+ if ( rootSession == null && hibernateTransaction != null ) {
try {
- interceptor.afterTransactionCompletion(tx);
+ interceptor.afterTransactionCompletion( hibernateTransaction );
}
catch (Throwable t) {
log.error("exception in interceptor afterTransactionCompletion()", t);
@@ -660,11 +676,11 @@ public final class SessionImpl extends AbstractSessionImpl
// saveOrUpdate() operations ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
public void saveOrUpdate(Object object) throws HibernateException {
- saveOrUpdate(null, object);
+ saveOrUpdate( null, object );
}
public void saveOrUpdate(String entityName, Object obj) throws HibernateException {
- fireSaveOrUpdate( new SaveOrUpdateEvent(entityName, obj, this) );
+ fireSaveOrUpdate( new SaveOrUpdateEvent( entityName, obj, this ) );
}
private void fireSaveOrUpdate(SaveOrUpdateEvent event) {
@@ -684,15 +700,15 @@ public final class SessionImpl extends AbstractSessionImpl
}
public Serializable save(Object obj) throws HibernateException {
- return save(null, obj);
+ return save( null, obj );
}
public Serializable save(String entityName, Object object) throws HibernateException {
- return fireSave( new SaveOrUpdateEvent(entityName, object, this) );
+ return fireSave( new SaveOrUpdateEvent( entityName, object, this ) );
}
public void save(String entityName, Object object, Serializable id) throws HibernateException {
- fireSave( new SaveOrUpdateEvent(entityName, object, id, this) );
+ fireSave( new SaveOrUpdateEvent( entityName, object, id, this ) );
}
private Serializable fireSave(SaveOrUpdateEvent event) {
@@ -713,15 +729,15 @@ public final class SessionImpl extends AbstractSessionImpl
}
public void update(Object obj, Serializable id) throws HibernateException {
- update(null, obj, id);
+ update( null, obj, id );
}
public void update(String entityName, Object object) throws HibernateException {
- fireUpdate( new SaveOrUpdateEvent(entityName, object, this) );
+ fireUpdate( new SaveOrUpdateEvent( entityName, object, this ) );
}
public void update(String entityName, Object object, Serializable id) throws HibernateException {
- fireUpdate(new SaveOrUpdateEvent(entityName, object, id, this));
+ fireUpdate( new SaveOrUpdateEvent( entityName, object, id, this ) );
}
private void fireUpdate(SaveOrUpdateEvent event) {
@@ -753,7 +769,7 @@ public final class SessionImpl extends AbstractSessionImpl
}
private void fireLock( Object object, LockOptions options) {
- fireLock( new LockEvent( object, options, this) );
+ fireLock( new LockEvent( object, options, this ) );
}
private void fireLock(LockEvent lockEvent) {
@@ -769,16 +785,16 @@ public final class SessionImpl extends AbstractSessionImpl
// persist() operations ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
public void persist(String entityName, Object object) throws HibernateException {
- firePersist( new PersistEvent(entityName, object, this) );
+ firePersist( new PersistEvent( entityName, object, this ) );
}
public void persist(Object object) throws HibernateException {
- persist(null, object);
+ persist( null, object );
}
public void persist(String entityName, Object object, Map copiedAlready)
throws HibernateException {
- firePersist( copiedAlready, new PersistEvent(entityName, object, this) );
+ firePersist( copiedAlready, new PersistEvent( entityName, object, this ) );
}
private void firePersist(Map copiedAlready, PersistEvent event) {
@@ -804,16 +820,16 @@ public final class SessionImpl extends AbstractSessionImpl
public void persistOnFlush(String entityName, Object object)
throws HibernateException {
- firePersistOnFlush( new PersistEvent(entityName, object, this) );
+ firePersistOnFlush( new PersistEvent( entityName, object, this ) );
}
public void persistOnFlush(Object object) throws HibernateException {
- persist(null, object);
+ persist( null, object );
}
public void persistOnFlush(String entityName, Object object, Map copiedAlready)
throws HibernateException {
- firePersistOnFlush( copiedAlready, new PersistEvent(entityName, object, this) );
+ firePersistOnFlush( copiedAlready, new PersistEvent( entityName, object, this ) );
}
private void firePersistOnFlush(Map copiedAlready, PersistEvent event) {
@@ -838,15 +854,15 @@ public final class SessionImpl extends AbstractSessionImpl
// merge() operations ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
public Object merge(String entityName, Object object) throws HibernateException {
- return fireMerge( new MergeEvent(entityName, object, this) );
+ return fireMerge( new MergeEvent( entityName, object, this ) );
}
public Object merge(Object object) throws HibernateException {
- return merge(null, object);
+ return merge( null, object );
}
public void merge(String entityName, Object object, Map copiedAlready) throws HibernateException {
- fireMerge( copiedAlready, new MergeEvent(entityName, object, this) );
+ fireMerge( copiedAlready, new MergeEvent( entityName, object, this ) );
}
private Object fireMerge(MergeEvent event) {
@@ -873,7 +889,7 @@ public final class SessionImpl extends AbstractSessionImpl
public Object saveOrUpdateCopy(String entityName, Object object)
throws HibernateException {
- return fireSaveOrUpdateCopy( new MergeEvent(entityName, object, this) );
+ return fireSaveOrUpdateCopy( new MergeEvent( entityName, object, this ) );
}
public Object saveOrUpdateCopy(Object object) throws HibernateException {
@@ -882,7 +898,7 @@ public final class SessionImpl extends AbstractSessionImpl
public Object saveOrUpdateCopy(String entityName, Object object, Serializable id)
throws HibernateException {
- return fireSaveOrUpdateCopy( new MergeEvent(entityName, object, id, this) );
+ return fireSaveOrUpdateCopy( new MergeEvent( entityName, object, id, this ) );
}
public Object saveOrUpdateCopy(Object object, Serializable id)
@@ -1037,7 +1053,7 @@ public final class SessionImpl extends AbstractSessionImpl
}
public Object load(Class entityClass, Serializable id, LockOptions lockOptions) throws HibernateException {
- return load( entityClass.getName(), id, lockOptions);
+ return load( entityClass.getName(), id, lockOptions );
}
public Object load(String entityName, Serializable id, LockMode lockMode) throws HibernateException {
@@ -1057,7 +1073,7 @@ public final class SessionImpl extends AbstractSessionImpl
}
public Object get(Class entityClass, Serializable id, LockOptions lockOptions) throws HibernateException {
- return get( entityClass.getName(), id, lockOptions);
+ return get( entityClass.getName(), id, lockOptions );
}
public Object get(String entityName, Serializable id, LockMode lockMode) throws HibernateException {
@@ -1068,7 +1084,7 @@ public final class SessionImpl extends AbstractSessionImpl
public Object get(String entityName, Serializable id, LockOptions lockOptions) throws HibernateException {
LoadEvent event = new LoadEvent(id, entityName, lockOptions, this);
- fireLoad(event, LoadEventListener.GET);
+ fireLoad( event, LoadEventListener.GET );
return event.getResult();
}
@@ -1097,7 +1113,7 @@ public final class SessionImpl extends AbstractSessionImpl
}
public void refresh(Object object, Map refreshedAlready) throws HibernateException {
- fireRefresh( refreshedAlready, new RefreshEvent(object, this) );
+ fireRefresh( refreshedAlready, new RefreshEvent( object, this ) );
}
private void fireRefresh(RefreshEvent refreshEvent) {
@@ -1127,7 +1143,7 @@ public final class SessionImpl extends AbstractSessionImpl
public void replicate(String entityName, Object obj, ReplicationMode replicationMode)
throws HibernateException {
- fireReplicate( new ReplicateEvent(entityName, obj, replicationMode, this) );
+ fireReplicate( new ReplicateEvent( entityName, obj, replicationMode, this ) );
}
private void fireReplicate(ReplicateEvent event) {
@@ -1147,7 +1163,7 @@ public final class SessionImpl extends AbstractSessionImpl
* (references held by application or other persistant instances are okay)
*/
public void evict(Object object) throws HibernateException {
- fireEvict( new EvictEvent(object, this) );
+ fireEvict( new EvictEvent( object, this ) );
}
private void fireEvict(EvictEvent evictEvent) {
@@ -1289,7 +1305,7 @@ public final class SessionImpl extends AbstractSessionImpl
errorIfClosed();
checkTransactionSynchStatus();
queryParameters.validateParameters();
- NativeSQLQueryPlan plan = getNativeSQLQueryPlan(nativeQuerySpecification);
+ NativeSQLQueryPlan plan = getNativeSQLQueryPlan( nativeQuerySpecification );
autoFlushIfRequired( plan.getCustomQuery().getQuerySpaces() );
@@ -1394,11 +1410,11 @@ public final class SessionImpl extends AbstractSessionImpl
public Query getNamedQuery(String queryName) throws MappingException {
errorIfClosed();
checkTransactionSynchStatus();
- return super.getNamedQuery(queryName);
+ return super.getNamedQuery( queryName );
}
public Object instantiate(String entityName, Serializable id) throws HibernateException {
- return instantiate( factory.getEntityPersister(entityName), id );
+ return instantiate( factory.getEntityPersister( entityName ), id );
}
/**
@@ -1449,7 +1465,7 @@ public final class SessionImpl extends AbstractSessionImpl
public Transaction getTransaction() throws HibernateException {
errorIfClosed();
- return jdbcContext.getTransaction();
+ return transactionCoordinator.getTransaction();
}
public Transaction beginTransaction() throws HibernateException {
@@ -1463,11 +1479,6 @@ public final class SessionImpl extends AbstractSessionImpl
result.begin();
return result;
}
-
- public void afterTransactionBegin(Transaction tx) {
- errorIfClosed();
- interceptor.afterTransactionBegin(tx);
- }
public EntityPersister getEntityPersister(final String entityName, final Object object) {
errorIfClosed();
@@ -1522,7 +1533,7 @@ public final class SessionImpl extends AbstractSessionImpl
public Serializable getContextEntityIdentifier(Object object) {
errorIfClosed();
if ( object instanceof HibernateProxy ) {
- return getProxyIdentifier(object);
+ return getProxyIdentifier( object );
}
else {
EntityEntry entry = persistenceContext.getEntry(object);
@@ -1757,13 +1768,13 @@ public final class SessionImpl extends AbstractSessionImpl
public Query createQuery(String queryString) {
errorIfClosed();
checkTransactionSynchStatus();
- return super.createQuery(queryString);
+ return super.createQuery( queryString );
}
public SQLQuery createSQLQuery(String sql) {
errorIfClosed();
checkTransactionSynchStatus();
- return super.createSQLQuery(sql);
+ return super.createSQLQuery( sql );
}
public Query createSQLQuery(String sql, String returnAlias, Class returnClass) {
@@ -1839,11 +1850,11 @@ public final class SessionImpl extends AbstractSessionImpl
}
}
- public SessionFactory getSessionFactory() {
+ public SessionFactoryImplementor getSessionFactory() {
checkTransactionSynchStatus();
return factory;
}
-
+
public void initializeCollection(PersistentCollection collection, boolean writing)
throws HibernateException {
errorIfClosed();
@@ -1858,7 +1869,7 @@ public final class SessionImpl extends AbstractSessionImpl
if (object instanceof HibernateProxy) {
LazyInitializer initializer = ( ( HibernateProxy ) object ).getHibernateLazyInitializer();
// it is possible for this method to be called during flush processing,
- // so make certain that we do not accidently initialize an uninitialized proxy
+ // so make certain that we do not accidentally initialize an uninitialized proxy
if ( initializer.isUninitialized() ) {
return initializer.getEntityName();
}
@@ -1904,7 +1915,7 @@ public final class SessionImpl extends AbstractSessionImpl
public void cancelQuery() throws HibernateException {
errorIfClosed();
- getJDBCContext().getConnectionManager().cancelLastQuery();
+ getTransactionCoordinator().getJdbcCoordinator().cancelLastQuery();
}
public Interceptor getInterceptor() {
@@ -1983,23 +1994,17 @@ public final class SessionImpl extends AbstractSessionImpl
}
public void doWork(Work work) throws HibernateException {
- try {
- work.execute( jdbcContext.getConnectionManager().getConnection() );
- jdbcContext.getConnectionManager().afterStatement();
- }
- catch ( SQLException e ) {
- throw factory.getSQLExceptionHelper().convert( e, "error executing work" );
- }
+ transactionCoordinator.getJdbcCoordinator().coordinateWork( work );
}
public void afterScrollOperation() {
// nothing to do in a stateful session
}
- public JDBCContext getJDBCContext() {
+ @Override
+ public TransactionCoordinator getTransactionCoordinator() {
errorIfClosed();
- checkTransactionSynchStatus();
- return jdbcContext;
+ return transactionCoordinator;
}
public LoadQueryInfluencers getLoadQueryInfluencers() {
@@ -2098,8 +2103,8 @@ public final class SessionImpl extends AbstractSessionImpl
private void checkTransactionSynchStatus() {
- if ( jdbcContext != null && !isClosed() ) {
- jdbcContext.registerSynchronizationIfPossible();
+ if ( !isClosed() ) {
+ transactionCoordinator.pulse();
}
}
@@ -2131,7 +2136,7 @@ public final class SessionImpl extends AbstractSessionImpl
listeners = factory.getEventListeners();
if ( isRootSession ) {
- jdbcContext = JDBCContextImpl.deserialize( ois, this, interceptor );
+ transactionCoordinator = TransactionCoordinatorImpl.deserialize( ois, this );
}
persistenceContext = StatefulPersistenceContext.deserialize( ois, this );
@@ -2156,7 +2161,7 @@ public final class SessionImpl extends AbstractSessionImpl
while ( iter.hasNext() ) {
final SessionImpl child = ( ( SessionImpl ) iter.next() );
child.rootSession = this;
- child.jdbcContext = this.jdbcContext;
+ child.transactionCoordinator = this.transactionCoordinator;
}
}
}
@@ -2168,7 +2173,7 @@ public final class SessionImpl extends AbstractSessionImpl
* @throws IOException Indicates a general IO stream exception
*/
private void writeObject(ObjectOutputStream oos) throws IOException {
- if ( !jdbcContext.isReadyForSerialization() ) {
+ if ( ! transactionCoordinator.getJdbcCoordinator().getLogicalConnection().isReadyForSerialization() ) {
throw new IllegalStateException( "Cannot serialize a session while connected" );
}
@@ -2190,7 +2195,7 @@ public final class SessionImpl extends AbstractSessionImpl
factory.serialize( oos );
if ( rootSession == null ) {
- jdbcContext.serialize( oos );
+ transactionCoordinator.serialize( oos );
}
persistenceContext.serialize( oos );
@@ -2204,8 +2209,8 @@ public final class SessionImpl extends AbstractSessionImpl
/**
* {@inheritDoc}
*/
- public Object execute(Callback callback) {
- Connection connection = jdbcContext.getConnectionManager().getConnection();
+ public Object execute(LobCreationContext.Callback callback) {
+ Connection connection = transactionCoordinator.getJdbcCoordinator().getLogicalConnection().getConnection();
try {
return callback.executeOnConnection( connection );
}
@@ -2216,7 +2221,7 @@ public final class SessionImpl extends AbstractSessionImpl
);
}
finally {
- jdbcContext.getConnectionManager().afterStatement();
+ transactionCoordinator.getJdbcCoordinator().getLogicalConnection().afterStatementExecution();
}
}
diff --git a/hibernate-core/src/main/java/org/hibernate/impl/StatelessSessionImpl.java b/hibernate-core/src/main/java/org/hibernate/impl/StatelessSessionImpl.java
index c18b38f2fd..a564766587 100755
--- a/hibernate-core/src/main/java/org/hibernate/impl/StatelessSessionImpl.java
+++ b/hibernate-core/src/main/java/org/hibernate/impl/StatelessSessionImpl.java
@@ -21,16 +21,6 @@
*/
package org.hibernate.impl;
-import java.io.Serializable;
-import java.sql.Connection;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import org.hibernate.CacheMode;
import org.hibernate.ConnectionReleaseMode;
import org.hibernate.Criteria;
@@ -50,17 +40,19 @@ import org.hibernate.UnresolvableObjectException;
import org.hibernate.cache.CacheKey;
import org.hibernate.collection.PersistentCollection;
import org.hibernate.engine.EntityKey;
+import org.hibernate.engine.LoadQueryInfluencers;
+import org.hibernate.engine.NonFlushedChanges;
import org.hibernate.engine.PersistenceContext;
import org.hibernate.engine.QueryParameters;
import org.hibernate.engine.StatefulPersistenceContext;
import org.hibernate.engine.Versioning;
-import org.hibernate.engine.LoadQueryInfluencers;
-import org.hibernate.engine.NonFlushedChanges;
-import org.hibernate.engine.jdbc.internal.JDBCContextImpl;
-import org.hibernate.engine.jdbc.spi.JDBCContext;
import org.hibernate.engine.query.HQLQueryPlan;
import org.hibernate.engine.query.NativeSQLQueryPlan;
import org.hibernate.engine.query.sql.NativeSQLQuerySpecification;
+import org.hibernate.engine.transaction.internal.TransactionCoordinatorImpl;
+import org.hibernate.engine.transaction.spi.TransactionCoordinator;
+import org.hibernate.engine.transaction.spi.TransactionEnvironment;
+import org.hibernate.engine.transaction.spi.TransactionImplementor;
import org.hibernate.event.EventListeners;
import org.hibernate.id.IdentifierGeneratorHelper;
import org.hibernate.loader.criteria.CriteriaLoader;
@@ -72,23 +64,42 @@ import org.hibernate.pretty.MessageHelper;
import org.hibernate.proxy.HibernateProxy;
import org.hibernate.type.Type;
import org.hibernate.util.CollectionHelper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.Serializable;
+import java.sql.Connection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
/**
* @author Gavin King
*/
-public class StatelessSessionImpl extends AbstractSessionImpl
- implements JDBCContext.Context, StatelessSession {
-
+public class StatelessSessionImpl extends AbstractSessionImpl implements StatelessSession {
private static final Logger log = LoggerFactory.getLogger( StatelessSessionImpl.class );
- private JDBCContextImpl jdbcContext;
+ private TransactionCoordinator transactionCoordinator;
private PersistenceContext temporaryPersistenceContext = new StatefulPersistenceContext( this );
StatelessSessionImpl(Connection connection, SessionFactoryImpl factory) {
super( factory );
- this.jdbcContext = new JDBCContextImpl( this, connection, EmptyInterceptor.INSTANCE );
+ this.transactionCoordinator = new TransactionCoordinatorImpl( connection, this );
}
+ // TransactionContext ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ @Override
+ public TransactionCoordinator getTransactionCoordinator() {
+ return transactionCoordinator;
+ }
+
+ @Override
+ public TransactionEnvironment getTransactionEnvironment() {
+ return factory.getTransactionEnvironment();
+ }
// inserts ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -324,22 +335,33 @@ public class StatelessSessionImpl extends AbstractSessionImpl
if ( isClosed() ) {
throw new SessionException( "Session was already closed!" );
}
- jdbcContext.getConnectionManager().close();
+ transactionCoordinator.close();
setClosed();
}
public void managedFlush() {
errorIfClosed();
- getJDBCContext().getConnectionManager().executeBatch();
+ getTransactionCoordinator().getJdbcCoordinator().executeBatch();
}
public boolean shouldAutoClose() {
return isAutoCloseSessionEnabled() && !isClosed();
}
- public void afterTransactionCompletion(boolean successful, Transaction tx) {}
+ @Override
+ public void afterTransactionBegin(TransactionImplementor hibernateTransaction) {
+ // nothing to do here
+ }
- public void beforeTransactionCompletion(Transaction tx) {}
+ @Override
+ public void beforeTransactionCompletion(TransactionImplementor hibernateTransaction) {
+ // nothing to do here
+ }
+
+ @Override
+ public void afterTransactionCompletion(TransactionImplementor hibernateTransaction, boolean successful) {
+ // nothing to do here
+ }
public String bestGuessEntityName(Object object) {
if (object instanceof HibernateProxy) {
@@ -350,7 +372,7 @@ public class StatelessSessionImpl extends AbstractSessionImpl
public Connection connection() {
errorIfClosed();
- return jdbcContext.borrowConnection();
+ return transactionCoordinator.getJdbcCoordinator().getLogicalConnection().getDistinctConnectionProxy();
}
public int executeUpdate(String query, QueryParameters queryParameters)
@@ -444,11 +466,11 @@ public class StatelessSessionImpl extends AbstractSessionImpl
public boolean isConnected() {
- return jdbcContext.getConnectionManager().isCurrentlyConnected();
+ return transactionCoordinator.getJdbcCoordinator().getLogicalConnection().isPhysicallyConnected();
}
public boolean isTransactionInProgress() {
- return jdbcContext.isTransactionInProgress();
+ return transactionCoordinator.isTransactionInProgress();
}
public void setAutoClear(boolean enabled) {
@@ -465,7 +487,7 @@ public class StatelessSessionImpl extends AbstractSessionImpl
public Transaction getTransaction() throws HibernateException {
errorIfClosed();
- return jdbcContext.getTransaction();
+ return transactionCoordinator.getTransaction();
}
public Transaction beginTransaction() throws HibernateException {
@@ -517,8 +539,8 @@ public class StatelessSessionImpl extends AbstractSessionImpl
}
public void afterOperation(boolean success) {
- if ( !jdbcContext.isTransactionInProgress() ) {
- jdbcContext.afterNontransactionalQuery(success);
+ if ( ! transactionCoordinator.isTransactionInProgress() ) {
+ transactionCoordinator.afterNonTransactionalQuery( success );;
}
}
@@ -619,7 +641,7 @@ public class StatelessSessionImpl extends AbstractSessionImpl
throws HibernateException {
errorIfClosed();
CustomLoader loader = new CustomLoader( customQuery, getFactory() );
- return loader.scroll(queryParameters, this);
+ return loader.scroll( queryParameters, this );
}
public ScrollableResults scroll(String query, QueryParameters queryParameters) throws HibernateException {
@@ -646,10 +668,6 @@ public class StatelessSessionImpl extends AbstractSessionImpl
return null;
}
- public JDBCContext getJDBCContext() {
- return jdbcContext;
- }
-
public LoadQueryInfluencers getLoadQueryInfluencers() {
return LoadQueryInfluencers.NONE;
}
@@ -667,8 +685,6 @@ public class StatelessSessionImpl extends AbstractSessionImpl
public void setFetchProfile(String name) {}
- public void afterTransactionBegin(Transaction tx) {}
-
protected boolean autoFlushIfRequired(Set querySpaces) throws HibernateException {
// no auto-flushing to support in stateless session
return false;
diff --git a/hibernate-core/src/main/java/org/hibernate/impl/TransactionEnvironmentImpl.java b/hibernate-core/src/main/java/org/hibernate/impl/TransactionEnvironmentImpl.java
new file mode 100644
index 0000000000..a3b67f7f5d
--- /dev/null
+++ b/hibernate-core/src/main/java/org/hibernate/impl/TransactionEnvironmentImpl.java
@@ -0,0 +1,67 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2011, 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
+ */
+package org.hibernate.impl;
+
+import org.hibernate.ConnectionReleaseMode;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.engine.jdbc.spi.JdbcServices;
+import org.hibernate.engine.transaction.spi.TransactionEnvironment;
+import org.hibernate.engine.transaction.spi.TransactionFactory;
+import org.hibernate.service.jta.platform.spi.JtaPlatform;
+import org.hibernate.service.spi.ServiceRegistry;
+
+/**
+ * @author Steve Ebersole
+ */
+public class TransactionEnvironmentImpl implements TransactionEnvironment {
+ private final SessionFactoryImpl sessionFactory;
+
+ public TransactionEnvironmentImpl(SessionFactoryImpl sessionFactory) {
+ this.sessionFactory = sessionFactory;
+ }
+
+ @Override
+ public SessionFactoryImplementor getSessionFactory() {
+ return sessionFactory;
+ }
+
+ protected ServiceRegistry serviceRegistry() {
+ return sessionFactory.getServiceRegistry();
+ }
+
+ @Override
+ public JdbcServices getJdbcServices() {
+ return serviceRegistry().getService( JdbcServices.class );
+ }
+
+ @Override
+ public JtaPlatform getJtaPlatform() {
+ return serviceRegistry().getService( JtaPlatform.class );
+ }
+
+ @Override
+ public TransactionFactory getTransactionFactory() {
+ return serviceRegistry().getService( TransactionFactory.class );
+ }
+}
diff --git a/hibernate-core/src/main/java/org/hibernate/jdbc/BorrowedConnectionProxy.java b/hibernate-core/src/main/java/org/hibernate/jdbc/BorrowedConnectionProxy.java
deleted file mode 100644
index 3b3ff05b5d..0000000000
--- a/hibernate-core/src/main/java/org/hibernate/jdbc/BorrowedConnectionProxy.java
+++ /dev/null
@@ -1,138 +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.jdbc;
-
-import org.hibernate.HibernateException;
-import org.hibernate.engine.jdbc.internal.LogicalConnectionImpl;
-
-import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.Method;
-import java.lang.reflect.Proxy;
-import java.lang.reflect.InvocationTargetException;
-import java.sql.Connection;
-
-/**
- * A proxy for borrowed connections which funnels all requests back
- * into the ConnectionManager from which it was borrowed to be properly
- * handled (in terms of connection release modes).
- *
- * Note: the term borrowed here refers to connection references obtained
- * via {@link org.hibernate.Session#connection()} for application usage.
- *
- * @author Steve Ebersole
- */
-public class BorrowedConnectionProxy implements InvocationHandler {
-
- private static final Class[] PROXY_INTERFACES = new Class[] { Connection.class, ConnectionWrapper.class };
-
- private final LogicalConnectionImpl logicalConnection;
- private boolean useable = true;
-
- public BorrowedConnectionProxy(LogicalConnectionImpl logicalConnection) {
- this.logicalConnection = logicalConnection;
- }
-
- /**
- * {@inheritDoc}
- */
- public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
- if ( "close".equals( method.getName() ) ) {
- logicalConnection.releaseBorrowedConnection();
- return null;
- }
- // should probably no-op commit/rollback here, at least in JTA scenarios
- if ( !useable ) {
- throw new HibernateException( "connnection proxy not usable after transaction completion" );
- }
-
- if ( "getWrappedConnection".equals( method.getName() ) ) {
- return logicalConnection.getConnection();
- }
-
- try {
- return method.invoke( logicalConnection.getConnection(), args );
- }
- catch( InvocationTargetException e ) {
- throw e.getTargetException();
- }
- }
-
- /**
- * Generates a Connection proxy wrapping the connection managed by the passed
- * connection manager.
- *
- * @param logicalConnection The logical connection to wrap with the
- * connection proxy.
- * @return The generated proxy.
- */
- public static Connection generateProxy(LogicalConnectionImpl logicalConnection) {
- BorrowedConnectionProxy handler = new BorrowedConnectionProxy( logicalConnection );
- return ( Connection ) Proxy.newProxyInstance(
- getProxyClassLoader(),
- PROXY_INTERFACES,
- handler
- );
- }
-
- /**
- * Marks a borrowed connection as no longer usable.
- *
- * @param connection The connection (proxy) to be marked.
- */
- public static void renderUnuseable(Connection connection) {
- if ( connection != null && Proxy.isProxyClass( connection.getClass() ) ) {
- InvocationHandler handler = Proxy.getInvocationHandler( connection );
- if ( BorrowedConnectionProxy.class.isAssignableFrom( handler.getClass() ) ) {
- ( ( BorrowedConnectionProxy ) handler ).useable = false;
- }
- }
- }
-
- /**
- * Convience method for unwrapping a connection proxy and getting a
- * handle to an underlying connection.
- *
- * @param connection The connection (proxy) to be unwrapped.
- * @return The unwrapped connection.
- */
- public static Connection getWrappedConnection(Connection connection) {
- if ( connection != null && connection instanceof ConnectionWrapper ) {
- return ( ( ConnectionWrapper ) connection ).getWrappedConnection();
- }
- else {
- return connection;
- }
- }
-
- /**
- * Determines the appropriate class loader to which the generated proxy
- * should be scoped.
- *
- * @return The class loader appropriate for proxy construction.
- */
- public static ClassLoader getProxyClassLoader() {
- return ConnectionWrapper.class.getClassLoader();
- }
-}
diff --git a/hibernate-core/src/main/java/org/hibernate/jmx/HibernateService.java b/hibernate-core/src/main/java/org/hibernate/jmx/HibernateService.java
index 9b3396b638..68c109f8ff 100644
--- a/hibernate-core/src/main/java/org/hibernate/jmx/HibernateService.java
+++ b/hibernate-core/src/main/java/org/hibernate/jmx/HibernateService.java
@@ -13,6 +13,7 @@ import org.hibernate.HibernateException;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Environment;
import org.hibernate.service.internal.ServiceRegistryImpl;
+import org.hibernate.service.jta.platform.internal.JtaPlatformInitiator;
import org.hibernate.tool.hbm2ddl.SchemaExport;
import org.hibernate.internal.util.jndi.JndiHelper;
import org.hibernate.util.ExternalSessionFactoryConfig;
@@ -28,12 +29,12 @@ import org.hibernate.util.ExternalSessionFactoryConfig;
* @author John Urberg, Gavin King
*/
public class HibernateService extends ExternalSessionFactoryConfig implements HibernateServiceMBean {
-
- private static final Logger log = LoggerFactory.getLogger(HibernateServiceMBean.class);
+ private static final Logger log = LoggerFactory.getLogger( HibernateServiceMBean.class );
private String boundName;
private Properties properties = new Properties();
+ @Override
public void start() throws HibernateException {
boundName = getJndiName();
try {
@@ -46,6 +47,7 @@ public class HibernateService extends ExternalSessionFactoryConfig implements Hi
}
}
+ @Override
public void stop() {
log.info("stopping service");
try {
@@ -64,100 +66,126 @@ public class HibernateService extends ExternalSessionFactoryConfig implements Hi
return buildConfiguration().buildSessionFactory( new ServiceRegistryImpl( properties ) );
}
+ @Override
protected Map getExtraProperties() {
return properties;
}
+ @Override
public String getTransactionStrategy() {
return getProperty(Environment.TRANSACTION_STRATEGY);
}
+ @Override
public void setTransactionStrategy(String txnStrategy) {
setProperty(Environment.TRANSACTION_STRATEGY, txnStrategy);
}
+ @Override
public String getUserTransactionName() {
return getProperty(Environment.USER_TRANSACTION);
}
+ @Override
public void setUserTransactionName(String utName) {
setProperty(Environment.USER_TRANSACTION, utName);
}
- public String getTransactionManagerLookupStrategy() {
- return getProperty(Environment.TRANSACTION_MANAGER_STRATEGY);
+ @Override
+ public String getJtaPlatformName() {
+ return getProperty( JtaPlatformInitiator.JTA_PLATFORM );
}
- public void setTransactionManagerLookupStrategy(String lkpStrategy) {
- setProperty(Environment.TRANSACTION_MANAGER_STRATEGY, lkpStrategy);
+ @Override
+ public void setJtaPlatformName(String name) {
+ setProperty( JtaPlatformInitiator.JTA_PLATFORM, name );
}
+ @Override
public String getPropertyList() {
return buildProperties().toString();
}
+ @Override
public String getProperty(String property) {
return properties.getProperty(property);
}
+ @Override
public void setProperty(String property, String value) {
properties.setProperty(property, value);
}
+ @Override
public void dropSchema() {
new SchemaExport( buildConfiguration() ).drop(false, true);
}
+ @Override
public void createSchema() {
new SchemaExport( buildConfiguration() ).create(false, true);
- } public String getName() {
+ }
+
+ public String getName() {
return getProperty(Environment.SESSION_FACTORY_NAME);
}
+ @Override
public String getDatasource() {
return getProperty(Environment.DATASOURCE);
}
+ @Override
public void setDatasource(String datasource) {
setProperty(Environment.DATASOURCE, datasource);
}
+ @Override
public String getJndiName() {
return getProperty(Environment.SESSION_FACTORY_NAME);
}
+ @Override
public void setJndiName(String jndiName) {
setProperty(Environment.SESSION_FACTORY_NAME, jndiName);
}
+ @Override
public String getUserName() {
return getProperty(Environment.USER);
}
+ @Override
public void setUserName(String userName) {
setProperty(Environment.USER, userName);
}
+ @Override
public String getPassword() {
return getProperty(Environment.PASS);
}
+ @Override
public void setPassword(String password) {
setProperty(Environment.PASS, password);
}
+ @Override
public void setFlushBeforeCompletionEnabled(String enabled) {
setProperty(Environment.FLUSH_BEFORE_COMPLETION, enabled);
}
+ @Override
public String getFlushBeforeCompletionEnabled() {
return getProperty(Environment.FLUSH_BEFORE_COMPLETION);
}
+ @Override
public void setAutoCloseSessionEnabled(String enabled) {
setProperty(Environment.AUTO_CLOSE_SESSION, enabled);
}
+ @Override
public String getAutoCloseSessionEnabled() {
return getProperty(Environment.AUTO_CLOSE_SESSION);
}
diff --git a/hibernate-core/src/main/java/org/hibernate/jmx/HibernateServiceMBean.java b/hibernate-core/src/main/java/org/hibernate/jmx/HibernateServiceMBean.java
index d161c7f0cf..13e768405d 100644
--- a/hibernate-core/src/main/java/org/hibernate/jmx/HibernateServiceMBean.java
+++ b/hibernate-core/src/main/java/org/hibernate/jmx/HibernateServiceMBean.java
@@ -104,44 +104,47 @@ public interface HibernateServiceMBean {
public void setJndiName(String jndiName);
/**
- * The fully qualified class name of the Hibernate TransactionFactory implementation
+ * The fully qualified class name of the Hibernate {@link org.hibernate.engine.transaction.spi.TransactionFactory}
+ * implementation to use
+ *
* @return the class name
- * @see org.hibernate.transaction.TransactionFactory
*/
public String getTransactionStrategy();
/**
- * Set the fully qualified class name of the Hibernate TransactionFactory implementation
+ * Set the fully qualified class name of the Hibernate {@link org.hibernate.engine.transaction.spi.TransactionFactory}
+ * implementation to use.
+ *
* @param txnStrategy the class name
- * @see org.hibernate.transaction.TransactionFactory
*/
public void setTransactionStrategy(String txnStrategy);
/**
- * The JNDI name of the JTA UserTransaction object (used only be JTATransaction).
+ * The JNDI name of the JTA UserTransaction object (used only be JtaTransaction).
* @return the JNDI name
- * @see org.hibernate.transaction.JTATransaction
+ * @see org.hibernate.engine.transaction.internal.jta.JtaTransaction
*/
public String getUserTransactionName();
/**
- * Set the JNDI name of the JTA UserTransaction object (used only by JTATransaction).
+ * Set the JNDI name of the JTA UserTransaction object (used only by JtaTransaction).
* @param utName the JNDI name
- * @see org.hibernate.transaction.JTATransaction
+ * @see org.hibernate.engine.transaction.internal.jta.JtaTransaction
*/
public void setUserTransactionName(String utName);
/**
- * Get the strategy for obtaining the JTA TransactionManager
- * @return the class name
- * @see org.hibernate.transaction.TransactionManagerLookup
+ * Get the name of the {@link org.hibernate.service.jta.platform.spi.JtaPlatform} implementation to use.
+ *
+ * @return The name of the {@link org.hibernate.service.jta.platform.spi.JtaPlatform} implementation to use.
*/
- public String getTransactionManagerLookupStrategy();
+ public String getJtaPlatformName();
+
/**
- * Set the strategy for obtaining the JTA TransactionManager
- * @param lkpStrategy the class name
- * @see org.hibernate.transaction.TransactionManagerLookup
+ * Sets the name of the {@link org.hibernate.service.jta.platform.spi.JtaPlatform} implementation to use.
+ *
+ * @param name The implementation class name.
*/
- public void setTransactionManagerLookupStrategy(String lkpStrategy);
+ public void setJtaPlatformName(String name);
/**
* Is SQL logging enabled?
diff --git a/hibernate-core/src/main/java/org/hibernate/loader/Loader.java b/hibernate-core/src/main/java/org/hibernate/loader/Loader.java
index b0e8d6ca91..2f67dd3e74 100644
--- a/hibernate-core/src/main/java/org/hibernate/loader/Loader.java
+++ b/hibernate-core/src/main/java/org/hibernate/loader/Loader.java
@@ -1731,11 +1731,17 @@ public abstract class Loader {
boolean hasFirstRow = getFirstRow( selection ) > 0;
boolean useOffset = hasFirstRow && useLimit && dialect.supportsLimitOffset();
boolean callable = queryParameters.isCallable();
-
- boolean useScrollableResultSetToSkip = hasFirstRow &&
+
+ final boolean canScroll = getFactory().getSettings().isScrollableResultSetsEnabled();
+ final boolean useScrollableResultSetToSkip = hasFirstRow &&
!useOffset &&
getFactory().getSettings().isScrollableResultSetsEnabled();
- ScrollMode scrollMode = scroll ? queryParameters.getScrollMode() : ScrollMode.SCROLL_INSENSITIVE;
+ final ScrollMode scrollMode =
+ canScroll
+ ? scroll || useScrollableResultSetToSkip
+ ? queryParameters.getScrollMode()
+ : ScrollMode.SCROLL_INSENSITIVE
+ : null;
if ( useLimit ) {
sql = dialect.getLimitString(
@@ -1746,14 +1752,14 @@ public abstract class Loader {
}
sql = preprocessSQL( sql, queryParameters, dialect );
-
+
PreparedStatement st = null;
- st = session.getJDBCContext().getConnectionManager().prepareQueryStatement(
+
+ st = session.getTransactionCoordinator().getJdbcCoordinator().getStatementPreparer().prepareQueryStatement(
sql,
- scroll || useScrollableResultSetToSkip,
- scrollMode,
- callable
+ callable,
+ scrollMode
);
try {
diff --git a/hibernate-core/src/main/java/org/hibernate/persister/collection/AbstractCollectionPersister.java b/hibernate-core/src/main/java/org/hibernate/persister/collection/AbstractCollectionPersister.java
index cabd43a6bd..9136e97486 100644
--- a/hibernate-core/src/main/java/org/hibernate/persister/collection/AbstractCollectionPersister.java
+++ b/hibernate-core/src/main/java/org/hibernate/persister/collection/AbstractCollectionPersister.java
@@ -23,15 +23,6 @@
*/
package org.hibernate.persister.collection;
-import java.io.Serializable;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-
import org.hibernate.AssertionFailure;
import org.hibernate.FetchMode;
import org.hibernate.HibernateException;
@@ -54,6 +45,7 @@ import org.hibernate.engine.PersistenceContext;
import org.hibernate.engine.SessionFactoryImplementor;
import org.hibernate.engine.SessionImplementor;
import org.hibernate.engine.SubselectFetch;
+import org.hibernate.engine.jdbc.batch.internal.BasicBatchKey;
import org.hibernate.engine.jdbc.spi.SQLExceptionHelper;
import org.hibernate.exception.SQLExceptionConverter;
import org.hibernate.id.IdentifierGenerator;
@@ -88,6 +80,15 @@ import org.hibernate.util.StringHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import java.io.Serializable;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
/**
* Base implementation of the QueryableCollection interface.
@@ -1062,8 +1063,9 @@ public abstract class AbstractCollectionPersister
return qualifiedTableName;
}
- public void remove(Serializable id, SessionImplementor session) throws HibernateException {
+ private BasicBatchKey removeBatchKey;
+ public void remove(Serializable id, SessionImplementor session) throws HibernateException {
if ( !isInverse && isRowDeleteEnabled() ) {
if ( log.isDebugEnabled() ) {
@@ -1083,10 +1085,22 @@ public abstract class AbstractCollectionPersister
boolean useBatch = expectation.canBeBatched();
String sql = getSQLDeleteString();
if ( useBatch ) {
- st = session.getJDBCContext().getConnectionManager().prepareBatchStatement( this, sql, callable );
+ if ( removeBatchKey == null ) {
+ removeBatchKey = new BasicBatchKey(
+ getRole() + "#REMOVE",
+ expectation
+ );
+ }
+ st = session.getTransactionCoordinator()
+ .getJdbcCoordinator()
+ .getBatch( removeBatchKey )
+ .getBatchStatement( sql, callable );
}
else {
- st = session.getJDBCContext().getConnectionManager().prepareStatement( sql, callable );
+ st = session.getTransactionCoordinator()
+ .getJdbcCoordinator()
+ .getStatementPreparer()
+ .prepareStatement( sql, callable );
}
@@ -1095,7 +1109,10 @@ public abstract class AbstractCollectionPersister
writeKey( st, id, offset, session );
if ( useBatch ) {
- session.getJDBCContext().getConnectionManager().addToBatch( this, sql, expectation );
+ session.getTransactionCoordinator()
+ .getJdbcCoordinator()
+ .getBatch( removeBatchKey )
+ .addToBatch();
}
else {
expectation.verifyOutcome( st.executeUpdate(), st, -1 );
@@ -1103,7 +1120,7 @@ public abstract class AbstractCollectionPersister
}
catch ( SQLException sqle ) {
if ( useBatch ) {
- session.getJDBCContext().getConnectionManager().abortBatch();
+ session.getTransactionCoordinator().getJdbcCoordinator().abortBatch();
}
throw sqle;
}
@@ -1130,6 +1147,8 @@ public abstract class AbstractCollectionPersister
}
+ private BasicBatchKey recreateBatchKey;
+
public void recreate(PersistentCollection collection, Serializable id, SessionImplementor session)
throws HibernateException {
@@ -1146,6 +1165,7 @@ public abstract class AbstractCollectionPersister
//create all the new entries
Iterator entries = collection.entries(this);
if ( entries.hasNext() ) {
+ Expectation expectation = Expectations.appropriateExpectation( getInsertCheckStyle() );
collection.preInsert( this );
int i = 0;
int count = 0;
@@ -1155,18 +1175,27 @@ public abstract class AbstractCollectionPersister
if ( collection.entryExists( entry, i ) ) {
int offset = 1;
PreparedStatement st = null;
- Expectation expectation = Expectations.appropriateExpectation( getInsertCheckStyle() );
boolean callable = isInsertCallable();
boolean useBatch = expectation.canBeBatched();
String sql = getSQLInsertRowString();
if ( useBatch ) {
- st = session.getJDBCContext().getConnectionManager().prepareBatchStatement(
- this, sql, callable
- );
+ if ( recreateBatchKey == null ) {
+ recreateBatchKey = new BasicBatchKey(
+ getRole() + "#RECREATE",
+ expectation
+ );
+ }
+ st = session.getTransactionCoordinator()
+ .getJdbcCoordinator()
+ .getBatch( recreateBatchKey )
+ .getBatchStatement( sql, callable );
}
else {
- st = session.getJDBCContext().getConnectionManager().prepareStatement( sql, callable );
+ st = session.getTransactionCoordinator()
+ .getJdbcCoordinator()
+ .getStatementPreparer()
+ .prepareStatement( sql, callable );
}
@@ -1184,7 +1213,10 @@ public abstract class AbstractCollectionPersister
loc = writeElement(st, collection.getElement(entry), loc, session );
if ( useBatch ) {
- session.getJDBCContext().getConnectionManager().addToBatch( this, sql, expectation );
+ session.getTransactionCoordinator()
+ .getJdbcCoordinator()
+ .getBatch( recreateBatchKey )
+ .addToBatch();
}
else {
expectation.verifyOutcome( st.executeUpdate(), st, -1 );
@@ -1195,7 +1227,7 @@ public abstract class AbstractCollectionPersister
}
catch ( SQLException sqle ) {
if ( useBatch ) {
- session.getJDBCContext().getConnectionManager().abortBatch();
+ session.getTransactionCoordinator().getJdbcCoordinator().abortBatch();
}
throw sqle;
}
@@ -1235,6 +1267,8 @@ public abstract class AbstractCollectionPersister
return true;
}
+ private BasicBatchKey deleteBatchKey;
+
public void deleteRows(PersistentCollection collection, Serializable id, SessionImplementor session)
throws HibernateException {
@@ -1248,7 +1282,7 @@ public abstract class AbstractCollectionPersister
}
boolean deleteByIndex = !isOneToMany() && hasIndex && !indexContainsFormula;
-
+ final Expectation expectation = Expectations.appropriateExpectation( getDeleteCheckStyle() );
try {
//delete all the deleted entries
Iterator deletes = collection.getDeletes( this, !deleteByIndex );
@@ -1257,18 +1291,27 @@ public abstract class AbstractCollectionPersister
int count = 0;
while ( deletes.hasNext() ) {
PreparedStatement st = null;
- Expectation expectation = Expectations.appropriateExpectation( getDeleteCheckStyle() );
boolean callable = isDeleteCallable();
boolean useBatch = expectation.canBeBatched();
String sql = getSQLDeleteRowString();
if ( useBatch ) {
- st = session.getJDBCContext().getConnectionManager().prepareBatchStatement(
- this, sql, callable
- );
+ if ( deleteBatchKey == null ) {
+ deleteBatchKey = new BasicBatchKey(
+ getRole() + "#DELETE",
+ expectation
+ );
+ }
+ st = session.getTransactionCoordinator()
+ .getJdbcCoordinator()
+ .getBatch( deleteBatchKey )
+ .getBatchStatement( sql, callable );
}
else {
- st = session.getJDBCContext().getConnectionManager().prepareStatement( sql, callable );
+ st = session.getTransactionCoordinator()
+ .getJdbcCoordinator()
+ .getStatementPreparer()
+ .prepareStatement( sql, callable );
}
try {
@@ -1290,7 +1333,10 @@ public abstract class AbstractCollectionPersister
}
if ( useBatch ) {
- session.getJDBCContext().getConnectionManager().addToBatch( this, sql, expectation );
+ session.getTransactionCoordinator()
+ .getJdbcCoordinator()
+ .getBatch( deleteBatchKey )
+ .addToBatch();
}
else {
expectation.verifyOutcome( st.executeUpdate(), st, -1 );
@@ -1299,7 +1345,7 @@ public abstract class AbstractCollectionPersister
}
catch ( SQLException sqle ) {
if ( useBatch ) {
- session.getJDBCContext().getConnectionManager().abortBatch();
+ session.getTransactionCoordinator().getJdbcCoordinator().abortBatch();
}
throw sqle;
}
@@ -1335,6 +1381,8 @@ public abstract class AbstractCollectionPersister
return true;
}
+ private BasicBatchKey insertBatchKey;
+
public void insertRows(PersistentCollection collection, Serializable id, SessionImplementor session)
throws HibernateException {
@@ -1364,14 +1412,24 @@ public abstract class AbstractCollectionPersister
if ( collection.needsInserting( entry, i, elementType ) ) {
if ( useBatch ) {
- if ( st == null ) {
- st = session.getJDBCContext().getConnectionManager().prepareBatchStatement(
- this, sql, callable
+ if ( insertBatchKey == null ) {
+ insertBatchKey = new BasicBatchKey(
+ getRole() + "#INSERT",
+ expectation
);
}
+ if ( st == null ) {
+ st = session.getTransactionCoordinator()
+ .getJdbcCoordinator()
+ .getBatch( insertBatchKey )
+ .getBatchStatement( sql, callable );
+ }
}
else {
- st = session.getJDBCContext().getConnectionManager().prepareStatement( sql, callable );
+ st = session.getTransactionCoordinator()
+ .getJdbcCoordinator()
+ .getStatementPreparer()
+ .prepareStatement( sql, callable );
}
try {
@@ -1387,7 +1445,7 @@ public abstract class AbstractCollectionPersister
writeElement(st, collection.getElement(entry), offset, session );
if ( useBatch ) {
- session.getJDBCContext().getConnectionManager().addToBatch( this, sql, expectation );
+ session.getTransactionCoordinator().getJdbcCoordinator().getBatch( insertBatchKey ).addToBatch();
}
else {
expectation.verifyOutcome( st.executeUpdate(), st, -1 );
@@ -1397,7 +1455,7 @@ public abstract class AbstractCollectionPersister
}
catch ( SQLException sqle ) {
if ( useBatch ) {
- session.getJDBCContext().getConnectionManager().abortBatch();
+ session.getTransactionCoordinator().getJdbcCoordinator().abortBatch();
}
throw sqle;
}
@@ -1709,7 +1767,10 @@ public abstract class AbstractCollectionPersister
public int getSize(Serializable key, SessionImplementor session) {
try {
- PreparedStatement st = session.getJDBCContext().getConnectionManager().prepareSelectStatement(sqlSelectSizeString);
+ PreparedStatement st = session.getTransactionCoordinator()
+ .getJdbcCoordinator()
+ .getStatementPreparer()
+ .prepareStatement( sqlSelectSizeString );
try {
getKeyType().nullSafeSet(st, key, 1, session);
ResultSet rs = st.executeQuery();
@@ -1744,7 +1805,10 @@ public abstract class AbstractCollectionPersister
private boolean exists(Serializable key, Object indexOrElement, Type indexOrElementType, String sql, SessionImplementor session) {
try {
- PreparedStatement st = session.getJDBCContext().getConnectionManager().prepareSelectStatement(sql);
+ PreparedStatement st = session.getTransactionCoordinator()
+ .getJdbcCoordinator()
+ .getStatementPreparer()
+ .prepareStatement( sql );
try {
getKeyType().nullSafeSet(st, key, 1, session);
indexOrElementType.nullSafeSet( st, indexOrElement, keyColumnNames.length + 1, session );
@@ -1775,7 +1839,10 @@ public abstract class AbstractCollectionPersister
public Object getElementByIndex(Serializable key, Object index, SessionImplementor session, Object owner) {
try {
- PreparedStatement st = session.getJDBCContext().getConnectionManager().prepareSelectStatement(sqlSelectRowByIndexString);
+ PreparedStatement st = session.getTransactionCoordinator()
+ .getJdbcCoordinator()
+ .getStatementPreparer()
+ .prepareStatement( sqlSelectRowByIndexString );
try {
getKeyType().nullSafeSet(st, key, 1, session);
getIndexType().nullSafeSet( st, incrementIndexByBase(index), keyColumnNames.length + 1, session );
diff --git a/hibernate-core/src/main/java/org/hibernate/persister/collection/BasicCollectionPersister.java b/hibernate-core/src/main/java/org/hibernate/persister/collection/BasicCollectionPersister.java
index 4fa624149b..80e5c73487 100644
--- a/hibernate-core/src/main/java/org/hibernate/persister/collection/BasicCollectionPersister.java
+++ b/hibernate-core/src/main/java/org/hibernate/persister/collection/BasicCollectionPersister.java
@@ -39,6 +39,7 @@ import org.hibernate.engine.SessionFactoryImplementor;
import org.hibernate.engine.SessionImplementor;
import org.hibernate.engine.SubselectFetch;
import org.hibernate.engine.LoadQueryInfluencers;
+import org.hibernate.engine.jdbc.batch.internal.BasicBatchKey;
import org.hibernate.jdbc.Expectation;
import org.hibernate.jdbc.Expectations;
import org.hibernate.loader.collection.BatchingCollectionInitializer;
@@ -190,6 +191,8 @@ public class BasicCollectionPersister extends AbstractCollectionPersister {
return elementType.isEntityType(); //instanceof AssociationType;
}
+ private BasicBatchKey updateBatchKey;
+
protected int doUpdateRows(Serializable id, PersistentCollection collection, SessionImplementor session)
throws HibernateException {
@@ -210,14 +213,22 @@ public class BasicCollectionPersister extends AbstractCollectionPersister {
int offset = 1;
if ( useBatch ) {
- if ( st == null ) {
- st = session.getJDBCContext().getConnectionManager().prepareBatchStatement(
- this, sql, callable
+ if ( updateBatchKey == null ) {
+ updateBatchKey = new BasicBatchKey(
+ getRole() + "#UPDATE",
+ expectation
);
}
+ st = session.getTransactionCoordinator()
+ .getJdbcCoordinator()
+ .getBatch( updateBatchKey )
+ .getBatchStatement( sql, callable );
}
else {
- st = session.getJDBCContext().getConnectionManager().prepareStatement( sql, callable );
+ st = session.getTransactionCoordinator()
+ .getJdbcCoordinator()
+ .getStatementPreparer()
+ .prepareStatement( sql, callable );
}
try {
@@ -237,7 +248,10 @@ public class BasicCollectionPersister extends AbstractCollectionPersister {
}
if ( useBatch ) {
- session.getJDBCContext().getConnectionManager().addToBatch( this, sql, expectation );
+ session.getTransactionCoordinator()
+ .getJdbcCoordinator()
+ .getBatch( updateBatchKey )
+ .addToBatch();
}
else {
expectation.verifyOutcome( st.executeUpdate(), st, -1 );
@@ -245,7 +259,7 @@ public class BasicCollectionPersister extends AbstractCollectionPersister {
}
catch ( SQLException sqle ) {
if ( useBatch ) {
- session.getJDBCContext().getConnectionManager().abortBatch();
+ session.getTransactionCoordinator().getJdbcCoordinator().abortBatch();
}
throw sqle;
}
diff --git a/hibernate-core/src/main/java/org/hibernate/persister/collection/OneToManyPersister.java b/hibernate-core/src/main/java/org/hibernate/persister/collection/OneToManyPersister.java
index 2057a92cd6..64978a4af9 100644
--- a/hibernate-core/src/main/java/org/hibernate/persister/collection/OneToManyPersister.java
+++ b/hibernate-core/src/main/java/org/hibernate/persister/collection/OneToManyPersister.java
@@ -24,21 +24,16 @@
*/
package org.hibernate.persister.collection;
-import java.io.Serializable;
-import java.sql.PreparedStatement;
-import java.sql.SQLException;
-import java.util.Iterator;
-
-import org.hibernate.HibernateException;
import org.hibernate.MappingException;
import org.hibernate.cache.CacheException;
import org.hibernate.cache.access.CollectionRegionAccessStrategy;
import org.hibernate.cfg.Configuration;
import org.hibernate.collection.PersistentCollection;
+import org.hibernate.engine.LoadQueryInfluencers;
import org.hibernate.engine.SessionFactoryImplementor;
import org.hibernate.engine.SessionImplementor;
import org.hibernate.engine.SubselectFetch;
-import org.hibernate.engine.LoadQueryInfluencers;
+import org.hibernate.engine.jdbc.batch.internal.BasicBatchKey;
import org.hibernate.jdbc.Expectation;
import org.hibernate.jdbc.Expectations;
import org.hibernate.loader.collection.BatchingCollectionInitializer;
@@ -52,6 +47,11 @@ import org.hibernate.pretty.MessageHelper;
import org.hibernate.sql.Update;
import org.hibernate.util.ArrayHelper;
+import java.io.Serializable;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.util.Iterator;
+
/**
* Collection persister for one-to-many associations.
*
@@ -174,8 +174,10 @@ public class OneToManyPersister extends AbstractCollectionPersister {
return false;
}
- protected int doUpdateRows(Serializable id, PersistentCollection collection, SessionImplementor session)
- throws HibernateException {
+ private BasicBatchKey deleteRowBatchKey;
+ private BasicBatchKey insertRowBatchKey;
+
+ protected int doUpdateRows(Serializable id, PersistentCollection collection, SessionImplementor session) {
// we finish all the "removes" first to take care of possible unique
// constraints and so that we can take better advantage of batching
@@ -183,53 +185,58 @@ public class OneToManyPersister extends AbstractCollectionPersister {
try {
int count = 0;
if ( isRowDeleteEnabled() ) {
- boolean useBatch = true;
+ final Expectation deleteExpectation = Expectations.appropriateExpectation( getDeleteCheckStyle() );
+ final boolean useBatch = deleteExpectation.canBeBatched();
+ if ( useBatch && deleteRowBatchKey == null ) {
+ deleteRowBatchKey = new BasicBatchKey(
+ getRole() + "#DELETEROW",
+ deleteExpectation
+ );
+ }
+ final String sql = getSQLDeleteRowString();
+
PreparedStatement st = null;
// update removed rows fks to null
try {
int i = 0;
-
Iterator entries = collection.entries( this );
int offset = 1;
- Expectation expectation = Expectations.NONE;
while ( entries.hasNext() ) {
-
Object entry = entries.next();
if ( collection.needsUpdating( entry, i, elementType ) ) { // will still be issued when it used to be null
- String sql = getSQLDeleteRowString();
- if ( st == null ) {
- if ( isDeleteCallable() ) {
- expectation = Expectations.appropriateExpectation( getDeleteCheckStyle() );
- useBatch = expectation.canBeBatched();
- st = useBatch
- ? session.getJDBCContext().getConnectionManager().prepareBatchStatement( this, sql, true )
- : session.getJDBCContext().getConnectionManager().prepareStatement( sql, true );
- offset += expectation.prepare( st );
- }
- else {
- st = session.getJDBCContext().getConnectionManager().prepareBatchStatement(
- this, sql, false
- );
- }
+ if ( useBatch ) {
+ st = session.getTransactionCoordinator()
+ .getJdbcCoordinator()
+ .getBatch( deleteRowBatchKey )
+ .getBatchStatement( sql, isDeleteCallable() );
+ }
+ else {
+ st = session.getTransactionCoordinator()
+ .getJdbcCoordinator()
+ .getStatementPreparer()
+ .prepareStatement( sql, isDeleteCallable() );
}
int loc = writeKey( st, id, offset, session );
writeElementToWhere( st, collection.getSnapshotElement(entry, i), loc, session );
if ( useBatch ) {
- session.getJDBCContext().getConnectionManager().addToBatch( this, sql, expectation );
+ session.getTransactionCoordinator()
+ .getJdbcCoordinator()
+ .getBatch( deleteRowBatchKey )
+ .addToBatch();
}
else {
- expectation.verifyOutcome( st.executeUpdate(), st, -1 );
+ deleteExpectation.verifyOutcome( st.executeUpdate(), st, -1 );
}
count++;
}
i++;
}
}
- catch ( SQLException sqle ) {
+ catch ( SQLException e ) {
if ( useBatch ) {
- session.getJDBCContext().getConnectionManager().abortBatch();
+ session.getTransactionCoordinator().getJdbcCoordinator().abortBatch();
}
- throw sqle;
+ throw e;
}
finally {
if ( !useBatch ) {
@@ -239,10 +246,17 @@ public class OneToManyPersister extends AbstractCollectionPersister {
}
if ( isRowInsertEnabled() ) {
- Expectation expectation = Expectations.appropriateExpectation( getInsertCheckStyle() );
+ final Expectation insertExpectation = Expectations.appropriateExpectation( getInsertCheckStyle() );
+ boolean useBatch = insertExpectation.canBeBatched();
boolean callable = isInsertCallable();
- boolean useBatch = expectation.canBeBatched();
- String sql = getSQLInsertRowString();
+ if ( useBatch && insertRowBatchKey == null ) {
+ insertRowBatchKey = new BasicBatchKey(
+ getRole() + "#INSERTROW",
+ insertExpectation
+ );
+ }
+ final String sql = getSQLInsertRowString();
+
PreparedStatement st = null;
// now update all changed or added rows fks
try {
@@ -253,17 +267,19 @@ public class OneToManyPersister extends AbstractCollectionPersister {
int offset = 1;
if ( collection.needsUpdating( entry, i, elementType ) ) {
if ( useBatch ) {
- if ( st == null ) {
- st = session.getJDBCContext().getConnectionManager().prepareBatchStatement(
- this, sql, callable
- );
- }
+ st = session.getTransactionCoordinator()
+ .getJdbcCoordinator()
+ .getBatch( insertRowBatchKey )
+ .getBatchStatement( sql, callable );
}
else {
- st = session.getJDBCContext().getConnectionManager().prepareStatement( sql, callable );
+ st = session.getTransactionCoordinator()
+ .getJdbcCoordinator()
+ .getStatementPreparer()
+ .prepareStatement( sql, callable );
}
- offset += expectation.prepare( st );
+ offset += insertExpectation.prepare( st );
int loc = writeKey( st, id, offset, session );
if ( hasIndex && !indexContainsFormula ) {
@@ -273,10 +289,10 @@ public class OneToManyPersister extends AbstractCollectionPersister {
writeElementToWhere( st, collection.getElement( entry ), loc, session );
if ( useBatch ) {
- session.getJDBCContext().getConnectionManager().addToBatch( this, sql, expectation );
+ session.getTransactionCoordinator().getJdbcCoordinator().getBatch( insertRowBatchKey ).addToBatch();
}
else {
- expectation.verifyOutcome( st.executeUpdate(), st, -1 );
+ insertExpectation.verifyOutcome( st.executeUpdate(), st, -1 );
}
count++;
}
@@ -285,7 +301,7 @@ public class OneToManyPersister extends AbstractCollectionPersister {
}
catch ( SQLException sqle ) {
if ( useBatch ) {
- session.getJDBCContext().getConnectionManager().abortBatch();
+ session.getTransactionCoordinator().getJdbcCoordinator().abortBatch();
}
throw sqle;
}
diff --git a/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java b/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java
index 612ed153fb..22b6f8dcab 100644
--- a/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java
+++ b/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java
@@ -23,22 +23,6 @@
*/
package org.hibernate.persister.entity;
-import java.io.Serializable;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Set;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
import org.hibernate.AssertionFailure;
import org.hibernate.EntityMode;
import org.hibernate.FetchMode;
@@ -67,6 +51,7 @@ import org.hibernate.engine.SessionFactoryImplementor;
import org.hibernate.engine.SessionImplementor;
import org.hibernate.engine.ValueInclusion;
import org.hibernate.engine.Versioning;
+import org.hibernate.engine.jdbc.batch.internal.BasicBatchKey;
import org.hibernate.id.IdentifierGenerator;
import org.hibernate.id.PostInsertIdentifierGenerator;
import org.hibernate.id.PostInsertIdentityPersister;
@@ -111,6 +96,21 @@ import org.hibernate.type.VersionType;
import org.hibernate.util.ArrayHelper;
import org.hibernate.util.FilterHelper;
import org.hibernate.util.StringHelper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.Serializable;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
/**
* Basic functionality for persisting an entity via JDBC
@@ -854,7 +854,10 @@ public abstract class AbstractEntityPersister
// null sql means that the only lazy properties
// are shared PK one-to-one associations which are
// handled differently in the Type#nullSafeGet code...
- ps = session.getJDBCContext().getConnectionManager().prepareSelectStatement(lazySelect);
+ ps = session.getTransactionCoordinator()
+ .getJdbcCoordinator()
+ .getStatementPreparer()
+ .prepareStatement( lazySelect );
getIdentifierType().nullSafeSet( ps, id, 1, session );
rs = ps.executeQuery();
rs.next();
@@ -1101,7 +1104,10 @@ public abstract class AbstractEntityPersister
}
try {
- PreparedStatement ps = session.getJDBCContext().getConnectionManager().prepareSelectStatement( getSQLSnapshotSelectString() );
+ PreparedStatement ps = session.getTransactionCoordinator()
+ .getJdbcCoordinator()
+ .getStatementPreparer()
+ .prepareStatement( getSQLSnapshotSelectString() );
try {
getIdentifierType().nullSafeSet( ps, id, 1, session );
//if ( isVersioned() ) getVersionType().nullSafeSet( ps, version, getIdentifierColumnSpan()+1, session );
@@ -1111,7 +1117,6 @@ public abstract class AbstractEntityPersister
if ( !rs.next() ) {
return null;
}
-
//otherwise return the "hydrated" state (ie. associations are not resolved)
Type[] types = getPropertyTypes();
Object[] values = new Object[types.length];
@@ -1131,13 +1136,12 @@ public abstract class AbstractEntityPersister
ps.close();
}
}
- catch ( SQLException sqle ) {
+ catch ( SQLException e ) {
throw getFactory().getSQLExceptionHelper().convert(
- sqle,
- "could not retrieve snapshot: " +
- MessageHelper.infoString( this, id, getFactory() ),
+ e,
+ "could not retrieve snapshot: " + MessageHelper.infoString( this, id, getFactory() ),
getSQLSnapshotSelectString()
- );
+ );
}
}
@@ -1315,8 +1319,11 @@ public abstract class AbstractEntityPersister
String versionIncrementString = generateVersionIncrementUpdateString();
PreparedStatement st = null;
try {
+ st = session.getTransactionCoordinator()
+ .getJdbcCoordinator()
+ .getStatementPreparer()
+ .prepareStatement( versionIncrementString, false );
try {
- st = session.getJDBCContext().getConnectionManager().prepareStatement( versionIncrementString, false );
getVersionType().nullSafeSet( st, nextVersion, 1, session );
getIdentifierType().nullSafeSet( st, id, 2, session );
getVersionType().nullSafeSet( st, currentVersion, 2 + getIdentifierColumnSpan(), session );
@@ -1363,11 +1370,12 @@ public abstract class AbstractEntityPersister
}
try {
-
- PreparedStatement st = session.getJDBCContext().getConnectionManager().prepareSelectStatement( getVersionSelectString() );
+ PreparedStatement st = session.getTransactionCoordinator()
+ .getJdbcCoordinator()
+ .getStatementPreparer()
+ .prepareStatement( getVersionSelectString() );
try {
getIdentifierType().nullSafeSet( st, id, 1, session );
-
ResultSet rs = st.executeQuery();
try {
if ( !rs.next() ) {
@@ -1385,17 +1393,14 @@ public abstract class AbstractEntityPersister
finally {
st.close();
}
-
}
- catch ( SQLException sqle ) {
+ catch ( SQLException e ) {
throw getFactory().getSQLExceptionHelper().convert(
- sqle,
- "could not retrieve version: " +
- MessageHelper.infoString( this, id, getFactory() ),
+ e,
+ "could not retrieve version: " + MessageHelper.infoString( this, id, getFactory() ),
getVersionSelectString()
- );
+ );
}
-
}
protected void initLockers() {
@@ -2223,7 +2228,10 @@ public abstract class AbstractEntityPersister
final String sql = rootPersister.getSequentialSelect( getEntityName() );
if ( sql != null ) {
//TODO: I am not so sure about the exception handling in this bit!
- sequentialSelect = session.getJDBCContext().getConnectionManager().prepareSelectStatement( sql );
+ sequentialSelect = session.getTransactionCoordinator()
+ .getJdbcCoordinator()
+ .getStatementPreparer()
+ .prepareStatement( sql );
rootPersister.getIdentifierType().nullSafeSet( sequentialSelect, id, 1, session );
sequentialResultSet = sequentialSelect.executeQuery();
if ( !sequentialResultSet.next() ) {
@@ -2355,6 +2363,8 @@ public abstract class AbstractEntityPersister
.toStatementString();
}
+ private BasicBatchKey inserBatchKey;
+
/**
* Perform an SQL INSERT.
*
@@ -2387,20 +2397,33 @@ public abstract class AbstractEntityPersister
}
}
- Expectation expectation = Expectations.appropriateExpectation( insertResultCheckStyles[j] );
- boolean callable = isInsertCallable( j );
+ // TODO : shouldn't inserts be Expectations.NONE?
+ final Expectation expectation = Expectations.appropriateExpectation( insertResultCheckStyles[j] );
// we can't batch joined inserts, *especially* not if it is an identity insert;
// nor can we batch statements where the expectation is based on an output param
final boolean useBatch = j == 0 && expectation.canBeBatched();
- try {
+ if ( useBatch && inserBatchKey == null ) {
+ inserBatchKey = new BasicBatchKey(
+ getEntityName() + "#INSERT",
+ expectation
+ );
+ }
+ final boolean callable = isInsertCallable( j );
+ try {
// Render the SQL query
final PreparedStatement insert;
if ( useBatch ) {
- insert = session.getJDBCContext().getConnectionManager().prepareBatchStatement( this, sql, callable );
+ insert = session.getTransactionCoordinator()
+ .getJdbcCoordinator()
+ .getBatch( inserBatchKey )
+ .getBatchStatement( sql, callable );
}
else {
- insert = session.getJDBCContext().getConnectionManager().prepareStatement( sql, callable );
+ insert = session.getTransactionCoordinator()
+ .getJdbcCoordinator()
+ .getStatementPreparer()
+ .prepareStatement( sql, callable );
}
try {
@@ -2413,19 +2436,18 @@ public abstract class AbstractEntityPersister
dehydrate( id, fields, null, notNull, propertyColumnInsertable, j, insert, session, index );
if ( useBatch ) {
- // TODO : shouldnt inserts be Expectations.NONE?
- session.getJDBCContext().getConnectionManager().addToBatch( this, sql, expectation );
+ session.getTransactionCoordinator().getJdbcCoordinator().getBatch( inserBatchKey ).addToBatch();
}
else {
expectation.verifyOutcome( insert.executeUpdate(), insert, -1 );
}
}
- catch ( SQLException sqle ) {
+ catch ( SQLException e ) {
if ( useBatch ) {
- session.getJDBCContext().getConnectionManager().abortBatch();
+ session.getTransactionCoordinator().getJdbcCoordinator().abortBatch();
}
- throw sqle;
+ throw e;
}
finally {
if ( !useBatch ) {
@@ -2433,12 +2455,12 @@ public abstract class AbstractEntityPersister
}
}
}
- catch ( SQLException sqle ) {
+ catch ( SQLException e ) {
throw getFactory().getSQLExceptionHelper().convert(
- sqle,
+ e,
"could not insert: " + MessageHelper.infoString( this ),
sql
- );
+ );
}
}
@@ -2487,6 +2509,8 @@ public abstract class AbstractEntityPersister
}
+ private BasicBatchKey updateBatchKey;
+
protected boolean update(
final Serializable id,
final Object[] fields,
@@ -2499,10 +2523,16 @@ public abstract class AbstractEntityPersister
final String sql,
final SessionImplementor session) throws HibernateException {
- final boolean useVersion = j == 0 && isVersioned();
final Expectation expectation = Expectations.appropriateExpectation( updateResultCheckStyles[j] );
- final boolean callable = isUpdateCallable( j );
final boolean useBatch = j == 0 && expectation.canBeBatched() && isBatchable(); //note: updates to joined tables can't be batched...
+ if ( useBatch && updateBatchKey == null ) {
+ updateBatchKey = new BasicBatchKey(
+ getEntityName() + "#UPDATE",
+ expectation
+ );
+ }
+ final boolean callable = isUpdateCallable( j );
+ final boolean useVersion = j == 0 && isVersioned();
if ( log.isTraceEnabled() ) {
log.trace( "Updating entity: " + MessageHelper.infoString( this, id, getFactory() ) );
@@ -2512,18 +2542,22 @@ public abstract class AbstractEntityPersister
}
try {
-
int index = 1; // starting index
final PreparedStatement update;
if ( useBatch ) {
- update = session.getJDBCContext().getConnectionManager().prepareBatchStatement( this, sql, callable );
+ update = session.getTransactionCoordinator()
+ .getJdbcCoordinator()
+ .getBatch( updateBatchKey )
+ .getBatchStatement( sql, callable );
}
else {
- update = session.getJDBCContext().getConnectionManager().prepareStatement( sql, callable );
+ update = session.getTransactionCoordinator()
+ .getJdbcCoordinator()
+ .getStatementPreparer()
+ .prepareStatement( sql, callable );
}
try {
-
index+= expectation.prepare( update );
//Now write the values of fields onto the prepared statement
@@ -2559,7 +2593,7 @@ public abstract class AbstractEntityPersister
}
if ( useBatch ) {
- session.getJDBCContext().getConnectionManager().addToBatch( this, sql, expectation );
+ session.getTransactionCoordinator().getJdbcCoordinator().getBatch( updateBatchKey ).addToBatch();
return true;
}
else {
@@ -2567,11 +2601,11 @@ public abstract class AbstractEntityPersister
}
}
- catch ( SQLException sqle ) {
+ catch ( SQLException e ) {
if ( useBatch ) {
- session.getJDBCContext().getConnectionManager().abortBatch();
+ session.getTransactionCoordinator().getJdbcCoordinator().abortBatch();
}
- throw sqle;
+ throw e;
}
finally {
if ( !useBatch ) {
@@ -2580,15 +2614,17 @@ public abstract class AbstractEntityPersister
}
}
- catch ( SQLException sqle ) {
+ catch ( SQLException e ) {
throw getFactory().getSQLExceptionHelper().convert(
- sqle,
+ e,
"could not update: " + MessageHelper.infoString( this, id, getFactory() ),
sql
);
}
}
+ private BasicBatchKey deleteBatchKey;
+
/**
* Perform an SQL DELETE
*/
@@ -2609,6 +2645,12 @@ public abstract class AbstractEntityPersister
final boolean callable = isDeleteCallable( j );
final Expectation expectation = Expectations.appropriateExpectation( deleteResultCheckStyles[j] );
final boolean useBatch = j == 0 && isBatchable() && expectation.canBeBatched();
+ if ( useBatch && deleteBatchKey == null ) {
+ deleteBatchKey = new BasicBatchKey(
+ getEntityName() + "#DELETE",
+ expectation
+ );
+ }
if ( log.isTraceEnabled() ) {
log.trace( "Deleting entity: " + MessageHelper.infoString( this, id, getFactory() ) );
@@ -2625,15 +2667,20 @@ public abstract class AbstractEntityPersister
}
try {
-
//Render the SQL query
PreparedStatement delete;
int index = 1;
if ( useBatch ) {
- delete = session.getJDBCContext().getConnectionManager().prepareBatchStatement( this, sql, callable );
+ delete = session.getTransactionCoordinator()
+ .getJdbcCoordinator()
+ .getBatch( deleteBatchKey )
+ .getBatchStatement( sql, callable );
}
else {
- delete = session.getJDBCContext().getConnectionManager().prepareStatement( sql, callable );
+ delete = session.getTransactionCoordinator()
+ .getJdbcCoordinator()
+ .getStatementPreparer()
+ .prepareStatement( sql, callable );
}
try {
@@ -2665,7 +2712,7 @@ public abstract class AbstractEntityPersister
}
if ( useBatch ) {
- session.getJDBCContext().getConnectionManager().addToBatch( this, sql, expectation );
+ session.getTransactionCoordinator().getJdbcCoordinator().getBatch( deleteBatchKey ).addToBatch();
}
else {
check( delete.executeUpdate(), id, j, expectation, delete );
@@ -2674,7 +2721,7 @@ public abstract class AbstractEntityPersister
}
catch ( SQLException sqle ) {
if ( useBatch ) {
- session.getJDBCContext().getConnectionManager().abortBatch();
+ session.getTransactionCoordinator().getJdbcCoordinator().abortBatch();
}
throw sqle;
}
@@ -3956,11 +4003,14 @@ public abstract class AbstractEntityPersister
SessionImplementor session,
String selectionSQL,
ValueInclusion[] includeds) {
-
- session.getJDBCContext().getConnectionManager().executeBatch(); //force immediate execution of the insert
+ // force immediate execution of the insert batch (if one)
+ session.getTransactionCoordinator().getJdbcCoordinator().executeBatch();
try {
- PreparedStatement ps = session.getJDBCContext().getConnectionManager().prepareSelectStatement( selectionSQL );
+ PreparedStatement ps = session.getTransactionCoordinator()
+ .getJdbcCoordinator()
+ .getStatementPreparer()
+ .prepareStatement( selectionSQL );
try {
getIdentifierType().nullSafeSet( ps, id, 1, session );
ResultSet rs = ps.executeQuery();
@@ -3989,9 +4039,9 @@ public abstract class AbstractEntityPersister
ps.close();
}
}
- catch( SQLException sqle ) {
+ catch( SQLException e ) {
throw getFactory().getSQLExceptionHelper().convert(
- sqle,
+ e,
"unable to select generated column values",
selectionSQL
);
@@ -4056,7 +4106,10 @@ public abstract class AbstractEntityPersister
Object[] snapshot = new Object[ naturalIdPropertyCount ];
try {
- PreparedStatement ps = session.getJDBCContext().getConnectionManager().prepareSelectStatement( sql );
+ PreparedStatement ps = session.getTransactionCoordinator()
+ .getJdbcCoordinator()
+ .getStatementPreparer()
+ .prepareStatement( sql );
try {
getIdentifierType().nullSafeSet( ps, id, 1, session );
ResultSet rs = ps.executeQuery();
@@ -4065,7 +4118,6 @@ public abstract class AbstractEntityPersister
if ( !rs.next() ) {
return null;
}
-
final EntityKey key = new EntityKey( id, this, session.getEntityMode() );
Object owner = session.getPersistenceContext().getEntity( key );
for ( int i = 0; i < naturalIdPropertyCount; i++ ) {
@@ -4084,13 +4136,12 @@ public abstract class AbstractEntityPersister
ps.close();
}
}
- catch ( SQLException sqle ) {
+ catch ( SQLException e ) {
throw getFactory().getSQLExceptionHelper().convert(
- sqle,
- "could not retrieve snapshot: " +
- MessageHelper.infoString( this, id, getFactory() ),
+ e,
+ "could not retrieve snapshot: " + MessageHelper.infoString( this, id, getFactory() ),
sql
- );
+ );
}
}
diff --git a/hibernate-core/src/main/java/org/hibernate/service/internal/ServiceInitializer.java b/hibernate-core/src/main/java/org/hibernate/service/internal/ServiceInitializer.java
index 48002ff973..4917e50c6f 100644
--- a/hibernate-core/src/main/java/org/hibernate/service/internal/ServiceInitializer.java
+++ b/hibernate-core/src/main/java/org/hibernate/service/internal/ServiceInitializer.java
@@ -101,6 +101,9 @@ public class ServiceInitializer {
// PHASE 1 : create service
T service = createService( serviceRole );
+ if ( service == null ) {
+ return null;
+ }
// PHASE 2 : configure service (***potentially recursive***)
configureService( service );
@@ -145,13 +148,18 @@ public class ServiceInitializer {
}
private void applyInjections(T service) {
- for ( Method method : service.getClass().getMethods() ) {
- InjectService injectService = method.getAnnotation( InjectService.class );
- if ( injectService == null ) {
- continue;
- }
+ try {
+ for ( Method method : service.getClass().getMethods() ) {
+ InjectService injectService = method.getAnnotation( InjectService.class );
+ if ( injectService == null ) {
+ continue;
+ }
- applyInjection( service, method, injectService );
+ applyInjection( service, method, injectService );
+ }
+ }
+ catch (NullPointerException e) {
+ log.error( "NPE injecting service deps : " + service.getClass().getName() );
}
}
diff --git a/hibernate-core/src/main/java/org/hibernate/service/internal/ServiceRegistryImpl.java b/hibernate-core/src/main/java/org/hibernate/service/internal/ServiceRegistryImpl.java
index 65f8e094cf..bb53ab4a03 100644
--- a/hibernate-core/src/main/java/org/hibernate/service/internal/ServiceRegistryImpl.java
+++ b/hibernate-core/src/main/java/org/hibernate/service/internal/ServiceRegistryImpl.java
@@ -39,6 +39,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
@@ -73,7 +74,7 @@ public class ServiceRegistryImpl implements ServiceRegistry, ServiceProxyTargetS
}
public void destroy() {
- ListIterator serviceIterator = serviceList.listIterator();
+ ListIterator serviceIterator = serviceList.listIterator( serviceList.size() );
while ( serviceIterator.hasPrevious() ) {
final Service service = serviceIterator.previous();
if ( Stoppable.class.isInstance( service ) ) {
diff --git a/hibernate-core/src/main/java/org/hibernate/service/jdbc/connections/internal/DriverManagerConnectionProviderImpl.java b/hibernate-core/src/main/java/org/hibernate/service/jdbc/connections/internal/DriverManagerConnectionProviderImpl.java
index 8ce96e19c9..de059feb8d 100644
--- a/hibernate-core/src/main/java/org/hibernate/service/jdbc/connections/internal/DriverManagerConnectionProviderImpl.java
+++ b/hibernate-core/src/main/java/org/hibernate/service/jdbc/connections/internal/DriverManagerConnectionProviderImpl.java
@@ -51,6 +51,7 @@ import org.hibernate.util.ReflectHelper;
* @author Gavin King
* @author Steve Ebersole
*/
+@SuppressWarnings( {"UnnecessaryUnboxing"})
public class DriverManagerConnectionProviderImpl implements ConnectionProvider, Configurable, Stoppable {
private static final Logger log = LoggerFactory.getLogger( DriverManagerConnectionProviderImpl.class );
@@ -63,6 +64,8 @@ public class DriverManagerConnectionProviderImpl implements ConnectionProvider,
private final ArrayList pool = new ArrayList();
private int checkedOut = 0;
+ private boolean stopped;
+
@Override
public boolean isUnwrappableAs(Class unwrapType) {
return ConnectionProvider.class.equals( unwrapType ) ||
@@ -144,6 +147,7 @@ public class DriverManagerConnectionProviderImpl implements ConnectionProvider,
}
}
pool.clear();
+ stopped = true;
}
public Connection getConnection() throws SQLException {
@@ -157,7 +161,7 @@ public class DriverManagerConnectionProviderImpl implements ConnectionProvider,
log.trace( "using pooled JDBC connection, pool size: " + last );
checkedOut++;
}
- Connection pooled = (Connection) pool.remove(last);
+ Connection pooled = pool.remove(last);
if ( isolation != null ) {
pooled.setTransactionIsolation( isolation.intValue() );
}
@@ -205,8 +209,11 @@ public class DriverManagerConnectionProviderImpl implements ConnectionProvider,
conn.close();
}
- protected void finalize() {
- stop();
+ protected void finalize() throws Throwable {
+ if ( !stopped ) {
+ stop();
+ }
+ super.finalize();
}
public boolean supportsAggressiveRelease() {
diff --git a/hibernate-core/src/main/java/org/hibernate/service/jta/platform/internal/AbstractJtaPlatform.java b/hibernate-core/src/main/java/org/hibernate/service/jta/platform/internal/AbstractJtaPlatform.java
new file mode 100644
index 0000000000..8a6f696b17
--- /dev/null
+++ b/hibernate-core/src/main/java/org/hibernate/service/jta/platform/internal/AbstractJtaPlatform.java
@@ -0,0 +1,133 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2011, 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
+ */
+package org.hibernate.service.jta.platform.internal;
+
+import org.hibernate.internal.util.config.ConfigurationHelper;
+import org.hibernate.service.jndi.spi.JndiService;
+import org.hibernate.service.jta.platform.spi.JtaPlatform;
+import org.hibernate.service.spi.Configurable;
+import org.hibernate.service.spi.ServiceRegistry;
+import org.hibernate.service.spi.ServiceRegistryAwareService;
+
+import javax.transaction.Synchronization;
+import javax.transaction.SystemException;
+import javax.transaction.Transaction;
+import javax.transaction.TransactionManager;
+import javax.transaction.UserTransaction;
+import java.util.Map;
+
+/**
+ * @author Steve Ebersole
+ */
+public abstract class AbstractJtaPlatform
+ implements JtaPlatform, Configurable, ServiceRegistryAwareService, TransactionManagerAccess {
+ private boolean cacheTransactionManager;
+ private boolean cacheUserTransaction;
+ private ServiceRegistry serviceRegistry;
+
+ @Override
+ public void injectServices(ServiceRegistry serviceRegistry) {
+ this.serviceRegistry = serviceRegistry;
+ }
+
+ protected ServiceRegistry serviceRegistry() {
+ return serviceRegistry;
+ }
+
+ protected JndiService jndiService() {
+ return serviceRegistry().getService( JndiService.class );
+ }
+
+ protected abstract TransactionManager locateTransactionManager();
+ protected abstract UserTransaction locateUserTransaction();
+
+ public void configure(Map configValues) {
+ cacheTransactionManager = ConfigurationHelper.getBoolean( CACHE_TM, configValues, true );
+ cacheUserTransaction = ConfigurationHelper.getBoolean( CACHE_UT, configValues, false );
+ }
+
+ protected boolean canCacheTransactionManager() {
+ return cacheTransactionManager;
+ }
+
+ protected boolean canCacheUserTransaction() {
+ return cacheUserTransaction;
+ }
+
+ private TransactionManager transactionManager;
+
+ @Override
+ public TransactionManager retrieveTransactionManager() {
+ if ( canCacheTransactionManager() ) {
+ if ( transactionManager == null ) {
+ transactionManager = locateTransactionManager();
+ }
+ return transactionManager;
+ }
+ else {
+ return locateTransactionManager();
+ }
+ }
+
+ @Override
+ public TransactionManager getTransactionManager() {
+ return retrieveTransactionManager();
+ }
+
+ private UserTransaction userTransaction;
+
+ @Override
+ public UserTransaction retrieveUserTransaction() {
+ if ( canCacheUserTransaction() ) {
+ if ( userTransaction == null ) {
+ userTransaction = locateUserTransaction();
+ }
+ return userTransaction;
+ }
+ return locateUserTransaction();
+ }
+
+ @Override
+ public Object getTransactionIdentifier(Transaction transaction) {
+ // generally we use the transaction itself.
+ return transaction;
+ }
+
+ protected abstract JtaSynchronizationStrategy getSynchronizationStrategy();
+
+ @Override
+ public void registerSynchronization(Synchronization synchronization) {
+ getSynchronizationStrategy().registerSynchronization( synchronization );
+ }
+
+ @Override
+ public boolean canRegisterSynchronization() {
+ return getSynchronizationStrategy().canRegisterSynchronization();
+ }
+
+ @Override
+ public int getCurrentStatus() throws SystemException {
+ return retrieveTransactionManager().getStatus();
+ }
+}
diff --git a/hibernate-core/src/main/java/org/hibernate/transaction/BTMTransactionManagerLookup.java b/hibernate-core/src/main/java/org/hibernate/service/jta/platform/internal/BitronixJtaPlatform.java
similarity index 51%
rename from hibernate-core/src/main/java/org/hibernate/transaction/BTMTransactionManagerLookup.java
rename to hibernate-core/src/main/java/org/hibernate/service/jta/platform/internal/BitronixJtaPlatform.java
index e59ed39a9e..f8c2978fa9 100644
--- a/hibernate-core/src/main/java/org/hibernate/transaction/BTMTransactionManagerLookup.java
+++ b/hibernate-core/src/main/java/org/hibernate/service/jta/platform/internal/BitronixJtaPlatform.java
@@ -1,71 +1,62 @@
-/*
- * Hibernate, Relational Persistence for Idiomatic Java
- *
- * Copyright (c) 2011, 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
- */
-package org.hibernate.transaction;
-
-import java.lang.reflect.Method;
-import java.util.Properties;
-
-import javax.transaction.TransactionManager;
-import javax.transaction.Transaction;
-
-import org.hibernate.HibernateException;
-
-/**
- * TransactionManager lookup strategy for BTM
- *
- * @author Ludovic Orban
- */
-@SuppressWarnings( {"UnusedDeclaration"})
-public class BTMTransactionManagerLookup implements TransactionManagerLookup {
-
- private static final String TM_CLASS_NAME = "bitronix.tm.TransactionManagerServices";
-
- /**
- * {@inheritDoc}
- */
- public TransactionManager getTransactionManager(Properties props) throws HibernateException {
- try {
- final Class clazz = Class.forName( TM_CLASS_NAME );
- final Method method = clazz.getMethod( "getTransactionManager", (Class[]) null );
- return (TransactionManager) method.invoke( null, (Object[]) null );
- }
- catch (Exception e) {
- throw new HibernateException( "Could not obtain BTM transaction manager instance", e );
- }
- }
-
- /**
- * {@inheritDoc}
- */
- public String getUserTransactionName() {
- return "java:comp/UserTransaction";
- }
-
- /**
- * {@inheritDoc}
- */
- public Object getTransactionIdentifier(Transaction transaction) {
- return transaction;
- }
-}
\ No newline at end of file
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2011, 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
+ */
+package org.hibernate.service.jta.platform.internal;
+
+import org.hibernate.service.classloading.spi.ClassLoaderService;
+import org.hibernate.service.jta.platform.spi.JtaPlatformException;
+
+import javax.transaction.TransactionManager;
+import javax.transaction.UserTransaction;
+import java.lang.reflect.Method;
+
+/**
+ * @author Steve Ebersole
+ */
+public class BitronixJtaPlatform extends AbstractJtaPlatform {
+ private static final String TM_CLASS_NAME = "bitronix.tm.TransactionManagerServices";
+
+ private final JtaSynchronizationStrategy synchronizationStrategy = new TransactionManagerBasedSynchronizationStrategy( this );
+
+ @Override
+ protected JtaSynchronizationStrategy getSynchronizationStrategy() {
+ return synchronizationStrategy;
+ }
+
+ @Override
+ protected TransactionManager locateTransactionManager() {
+ try {
+ Class transactionManagerServicesClass = serviceRegistry().getService( ClassLoaderService.class ).classForName( TM_CLASS_NAME );
+ final Method getTransactionManagerMethod = transactionManagerServicesClass.getMethod( "getTransactionManager" );
+ return (TransactionManager) getTransactionManagerMethod.invoke( null );
+ }
+ catch (Exception e) {
+ throw new JtaPlatformException( "Could not locate Bitronix TransactionManager", e );
+ }
+ }
+
+ @Override
+ protected UserTransaction locateUserTransaction() {
+ return (UserTransaction) jndiService().locate( "java:comp/UserTransaction" );
+ }
+}
diff --git a/hibernate-core/src/main/java/org/hibernate/service/jta/platform/internal/BorlandEnterpriseServerJtaPlatform.java b/hibernate-core/src/main/java/org/hibernate/service/jta/platform/internal/BorlandEnterpriseServerJtaPlatform.java
new file mode 100644
index 0000000000..4a6c0770e7
--- /dev/null
+++ b/hibernate-core/src/main/java/org/hibernate/service/jta/platform/internal/BorlandEnterpriseServerJtaPlatform.java
@@ -0,0 +1,52 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2011, 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
+ */
+package org.hibernate.service.jta.platform.internal;
+
+import javax.transaction.TransactionManager;
+import javax.transaction.UserTransaction;
+
+/**
+ * @author Steve Ebersole
+ */
+public class BorlandEnterpriseServerJtaPlatform extends AbstractJtaPlatform {
+ protected static final String TM_NAME = "java:pm/TransactionManager";
+ protected static final String UT_NAME = "java:comp/UserTransaction";
+
+ private final JtaSynchronizationStrategy synchronizationStrategy = new TransactionManagerBasedSynchronizationStrategy( this );
+
+ @Override
+ protected TransactionManager locateTransactionManager() {
+ return (TransactionManager) jndiService().locate( TM_NAME );
+ }
+
+ @Override
+ protected UserTransaction locateUserTransaction() {
+ return (UserTransaction) jndiService().locate( UT_NAME );
+ }
+
+ @Override
+ protected JtaSynchronizationStrategy getSynchronizationStrategy() {
+ return synchronizationStrategy;
+ }
+}
diff --git a/hibernate-core/src/main/java/org/hibernate/service/jta/platform/internal/JBossAppServerPlatform.java b/hibernate-core/src/main/java/org/hibernate/service/jta/platform/internal/JBossAppServerPlatform.java
index 6250106a95..c3202f8d23 100644
--- a/hibernate-core/src/main/java/org/hibernate/service/jta/platform/internal/JBossAppServerPlatform.java
+++ b/hibernate-core/src/main/java/org/hibernate/service/jta/platform/internal/JBossAppServerPlatform.java
@@ -23,72 +23,38 @@
*/
package org.hibernate.service.jta.platform.internal;
-import java.util.Map;
-import javax.transaction.Synchronization;
import javax.transaction.TransactionManager;
import javax.transaction.TransactionSynchronizationRegistry;
import javax.transaction.UserTransaction;
-import org.hibernate.internal.util.jta.JtaStatusHelper;
-import org.hibernate.service.jta.platform.spi.JtaPlatform;
-import org.hibernate.service.spi.Configurable;
-import org.hibernate.service.spi.InjectService;
-import org.hibernate.internal.util.config.ConfigurationHelper;
-import org.hibernate.service.jndi.spi.JndiService;
-
-
/**
- * TODO : javadoc
+ * JtaPlatform definition for JBoss Application Server.
*
* @author Steve Ebersole
*/
-public class JBossAppServerPlatform implements JtaPlatform, Configurable {
+public class JBossAppServerPlatform extends AbstractJtaPlatform implements SynchronizationRegistryAccess {
public static final String TM_NAME = "java:/TransactionManager";
public static final String UT_NAME = "UserTransaction";
public static final String REG_NAME = "java:comp/TransactionSynchronizationRegistry";
- private JndiService jndiService;
-
- @InjectService
- public void setJndiService(JndiService jndiService) {
- this.jndiService = jndiService;
+ private final JtaSynchronizationStrategy synchronizationStrategy = new SynchronizationRegistryBasedSynchronizationStrategy( this );
+ @Override
+ protected TransactionManager locateTransactionManager() {
+ return (TransactionManager) jndiService().locate( TM_NAME );
}
- private boolean cacheTransactionManager;
-
- public void configure(Map configValues) {
- cacheTransactionManager = ConfigurationHelper.getBoolean( CACHE_TM, configValues, true );
+ @Override
+ protected UserTransaction locateUserTransaction() {
+ return (UserTransaction) jndiService().locate( UT_NAME );
}
- private TransactionManager transactionManager;
-
- public TransactionManager resolveTransactionManager() {
- if ( cacheTransactionManager ) {
- if ( transactionManager == null ) {
- transactionManager = (TransactionManager) jndiService.locate( TM_NAME );
- }
- return transactionManager;
- }
- else {
- return (TransactionManager) jndiService.locate( TM_NAME );
- }
+ @Override
+ protected JtaSynchronizationStrategy getSynchronizationStrategy() {
+ return synchronizationStrategy;
}
- public UserTransaction resolveUserTransaction() {
- return (UserTransaction) jndiService.locate( UT_NAME );
- }
-
- public void registerSynchronization(Synchronization synchronization) {
- getTransactionSynchronizationRegistry().registerInterposedSynchronization( synchronization );
- }
-
- private TransactionSynchronizationRegistry getTransactionSynchronizationRegistry() {
- return (TransactionSynchronizationRegistry) jndiService.locate( REG_NAME );
- }
-
- public boolean canRegisterSynchronization() {
- TransactionSynchronizationRegistry registry = getTransactionSynchronizationRegistry();
- int status = registry.getTransactionStatus();
- return JtaStatusHelper.isActive( status ) && ! registry.getRollbackOnly();
+ @Override
+ public TransactionSynchronizationRegistry getSynchronizationRegistry() {
+ return (TransactionSynchronizationRegistry) jndiService().locate( REG_NAME );
}
}
diff --git a/hibernate-core/src/main/java/org/hibernate/service/jta/platform/internal/JBossStandAloneJtaPlatform.java b/hibernate-core/src/main/java/org/hibernate/service/jta/platform/internal/JBossStandAloneJtaPlatform.java
new file mode 100644
index 0000000000..01f48e49fe
--- /dev/null
+++ b/hibernate-core/src/main/java/org/hibernate/service/jta/platform/internal/JBossStandAloneJtaPlatform.java
@@ -0,0 +1,70 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2011, 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
+ */
+package org.hibernate.service.jta.platform.internal;
+
+import org.hibernate.service.classloading.spi.ClassLoaderService;
+import org.hibernate.service.jta.platform.spi.JtaPlatformException;
+
+import javax.transaction.TransactionManager;
+import javax.transaction.UserTransaction;
+import java.lang.reflect.Method;
+
+/**
+ * Return a standalone JTA transaction manager for JBoss Transactions
+ * Known to work for org.jboss.jbossts:jbossjta:4.11.0.Final
+ *
+ * @author Emmanuel Bernard
+ * @author Steve Ebersole
+ */
+public class JBossStandAloneJtaPlatform extends AbstractJtaPlatform {
+ private static final String PROPERTY_MANAGER_CLASS_NAME = "com.arjuna.ats.jta.common.jtaPropertyManager";
+
+ private final JtaSynchronizationStrategy synchronizationStrategy = new TransactionManagerBasedSynchronizationStrategy( this );
+
+ @Override
+ protected TransactionManager locateTransactionManager() {
+ try {
+ final Class propertyManagerClass = serviceRegistry()
+ .getService( ClassLoaderService.class )
+ .classForName( PROPERTY_MANAGER_CLASS_NAME );
+ final Method getJTAEnvironmentBeanMethod = propertyManagerClass.getMethod( "getJTAEnvironmentBean" );
+ final Object jtaEnvironmentBean = getJTAEnvironmentBeanMethod.invoke( null );
+ final Method getTransactionManagerMethod = jtaEnvironmentBean.getClass().getMethod( "getTransactionManager" );
+ return ( TransactionManager ) getTransactionManagerMethod.invoke( jtaEnvironmentBean );
+ }
+ catch ( Exception e ) {
+ throw new JtaPlatformException( "Could not obtain JBoss Transactions transaction manager instance", e );
+ }
+ }
+
+ @Override
+ protected UserTransaction locateUserTransaction() {
+ return null;
+ }
+
+ @Override
+ protected JtaSynchronizationStrategy getSynchronizationStrategy() {
+ return synchronizationStrategy;
+ }
+}
diff --git a/hibernate-core/src/main/java/org/hibernate/service/jta/platform/internal/JOTMJtaPlatform.java b/hibernate-core/src/main/java/org/hibernate/service/jta/platform/internal/JOTMJtaPlatform.java
new file mode 100644
index 0000000000..6360d3fb82
--- /dev/null
+++ b/hibernate-core/src/main/java/org/hibernate/service/jta/platform/internal/JOTMJtaPlatform.java
@@ -0,0 +1,63 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2011, 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
+ */
+package org.hibernate.service.jta.platform.internal;
+
+import org.hibernate.service.classloading.spi.ClassLoaderService;
+import org.hibernate.service.jta.platform.spi.JtaPlatformException;
+
+import javax.transaction.TransactionManager;
+import javax.transaction.UserTransaction;
+import java.lang.reflect.Method;
+
+/**
+ * @author Steve Ebersole
+ */
+public class JOTMJtaPlatform extends AbstractJtaPlatform {
+ public static final String TM_CLASS_NAME = "org.objectweb.jotm.Current";
+ public static final String UT_NAME = "java:comp/UserTransaction";
+
+ private final JtaSynchronizationStrategy synchronizationStrategy = new TransactionManagerBasedSynchronizationStrategy( this );
+
+ @Override
+ protected TransactionManager locateTransactionManager() {
+ try {
+ final Class tmClass = serviceRegistry().getService( ClassLoaderService.class ).classForName( TM_CLASS_NAME );
+ final Method getTransactionManagerMethod = tmClass.getMethod( "getTransactionManager" );
+ return (TransactionManager) getTransactionManagerMethod.invoke( null, (Object[]) null );
+ }
+ catch (Exception e) {
+ throw new JtaPlatformException( "Could not obtain JOTM transaction manager instance", e );
+ }
+ }
+
+ @Override
+ protected UserTransaction locateUserTransaction() {
+ return (UserTransaction) jndiService().locate( UT_NAME );
+ }
+
+ @Override
+ protected JtaSynchronizationStrategy getSynchronizationStrategy() {
+ return synchronizationStrategy;
+ }
+}
diff --git a/hibernate-core/src/main/java/org/hibernate/transaction/JOnASTransactionManagerLookup.java b/hibernate-core/src/main/java/org/hibernate/service/jta/platform/internal/JOnASJtaPlatform.java
similarity index 55%
rename from hibernate-core/src/main/java/org/hibernate/transaction/JOnASTransactionManagerLookup.java
rename to hibernate-core/src/main/java/org/hibernate/service/jta/platform/internal/JOnASJtaPlatform.java
index 063033bf1d..617cdf4b90 100644
--- a/hibernate-core/src/main/java/org/hibernate/transaction/JOnASTransactionManagerLookup.java
+++ b/hibernate-core/src/main/java/org/hibernate/service/jta/platform/internal/JOnASJtaPlatform.java
@@ -21,50 +21,44 @@
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
-package org.hibernate.transaction;
+package org.hibernate.service.jta.platform.internal;
-import java.lang.reflect.Method;
-import java.util.Properties;
+import org.hibernate.service.jta.platform.spi.JtaPlatformException;
import javax.transaction.TransactionManager;
-import javax.transaction.Transaction;
-
-import org.hibernate.HibernateException;
+import javax.transaction.UserTransaction;
+import java.lang.reflect.Method;
/**
- * {@link TransactionManagerLookup} strategy for JOnAS
+ * JTA platform implementation for JOnAS
+ *
+ * @author Steve Ebersole
*/
-@SuppressWarnings( {"UnusedDeclaration"})
-public class JOnASTransactionManagerLookup implements TransactionManagerLookup {
-
+public class JOnASJtaPlatform extends AbstractJtaPlatform {
+ public static final String UT_NAME = "java:comp/UserTransaction";
private static final String TM_CLASS_NAME = "org.objectweb.jonas_tm.Current";
- /**
- * {@inheritDoc}
- */
- public TransactionManager getTransactionManager(Properties props) throws HibernateException {
+ private final JtaSynchronizationStrategy synchronizationStrategy = new TransactionManagerBasedSynchronizationStrategy( this );
+
+ @Override
+ protected TransactionManager locateTransactionManager() {
try {
final Class clazz = Class.forName( TM_CLASS_NAME );
- final Method method = clazz.getMethod( "getTransactionManager", (Class[]) null );
- return (TransactionManager) method.invoke( null, (Object[]) null );
+ final Method getTransactionManagerMethod = clazz.getMethod( "getTransactionManager" );
+ return (TransactionManager) getTransactionManagerMethod.invoke( null );
}
catch (Exception e) {
- throw new HibernateException( "Could not obtain JOnAS transaction manager instance", e );
+ throw new JtaPlatformException( "Could not obtain JOnAS transaction manager instance", e );
}
}
- /**
- * {@inheritDoc}
- */
- public String getUserTransactionName() {
- return "java:comp/UserTransaction";
+ @Override
+ protected UserTransaction locateUserTransaction() {
+ return (UserTransaction) jndiService().locate( UT_NAME );
}
- /**
- * {@inheritDoc}
- */
- public Object getTransactionIdentifier(Transaction transaction) {
- return transaction;
+ @Override
+ protected JtaSynchronizationStrategy getSynchronizationStrategy() {
+ return synchronizationStrategy;
}
}
-
diff --git a/hibernate-core/src/main/java/org/hibernate/service/jta/platform/internal/JRun4JtaPlatform.java b/hibernate-core/src/main/java/org/hibernate/service/jta/platform/internal/JRun4JtaPlatform.java
new file mode 100644
index 0000000000..fde0d6eecd
--- /dev/null
+++ b/hibernate-core/src/main/java/org/hibernate/service/jta/platform/internal/JRun4JtaPlatform.java
@@ -0,0 +1,55 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2011, 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
+ */
+package org.hibernate.service.jta.platform.internal;
+
+import javax.transaction.TransactionManager;
+import javax.transaction.UserTransaction;
+
+/**
+ * {@link org.hibernate.service.jta.platform.spi.JtaPlatform} implementation for JRun4 AS
+ *
+ * @author Joseph Bissen
+ * @author Steve Ebersole
+ */
+public class JRun4JtaPlatform extends AbstractJtaPlatform {
+ public static final String TM_NAME = "java:/TransactionManager";
+ public static final String UT_NAME = "java:comp/UserTransaction";
+
+ private final JtaSynchronizationStrategy synchronizationStrategy = new TransactionManagerBasedSynchronizationStrategy( this );
+
+ @Override
+ protected TransactionManager locateTransactionManager() {
+ return (TransactionManager) jndiService().locate( TM_NAME );
+ }
+
+ @Override
+ protected UserTransaction locateUserTransaction() {
+ return (UserTransaction) jndiService().locate( UT_NAME );
+ }
+
+ @Override
+ protected JtaSynchronizationStrategy getSynchronizationStrategy() {
+ return synchronizationStrategy;
+ }
+}
diff --git a/hibernate-core/src/main/java/org/hibernate/service/jta/platform/internal/JtaPlatformInitiator.java b/hibernate-core/src/main/java/org/hibernate/service/jta/platform/internal/JtaPlatformInitiator.java
index 5e548dbee6..9254eb76a7 100644
--- a/hibernate-core/src/main/java/org/hibernate/service/jta/platform/internal/JtaPlatformInitiator.java
+++ b/hibernate-core/src/main/java/org/hibernate/service/jta/platform/internal/JtaPlatformInitiator.java
@@ -26,10 +26,16 @@ package org.hibernate.service.jta.platform.internal;
import java.util.Map;
import org.hibernate.HibernateException;
+import org.hibernate.cfg.Environment;
+import org.hibernate.internal.util.jndi.JndiHelper;
import org.hibernate.service.classloading.spi.ClassLoaderService;
import org.hibernate.service.jta.platform.spi.JtaPlatform;
+import org.hibernate.service.jta.platform.spi.JtaPlatformException;
import org.hibernate.service.spi.ServiceInitiator;
import org.hibernate.service.spi.ServiceRegistry;
+import org.hibernate.transaction.TransactionManagerLookup;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
* Standard initiator for the standard {@link org.hibernate.service.jta.platform.spi.JtaPlatform}
@@ -38,27 +44,24 @@ import org.hibernate.service.spi.ServiceRegistry;
*/
public class JtaPlatformInitiator implements ServiceInitiator {
public static final JtaPlatformInitiator INSTANCE = new JtaPlatformInitiator();
-
public static final String JTA_PLATFORM = "hibernate.jta.platform";
- /**
- * {@inheritDoc}
- */
+ private static final Logger log = LoggerFactory.getLogger( JtaPlatformInitiator.class );
+
+ @Override
public Class getServiceInitiated() {
return JtaPlatform.class;
}
- /**
- * {@inheritDoc}
- */
+ @Override
public JtaPlatform initiateService(Map configVales, ServiceRegistry registry) {
- final Object platform = configVales.get( JTA_PLATFORM );
- if ( JtaPlatform.class.isInstance( platform ) ) {
- return (JtaPlatform) platform;
+ final Object platform = getConfiguredPlatform( configVales, registry );
+ if ( platform == null ) {
+ return new NoJtaPlatform();
}
- if ( platform == null ) {
- return null;
+ if ( JtaPlatform.class.isInstance( platform ) ) {
+ return (JtaPlatform) platform;
}
final String platformImplName = platform.toString();
@@ -71,4 +74,107 @@ public class JtaPlatformInitiator implements ServiceInitiator {
throw new HibernateException( "Unable to create specified JtaPlatform class [" + platformImplName + "]", e );
}
}
+
+ private Object getConfiguredPlatform(Map configVales, ServiceRegistry registry) {
+ Object platform = configVales.get( JTA_PLATFORM );
+ if ( platform == null ) {
+ final String transactionManagerLookupImplName = (String) configVales.get( Environment.TRANSACTION_MANAGER_STRATEGY );
+ if ( transactionManagerLookupImplName != null ) {
+ log.warn(
+ "Using deprecated " + TransactionManagerLookup.class.getName() + " strategy [" +
+ Environment.TRANSACTION_MANAGER_STRATEGY +
+ "], use newer " + JtaPlatform.class.getName() +
+ " strategy instead [" + JTA_PLATFORM + "]"
+ );
+ platform = mapLegacyClasses( transactionManagerLookupImplName, configVales, registry );
+ log.debug( "Mapped {} -> {}", transactionManagerLookupImplName, platform );
+ }
+ }
+ return platform;
+ }
+
+ private JtaPlatform mapLegacyClasses(
+ String transactionManagerLookupImplName,
+ Map configVales,
+ ServiceRegistry registry) {
+ if ( transactionManagerLookupImplName == null ) {
+ return null;
+ }
+
+ log.info(
+ "Encountered legacy TransactionManagerLookup specified; convert to newer " +
+ JtaPlatform.class.getName() + " contract specified via " +
+ JTA_PLATFORM + "setting"
+ );
+
+ if ( "org.hibernate.transaction.BESTransactionManagerLookup".equals( transactionManagerLookupImplName ) ) {
+ return new BorlandEnterpriseServerJtaPlatform();
+ }
+
+ if ( "org.hibernate.transaction.BTMTransactionManagerLookup".equals( transactionManagerLookupImplName ) ) {
+ return new BitronixJtaPlatform();
+ }
+
+ if ( "org.hibernate.transaction.JBossTransactionManagerLookup".equals( transactionManagerLookupImplName ) ) {
+ return new JBossAppServerPlatform();
+ }
+
+ if ( "org.hibernate.transaction.JBossTSStandaloneTransactionManagerLookup".equals( transactionManagerLookupImplName ) ) {
+ return new JBossStandAloneJtaPlatform();
+ }
+
+ if ( "org.hibernate.transaction.JOnASTransactionManagerLookup".equals( transactionManagerLookupImplName ) ) {
+ return new JOnASJtaPlatform();
+ }
+
+ if ( "org.hibernate.transaction.JOTMTransactionManagerLookup".equals( transactionManagerLookupImplName ) ) {
+ return new JOTMJtaPlatform();
+ }
+
+ if ( "org.hibernate.transaction.JRun4TransactionManagerLookup".equals( transactionManagerLookupImplName ) ) {
+ return new JRun4JtaPlatform();
+ }
+
+ if ( "org.hibernate.transaction.OC4JTransactionManagerLookup".equals( transactionManagerLookupImplName ) ) {
+ return new OC4JJtaPlatform();
+ }
+
+ if ( "org.hibernate.transaction.OrionTransactionManagerLookup".equals( transactionManagerLookupImplName ) ) {
+ return new OrionJtaPlatform();
+ }
+
+ if ( "org.hibernate.transaction.ResinTransactionManagerLookup".equals( transactionManagerLookupImplName ) ) {
+ return new ResinJtaPlatform();
+ }
+
+ if ( "org.hibernate.transaction.SunONETransactionManagerLookup".equals( transactionManagerLookupImplName ) ) {
+ return new SunOneJtaPlatform();
+ }
+
+ if ( "org.hibernate.transaction.WeblogicTransactionManagerLookup".equals( transactionManagerLookupImplName ) ) {
+ return new WeblogicJtaPlatform();
+ }
+
+ if ( "org.hibernate.transaction.WebSphereTransactionManagerLookup".equals( transactionManagerLookupImplName ) ) {
+ return new WebSphereJtaPlatform();
+ }
+
+ if ( "org.hibernate.transaction.WebSphereExtendedJTATransactionLookup".equals( transactionManagerLookupImplName ) ) {
+ return new WebSphereExtendedJtaPlatform();
+ }
+
+ try {
+ TransactionManagerLookup lookup = (TransactionManagerLookup) registry.getService( ClassLoaderService.class )
+ .classForName( transactionManagerLookupImplName )
+ .newInstance();
+ return new TransactionManagerLookupBridge( lookup, JndiHelper.extractJndiProperties( configVales ) );
+ }
+ catch ( Exception e ) {
+ throw new JtaPlatformException(
+ "Unable to build " + TransactionManagerLookupBridge.class.getName() + " from specified " +
+ TransactionManagerLookup.class.getName() + " implementation: " +
+ transactionManagerLookupImplName
+ );
+ }
+ }
}
diff --git a/hibernate-core/src/main/java/org/hibernate/service/jta/platform/internal/JtaSynchronizationStrategy.java b/hibernate-core/src/main/java/org/hibernate/service/jta/platform/internal/JtaSynchronizationStrategy.java
new file mode 100644
index 0000000000..64d89e8bb8
--- /dev/null
+++ b/hibernate-core/src/main/java/org/hibernate/service/jta/platform/internal/JtaSynchronizationStrategy.java
@@ -0,0 +1,48 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2011, 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
+ */
+package org.hibernate.service.jta.platform.internal;
+
+import javax.transaction.Synchronization;
+import java.io.Serializable;
+
+/**
+ * Contract used to centralize {@link Synchronization} handling logic.
+ *
+ * @author Steve Ebersole
+ */
+public interface JtaSynchronizationStrategy extends Serializable {
+ /**
+ * Register a synchronization
+ *
+ * @param synchronization The synchronization to register.
+ */
+ public void registerSynchronization(Synchronization synchronization);
+
+ /**
+ * Can a synchronization be registered?
+ *
+ * @return {@literal true}/{@literal false}
+ */
+ public boolean canRegisterSynchronization();
+}
diff --git a/hibernate-core/src/main/java/org/hibernate/transaction/JOTMTransactionManagerLookup.java b/hibernate-core/src/main/java/org/hibernate/service/jta/platform/internal/NoJtaPlatform.java
similarity index 53%
rename from hibernate-core/src/main/java/org/hibernate/transaction/JOTMTransactionManagerLookup.java
rename to hibernate-core/src/main/java/org/hibernate/service/jta/platform/internal/NoJtaPlatform.java
index 23a6ec967f..6d60fe198b 100644
--- a/hibernate-core/src/main/java/org/hibernate/transaction/JOTMTransactionManagerLookup.java
+++ b/hibernate-core/src/main/java/org/hibernate/service/jta/platform/internal/NoJtaPlatform.java
@@ -21,57 +21,49 @@
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
-package org.hibernate.transaction;
+package org.hibernate.service.jta.platform.internal;
-import java.lang.reflect.Method;
-import java.util.Properties;
+import org.hibernate.service.jta.platform.spi.JtaPlatform;
-import javax.transaction.TransactionManager;
+import javax.transaction.Status;
+import javax.transaction.Synchronization;
+import javax.transaction.SystemException;
import javax.transaction.Transaction;
-
-import org.hibernate.HibernateException;
+import javax.transaction.TransactionManager;
+import javax.transaction.UserTransaction;
/**
- * {@link TransactionManagerLookup} strategy for JOTM
+ * The non-configured form of JTA platform. This is what is used if none was set up.
*
- * @author Low Heng Sin
+ * @author Steve Ebersole
*/
-@SuppressWarnings( {"UnusedDeclaration"})
-public class JOTMTransactionManagerLookup implements TransactionManagerLookup {
-
- private static final String TM_CLASS_NAME = "org.objectweb.jotm.Current";
-
- /**
- * {@inheritDoc}
- */
- public TransactionManager getTransactionManager(Properties props) throws HibernateException {
- try {
- final Class clazz = Class.forName( TM_CLASS_NAME );
- final Method method = clazz.getMethod( "getTransactionManager", (Class[]) null );
- return (TransactionManager) method.invoke( null, (Object[]) null );
- }
- catch (Exception e) {
- throw new HibernateException( "Could not obtain JOTM transaction manager instance", e );
- }
+public class NoJtaPlatform implements JtaPlatform {
+ @Override
+ public TransactionManager retrieveTransactionManager() {
+ return null;
}
- /**
- * {@inheritDoc}
- */
- public String getUserTransactionName() {
- return "java:comp/UserTransaction";
+ @Override
+ public UserTransaction retrieveUserTransaction() {
+ return null;
}
- /**
- * {@inheritDoc}
- */
+ @Override
public Object getTransactionIdentifier(Transaction transaction) {
- return transaction;
+ return null;
+ }
+
+ @Override
+ public void registerSynchronization(Synchronization synchronization) {
+ }
+
+ @Override
+ public boolean canRegisterSynchronization() {
+ return false;
+ }
+
+ @Override
+ public int getCurrentStatus() throws SystemException {
+ return Status.STATUS_UNKNOWN;
}
}
-
-
-
-
-
-
diff --git a/hibernate-core/src/main/java/org/hibernate/service/jta/platform/internal/OC4JJtaPlatform.java b/hibernate-core/src/main/java/org/hibernate/service/jta/platform/internal/OC4JJtaPlatform.java
new file mode 100644
index 0000000000..4112ebdf4d
--- /dev/null
+++ b/hibernate-core/src/main/java/org/hibernate/service/jta/platform/internal/OC4JJtaPlatform.java
@@ -0,0 +1,55 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2011, 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
+ */
+package org.hibernate.service.jta.platform.internal;
+
+import javax.transaction.TransactionManager;
+import javax.transaction.UserTransaction;
+
+/**
+ * {@link org.hibernate.service.jta.platform.spi.JtaPlatform} implementation for the OC4J (Oracle) AS.
+ *
+ * @author Stijn Janssens
+ * @author Steve Ebersole
+ */
+public class OC4JJtaPlatform extends AbstractJtaPlatform {
+ public static final String TM_NAME = "java:comp/pm/TransactionManager";
+ public static final String UT_NAME = "java:comp/UserTransaction";
+
+ private final JtaSynchronizationStrategy synchronizationStrategy = new TransactionManagerBasedSynchronizationStrategy( this );
+
+ @Override
+ protected TransactionManager locateTransactionManager() {
+ return (TransactionManager) jndiService().locate( TM_NAME );
+ }
+
+ @Override
+ protected UserTransaction locateUserTransaction() {
+ return (UserTransaction) jndiService().locate( UT_NAME );
+ }
+
+ @Override
+ protected JtaSynchronizationStrategy getSynchronizationStrategy() {
+ return synchronizationStrategy;
+ }
+}
diff --git a/hibernate-core/src/main/java/org/hibernate/service/jta/platform/internal/OrionJtaPlatform.java b/hibernate-core/src/main/java/org/hibernate/service/jta/platform/internal/OrionJtaPlatform.java
new file mode 100644
index 0000000000..44b862c6c4
--- /dev/null
+++ b/hibernate-core/src/main/java/org/hibernate/service/jta/platform/internal/OrionJtaPlatform.java
@@ -0,0 +1,55 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2011, 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
+ */
+package org.hibernate.service.jta.platform.internal;
+
+import javax.transaction.TransactionManager;
+import javax.transaction.UserTransaction;
+
+/**
+ * {@link org.hibernate.service.jta.platform.spi.JtaPlatform} implementation for Orion
+ *
+ * @author Gavin King
+ * @author Steve Ebersole
+ */
+public class OrionJtaPlatform extends AbstractJtaPlatform {
+ public static final String TM_NAME = "java:comp/UserTransaction";
+ public static final String UT_NAME = "java:comp/UserTransaction";
+
+ private final JtaSynchronizationStrategy synchronizationStrategy = new TransactionManagerBasedSynchronizationStrategy( this );
+
+ @Override
+ protected TransactionManager locateTransactionManager() {
+ return (TransactionManager) jndiService().locate( TM_NAME );
+ }
+
+ @Override
+ protected UserTransaction locateUserTransaction() {
+ return (UserTransaction) jndiService().locate( UT_NAME );
+ }
+
+ @Override
+ protected JtaSynchronizationStrategy getSynchronizationStrategy() {
+ return synchronizationStrategy;
+ }
+}
diff --git a/hibernate-core/src/main/java/org/hibernate/service/jta/platform/internal/ResinJtaPlatform.java b/hibernate-core/src/main/java/org/hibernate/service/jta/platform/internal/ResinJtaPlatform.java
new file mode 100644
index 0000000000..6b44cc305e
--- /dev/null
+++ b/hibernate-core/src/main/java/org/hibernate/service/jta/platform/internal/ResinJtaPlatform.java
@@ -0,0 +1,55 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2011, 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
+ */
+package org.hibernate.service.jta.platform.internal;
+
+import javax.transaction.TransactionManager;
+import javax.transaction.UserTransaction;
+
+/**
+ * {@link org.hibernate.service.jta.platform.spi.JtaPlatform} implementation for Resin
+ *
+ * @author Aapo Laakkonen
+ * @author Steve Ebersole
+ */
+public class ResinJtaPlatform extends AbstractJtaPlatform {
+ public static final String TM_NAME = "java:comp/TransactionManager";
+ public static final String UT_NAME = "java:comp/UserTransaction";
+
+ private final JtaSynchronizationStrategy synchronizationStrategy = new TransactionManagerBasedSynchronizationStrategy( this );
+
+ @Override
+ protected TransactionManager locateTransactionManager() {
+ return (TransactionManager) jndiService().locate( TM_NAME );
+ }
+
+ @Override
+ protected UserTransaction locateUserTransaction() {
+ return (UserTransaction) jndiService().locate( UT_NAME );
+ }
+
+ @Override
+ protected JtaSynchronizationStrategy getSynchronizationStrategy() {
+ return synchronizationStrategy;
+ }
+}
diff --git a/hibernate-core/src/main/java/org/hibernate/service/jta/platform/internal/SunOneJtaPlatform.java b/hibernate-core/src/main/java/org/hibernate/service/jta/platform/internal/SunOneJtaPlatform.java
new file mode 100644
index 0000000000..0213b9e52a
--- /dev/null
+++ b/hibernate-core/src/main/java/org/hibernate/service/jta/platform/internal/SunOneJtaPlatform.java
@@ -0,0 +1,57 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2011, 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
+ */
+package org.hibernate.service.jta.platform.internal;
+
+import javax.transaction.TransactionManager;
+import javax.transaction.UserTransaction;
+
+/**
+ * {@link org.hibernate.service.jta.platform.spi.JtaPlatform} implementation for Sun ONE Application Server 7 and above
+ *
+ * @author Robert Davidson
+ * @author Sanjeev Krishnan
+ * @author Emmanuel Bernard
+ * @author Steve Ebersole
+ */
+public class SunOneJtaPlatform extends AbstractJtaPlatform {
+ public static final String TM_NAME = "java:appserver/TransactionManager";
+ public static final String UT_NAME = "java:comp/UserTransaction";
+
+ private final JtaSynchronizationStrategy synchronizationStrategy = new TransactionManagerBasedSynchronizationStrategy( this );
+
+ @Override
+ protected TransactionManager locateTransactionManager() {
+ return (TransactionManager) jndiService().locate( TM_NAME );
+ }
+
+ @Override
+ protected UserTransaction locateUserTransaction() {
+ return (UserTransaction) jndiService().locate( UT_NAME );
+ }
+
+ @Override
+ protected JtaSynchronizationStrategy getSynchronizationStrategy() {
+ return synchronizationStrategy;
+ }
+}
diff --git a/hibernate-core/src/main/java/org/hibernate/service/jta/platform/internal/SynchronizationRegistryAccess.java b/hibernate-core/src/main/java/org/hibernate/service/jta/platform/internal/SynchronizationRegistryAccess.java
new file mode 100644
index 0000000000..2f7698f0fd
--- /dev/null
+++ b/hibernate-core/src/main/java/org/hibernate/service/jta/platform/internal/SynchronizationRegistryAccess.java
@@ -0,0 +1,42 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2011, 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
+ */
+package org.hibernate.service.jta.platform.internal;
+
+import javax.transaction.TransactionSynchronizationRegistry;
+import java.io.Serializable;
+
+/**
+ * Provides access to a {@link TransactionSynchronizationRegistry} for use by {@link TransactionSynchronizationRegistry}-based
+ * {@link JtaSynchronizationStrategy} implementations.
+ *
+ * @author Steve Ebersole
+ */
+public interface SynchronizationRegistryAccess extends Serializable {
+ /**
+ * Obtain the synchronization registry
+ *
+ * @return the synchronization registry
+ */
+ public TransactionSynchronizationRegistry getSynchronizationRegistry();
+}
diff --git a/hibernate-core/src/main/java/org/hibernate/service/jta/platform/internal/SynchronizationRegistryBasedSynchronizationStrategy.java b/hibernate-core/src/main/java/org/hibernate/service/jta/platform/internal/SynchronizationRegistryBasedSynchronizationStrategy.java
new file mode 100644
index 0000000000..c735ec7cf5
--- /dev/null
+++ b/hibernate-core/src/main/java/org/hibernate/service/jta/platform/internal/SynchronizationRegistryBasedSynchronizationStrategy.java
@@ -0,0 +1,56 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2011, 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
+ */
+package org.hibernate.service.jta.platform.internal;
+
+import org.hibernate.engine.transaction.internal.jta.JtaStatusHelper;
+
+import javax.transaction.Synchronization;
+import javax.transaction.TransactionSynchronizationRegistry;
+
+/**
+ * Implementation of the {@link JtaSynchronizationStrategy} contract based on using a
+ * {@link TransactionSynchronizationRegistry}
+ *
+ * @author Steve Ebersole
+ */
+public class SynchronizationRegistryBasedSynchronizationStrategy implements JtaSynchronizationStrategy {
+ private final SynchronizationRegistryAccess synchronizationRegistryAccess;
+
+ public SynchronizationRegistryBasedSynchronizationStrategy(SynchronizationRegistryAccess synchronizationRegistryAccess) {
+ this.synchronizationRegistryAccess = synchronizationRegistryAccess;
+ }
+
+ @Override
+ public void registerSynchronization(Synchronization synchronization) {
+ synchronizationRegistryAccess.getSynchronizationRegistry().registerInterposedSynchronization(
+ synchronization
+ );
+ }
+
+ @Override
+ public boolean canRegisterSynchronization() {
+ final TransactionSynchronizationRegistry registry = synchronizationRegistryAccess.getSynchronizationRegistry();
+ return JtaStatusHelper.isActive( registry.getTransactionStatus() ) && ! registry.getRollbackOnly();
+ }
+}
diff --git a/hibernate-core/src/main/java/org/hibernate/engine/transaction/IsolatedWork.java b/hibernate-core/src/main/java/org/hibernate/service/jta/platform/internal/TransactionManagerAccess.java
similarity index 61%
rename from hibernate-core/src/main/java/org/hibernate/engine/transaction/IsolatedWork.java
rename to hibernate-core/src/main/java/org/hibernate/service/jta/platform/internal/TransactionManagerAccess.java
index 94269d99f4..788c8cc7c3 100644
--- a/hibernate-core/src/main/java/org/hibernate/engine/transaction/IsolatedWork.java
+++ b/hibernate-core/src/main/java/org/hibernate/service/jta/platform/internal/TransactionManagerAccess.java
@@ -1,10 +1,10 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
- * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * Copyright (c) 2011, 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 Middleware LLC.
+ * 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
@@ -20,27 +20,23 @@
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
- *
*/
-package org.hibernate.engine.transaction;
+package org.hibernate.service.jta.platform.internal;
-import org.hibernate.HibernateException;
-
-import java.sql.Connection;
+import javax.transaction.TransactionManager;
+import java.io.Serializable;
/**
- * Represents work that needs to be performed in a manner
- * which isolates it from any current application unit of
- * work transaction.
+ * Provides access to a {@link TransactionManager} for use by {@link TransactionManager}-based
+ * {@link JtaSynchronizationStrategy} implementations.
*
* @author Steve Ebersole
*/
-public interface IsolatedWork {
+public interface TransactionManagerAccess extends Serializable {
/**
- * Perform the actual work to be done.
+ * Obtain the transaction manager
*
- * @param connection The JDBC connection to use.
- * @throws HibernateException
+ * @return The transaction manager.
*/
- public void doWork(Connection connection) throws HibernateException;
+ public TransactionManager getTransactionManager();
}
diff --git a/hibernate-core/src/main/java/org/hibernate/service/jta/platform/internal/TransactionManagerBasedSynchronizationStrategy.java b/hibernate-core/src/main/java/org/hibernate/service/jta/platform/internal/TransactionManagerBasedSynchronizationStrategy.java
new file mode 100644
index 0000000000..45f25531d8
--- /dev/null
+++ b/hibernate-core/src/main/java/org/hibernate/service/jta/platform/internal/TransactionManagerBasedSynchronizationStrategy.java
@@ -0,0 +1,58 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2011, 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
+ */
+package org.hibernate.service.jta.platform.internal;
+
+import org.hibernate.engine.transaction.internal.jta.JtaStatusHelper;
+import org.hibernate.service.jta.platform.spi.JtaPlatformException;
+
+import javax.transaction.Synchronization;
+
+/**
+ * Implementation of the {@link JtaSynchronizationStrategy} contract based on using a
+ * {@link javax.transaction.TransactionManager}
+ *
+ * @author Steve Ebersole
+ */
+public class TransactionManagerBasedSynchronizationStrategy implements JtaSynchronizationStrategy {
+ private final TransactionManagerAccess transactionManagerAccess;
+
+ public TransactionManagerBasedSynchronizationStrategy(TransactionManagerAccess transactionManagerAccess) {
+ this.transactionManagerAccess = transactionManagerAccess;
+ }
+
+ @Override
+ public void registerSynchronization(Synchronization synchronization) {
+ try {
+ transactionManagerAccess.getTransactionManager().getTransaction().registerSynchronization( synchronization );
+ }
+ catch (Exception e) {
+ throw new JtaPlatformException( "Could not access JTA Transaction to register synchronization", e );
+ }
+ }
+
+ @Override
+ public boolean canRegisterSynchronization() {
+ return JtaStatusHelper.isActive( transactionManagerAccess.getTransactionManager() );
+ }
+}
diff --git a/hibernate-core/src/main/java/org/hibernate/service/jta/platform/internal/TransactionManagerLookupBridge.java b/hibernate-core/src/main/java/org/hibernate/service/jta/platform/internal/TransactionManagerLookupBridge.java
new file mode 100644
index 0000000000..5d90ea8368
--- /dev/null
+++ b/hibernate-core/src/main/java/org/hibernate/service/jta/platform/internal/TransactionManagerLookupBridge.java
@@ -0,0 +1,67 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2011, 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
+ */
+package org.hibernate.service.jta.platform.internal;
+
+import org.hibernate.service.jndi.spi.JndiService;
+import org.hibernate.transaction.TransactionManagerLookup;
+
+import javax.transaction.Transaction;
+import javax.transaction.TransactionManager;
+import javax.transaction.UserTransaction;
+import java.util.Properties;
+
+/**
+ * @author Steve Ebersole
+ */
+public class TransactionManagerLookupBridge extends AbstractJtaPlatform {
+ private final TransactionManagerLookup lookup;
+ private final Properties jndiProperties;
+
+ private final JtaSynchronizationStrategy synchronizationStrategy = new TransactionManagerBasedSynchronizationStrategy( this );
+
+ public TransactionManagerLookupBridge(TransactionManagerLookup lookup, Properties jndiProperties) {
+ this.lookup = lookup;
+ this.jndiProperties = jndiProperties;
+ }
+
+ @Override
+ protected TransactionManager locateTransactionManager() {
+ return lookup.getTransactionManager( jndiProperties );
+ }
+
+ @Override
+ protected UserTransaction locateUserTransaction() {
+ return (UserTransaction) serviceRegistry().getService( JndiService.class ).locate( lookup.getUserTransactionName() );
+ }
+
+ @Override
+ protected JtaSynchronizationStrategy getSynchronizationStrategy() {
+ return synchronizationStrategy;
+ }
+
+ @Override
+ public Object getTransactionIdentifier(Transaction transaction) {
+ return lookup.getTransactionIdentifier( transaction );
+ }
+}
diff --git a/hibernate-core/src/main/java/org/hibernate/transaction/WebSphereExtendedJTATransactionLookup.java b/hibernate-core/src/main/java/org/hibernate/service/jta/platform/internal/WebSphereExtendedJtaPlatform.java
old mode 100755
new mode 100644
similarity index 73%
rename from hibernate-core/src/main/java/org/hibernate/transaction/WebSphereExtendedJTATransactionLookup.java
rename to hibernate-core/src/main/java/org/hibernate/service/jta/platform/internal/WebSphereExtendedJtaPlatform.java
index 300ae58a06..3449efbd0b
--- a/hibernate-core/src/main/java/org/hibernate/transaction/WebSphereExtendedJTATransactionLookup.java
+++ b/hibernate-core/src/main/java/org/hibernate/service/jta/platform/internal/WebSphereExtendedJtaPlatform.java
@@ -21,14 +21,10 @@
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
-package org.hibernate.transaction;
+package org.hibernate.service.jta.platform.internal;
-import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.Method;
-import java.lang.reflect.Proxy;
-import java.util.Properties;
+import org.hibernate.HibernateException;
-import javax.naming.NamingException;
import javax.transaction.NotSupportedException;
import javax.transaction.RollbackException;
import javax.transaction.Status;
@@ -36,64 +32,68 @@ import javax.transaction.Synchronization;
import javax.transaction.SystemException;
import javax.transaction.Transaction;
import javax.transaction.TransactionManager;
+import javax.transaction.UserTransaction;
import javax.transaction.xa.XAResource;
-
-import org.hibernate.HibernateException;
-import org.hibernate.internal.util.jndi.JndiHelper;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
/**
- * TransactionManagerLookup implementation intended for use with WebSphere
- * Application Server (WAS).
+ * JTA platform implementation intended for use with WebSphere Application Server (WAS).
*
- * WAS, unlike every other app server on the planet, does not allow direct
- * access to the JTS TransactionManager. Instead, for common transaction-
- * related tasks users must utilize a proprietary API known as
- * ExtendedJTATransaction.
+ * WAS, unlike every other app server on the planet, does not allow direct access to the JTS TransactionManager.
+ * Instead, for common transaction-related tasks users must utilize a proprietary API known as ExtendedJTATransaction.
*
- * Even more unfortunate, the exact TransactionManagerLookup to use inside of
- * WAS is highly dependent upon (1) WAS version as well as (2) the WAS
- * container in which Hibernate will be utilized.
+ * Even more unfortunate, the exact TransactionManagerLookup to use inside of WAS is highly dependent upon
+ * - WAS version
+ * - the WAS container in which Hibernate will be utilized
+ *
*
- * WebSphereExtendedJTATransactionLookup is reported to work on WAS version 6
- * in any of the standard J2EE/JEE component containers.
+ * This class is reported to work on WAS version 6 in any of the standard J2EE/JEE component containers.
*
* @author Gavin King
* @author
+ * Generally speaking the transaction itself will be returned here. This method was added specifically
+ * for use in WebSphere and other unfriendly JEE containers (although WebSphere is still the only known
+ * such brain-dead, sales-driven impl).
+ *
+ * @param transaction The transaction to be identified.
+ * @return An appropriate identifier
+ */
+ public Object getTransactionIdentifier(Transaction transaction);
+
+ /**
+ * Can we currently register a {@link Synchronization}?
+ *
+ * @return True if registering a {@link Synchronization} is currently allowed; false otherwise.
+ */
+ public boolean canRegisterSynchronization();
/**
* Register a JTA {@link Synchronization} in the means defined by the platform.
@@ -66,9 +89,11 @@ public interface JtaPlatform extends Service {
public void registerSynchronization(Synchronization synchronization);
/**
- * Can we currently regsiter a {@link Synchronization}?
+ * Obtain the current transaction status using whatever means is preferred for this platform
*
- * @return True if regsitering a {@link Synchronization} is currently allowed; false otherwise.
+ * @return The current status.
+ *
+ * @throws SystemException Indicates a problem access the underlying status
*/
- public boolean canRegisterSynchronization();
+ public int getCurrentStatus() throws SystemException;
}
diff --git a/hibernate-core/src/main/java/org/hibernate/transaction/OC4JTransactionManagerLookup.java b/hibernate-core/src/main/java/org/hibernate/service/jta/platform/spi/JtaPlatformException.java
similarity index 65%
rename from hibernate-core/src/main/java/org/hibernate/transaction/OC4JTransactionManagerLookup.java
rename to hibernate-core/src/main/java/org/hibernate/service/jta/platform/spi/JtaPlatformException.java
index f71e290c82..abc7f31d79 100644
--- a/hibernate-core/src/main/java/org/hibernate/transaction/OC4JTransactionManagerLookup.java
+++ b/hibernate-core/src/main/java/org/hibernate/service/jta/platform/spi/JtaPlatformException.java
@@ -1,10 +1,10 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
- * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * Copyright (c) 2011, 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 Middleware LLC.
+ * 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
@@ -20,21 +20,22 @@
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
- *
*/
-package org.hibernate.transaction;
+package org.hibernate.service.jta.platform.spi;
+
+import org.hibernate.HibernateException;
/**
- * {@link TransactionManagerLookup} for the OC4J (Oracle) AS.
- *
- * @author Stijn Janssens
+ * Indicates a problem interacting with the underlying JTA platform.
+ *
+ * @author Steve Ebersole
*/
-public class OC4JTransactionManagerLookup extends JNDITransactionManagerLookup {
- protected String getName() {
- return "java:comp/pm/TransactionManager";
+public class JtaPlatformException extends HibernateException {
+ public JtaPlatformException(String s) {
+ super( s );
}
- public String getUserTransactionName() {
- return "java:comp/UserTransaction";
+ public JtaPlatformException(String string, Throwable root) {
+ super( string, root );
}
}
diff --git a/hibernate-core/src/main/java/org/hibernate/service/spi/Service.java b/hibernate-core/src/main/java/org/hibernate/service/spi/Service.java
index 134f3e5836..796e1afd83 100644
--- a/hibernate-core/src/main/java/org/hibernate/service/spi/Service.java
+++ b/hibernate-core/src/main/java/org/hibernate/service/spi/Service.java
@@ -23,10 +23,14 @@
*/
package org.hibernate.service.spi;
+import java.io.Serializable;
+
/**
* Marker interface for services.
+ *
+ * NOTE : All services must be {@link Serializable}!
*
* @author Steve Ebersole
*/
-public interface Service {
+public interface Service extends Serializable {
}
diff --git a/hibernate-core/src/main/java/org/hibernate/service/spi/StandardServiceInitiators.java b/hibernate-core/src/main/java/org/hibernate/service/spi/StandardServiceInitiators.java
index 06ea81e9e7..a6b8a545e7 100644
--- a/hibernate-core/src/main/java/org/hibernate/service/spi/StandardServiceInitiators.java
+++ b/hibernate-core/src/main/java/org/hibernate/service/spi/StandardServiceInitiators.java
@@ -23,7 +23,9 @@
*/
package org.hibernate.service.spi;
+import org.hibernate.engine.jdbc.batch.internal.BatchBuilderInitiator;
import org.hibernate.engine.jdbc.internal.JdbcServicesInitiator;
+import org.hibernate.engine.transaction.internal.TransactionFactoryInitiator;
import org.hibernate.service.classloading.internal.ClassLoaderServiceInitiator;
import org.hibernate.service.jdbc.connections.internal.ConnectionProviderInitiator;
import org.hibernate.service.jdbc.dialect.internal.DialectFactoryInitiator;
@@ -51,10 +53,11 @@ public class StandardServiceInitiators {
serviceInitiators.add( ConnectionProviderInitiator.INSTANCE );
serviceInitiators.add( DialectResolverInitiator.INSTANCE );
serviceInitiators.add( DialectFactoryInitiator.INSTANCE );
+ serviceInitiators.add( BatchBuilderInitiator.INSTANCE );
serviceInitiators.add( JdbcServicesInitiator.INSTANCE );
serviceInitiators.add( JtaPlatformInitiator.INSTANCE );
- //serviceInitiators.add( TransactionFactoryInitiator.INSTANCE );
+ serviceInitiators.add( TransactionFactoryInitiator.INSTANCE );
return serviceInitiators;
}
diff --git a/hibernate-core/src/main/java/org/hibernate/transaction/BESTransactionManagerLookup.java b/hibernate-core/src/main/java/org/hibernate/transaction/BESTransactionManagerLookup.java
deleted file mode 100644
index 0d1e235f5d..0000000000
--- a/hibernate-core/src/main/java/org/hibernate/transaction/BESTransactionManagerLookup.java
+++ /dev/null
@@ -1,42 +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.transaction;
-
-/**
- * A TransactionManager lookup strategy for Borland ES.
- *
- * @author Etienne Hardy
- */
-public final class BESTransactionManagerLookup extends JNDITransactionManagerLookup {
-
- protected String getName() {
- return "java:pm/TransactionManager";
- }
-
- public String getUserTransactionName() {
- return "java:comp/UserTransaction";
- }
-
-}
\ No newline at end of file
diff --git a/hibernate-core/src/main/java/org/hibernate/transaction/CMTTransaction.java b/hibernate-core/src/main/java/org/hibernate/transaction/CMTTransaction.java
deleted file mode 100755
index ab56daed6d..0000000000
--- a/hibernate-core/src/main/java/org/hibernate/transaction/CMTTransaction.java
+++ /dev/null
@@ -1,224 +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.transaction;
-
-import javax.transaction.Status;
-import javax.transaction.Synchronization;
-import javax.transaction.SystemException;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.hibernate.HibernateException;
-import org.hibernate.Transaction;
-import org.hibernate.TransactionException;
-import org.hibernate.engine.jdbc.spi.JDBCContext;
-import org.hibernate.util.JTAHelper;
-
-/**
- * Implements a basic transaction strategy for CMT transactions. All work is
- * done in the context of the container managed transaction.
- *
- * The term 'CMT' is potentially misleading here; the pertinent point simply
- * being that the transactions are being managed by something other than the
- * Hibernate transaction mechanism.
- *
- * @author Gavin King
- */
-public class CMTTransaction implements Transaction {
-
- private static final Logger log = LoggerFactory.getLogger(CMTTransaction.class);
-
- protected final JDBCContext jdbcContext;
- protected final TransactionFactory.Context transactionContext;
-
- private boolean begun;
-
- public CMTTransaction(JDBCContext jdbcContext, TransactionFactory.Context transactionContext) {
- this.jdbcContext = jdbcContext;
- this.transactionContext = transactionContext;
- }
-
- /**
- * {@inheritDoc}
- */
- public void begin() throws HibernateException {
- if (begun) {
- return;
- }
-
- log.debug("begin");
-
- boolean synchronization = jdbcContext.registerSynchronizationIfPossible();
-
- if ( !synchronization ) {
- throw new TransactionException("Could not register synchronization for container transaction");
- }
-
- begun = true;
-
- jdbcContext.afterTransactionBegin(this);
- }
-
- /**
- * {@inheritDoc}
- */
- public void commit() throws HibernateException {
- if (!begun) {
- throw new TransactionException("Transaction not successfully started");
- }
-
- log.debug("commit");
-
- boolean flush = !transactionContext.isFlushModeNever() &&
- !transactionContext.isFlushBeforeCompletionEnabled();
-
- if (flush) {
- transactionContext.managedFlush(); //if an exception occurs during flush, user must call rollback()
- }
-
- begun = false;
-
- }
-
- /**
- * {@inheritDoc}
- */
- public void rollback() throws HibernateException {
- if (!begun) {
- throw new TransactionException("Transaction not successfully started");
- }
-
- log.debug("rollback");
-
- try {
- getTransaction().setRollbackOnly();
- }
- catch (SystemException se) {
- log.error("Could not set transaction to rollback only", se);
- throw new TransactionException("Could not set transaction to rollback only", se);
- }
-
- begun = false;
-
- }
-
- /**
- * Getter for property 'transaction'.
- *
- * @return Value for property 'transaction'.
- */
- public javax.transaction.Transaction getTransaction() throws SystemException {
- return transactionContext.getFactory().getTransactionManager().getTransaction();
- }
-
- /**
- * {@inheritDoc}
- */
- public boolean isActive() throws TransactionException {
-
- if (!begun) return false;
-
- final int status;
- try {
- status = getTransaction().getStatus();
- }
- catch (SystemException se) {
- log.error("Could not determine transaction status", se);
- throw new TransactionException("Could not determine transaction status: ", se);
- }
- if (status==Status.STATUS_UNKNOWN) {
- throw new TransactionException("Could not determine transaction status");
- }
- else {
- return status==Status.STATUS_ACTIVE;
- }
- }
-
- /**
- * {@inheritDoc}
- */
- public boolean wasRolledBack() throws TransactionException {
-
- if (!begun) return false;
-
- final int status;
- try {
- status = getTransaction().getStatus();
- }
- catch (SystemException se) {
- log.error("Could not determine transaction status", se);
- throw new TransactionException("Could not determine transaction status", se);
- }
- if (status==Status.STATUS_UNKNOWN) {
- throw new TransactionException("Could not determine transaction status");
- }
- else {
- return JTAHelper.isRollback(status);
- }
- }
-
- /**
- * {@inheritDoc}
- */
- public boolean wasCommitted() throws TransactionException {
-
- if ( !begun ) return false;
-
- final int status;
- try {
- status = getTransaction().getStatus();
- }
- catch (SystemException se) {
- log.error("Could not determine transaction status", se);
- throw new TransactionException("Could not determine transaction status: ", se);
- }
- if (status==Status.STATUS_UNKNOWN) {
- throw new TransactionException("Could not determine transaction status");
- }
- else {
- return status==Status.STATUS_COMMITTED;
- }
- }
-
- /**
- * {@inheritDoc}
- */
- public void registerSynchronization(Synchronization sync) throws HibernateException {
- try {
- getTransaction().registerSynchronization(sync);
- }
- catch (Exception e) {
- throw new TransactionException("Could not register synchronization", e);
- }
- }
-
- /**
- * {@inheritDoc}
- */
- public void setTimeout(int seconds) {
- throw new UnsupportedOperationException("cannot set transaction timeout in CMT");
- }
-
-}
diff --git a/hibernate-core/src/main/java/org/hibernate/transaction/CacheSynchronization.java b/hibernate-core/src/main/java/org/hibernate/transaction/CacheSynchronization.java
deleted file mode 100644
index 885443f9f3..0000000000
--- a/hibernate-core/src/main/java/org/hibernate/transaction/CacheSynchronization.java
+++ /dev/null
@@ -1,134 +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.transaction;
-
-import javax.transaction.Status;
-import javax.transaction.Synchronization;
-import javax.transaction.SystemException;
-import javax.transaction.Transaction;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.hibernate.TransactionException;
-import org.hibernate.engine.jdbc.spi.JDBCContext;
-import org.hibernate.util.JTAHelper;
-
-/**
- * A JTA transaction synch used to allow the {@link org.hibernate.Session} to know about transaction
- * events.
- *
- * @author Gavin King
- */
-public final class CacheSynchronization implements Synchronization {
-
- private static final Logger log = LoggerFactory.getLogger(CacheSynchronization.class);
-
- private final TransactionFactory.Context ctx;
- private JDBCContext jdbcContext;
- private final Transaction transaction;
- private final org.hibernate.Transaction hibernateTransaction;
-
- public CacheSynchronization(
- TransactionFactory.Context ctx,
- JDBCContext jdbcContext,
- Transaction transaction,
- org.hibernate.Transaction tx) {
- this.ctx = ctx;
- this.jdbcContext = jdbcContext;
- this.transaction = transaction;
- this.hibernateTransaction = tx;
- }
-
- /**
- * {@inheritDoc}
- */
- public void beforeCompletion() {
- log.trace("transaction before completion callback");
-
- boolean flush;
- try {
- flush = !ctx.isFlushModeNever() &&
- ctx.isFlushBeforeCompletionEnabled() &&
- !JTAHelper.isRollback( transaction.getStatus() );
- //actually, this last test is probably unnecessary, since
- //beforeCompletion() doesn't get called during rollback
- }
- catch (SystemException se) {
- log.error("could not determine transaction status", se);
- setRollbackOnly();
- throw new TransactionException("could not determine transaction status in beforeCompletion()", se);
- }
-
- try {
- if (flush) {
- log.trace("automatically flushing session");
- ctx.managedFlush();
- }
- }
- catch (RuntimeException re) {
- setRollbackOnly();
- throw re;
- }
- finally {
- jdbcContext.beforeTransactionCompletion(hibernateTransaction);
- }
- }
-
- private void setRollbackOnly() {
- try {
- transaction.setRollbackOnly();
- }
- catch (SystemException se) {
- log.error("could not set transaction to rollback only", se);
- }
- }
-
- /**
- * {@inheritDoc}
- */
- public void afterCompletion(int status) {
- if ( log.isTraceEnabled() ) {
- log.trace("transaction after completion callback, status: " + status);
- }
- try {
- jdbcContext.afterTransactionCompletion(status==Status.STATUS_COMMITTED, hibernateTransaction);
- }
- finally {
- if ( ctx.shouldAutoClose() && !ctx.isClosed() ) {
- log.trace("automatically closing session");
- ctx.managedClose();
- }
- }
- }
-
- /**
- * {@inheritDoc}
- */
- public String toString() {
- return CacheSynchronization.class.getName();
- }
-
-}
diff --git a/hibernate-core/src/main/java/org/hibernate/transaction/JBossTSStandaloneTransactionManagerLookup.java b/hibernate-core/src/main/java/org/hibernate/transaction/JBossTSStandaloneTransactionManagerLookup.java
deleted file mode 100644
index 380e10bf5e..0000000000
--- a/hibernate-core/src/main/java/org/hibernate/transaction/JBossTSStandaloneTransactionManagerLookup.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * 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
- *
- */
-package org.hibernate.transaction;
-
-import java.lang.reflect.Method;
-import java.util.Properties;
-import javax.transaction.Transaction;
-import javax.transaction.TransactionManager;
-
-import org.hibernate.HibernateException;
-
-/**
- * Return a standalone JTA transaction manager for JBoss Transactions
- * Known to work for org.jboss.jbossts:jbossjta:4.11.0.Final
- *
- * @author Emmanuel Bernard
- */
-public class JBossTSStandaloneTransactionManagerLookup implements TransactionManagerLookup {
-
- public TransactionManager getTransactionManager(Properties props) throws HibernateException {
- try {
- //Call jtaPropertyManager.getJTAEnvironmentBean().getTransactionManager();
-
- //improper camel case name for the class
- Class> propertyManager = Class.forName( "com.arjuna.ats.jta.common.jtaPropertyManager" );
- final Method getJTAEnvironmentBean = propertyManager.getMethod( "getJTAEnvironmentBean" );
- //static method
- final Object jtaEnvironmentBean = getJTAEnvironmentBean.invoke( null );
- final Method getTransactionManager = jtaEnvironmentBean.getClass().getMethod( "getTransactionManager" );
- return ( TransactionManager ) getTransactionManager.invoke( jtaEnvironmentBean );
- }
- catch ( Exception e ) {
- throw new HibernateException( "Could not obtain JBoss Transactions transaction manager instance", e );
- }
- }
-
- public String getUserTransactionName() {
- return null;
- }
-
- public Object getTransactionIdentifier(Transaction transaction) {
- return transaction;
- }
-}
diff --git a/hibernate-core/src/main/java/org/hibernate/transaction/JDBCTransaction.java b/hibernate-core/src/main/java/org/hibernate/transaction/JDBCTransaction.java
deleted file mode 100644
index f89813b646..0000000000
--- a/hibernate-core/src/main/java/org/hibernate/transaction/JDBCTransaction.java
+++ /dev/null
@@ -1,275 +0,0 @@
-/*
- * 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
- */
-package org.hibernate.transaction;
-
-import java.sql.SQLException;
-import javax.transaction.Status;
-import javax.transaction.Synchronization;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.hibernate.HibernateException;
-import org.hibernate.Transaction;
-import org.hibernate.TransactionException;
-import org.hibernate.engine.jdbc.spi.JDBCContext;
-import org.hibernate.engine.transaction.SynchronizationRegistry;
-
-/**
- * {@link Transaction} implementation based on transaction management through a JDBC {@link java.sql.Connection}.
- *
- * This the Hibernate's default transaction strategy.
- *
- * @author Anton van Straaten
- * @author Gavin King
- */
-public class JDBCTransaction implements Transaction {
- private static final Logger log = LoggerFactory.getLogger(JDBCTransaction.class);
-
- private final SynchronizationRegistry synchronizationRegistry = new SynchronizationRegistry();
- private final JDBCContext jdbcContext;
- private final TransactionFactory.Context transactionContext;
-
- private boolean toggleAutoCommit;
- private boolean begun;
- private boolean rolledBack;
- private boolean committed;
- private boolean commitFailed;
- private boolean callback;
- private int timeout = -1;
-
- public JDBCTransaction(JDBCContext jdbcContext, TransactionFactory.Context transactionContext) {
- this.jdbcContext = jdbcContext;
- this.transactionContext = transactionContext;
- }
-
- /**
- * {@inheritDoc}
- */
- public void begin() throws HibernateException {
- if (begun) {
- return;
- }
- if (commitFailed) {
- throw new TransactionException("cannot re-start transaction after failed commit");
- }
-
- log.debug("begin");
-
- try {
- toggleAutoCommit = jdbcContext.connection().getAutoCommit();
- if ( log.isDebugEnabled() ) {
- log.debug("current autocommit status: " + toggleAutoCommit);
- }
- if (toggleAutoCommit) {
- log.debug("disabling autocommit");
- jdbcContext.connection().setAutoCommit(false);
- }
- }
- catch (SQLException e) {
- log.error("JDBC begin failed", e);
- throw new TransactionException("JDBC begin failed: ", e);
- }
-
- callback = jdbcContext.registerCallbackIfNecessary();
-
- begun = true;
- committed = false;
- rolledBack = false;
-
- if ( timeout>0 ) {
- jdbcContext.getConnectionManager()
- .setTransactionTimeout(timeout);
- }
-
- jdbcContext.afterTransactionBegin(this);
- }
-
- private void closeIfRequired() throws HibernateException {
- if ( callback && transactionContext.shouldAutoClose() && !transactionContext.isClosed() ) {
- try {
- transactionContext.managedClose();
- }
- catch (HibernateException he) {
- log.error("Could not close session", he);
- //swallow, the transaction was finished
- }
- }
- }
-
- /**
- * {@inheritDoc}
- */
- public void commit() throws HibernateException {
- if (!begun) {
- throw new TransactionException("Transaction not successfully started");
- }
-
- log.debug("commit");
-
- if ( !transactionContext.isFlushModeNever() && callback ) {
- transactionContext.managedFlush(); //if an exception occurs during flush, user must call rollback()
- }
-
- notifySynchronizationsBeforeTransactionCompletion();
- if ( callback ) {
- jdbcContext.beforeTransactionCompletion( this );
- }
-
- try {
- commitAndResetAutoCommit();
- log.debug("committed JDBC Connection");
- committed = true;
- if ( callback ) {
- jdbcContext.afterTransactionCompletion( true, this );
- }
- notifySynchronizationsAfterTransactionCompletion( Status.STATUS_COMMITTED );
- }
- catch (SQLException e) {
- log.error("JDBC commit failed", e);
- commitFailed = true;
- if ( callback ) {
- jdbcContext.afterTransactionCompletion( false, this );
- }
- notifySynchronizationsAfterTransactionCompletion( Status.STATUS_UNKNOWN );
- throw new TransactionException("JDBC commit failed", e);
- }
- finally {
- closeIfRequired();
- }
- }
-
- private void commitAndResetAutoCommit() throws SQLException {
- try {
- jdbcContext.connection().commit();
- }
- finally {
- toggleAutoCommit();
- }
- }
-
- /**
- * {@inheritDoc}
- */
- public void rollback() throws HibernateException {
-
- if (!begun && !commitFailed) {
- throw new TransactionException("Transaction not successfully started");
- }
-
- log.debug("rollback");
-
- if (!commitFailed) {
-
- /*notifyLocalSynchsBeforeTransactionCompletion();
- if ( callback ) {
- jdbcContext.notifyLocalSynchsBeforeTransactionCompletion( this );
- }*/
-
- try {
- rollbackAndResetAutoCommit();
- log.debug("rolled back JDBC Connection");
- rolledBack = true;
- notifySynchronizationsAfterTransactionCompletion(Status.STATUS_ROLLEDBACK);
- }
- catch (SQLException e) {
- log.error("JDBC rollback failed", e);
- notifySynchronizationsAfterTransactionCompletion(Status.STATUS_UNKNOWN);
- throw new TransactionException("JDBC rollback failed", e);
- }
- finally {
- if ( callback ) {
- jdbcContext.afterTransactionCompletion( false, this );
- }
- closeIfRequired();
- }
- }
- }
-
- private void rollbackAndResetAutoCommit() throws SQLException {
- try {
- jdbcContext.connection().rollback();
- }
- finally {
- toggleAutoCommit();
- }
- }
-
- private void toggleAutoCommit() {
- try {
- if (toggleAutoCommit) {
- log.debug("re-enabling autocommit");
- jdbcContext.connection().setAutoCommit( true );
- }
- }
- catch (Exception sqle) {
- log.error("Could not toggle autocommit", sqle);
- //swallow it (the transaction _was_ successful or successfully rolled back)
- }
- }
-
- /**
- * {@inheritDoc}
- */
- public boolean wasRolledBack() {
- return rolledBack;
- }
-
- /**
- * {@inheritDoc}
- */
- public boolean wasCommitted() {
- return committed;
- }
-
- /**
- * {@inheritDoc}
- */
- public boolean isActive() {
- return begun && ! ( rolledBack || committed | commitFailed );
- }
-
- /**
- * {@inheritDoc}
- */
- public void registerSynchronization(Synchronization sync) {
- synchronizationRegistry.registerSynchronization( sync );
- }
-
- private void notifySynchronizationsBeforeTransactionCompletion() {
- synchronizationRegistry.notifySynchronizationsBeforeTransactionCompletion();
- }
-
- private void notifySynchronizationsAfterTransactionCompletion(int status) {
- begun = false;
- synchronizationRegistry.notifySynchronizationsAfterTransactionCompletion( status );
- }
-
- /**
- * {@inheritDoc}
- */
- public void setTimeout(int seconds) {
- timeout = seconds;
- }
-}
diff --git a/hibernate-core/src/main/java/org/hibernate/transaction/JDBCTransactionFactory.java b/hibernate-core/src/main/java/org/hibernate/transaction/JDBCTransactionFactory.java
deleted file mode 100644
index a0f6136550..0000000000
--- a/hibernate-core/src/main/java/org/hibernate/transaction/JDBCTransactionFactory.java
+++ /dev/null
@@ -1,96 +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.transaction;
-
-import java.util.Properties;
-
-import org.hibernate.ConnectionReleaseMode;
-import org.hibernate.HibernateException;
-import org.hibernate.Transaction;
-import org.hibernate.engine.jdbc.spi.JDBCContext;
-
-/**
- * Factory for {@link JDBCTransaction} instances.
- *
- * @author Anton van Straaten
- */
-public final class JDBCTransactionFactory implements TransactionFactory {
-
- /**
- * {@inheritDoc}
- */
- public ConnectionReleaseMode getDefaultReleaseMode() {
- return ConnectionReleaseMode.AFTER_TRANSACTION;
- }
-
- /**
- * {@inheritDoc}
- */
- public Transaction createTransaction(JDBCContext jdbcContext, Context transactionContext)
- throws HibernateException {
- return new JDBCTransaction( jdbcContext, transactionContext );
- }
-
- /**
- * {@inheritDoc}
- */
- public void configure(Properties props) throws HibernateException {}
-
- /**
- * {@inheritDoc}
- */
- public boolean isTransactionManagerRequired() {
- return false;
- }
-
- /**
- * {@inheritDoc}
- */
- public boolean areCallbacksLocalToHibernateTransactions() {
- return true;
- }
-
- /**
- * {@inheritDoc}
- */
- public boolean isTransactionInProgress(
- JDBCContext jdbcContext,
- Context transactionContext,
- Transaction transaction) {
-// try {
-// // for JDBC-based transactions, we only want to return true
-// // here if we (this transaction) are managing the transaction
-// return transaction != null &&
-// transaction.isActive() &&
-// !jdbcContext.getConnectionManager().isAutoCommit();
-// }
-// catch ( SQLException e ) {
-// // assume we are in auto-commit!
-// return false;
-// }
- return transaction != null && transaction.isActive();
- }
-
-}
diff --git a/hibernate-core/src/main/java/org/hibernate/transaction/JNDITransactionManagerLookup.java b/hibernate-core/src/main/java/org/hibernate/transaction/JNDITransactionManagerLookup.java
deleted file mode 100644
index 78b0a71bfc..0000000000
--- a/hibernate-core/src/main/java/org/hibernate/transaction/JNDITransactionManagerLookup.java
+++ /dev/null
@@ -1,77 +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.transaction;
-
-import java.util.Properties;
-
-import javax.naming.NamingException;
-import javax.transaction.TransactionManager;
-import javax.transaction.Transaction;
-
-import org.hibernate.HibernateException;
-import org.hibernate.internal.util.jndi.JndiHelper;
-
-/**
- * Template implementation of {@link TransactionManagerLookup} where the
- * underlying {@link TransactionManager} is available via JNDI lookup at the
- * specified location - {@link #getName}.
- *
- * @author Gavin King
- */
-public abstract class JNDITransactionManagerLookup implements TransactionManagerLookup {
-
- /**
- * Get the JNDI namespace under wich we can locate the {@link TransactionManager}.
- *
- * @return The {@link TransactionManager} JNDI namespace
- */
- protected abstract String getName();
-
- /**
- * {@inheritDoc}
- */
- public TransactionManager getTransactionManager(Properties props) throws HibernateException {
- try {
- return (TransactionManager) JndiHelper.getInitialContext(props).lookup( getName() );
- }
- catch (NamingException ne) {
- throw new HibernateException( "Could not locate TransactionManager", ne );
- }
- }
-
- /**
- * {@inheritDoc}
- */
- public Object getTransactionIdentifier(Transaction transaction) {
- // for sane JEE/JTA containers, the transaction itself functions as its identifier...
- return transaction;
- }
-}
-
-
-
-
-
-
diff --git a/hibernate-core/src/main/java/org/hibernate/transaction/JTATransaction.java b/hibernate-core/src/main/java/org/hibernate/transaction/JTATransaction.java
deleted file mode 100644
index 856362414e..0000000000
--- a/hibernate-core/src/main/java/org/hibernate/transaction/JTATransaction.java
+++ /dev/null
@@ -1,359 +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.transaction;
-
-import javax.transaction.Status;
-import javax.transaction.Synchronization;
-import javax.transaction.SystemException;
-import javax.transaction.TransactionManager;
-import javax.transaction.UserTransaction;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.hibernate.HibernateException;
-import org.hibernate.Transaction;
-import org.hibernate.TransactionException;
-import org.hibernate.engine.jdbc.spi.JDBCContext;
-import org.hibernate.util.JTAHelper;
-
-/**
- * {@link Transaction} implementation based on transaction management through
- * a JTA {@link UserTransaction}. Similar to {@link CMTTransaction}, except
- * here we are actually managing the transactions through the Hibernate
- * transaction mechanism.
- *
- * @author Gavin King
- * @author Steve Ebersole
- * @author Les Hazlewood
- */
-public class JTATransaction implements Transaction {
-
- private static final Logger log = LoggerFactory.getLogger( JTATransaction.class );
-
- private final JDBCContext jdbcContext;
- private final TransactionFactory.Context transactionContext;
-
- private UserTransaction userTransaction;
- private boolean newTransaction;
- private boolean begun;
- private boolean commitFailed;
- private boolean commitSucceeded;
- private boolean callback;
-
- public JTATransaction(
- UserTransaction userTransaction,
- JDBCContext jdbcContext,
- TransactionFactory.Context transactionContext) {
- this.jdbcContext = jdbcContext;
- this.transactionContext = transactionContext;
- this.userTransaction = userTransaction;
- }
-
- /**
- * {@inheritDoc}
- */
- public void begin() throws HibernateException {
- if ( begun ) {
- return;
- }
- if ( commitFailed ) {
- throw new TransactionException( "cannot re-start transaction after failed commit" );
- }
-
- log.debug( "begin" );
-
- try {
- newTransaction = userTransaction.getStatus() == Status.STATUS_NO_TRANSACTION;
- if ( newTransaction ) {
- userTransaction.begin();
- log.debug( "Began a new JTA transaction" );
- }
- }
- catch ( Exception e ) {
- log.error( "JTA transaction begin failed", e );
- throw new TransactionException( "JTA transaction begin failed", e );
- }
-
- /*if (newTransaction) {
- // don't need a synchronization since we are committing
- // or rolling back the transaction ourselves - assuming
- // that we do no work in beforeTransactionCompletion()
- synchronization = false;
- }*/
-
- boolean synchronization = jdbcContext.registerSynchronizationIfPossible();
-
- if ( !newTransaction && !synchronization ) {
- log.warn( "You should set hibernate.transaction.manager_lookup_class if cache is enabled" );
- }
-
- if ( !synchronization ) {
- //if we could not register a synchronization,
- //do the before/after completion callbacks
- //ourself (but we need to let jdbcContext
- //know that this is what we are going to
- //do, so it doesn't keep trying to register
- //synchronizations)
- callback = jdbcContext.registerCallbackIfNecessary();
- }
-
- begun = true;
- commitSucceeded = false;
-
- jdbcContext.afterTransactionBegin( this );
- }
-
- /**
- * {@inheritDoc}
- */
- public void commit() throws HibernateException {
- if ( !begun ) {
- throw new TransactionException( "Transaction not successfully started" );
- }
-
- log.debug( "commit" );
-
- boolean flush = !transactionContext.isFlushModeNever()
- && ( callback || !transactionContext.isFlushBeforeCompletionEnabled() );
-
- if ( flush ) {
- transactionContext.managedFlush(); //if an exception occurs during flush, user must call rollback()
- }
-
- if ( callback && newTransaction ) {
- jdbcContext.beforeTransactionCompletion( this );
- }
-
- closeIfRequired();
-
- if ( newTransaction ) {
- try {
- userTransaction.commit();
- commitSucceeded = true;
- log.debug( "Committed JTA UserTransaction" );
- }
- catch ( Exception e ) {
- commitFailed = true; // so the transaction is already rolled back, by JTA spec
- log.error( "JTA commit failed", e );
- throw new TransactionException( "JTA commit failed: ", e );
- }
- finally {
- afterCommitRollback();
- }
- }
- else {
- // this one only really needed for badly-behaved applications!
- // (if the TransactionManager has a Sychronization registered,
- // its a noop)
- // (actually we do need it for downgrading locks)
- afterCommitRollback();
- }
-
- }
-
- /**
- * {@inheritDoc}
- */
- public void rollback() throws HibernateException {
- if ( !begun && !commitFailed ) {
- throw new TransactionException( "Transaction not successfully started" );
- }
-
- log.debug( "rollback" );
-
- try {
- closeIfRequired();
- }
- catch ( Exception e ) {
- // swallow it, and continue to roll back JTA transaction
- log.error( "could not close session during rollback", e );
- }
-
- try {
- if ( newTransaction ) {
- if ( !commitFailed ) {
- userTransaction.rollback();
- log.debug( "Rolled back JTA UserTransaction" );
- }
- }
- else {
- userTransaction.setRollbackOnly();
- log.debug( "set JTA UserTransaction to rollback only" );
- }
- }
- catch ( Exception e ) {
- log.error( "JTA rollback failed", e );
- throw new TransactionException( "JTA rollback failed", e );
- }
- finally {
- afterCommitRollback();
- }
- }
-
- private static final int NULL = Integer.MIN_VALUE;
-
- private void afterCommitRollback() throws TransactionException {
-
- begun = false;
- // this method is a noop if there is a Synchronization!
- if ( callback ) {
- if ( !newTransaction ) {
- log.warn( "You should set hibernate.transaction.manager_lookup_class if cache is enabled" );
- }
- int status = NULL;
- try {
- status = userTransaction.getStatus();
- }
- catch ( Exception e ) {
- log.error( "Could not determine transaction status after commit", e );
- throw new TransactionException( "Could not determine transaction status after commit", e );
- }
- finally {
- jdbcContext.afterTransactionCompletion( status == Status.STATUS_COMMITTED, this );
- }
- }
- }
-
- /**
- * {@inheritDoc}
- */
- public boolean wasRolledBack() throws TransactionException {
- final int status;
- try {
- status = userTransaction.getStatus();
- }
- catch ( SystemException se ) {
- log.error( "Could not determine transaction status", se );
- throw new TransactionException( "Could not determine transaction status", se );
- }
- if ( status == Status.STATUS_UNKNOWN ) {
- throw new TransactionException( "Could not determine transaction status" );
- }
- else {
- return JTAHelper.isRollback( status );
- }
- }
-
- /**
- * {@inheritDoc}
- */
- public boolean wasCommitted() throws TransactionException {
- final int status;
- try {
- status = userTransaction.getStatus();
- }
- catch ( SystemException se ) {
- log.error( "Could not determine transaction status", se );
- throw new TransactionException( "Could not determine transaction status: ", se );
- }
- if ( status == Status.STATUS_UNKNOWN ) {
- throw new TransactionException( "Could not determine transaction status" );
- }
- else {
- return status == Status.STATUS_COMMITTED;
- }
- }
-
- /**
- * {@inheritDoc}
- */
- public boolean isActive() throws TransactionException {
- if ( !begun || commitFailed || commitSucceeded ) {
- return false;
- }
-
- final int status;
- try {
- status = userTransaction.getStatus();
- }
- catch ( SystemException se ) {
- log.error( "Could not determine transaction status", se );
- throw new TransactionException( "Could not determine transaction status: ", se );
- }
- if ( status == Status.STATUS_UNKNOWN ) {
- throw new TransactionException( "Could not determine transaction status" );
- }
- else {
- return status == Status.STATUS_ACTIVE;
- }
- }
-
- /**
- * {@inheritDoc}
- */
- public void registerSynchronization(Synchronization sync) throws HibernateException {
- if ( getTransactionManager() == null ) {
- throw new IllegalStateException( "JTA TransactionManager not available" );
- }
- else {
- try {
- getTransactionManager().getTransaction().registerSynchronization( sync );
- }
- catch ( Exception e ) {
- throw new TransactionException( "could not register synchronization", e );
- }
- }
- }
-
- /**
- * Getter for property 'transactionManager'.
- *
- * @return Value for property 'transactionManager'.
- */
- private TransactionManager getTransactionManager() {
- return transactionContext.getFactory().getTransactionManager();
- }
-
- private void closeIfRequired() throws HibernateException {
- boolean close = callback &&
- transactionContext.shouldAutoClose() &&
- !transactionContext.isClosed();
- if ( close ) {
- transactionContext.managedClose();
- }
- }
-
- /**
- * {@inheritDoc}
- */
- public void setTimeout(int seconds) {
- try {
- userTransaction.setTransactionTimeout( seconds );
- }
- catch ( SystemException se ) {
- throw new TransactionException( "could not set transaction timeout", se );
- }
- }
-
- /**
- * Getter for property 'userTransaction'.
- *
- * @return Value for property 'userTransaction'.
- */
- protected UserTransaction getUserTransaction() {
- return userTransaction;
- }
-}
diff --git a/hibernate-core/src/main/java/org/hibernate/transaction/JTATransactionFactory.java b/hibernate-core/src/main/java/org/hibernate/transaction/JTATransactionFactory.java
deleted file mode 100644
index 82b2713545..0000000000
--- a/hibernate-core/src/main/java/org/hibernate/transaction/JTATransactionFactory.java
+++ /dev/null
@@ -1,254 +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.transaction;
-
-import java.util.Properties;
-
-import javax.naming.InitialContext;
-import javax.naming.NamingException;
-import javax.transaction.SystemException;
-import javax.transaction.UserTransaction;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.hibernate.ConnectionReleaseMode;
-import org.hibernate.HibernateException;
-import org.hibernate.Transaction;
-import org.hibernate.TransactionException;
-import org.hibernate.engine.jdbc.spi.JDBCContext;
-import org.hibernate.internal.util.jndi.JndiHelper;
-import org.hibernate.cfg.Environment;
-import org.hibernate.util.JTAHelper;
-
-/**
- * Factory for {@link JTATransaction} instances.
- *
- * To be completely accurate to the JTA spec, JTA implementations should
- * publish their contextual {@link UserTransaction} reference into JNDI.
- * However, in practice there are quite a few stand-alone
- * implementations intended for use outside of J2EE/JEE containers and
- * which therefore do not publish their {@link UserTransaction} references
- * into JNDI but which otherwise follow the aspects of the JTA specification.
- * This {@link TransactionFactory} implementation can support both models.
- *
- * For complete JTA implementations (including dependence on JNDI), the
- * {@link UserTransaction} reference is obtained by a call to
- * {@link #resolveInitialContext}. Hibernate will then attempt to locate the
- * {@link UserTransaction} within this resolved
- * {@link InitialContext} based on the namespace returned by
- * {@link #resolveUserTransactionName}.
- *
- * For the so-called stand-alone implementations, we do not care at
- * all about the JNDI aspects just described. Here, the implementation would
- * have a specific manner to obtain a reference to its contextual
- * {@link UserTransaction}; usually this would be a static code reference, but
- * again it varies. Anyway, for each implementation the integration would need
- * to override the {@link #getUserTransaction} method and return the appropriate
- * thing.
- *
- * @author Gavin King
- * @author Steve Ebersole
- * @author Les Hazlewood
- */
-public class JTATransactionFactory implements TransactionFactory {
- public static final String DEFAULT_USER_TRANSACTION_NAME = "java:comp/UserTransaction";
- private static final Logger log = LoggerFactory.getLogger( JTATransactionFactory.class );
-
- protected InitialContext initialContext;
- protected String userTransactionName;
-
- /**
- * Configure this transaction factory. Specifically here we are attempting to
- * resolve both an {@link #getInitialContext InitialContext} as well as the
- * {@link #getUserTransactionName() JNDI namespace} for the {@link UserTransaction}.
- *
- * @param props The configuration properties
- *
- * @exception HibernateException
- */
- public void configure(Properties props) throws HibernateException {
- this.initialContext = resolveInitialContext( props );
- this.userTransactionName = resolveUserTransactionName( props );
- log.trace( "Configured JTATransactionFactory to use [{}] for UserTransaction JDNI namespace", userTransactionName );
- }
-
- /**
- * Given the lot of Hibernate configuration properties, resolve appropriate
- * reference to JNDI {@link InitialContext}.
- *
- * In general, the properties in which we are interested here all begin with
- * hibernate.jndi. Especially important depending on your
- * environment are {@link Environment#JNDI_URL hibernate.jndi.url} and
- * {@link Environment#JNDI_CLASS hibernate.jndi.class}
- *
- * @param properties The Hibernate config properties.
- * @return The resolved InitialContext.
- */
- protected final InitialContext resolveInitialContext(Properties properties) {
- try {
- return JndiHelper.getInitialContext( properties );
- }
- catch ( NamingException ne ) {
- throw new HibernateException( "Could not obtain initial context", ne );
- }
- }
-
- /**
- * Given the lot of Hibernate configuration properties, resolve appropriate
- * JNDI namespace to use for {@link UserTransaction} resolution.
- *
- * We determine the namespace to use by
- * - Any specified {@link Environment#USER_TRANSACTION jta.UserTransaction} config property
- * - If a {@link TransactionManagerLookup} was indicated, use its
- * {@link TransactionManagerLookup#getUserTransactionName}
- * - finally, as a last resort, we use {@link #DEFAULT_USER_TRANSACTION_NAME}
- *
- *
- * @param properties The Hibernate config properties.
- * @return The resolved {@link UserTransaction} namespace
- */
- protected final String resolveUserTransactionName(Properties properties) {
- String utName = properties.getProperty( Environment.USER_TRANSACTION );
- if ( utName == null ) {
- TransactionManagerLookup lookup = TransactionManagerLookupFactory.getTransactionManagerLookup( properties );
- if ( lookup != null ) {
- utName = lookup.getUserTransactionName();
- }
- }
- return utName == null ? DEFAULT_USER_TRANSACTION_NAME : utName;
- }
-
- /**
- * {@inheritDoc}
- */
- public Transaction createTransaction(JDBCContext jdbcContext, Context transactionContext)
- throws HibernateException {
- UserTransaction ut = getUserTransaction();
- return new JTATransaction( ut, jdbcContext, transactionContext );
- }
-
- /**
- * Get the {@link UserTransaction} reference.
- *
- * @return The appropriate {@link UserTransaction} reference.
- */
- protected UserTransaction getUserTransaction() {
- final String utName = getUserTransactionName();
- log.trace( "Attempting to locate UserTransaction via JNDI [{}]", utName );
-
- try {
- UserTransaction ut = ( UserTransaction ) getInitialContext().lookup( utName );
- if ( ut == null ) {
- throw new TransactionException( "Naming service lookup for UserTransaction returned null [" + utName +"]" );
- }
-
- log.trace( "Obtained UserTransaction" );
-
- return ut;
- }
- catch ( NamingException ne ) {
- throw new TransactionException( "Could not find UserTransaction in JNDI [" + utName + "]", ne );
- }
- }
-
- /**
- * Getter for property 'initialContext'.
- *
- * @return Value for property 'initialContext'.
- */
- protected InitialContext getInitialContext() {
- return initialContext;
- }
-
- /**
- * Getter for property 'userTransactionName'.
- * The algorithm here is
- *
- * @return Value for property 'userTransactionName'.
- */
- protected String getUserTransactionName() {
- return userTransactionName;
- }
-
- /**
- * {@inheritDoc}
- */
- public ConnectionReleaseMode getDefaultReleaseMode() {
- return ConnectionReleaseMode.AFTER_STATEMENT;
- }
-
- /**
- * {@inheritDoc}
- */
- public boolean isTransactionManagerRequired() {
- return false;
- }
-
- /**
- * {@inheritDoc}
- */
- public boolean areCallbacksLocalToHibernateTransactions() {
- return false;
- }
-
- /**
- * {@inheritDoc}
- */
- public boolean isTransactionInProgress(
- JDBCContext jdbcContext,
- Context transactionContext,
- Transaction transaction) {
- try {
- // Essentially:
- // 1) If we have a local (Hibernate) transaction in progress
- // and it already has the UserTransaction cached, use that
- // UserTransaction to determine the status.
- // 2) If a transaction manager has been located, use
- // that transaction manager to determine the status.
- // 3) Finally, as the last resort, try to lookup the
- // UserTransaction via JNDI and use that to determine the
- // status.
- if ( transaction != null ) {
- UserTransaction ut = ( ( JTATransaction ) transaction ).getUserTransaction();
- if ( ut != null ) {
- return JTAHelper.isInProgress( ut.getStatus() );
- }
- }
-
- if ( jdbcContext.getFactory().getTransactionManager() != null ) {
- return JTAHelper.isInProgress( jdbcContext.getFactory().getTransactionManager().getStatus() );
- }
- else {
- UserTransaction ut = getUserTransaction();
- return ut != null && JTAHelper.isInProgress( ut.getStatus() );
- }
- }
- catch ( SystemException se ) {
- throw new TransactionException( "Unable to check transaction status", se );
- }
- }
-
-}
diff --git a/hibernate-core/src/main/java/org/hibernate/transaction/SunONETransactionManagerLookup.java b/hibernate-core/src/main/java/org/hibernate/transaction/SunONETransactionManagerLookup.java
deleted file mode 100644
index 0bfd3283ce..0000000000
--- a/hibernate-core/src/main/java/org/hibernate/transaction/SunONETransactionManagerLookup.java
+++ /dev/null
@@ -1,50 +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.transaction;
-
-/**
- * {@link TransactionManagerLookup} strategy for Sun ONE Application Server 7 and above
- *
- * @author Robert Davidson
- * @author Sanjeev Krishnan
- * @author Emmanuel Bernard
- */
-public class SunONETransactionManagerLookup extends JNDITransactionManagerLookup {
-
- /**
- * {@inheritDoc}
- */
- protected String getName() {
- return "java:appserver/TransactionManager";
- }
-
- /**
- * {@inheritDoc}
- */
- public String getUserTransactionName() {
- return "java:comp/UserTransaction";
- }
-
-}
diff --git a/hibernate-core/src/main/java/org/hibernate/transaction/TransactionFactory.java b/hibernate-core/src/main/java/org/hibernate/transaction/TransactionFactory.java
deleted file mode 100644
index 1f55957649..0000000000
--- a/hibernate-core/src/main/java/org/hibernate/transaction/TransactionFactory.java
+++ /dev/null
@@ -1,124 +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.transaction;
-
-import java.util.Properties;
-
-import org.hibernate.ConnectionReleaseMode;
-import org.hibernate.HibernateException;
-import org.hibernate.Transaction;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.engine.jdbc.spi.JDBCContext;
-
-/**
- * Contract for generating Hibernate {@link Transaction} instances.
- *
- * The concrete implementation to be used is specified by the
- * {@link org.hibernate.cfg.Environment#TRANSACTION_STRATEGY} configuration
- * setting.
- *
- * Implementors must be threadsafe and should declare a public default constructor.
- *
- * @see Transaction
- *
- * @author Anton van Straaten
- * @author Gavin King
- */
-public interface TransactionFactory {
-
- /**
- * Callback mechanism; a context is always a {@link org.hibernate.Session}
- * in the Hibernate usage.
- */
- public static interface Context {
- public SessionFactoryImplementor getFactory();
- public boolean isClosed();
-
- public boolean isFlushModeNever();
- public boolean isFlushBeforeCompletionEnabled();
- public void managedFlush();
-
- public boolean shouldAutoClose();
- public void managedClose();
- }
-
- /**
- * Begin a transaction and return the associated Transaction instance.
- *
- * @param jdbcContext The jdbc context to which the transaction belongs
- * @param context The contract regarding the context in which this transaction will operate.
- * @return Transaction
- * @throws HibernateException Indicates a problem generating a transaction instance
- */
- public Transaction createTransaction(JDBCContext jdbcContext, Context context) throws HibernateException;
-
- /**
- * Configure from the given properties.
- *
- * @param props The configuration properties.
- * @throws HibernateException Indicates a problem configuring this factory.
- */
- public void configure(Properties props) throws HibernateException;
-
- /**
- * Get the default connection release mode.
- *
- * @return The default release mode associated with this strategy
- */
- public ConnectionReleaseMode getDefaultReleaseMode();
-
- /**
- * Do we require access to the JTA TransactionManager for
- * this strategy?
- *
- * @return True if this strategy requires access to the JTA TransactionManager;
- * false otherwise.
- */
- public boolean isTransactionManagerRequired();
-
- /**
- * Are all transaction callbacks local to Hibernate Transactions?
- * Or can the callbacks originate from some other source (e.g. a JTA
- * Synchronization).
- *
- * @return true if callbacks only ever originate from the Hibernate
- * {@link Transaction}; false otherwise.
- */
- public boolean areCallbacksLocalToHibernateTransactions();
-
- /**
- * Determine whether an underlying transaction is in progress.
- *
- * Mainly this is used in determining whether to register a
- * synchronization as well as whether or not to circumvent
- * auto flushing outside transactions.
- *
- * @param jdbcContext The JDBC context
- * @param transactionContext The transaction context
- * @param transaction The Hibernate transaction
- * @return true if an underlying transaction is know to be in effect.
- */
- public boolean isTransactionInProgress(JDBCContext jdbcContext, Context transactionContext, Transaction transaction);
-}
diff --git a/hibernate-core/src/main/java/org/hibernate/transaction/TransactionFactoryFactory.java b/hibernate-core/src/main/java/org/hibernate/transaction/TransactionFactoryFactory.java
deleted file mode 100644
index 903ae90faa..0000000000
--- a/hibernate-core/src/main/java/org/hibernate/transaction/TransactionFactoryFactory.java
+++ /dev/null
@@ -1,88 +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.transaction;
-
-import java.util.Properties;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.hibernate.HibernateException;
-import org.hibernate.cfg.Environment;
-import org.hibernate.util.ReflectHelper;
-
-/**
- * Helper for creating {@link TransactionFactory} instances.
- *
- * @author Gavin King
- */
-public final class TransactionFactoryFactory {
-
- private static final Logger log = LoggerFactory.getLogger( TransactionFactoryFactory.class );
-
- /**
- * Create an appropriate transaction factory based on the given configuration
- * properties.
- *
- * @param transactionProps transaction properties
- *
- * @return The appropriate transaction factory.
- *
- * @throws HibernateException Indicates a problem creating the appropriate
- * transaction factory.
- */
- public static TransactionFactory buildTransactionFactory(Properties transactionProps) throws HibernateException {
- String strategyClassName = transactionProps.getProperty( Environment.TRANSACTION_STRATEGY );
- if ( strategyClassName == null ) {
- log.info( "Using default transaction strategy (direct JDBC transactions)" );
- return new JDBCTransactionFactory();
- }
- log.info( "Transaction strategy: " + strategyClassName );
- TransactionFactory factory;
- try {
- factory = ( TransactionFactory ) ReflectHelper.classForName( strategyClassName ).newInstance();
- }
- catch ( ClassNotFoundException e ) {
- log.error( "TransactionFactory class not found", e );
- throw new HibernateException( "TransactionFactory class not found: " + strategyClassName );
- }
- catch ( IllegalAccessException e ) {
- log.error( "Failed to instantiate TransactionFactory", e );
- throw new HibernateException( "Failed to instantiate TransactionFactory: " + e );
- }
- catch ( java.lang.InstantiationException e ) {
- log.error( "Failed to instantiate TransactionFactory", e );
- throw new HibernateException( "Failed to instantiate TransactionFactory: " + e );
- }
- factory.configure( transactionProps );
- return factory;
- }
-
- /**
- * Disallow instantiation
- */
- private TransactionFactoryFactory() {
- }
-}
diff --git a/hibernate-core/src/main/java/org/hibernate/transaction/TransactionManagerLookupFactory.java b/hibernate-core/src/main/java/org/hibernate/transaction/TransactionManagerLookupFactory.java
deleted file mode 100644
index 11509cd508..0000000000
--- a/hibernate-core/src/main/java/org/hibernate/transaction/TransactionManagerLookupFactory.java
+++ /dev/null
@@ -1,97 +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.transaction;
-
-import java.util.Properties;
-
-import javax.transaction.TransactionManager;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.hibernate.HibernateException;
-import org.hibernate.cfg.Environment;
-import org.hibernate.util.ReflectHelper;
-
-/**
- * Helper for generating {@link TransactionManagerLookup} instances.
- *
- * @author Gavin King
- */
-public final class TransactionManagerLookupFactory {
-
- private static final Logger log = LoggerFactory.getLogger(TransactionManagerLookupFactory.class);
-
- /**
- * Disallow instantiation
- */
- private TransactionManagerLookupFactory() {
- }
-
- /**
- * Convenience method for locating the JTA {@link TransactionManager} from the
- * given platform config.
- *
- * Same as calling {@link #getTransactionManager}.getTransactionManager( props )
- *
- * @param props The properties representing the platform config
- * @return The located {@link TransactionManager}
- * @throws HibernateException Indicates a problem either (a) generatng the
- * {@link TransactionManagerLookup} or (b) asking it to locate the {@link TransactionManager}.
- */
- public static TransactionManager getTransactionManager(Properties props) throws HibernateException {
- log.info( "obtaining TransactionManager" );
- return getTransactionManagerLookup( props ).getTransactionManager( props );
- }
-
- /**
- * Generate the appropriate {@link TransactionManagerLookup} given the
- * config settings being passed.
- *
- * @param props The config settings
- * @return The appropriate {@link TransactionManagerLookup}
- * @throws HibernateException Indicates problem generating {@link TransactionManagerLookup}
- */
- public static TransactionManagerLookup getTransactionManagerLookup(Properties props) throws HibernateException {
- String tmLookupClass = props.getProperty( Environment.TRANSACTION_MANAGER_STRATEGY );
- if ( tmLookupClass == null ) {
- log.info( "No TransactionManagerLookup configured (in JTA environment, use of read-write or transactional second-level cache is not recommended)" );
- return null;
- }
- else {
- log.info( "instantiating TransactionManagerLookup: " + tmLookupClass );
- try {
- TransactionManagerLookup lookup = ( TransactionManagerLookup )
- ReflectHelper.classForName( tmLookupClass ).newInstance();
- log.info( "instantiated TransactionManagerLookup" );
- return lookup;
- }
- catch ( Exception e ) {
- log.error( "Could not instantiate TransactionManagerLookup", e );
- throw new HibernateException( "Could not instantiate TransactionManagerLookup '" + tmLookupClass + "'" );
- }
- }
- }
-}
diff --git a/hibernate-core/src/main/java/org/hibernate/transaction/WebSphereTransactionManagerLookup.java b/hibernate-core/src/main/java/org/hibernate/transaction/WebSphereTransactionManagerLookup.java
deleted file mode 100644
index 713a916a47..0000000000
--- a/hibernate-core/src/main/java/org/hibernate/transaction/WebSphereTransactionManagerLookup.java
+++ /dev/null
@@ -1,111 +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.transaction;
-
-import java.lang.reflect.Method;
-import java.util.Properties;
-
-import javax.transaction.TransactionManager;
-import javax.transaction.Transaction;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.hibernate.HibernateException;
-
-/**
- * {@link TransactionManagerLookup} strategy for WebSphere (versions 4, 5.0 and 5.1)
- *
- * @author Gavin King
- */
-@SuppressWarnings( {"UnusedDeclaration"})
-public class WebSphereTransactionManagerLookup implements TransactionManagerLookup {
-
- private static final Logger log = LoggerFactory.getLogger(WebSphereTransactionManagerLookup.class);
- private final int wsVersion;
- private final Class tmfClass;
-
- /**
- * Constructs a new WebSphereTransactionManagerLookup.
- */
- public WebSphereTransactionManagerLookup() {
- try {
- Class clazz;
- int version;
- try {
- clazz = Class.forName( "com.ibm.ws.Transaction.TransactionManagerFactory" );
- version = 5;
- log.info( "WebSphere 5.1" );
- }
- catch ( Exception e ) {
- try {
- clazz = Class.forName( "com.ibm.ejs.jts.jta.TransactionManagerFactory" );
- version = 5;
- log.info( "WebSphere 5.0" );
- }
- catch ( Exception e2 ) {
- clazz = Class.forName( "com.ibm.ejs.jts.jta.JTSXA" );
- version = 4;
- log.info( "WebSphere 4" );
- }
- }
-
- tmfClass = clazz;
- wsVersion = version;
- }
- catch ( Exception e ) {
- throw new HibernateException( "Could not obtain WebSphere TransactionManagerFactory instance", e );
- }
- }
-
- /**
- * {@inheritDoc}
- */
- public TransactionManager getTransactionManager(Properties props) throws HibernateException {
- try {
- final Method method = tmfClass.getMethod( "getTransactionManager", (Class[]) null );
- return ( TransactionManager ) method.invoke( null, (Object[]) null );
- }
- catch ( Exception e ) {
- throw new HibernateException( "Could not obtain WebSphere TransactionManager", e );
- }
- }
-
- /**
- * {@inheritDoc}
- */
- public String getUserTransactionName() {
- return wsVersion == 5
- ? "java:comp/UserTransaction"
- : "jta/usertransaction";
- }
-
- /**
- * {@inheritDoc}
- */
- public Object getTransactionIdentifier(Transaction transaction) {
- return transaction;
- }
-}
\ No newline at end of file
diff --git a/hibernate-core/src/main/java/org/hibernate/type/DbTimestampType.java b/hibernate-core/src/main/java/org/hibernate/type/DbTimestampType.java
index 46df7b29c0..316048d320 100644
--- a/hibernate-core/src/main/java/org/hibernate/type/DbTimestampType.java
+++ b/hibernate-core/src/main/java/org/hibernate/type/DbTimestampType.java
@@ -89,7 +89,10 @@ public class DbTimestampType extends TimestampType {
private Timestamp usePreparedStatement(String timestampSelectString, SessionImplementor session) {
PreparedStatement ps = null;
try {
- ps = session.getJDBCContext().getConnectionManager().prepareStatement( timestampSelectString, false );
+ ps = session.getTransactionCoordinator()
+ .getJdbcCoordinator()
+ .getStatementPreparer()
+ .prepareStatement( timestampSelectString, false );
ResultSet rs = ps.executeQuery();
rs.next();
Timestamp ts = rs.getTimestamp( 1 );
@@ -102,12 +105,12 @@ public class DbTimestampType extends TimestampType {
}
return ts;
}
- catch( SQLException sqle ) {
+ catch( SQLException e ) {
throw session.getFactory().getSQLExceptionHelper().convert(
- sqle,
+ e,
"could not select current db timestamp",
timestampSelectString
- );
+ );
}
finally {
if ( ps != null ) {
@@ -124,7 +127,10 @@ public class DbTimestampType extends TimestampType {
private Timestamp useCallableStatement(String callString, SessionImplementor session) {
CallableStatement cs = null;
try {
- cs = session.getJDBCContext().getConnectionManager().prepareCallableStatement( callString );
+ cs = (CallableStatement) session.getTransactionCoordinator()
+ .getJdbcCoordinator()
+ .getStatementPreparer()
+ .prepareStatement( callString, true );
cs.registerOutParameter( 1, java.sql.Types.TIMESTAMP );
cs.execute();
Timestamp ts = cs.getTimestamp( 1 );
@@ -137,12 +143,12 @@ public class DbTimestampType extends TimestampType {
}
return ts;
}
- catch( SQLException sqle ) {
+ catch( SQLException e ) {
throw session.getFactory().getSQLExceptionHelper().convert(
- sqle,
+ e,
"could not call current db timestamp function",
callString
- );
+ );
}
finally {
if ( cs != null ) {
diff --git a/hibernate-core/src/main/java/org/hibernate/util/JTAHelper.java b/hibernate-core/src/main/java/org/hibernate/util/JTAHelper.java
index 68b75da64f..8267d93b74 100755
--- a/hibernate-core/src/main/java/org/hibernate/util/JTAHelper.java
+++ b/hibernate-core/src/main/java/org/hibernate/util/JTAHelper.java
@@ -30,6 +30,7 @@ import javax.transaction.TransactionManager;
import org.hibernate.TransactionException;
import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.service.jta.platform.spi.JtaPlatform;
/**
* @author Gavin King
@@ -54,7 +55,7 @@ public final class JTAHelper {
* and false in *every* other cases (including in a JDBC transaction).
*/
public static boolean isTransactionInProgress(SessionFactoryImplementor factory) {
- TransactionManager tm = factory.getTransactionManager();
+ TransactionManager tm = factory.getServiceRegistry().getService( JtaPlatform.class ).retrieveTransactionManager();
try {
return tm != null && isTransactionInProgress( tm.getTransaction() );
}
diff --git a/hibernate-core/src/test/java/org/hibernate/test/annotations/manytomany/ManyToManyTest.java b/hibernate-core/src/test/java/org/hibernate/test/annotations/manytomany/ManyToManyTest.java
index 31300f24ea..206a7e96a3 100644
--- a/hibernate-core/src/test/java/org/hibernate/test/annotations/manytomany/ManyToManyTest.java
+++ b/hibernate-core/src/test/java/org/hibernate/test/annotations/manytomany/ManyToManyTest.java
@@ -3,6 +3,13 @@
package org.hibernate.test.annotations.manytomany;
+import org.hibernate.Hibernate;
+import org.hibernate.JDBCException;
+import org.hibernate.Session;
+import org.hibernate.Transaction;
+import org.hibernate.criterion.Restrictions;
+import org.hibernate.test.annotations.TestCase;
+
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
@@ -11,13 +18,6 @@ import java.util.Iterator;
import java.util.List;
import java.util.Set;
-import org.hibernate.Hibernate;
-import org.hibernate.JDBCException;
-import org.hibernate.Session;
-import org.hibernate.Transaction;
-import org.hibernate.criterion.Restrictions;
-import org.hibernate.test.annotations.TestCase;
-
/**
* Many to many tests
*
@@ -680,30 +680,29 @@ public class ManyToManyTest extends TestCase {
// or property.
public void testManyToManyEmbeddableBiDirectionalDotNotationInMappedBy() throws Exception {
Session s;
- Transaction tx;
s = openSession();
- tx = s.beginTransaction();
+ s.getTransaction().begin();
Employee e = new Employee();
e.setName( "Sharon" );
List phoneNumbers = new ArrayList();
Collection employees = new ArrayList();
employees.add( e );
- ContactInfo contactInfo = new ContactInfo();
+ ContactInfo contactInfo = new ContactInfo();
PhoneNumber number = new PhoneNumber();
number.setEmployees( employees );
phoneNumbers.add( number );
contactInfo.setPhoneNumbers( phoneNumbers );
e.setContactInfo( contactInfo );
s.persist( e );
- s.flush();
- s.clear();
- tx.commit();
+ s.getTransaction().commit();
+ s.close();
- tx.begin();
+ s = openSession();
+ s.getTransaction().begin();
e = (Employee)s.get( e.getClass(),e.getId() );
// follow both directions of many to many association
assertEquals("same employee", e.getName(), e.getContactInfo().getPhoneNumbers().get(0).getEmployees().iterator().next().getName());
- tx.commit();
+ s.getTransaction().commit();
s.close();
}
@@ -718,9 +717,8 @@ public class ManyToManyTest extends TestCase {
// with the dot notation is the name of the respective embedded field or property.
public void testOneToManyEmbeddableBiDirectionalDotNotationInMappedBy() throws Exception {
Session s;
- Transaction tx;
s = openSession();
- tx = s.beginTransaction();
+ s.getTransaction().begin();
Employee e = new Employee();
JobInfo job = new JobInfo();
job.setJobDescription( "Sushi Chef" );
@@ -731,16 +729,16 @@ public class ManyToManyTest extends TestCase {
job.setPm(pm);
e.setJobInfo( job );
s.persist( e );
- s.flush();
- s.clear();
- tx.commit();
+ s.getTransaction().commit();
+ s.close();
- tx.begin();
+ s = openSession();
+ s.getTransaction().begin();
e = (Employee) s.get( e.getClass(), e.getId() );
assertEquals( "same job in both directions",
e.getJobInfo().getJobDescription(),
e.getJobInfo().getPm().getManages().iterator().next().getJobInfo().getJobDescription() );
- tx.commit();
+ s.getTransaction().commit();
s.close();
}
diff --git a/hibernate-core/src/test/java/org/hibernate/test/annotations/polymorphism/PolymorphismTest.java b/hibernate-core/src/test/java/org/hibernate/test/annotations/polymorphism/PolymorphismTest.java
index 0929a56ff6..1b1acda0b3 100644
--- a/hibernate-core/src/test/java/org/hibernate/test/annotations/polymorphism/PolymorphismTest.java
+++ b/hibernate-core/src/test/java/org/hibernate/test/annotations/polymorphism/PolymorphismTest.java
@@ -17,7 +17,6 @@ public class PolymorphismTest extends TestCase {
car2.setModel( "350Z" );
Session s = openSession();
Transaction tx = s.beginTransaction();
- tx.begin();
s.persist( car );
s.persist( car2 );
s.flush();
diff --git a/hibernate-core/src/test/java/org/hibernate/test/annotations/subselect/SubselectTest.java b/hibernate-core/src/test/java/org/hibernate/test/annotations/subselect/SubselectTest.java
index 4614022d36..bf095d0692 100644
--- a/hibernate-core/src/test/java/org/hibernate/test/annotations/subselect/SubselectTest.java
+++ b/hibernate-core/src/test/java/org/hibernate/test/annotations/subselect/SubselectTest.java
@@ -43,8 +43,7 @@ public class SubselectTest extends TestCase {
Session s = openSession();
Transaction tx = s.beginTransaction();
- tx.begin();
-
+
//We don't use auto-generated ids because these seem to cause the session to flush.
//We want to test that the session flushes because of the 'synchronize' annotation
long itemId = 1;
diff --git a/hibernate-core/src/test/java/org/hibernate/test/common/JournalingBatchObserver.java b/hibernate-core/src/test/java/org/hibernate/test/common/JournalingBatchObserver.java
new file mode 100644
index 0000000000..bf9edee45e
--- /dev/null
+++ b/hibernate-core/src/test/java/org/hibernate/test/common/JournalingBatchObserver.java
@@ -0,0 +1,57 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2011, 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
+ */
+package org.hibernate.test.common;
+
+import org.hibernate.engine.jdbc.batch.spi.BatchObserver;
+
+/**
+ * @author Steve Ebersole
+ */
+public class JournalingBatchObserver implements BatchObserver {
+ private int implicitExecutionCount;
+ private int explicitExecutionCount;
+
+ @Override
+ public void batchExplicitlyExecuted() {
+ explicitExecutionCount++;
+ }
+
+ @Override
+ public void batchImplicitlyExecuted() {
+ implicitExecutionCount++;
+ }
+
+ public int getImplicitExecutionCount() {
+ return implicitExecutionCount;
+ }
+
+ public int getExplicitExecutionCount() {
+ return explicitExecutionCount;
+ }
+
+ public void reset() {
+ explicitExecutionCount = 0;
+ implicitExecutionCount = 0;
+ }
+}
diff --git a/hibernate-core/src/test/java/org/hibernate/test/common/JournalingConnectionObserver.java b/hibernate-core/src/test/java/org/hibernate/test/common/JournalingConnectionObserver.java
new file mode 100644
index 0000000000..d804d8fc68
--- /dev/null
+++ b/hibernate-core/src/test/java/org/hibernate/test/common/JournalingConnectionObserver.java
@@ -0,0 +1,74 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2011, 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
+ */
+package org.hibernate.test.common;
+
+import org.hibernate.engine.jdbc.spi.ConnectionObserver;
+
+import java.sql.Connection;
+
+/**
+ * @author Steve Ebersole
+ */
+public class JournalingConnectionObserver implements ConnectionObserver {
+ private int physicalConnectionObtainedCount = 0;
+ private int physicalConnectionReleasedCount = 0;
+ private int logicalConnectionClosedCount = 0;
+ private int statementPreparedCount = 0;
+
+ @Override
+ public void physicalConnectionObtained(Connection connection) {
+ physicalConnectionObtainedCount++;
+ }
+
+ @Override
+ public void physicalConnectionReleased() {
+ physicalConnectionReleasedCount++;
+ }
+
+ @Override
+ public void logicalConnectionClosed() {
+ logicalConnectionClosedCount++;
+ }
+
+ @Override
+ public void statementPrepared() {
+ statementPreparedCount++;
+ }
+
+ public int getPhysicalConnectionObtainedCount() {
+ return physicalConnectionObtainedCount;
+ }
+
+ public int getPhysicalConnectionReleasedCount() {
+ return physicalConnectionReleasedCount;
+ }
+
+ public int getLogicalConnectionClosedCount() {
+ return logicalConnectionClosedCount;
+ }
+
+ public int getStatementPreparedCount() {
+ return statementPreparedCount;
+ }
+}
diff --git a/hibernate-core/src/main/java/org/hibernate/transaction/WeblogicTransactionManagerLookup.java b/hibernate-core/src/test/java/org/hibernate/test/common/JournalingTransactionObserver.java
similarity index 50%
rename from hibernate-core/src/main/java/org/hibernate/transaction/WeblogicTransactionManagerLookup.java
rename to hibernate-core/src/test/java/org/hibernate/test/common/JournalingTransactionObserver.java
index de500b64ff..68dd256e87 100644
--- a/hibernate-core/src/main/java/org/hibernate/transaction/WeblogicTransactionManagerLookup.java
+++ b/hibernate-core/src/test/java/org/hibernate/test/common/JournalingTransactionObserver.java
@@ -1,10 +1,10 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
- * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * Copyright (c) 2011, 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 Middleware LLC.
+ * 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
@@ -20,31 +20,41 @@
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
- *
*/
-package org.hibernate.transaction;
+package org.hibernate.test.common;
+
+import org.hibernate.engine.transaction.spi.TransactionImplementor;
+import org.hibernate.engine.transaction.spi.TransactionObserver;
/**
- * TransactionManager lookup strategy for WebLogic
- * @author Gavin King
- */
-public final class WeblogicTransactionManagerLookup extends JNDITransactionManagerLookup {
+* @author Steve Ebersole
+*/
+public class JournalingTransactionObserver implements TransactionObserver {
+ private int begins = 0;
+ private int beforeCompletions = 0;
+ private int afterCompletions = 0;
- /**
- * @see org.hibernate.transaction.JNDITransactionManagerLookup#getName()
- */
- protected String getName() {
- return "javax.transaction.TransactionManager";
+ public void afterBegin(TransactionImplementor transaction) {
+ begins++;
}
- public String getUserTransactionName() {
- return "javax.transaction.UserTransaction";
+ public void beforeCompletion(TransactionImplementor transaction) {
+ beforeCompletions++;
}
+ public void afterCompletion(boolean successful, TransactionImplementor transaction) {
+ afterCompletions++;
+ }
+
+ public int getBegins() {
+ return begins;
+ }
+
+ public int getBeforeCompletions() {
+ return beforeCompletions;
+ }
+
+ public int getAfterCompletions() {
+ return afterCompletions;
+ }
}
-
-
-
-
-
-
diff --git a/hibernate-core/src/test/java/org/hibernate/test/common/TransactionContextImpl.java b/hibernate-core/src/test/java/org/hibernate/test/common/TransactionContextImpl.java
new file mode 100644
index 0000000000..1557f81995
--- /dev/null
+++ b/hibernate-core/src/test/java/org/hibernate/test/common/TransactionContextImpl.java
@@ -0,0 +1,95 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2011, 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
+ */
+package org.hibernate.test.common;
+
+import org.hibernate.ConnectionReleaseMode;
+import org.hibernate.engine.transaction.spi.TransactionContext;
+import org.hibernate.engine.transaction.spi.TransactionEnvironment;
+import org.hibernate.engine.transaction.spi.TransactionImplementor;
+
+/**
+ * @author Steve Ebersole
+ */
+public class TransactionContextImpl implements TransactionContext {
+ private final TransactionEnvironment transactionEnvironment;
+
+ public TransactionContextImpl(TransactionEnvironment transactionEnvironment) {
+ this.transactionEnvironment = transactionEnvironment;
+ }
+
+ @Override
+ public TransactionEnvironment getTransactionEnvironment() {
+ return transactionEnvironment;
+ }
+
+ @Override
+ public ConnectionReleaseMode getConnectionReleaseMode() {
+ return transactionEnvironment.getTransactionFactory().getDefaultReleaseMode();
+ }
+
+ @Override
+ public boolean isAutoCloseSessionEnabled() {
+ return false;
+ }
+
+ @Override
+ public boolean isClosed() {
+ return false;
+ }
+
+ @Override
+ public boolean isFlushModeNever() {
+ return false;
+ }
+
+ @Override
+ public boolean isFlushBeforeCompletionEnabled() {
+ return true;
+ }
+
+ @Override
+ public void managedFlush() {
+ }
+
+ @Override
+ public boolean shouldAutoClose() {
+ return false;
+ }
+
+ @Override
+ public void managedClose() {
+ }
+
+ @Override
+ public void afterTransactionBegin(TransactionImplementor hibernateTransaction) {
+ }
+
+ @Override
+ public void beforeTransactionCompletion(TransactionImplementor hibernateTransaction) {
+ }
+
+ @Override
+ public void afterTransactionCompletion(TransactionImplementor hibernateTransaction, boolean successful) {
+ }
+}
diff --git a/hibernate-core/src/test/java/org/hibernate/test/common/TransactionEnvironmentImpl.java b/hibernate-core/src/test/java/org/hibernate/test/common/TransactionEnvironmentImpl.java
new file mode 100644
index 0000000000..82a3b2ba5d
--- /dev/null
+++ b/hibernate-core/src/test/java/org/hibernate/test/common/TransactionEnvironmentImpl.java
@@ -0,0 +1,63 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2011, 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
+ */
+package org.hibernate.test.common;
+
+import org.hibernate.cfg.NotYetImplementedException;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.engine.jdbc.spi.JdbcServices;
+import org.hibernate.engine.transaction.spi.TransactionEnvironment;
+import org.hibernate.engine.transaction.spi.TransactionFactory;
+import org.hibernate.service.jta.platform.spi.JtaPlatform;
+import org.hibernate.service.spi.ServiceRegistry;
+
+/**
+ * @author Steve Ebersole
+ */
+public class TransactionEnvironmentImpl implements TransactionEnvironment {
+ private final ServiceRegistry serviceRegistry;
+
+ public TransactionEnvironmentImpl(ServiceRegistry serviceRegistry) {
+ this.serviceRegistry = serviceRegistry;
+ }
+
+ @Override
+ public SessionFactoryImplementor getSessionFactory() {
+ throw new NotYetImplementedException( "Not available in this context" );
+ }
+
+ @Override
+ public JdbcServices getJdbcServices() {
+ return serviceRegistry.getService( JdbcServices.class );
+ }
+
+ @Override
+ public JtaPlatform getJtaPlatform() {
+ return serviceRegistry.getService( JtaPlatform.class );
+ }
+
+ @Override
+ public TransactionFactory getTransactionFactory() {
+ return serviceRegistry.getService( TransactionFactory.class );
+ }
+}
diff --git a/hibernate-core/src/test/java/org/hibernate/test/common/jta/AtomikosDataSourceConnectionProvider.java b/hibernate-core/src/test/java/org/hibernate/test/common/jta/AtomikosDataSourceConnectionProvider.java
new file mode 100644
index 0000000000..bbb0fcbdda
--- /dev/null
+++ b/hibernate-core/src/test/java/org/hibernate/test/common/jta/AtomikosDataSourceConnectionProvider.java
@@ -0,0 +1,82 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2011, 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
+ */
+package org.hibernate.test.common.jta;
+
+import org.hibernate.service.internal.ServiceProxy;
+import org.hibernate.service.jdbc.connections.spi.ConnectionProvider;
+import org.hibernate.service.jta.platform.spi.JtaPlatform;
+import org.hibernate.service.spi.ServiceRegistry;
+import org.hibernate.service.spi.ServiceRegistryAwareService;
+import org.hibernate.service.spi.UnknownUnwrapTypeException;
+
+import javax.sql.DataSource;
+import java.sql.Connection;
+import java.sql.SQLException;
+
+/**
+ * @author Steve Ebersole
+ */
+public class AtomikosDataSourceConnectionProvider implements ConnectionProvider, ServiceRegistryAwareService {
+ private DataSource dataSource;
+
+ @Override
+ public Connection getConnection() throws SQLException {
+ return dataSource.getConnection();
+ }
+
+ @Override
+ public void closeConnection(Connection conn) throws SQLException {
+ conn.close();
+ }
+
+ @Override
+ public boolean supportsAggressiveRelease() {
+ return true;
+ }
+
+ @Override
+ public boolean isUnwrappableAs(Class unwrapType) {
+ return ConnectionProvider.class.equals( unwrapType )
+ || unwrapType.isInstance( this )
+ || DataSource.class.isAssignableFrom( unwrapType );
+ }
+
+ @Override
+ @SuppressWarnings( {"unchecked"})
+ public T unwrap(Class unwrapType) {
+ if ( ConnectionProvider.class.equals( unwrapType ) || unwrapType.isInstance( this ) ) {
+ return (T) this;
+ }
+ if ( DataSource.class.isAssignableFrom( unwrapType ) ) {
+ return (T) dataSource;
+ }
+ throw new UnknownUnwrapTypeException( unwrapType );
+ }
+
+ @Override
+ public void injectServices(ServiceRegistry serviceRegistry) {
+ AtomikosJtaPlatform jtaPlatform = (AtomikosJtaPlatform) ( (ServiceProxy) serviceRegistry.getService( JtaPlatform.class ) ).getTargetInstance();
+ dataSource = jtaPlatform.getDataSource();
+ }
+}
diff --git a/hibernate-core/src/test/java/org/hibernate/test/common/jta/AtomikosJtaPlatform.java b/hibernate-core/src/test/java/org/hibernate/test/common/jta/AtomikosJtaPlatform.java
new file mode 100644
index 0000000000..9a41bb6752
--- /dev/null
+++ b/hibernate-core/src/test/java/org/hibernate/test/common/jta/AtomikosJtaPlatform.java
@@ -0,0 +1,129 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2011, 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
+ */
+package org.hibernate.test.common.jta;
+
+import com.atomikos.icatch.jta.UserTransactionImp;
+import com.atomikos.icatch.jta.UserTransactionManager;
+import com.atomikos.jdbc.nonxa.AtomikosNonXADataSourceBean;
+
+import org.hibernate.service.internal.ServiceProxy;
+import org.hibernate.service.jta.platform.internal.AbstractJtaPlatform;
+import org.hibernate.service.jta.platform.internal.JtaSynchronizationStrategy;
+import org.hibernate.service.jta.platform.internal.TransactionManagerBasedSynchronizationStrategy;
+import org.hibernate.service.jta.platform.spi.JtaPlatform;
+import org.hibernate.service.jta.platform.spi.JtaPlatformException;
+import org.hibernate.service.spi.ServiceRegistry;
+import org.hibernate.service.spi.Startable;
+import org.hibernate.service.spi.Stoppable;
+import org.hibernate.test.common.ConnectionProviderBuilder;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.sql.DataSource;
+import javax.transaction.SystemException;
+import javax.transaction.TransactionManager;
+import javax.transaction.UserTransaction;
+
+/**
+ * @author Steve Ebersole
+ */
+public class AtomikosJtaPlatform extends AbstractJtaPlatform implements Startable, Stoppable {
+ private static final Logger log = LoggerFactory.getLogger( AtomikosJtaPlatform.class );
+
+ private final JtaSynchronizationStrategy synchronizationStrategy = new TransactionManagerBasedSynchronizationStrategy( this );
+
+ private UserTransactionManager transactionManager;
+ private AtomikosNonXADataSourceBean dataSourceBean;
+
+ public DataSource getDataSource() {
+ return dataSourceBean;
+ }
+
+ @Override
+ protected TransactionManager locateTransactionManager() {
+ return transactionManager;
+ }
+
+ @Override
+ protected UserTransaction locateUserTransaction() {
+ return new UserTransactionImp();
+ }
+
+ @Override
+ protected JtaSynchronizationStrategy getSynchronizationStrategy() {
+ return synchronizationStrategy;
+ }
+
+ @Override
+ public void start() {
+ if ( transactionManager == null ) {
+ transactionManager = new UserTransactionManager();
+ try {
+ transactionManager.init();
+ }
+ catch (Exception e) {
+ throw new JtaPlatformException( "Unable to init Atomikos UserTransactionManager", e );
+ }
+ }
+
+ if ( dataSourceBean == null ) {
+ // todo : extract sys props to handle functional testing...
+ dataSourceBean = new AtomikosNonXADataSourceBean();
+ dataSourceBean.setUniqueResourceName( "h2" );
+ dataSourceBean.setDriverClassName( ConnectionProviderBuilder.DRIVER );
+ dataSourceBean.setUrl( ConnectionProviderBuilder.URL );
+ dataSourceBean.setUser( ConnectionProviderBuilder.USER );
+ dataSourceBean.setPassword( ConnectionProviderBuilder.PASS );
+ dataSourceBean.setPoolSize( 3 );
+ try {
+ dataSourceBean.init();
+ }
+ catch (Exception e) {
+ throw new JtaPlatformException( "Unable to init Atomikos DataSourceBean", e );
+ }
+ }
+ }
+
+ @Override
+ public void stop() {
+ if ( dataSourceBean != null ) {
+ try {
+ dataSourceBean.close();
+ }
+ catch (Exception e) {
+ log.debug( "Error closing DataSourceBean", e );
+ }
+ }
+
+ if ( transactionManager != null ) {
+ try {
+ transactionManager.close();
+ }
+ catch (Exception e) {
+ log.debug( "Error closing UserTransactionManager", e );
+ }
+ }
+ }
+}
diff --git a/hibernate-core/src/test/java/org/hibernate/test/connections/AggressiveReleaseTest.java b/hibernate-core/src/test/java/org/hibernate/test/connections/AggressiveReleaseTest.java
index a46f1a10f3..a5bb35f5c1 100644
--- a/hibernate-core/src/test/java/org/hibernate/test/connections/AggressiveReleaseTest.java
+++ b/hibernate-core/src/test/java/org/hibernate/test/connections/AggressiveReleaseTest.java
@@ -1,11 +1,6 @@
// $Id: AggressiveReleaseTest.java 10977 2006-12-12 23:28:04Z steve.ebersole@jboss.com $
package org.hibernate.test.connections;
-import java.sql.Connection;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
import junit.framework.Test;
import org.hibernate.ConnectionReleaseMode;
@@ -14,14 +9,21 @@ import org.hibernate.ScrollableResults;
import org.hibernate.Session;
import org.hibernate.cfg.Configuration;
import org.hibernate.cfg.Environment;
+import org.hibernate.engine.transaction.internal.jta.CMTTransactionFactory;
import org.hibernate.impl.SessionImpl;
+import org.hibernate.service.jdbc.connections.spi.ConnectionProvider;
+import org.hibernate.service.jta.platform.internal.JtaPlatformInitiator;
+import org.hibernate.service.jta.platform.spi.JtaPlatform;
+import org.hibernate.test.common.jta.AtomikosDataSourceConnectionProvider;
+import org.hibernate.test.common.jta.AtomikosJtaPlatform;
import org.hibernate.testing.junit.functional.FunctionalTestClassTestSuite;
-import org.hibernate.testing.tm.ConnectionProviderImpl;
-import org.hibernate.testing.tm.SimpleJtaTransactionManagerImpl;
-import org.hibernate.testing.tm.TransactionManagerLookupImpl;
-import org.hibernate.transaction.CMTTransactionFactory;
import org.hibernate.util.SerializationHelper;
+import java.sql.Connection;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
/**
* Implementation of AggressiveReleaseTest.
*
@@ -39,8 +41,8 @@ public class AggressiveReleaseTest extends ConnectionManagementTestCase {
public void configure(Configuration cfg) {
super.configure( cfg );
- cfg.setProperty( Environment.CONNECTION_PROVIDER, ConnectionProviderImpl.class.getName() );
- cfg.setProperty( Environment.TRANSACTION_MANAGER_STRATEGY, TransactionManagerLookupImpl.class.getName() );
+ cfg.getProperties().put( JtaPlatformInitiator.JTA_PLATFORM, AtomikosJtaPlatform.class.getName() );
+ cfg.getProperties().put( Environment.CONNECTION_PROVIDER, AtomikosDataSourceConnectionProvider.class.getName() );
cfg.setProperty( Environment.TRANSACTION_STRATEGY, CMTTransactionFactory.class.getName() );
cfg.setProperty( Environment.RELEASE_CONNECTIONS, ConnectionReleaseMode.AFTER_STATEMENT.toString() );
cfg.setProperty( Environment.GENERATE_STATISTICS, "true" );
@@ -56,32 +58,36 @@ public class AggressiveReleaseTest extends ConnectionManagementTestCase {
}
protected void prepare() throws Throwable {
- SimpleJtaTransactionManagerImpl.getInstance().begin();
+ sfi().getServiceRegistry().getService( JtaPlatform.class ).retrieveTransactionManager().begin();
}
protected void done() throws Throwable {
- SimpleJtaTransactionManagerImpl.getInstance().commit();
+ sfi().getServiceRegistry().getService( JtaPlatform.class ).retrieveTransactionManager().commit();
}
// Some additional tests specifically for the aggressive-release functionality...
public void testSerializationOnAfterStatementAggressiveRelease() throws Throwable {
prepare();
- Session s = getSessionUnderTest();
- Silly silly = new Silly( "silly" );
- s.save( silly );
+ try {
+ Session s = getSessionUnderTest();
+ Silly silly = new Silly( "silly" );
+ s.save( silly );
- // this should cause the CM to obtain a connection, and then release it
- s.flush();
+ // this should cause the CM to obtain a connection, and then release it
+ s.flush();
- // We should be able to serialize the session at this point...
- SerializationHelper.serialize( s );
+ // We should be able to serialize the session at this point...
+ SerializationHelper.serialize( s );
- s.delete( silly );
- s.flush();
+ s.delete( silly );
+ s.flush();
- release( s );
- done();
+ release( s );
+ }
+ finally {
+ done();
+ }
}
public void testSerializationFailsOnAfterStatementAggressiveReleaseWithOpenResources() throws Throwable {
@@ -188,7 +194,7 @@ public class AggressiveReleaseTest extends ConnectionManagementTestCase {
public void testSuppliedConnection() throws Throwable {
prepare();
- Connection originalConnection = ConnectionProviderImpl.getActualConnectionProvider().getConnection();
+ Connection originalConnection = sfi().getServiceRegistry().getService( ConnectionProvider.class ).getConnection();
Session session = getSessions().openSession( originalConnection );
Silly silly = new Silly( "silly" );
@@ -197,8 +203,7 @@ public class AggressiveReleaseTest extends ConnectionManagementTestCase {
// this will cause the connection manager to cycle through the aggressive release logic;
// it should not release the connection since we explicitly suplied it ourselves.
session.flush();
-
- assertTrue( "Different connections", originalConnection == session.connection() );
+ assertTrue( session.isConnected() );
session.delete( silly );
session.flush();
@@ -206,17 +211,33 @@ public class AggressiveReleaseTest extends ConnectionManagementTestCase {
release( session );
done();
- ConnectionProviderImpl.getActualConnectionProvider().closeConnection( originalConnection );
+ sfi().getServiceRegistry().getService( ConnectionProvider.class ).closeConnection( originalConnection );
}
public void testBorrowedConnections() throws Throwable {
prepare();
Session s = getSessionUnderTest();
+ // todo : may need to come back here and make sure that closing the connection handles do not close the physical cached connection on LogicalConnection...
+
Connection conn = s.connection();
- assertTrue( ( ( SessionImpl ) s ).getJDBCContext().getConnectionManager().hasBorrowedConnection() );
+ assertFalse( conn.isClosed() );
+ assertFalse(
+ ((SessionImpl) s).getTransactionCoordinator()
+ .getJdbcCoordinator()
+ .getLogicalConnection()
+ .isPhysicallyConnected()
+ );
+ conn.getCatalog();
+ assertTrue(
+ ((SessionImpl) s).getTransactionCoordinator()
+ .getJdbcCoordinator()
+ .getLogicalConnection()
+ .isPhysicallyConnected()
+ );
conn.close();
- assertFalse( ( ( SessionImpl ) s ).getJDBCContext().getConnectionManager().hasBorrowedConnection() );
+ assertTrue( conn.isClosed() );
+ assertTrue( ( ( SessionImpl ) s ).getTransactionCoordinator().getJdbcCoordinator().getLogicalConnection().isPhysicallyConnected() );
release( s );
done();
diff --git a/hibernate-core/src/test/java/org/hibernate/test/connections/CurrentSessionConnectionTest.java b/hibernate-core/src/test/java/org/hibernate/test/connections/CurrentSessionConnectionTest.java
index c570ad657f..de6adf5511 100644
--- a/hibernate-core/src/test/java/org/hibernate/test/connections/CurrentSessionConnectionTest.java
+++ b/hibernate-core/src/test/java/org/hibernate/test/connections/CurrentSessionConnectionTest.java
@@ -28,4 +28,9 @@ public class CurrentSessionConnectionTest extends AggressiveReleaseTest {
protected void release(Session session) {
// do nothing, txn synch should release session as part of current-session definition
}
+
+ @Override
+ public void testSerializationOnAfterStatementAggressiveRelease() throws Throwable {
+ super.testSerializationOnAfterStatementAggressiveRelease();
+ }
}
diff --git a/hibernate-core/src/test/java/org/hibernate/test/exception/SQLExceptionConversionTest.java b/hibernate-core/src/test/java/org/hibernate/test/exception/SQLExceptionConversionTest.java
index 5fd330f94e..be245432a0 100644
--- a/hibernate-core/src/test/java/org/hibernate/test/exception/SQLExceptionConversionTest.java
+++ b/hibernate-core/src/test/java/org/hibernate/test/exception/SQLExceptionConversionTest.java
@@ -59,12 +59,7 @@ public class SQLExceptionConversionTest extends FunctionalTestCase {
fail("INSERT should have failed");
}
- catch(SQLException sqle) {
- JDBCExceptionReporter.logExceptions(sqle, "Just output!!!!");
- JDBCException jdbcException = converter.convert(sqle, null, null);
- assertEquals( "Bad conversion [" + sqle.getMessage() + "]", ConstraintViolationException.class , jdbcException.getClass() );
- ConstraintViolationException ex = (ConstraintViolationException) jdbcException;
- System.out.println("Violated constraint name: " + ex.getConstraintName());
+ catch (ConstraintViolationException expected) {
}
finally {
if ( ps != null ) {
@@ -95,8 +90,7 @@ public class SQLExceptionConversionTest extends FunctionalTestCase {
fail("SQL compilation should have failed");
}
- catch( SQLException sqle ) {
- assertEquals( "Bad conversion [" + sqle.getMessage() + "]", SQLGrammarException.class, converter.convert(sqle, null, null).getClass() );
+ catch (SQLGrammarException expected) {
}
finally {
if ( ps != null ) {
diff --git a/hibernate-core/src/test/java/org/hibernate/test/insertordering/InsertOrderingTest.java b/hibernate-core/src/test/java/org/hibernate/test/insertordering/InsertOrderingTest.java
index 4df42c0a47..b5130784eb 100644
--- a/hibernate-core/src/test/java/org/hibernate/test/insertordering/InsertOrderingTest.java
+++ b/hibernate-core/src/test/java/org/hibernate/test/insertordering/InsertOrderingTest.java
@@ -1,27 +1,26 @@
package org.hibernate.test.insertordering;
-import java.util.List;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.sql.PreparedStatement;
-
import junit.framework.Test;
-import org.hibernate.engine.jdbc.batch.internal.BatchBuilder;
-import org.hibernate.engine.jdbc.batch.internal.BatchingBatch;
-import org.hibernate.engine.jdbc.batch.spi.Batch;
-import org.hibernate.engine.jdbc.spi.SQLExceptionHelper;
-import org.hibernate.engine.jdbc.spi.SQLStatementLogger;
-import org.hibernate.testing.junit.functional.FunctionalTestCase;
-import org.hibernate.testing.junit.functional.FunctionalTestClassTestSuite;
+import org.hibernate.Session;
import org.hibernate.cfg.Configuration;
import org.hibernate.cfg.Environment;
-import org.hibernate.Session;
-import org.hibernate.jdbc.Expectation;
+import org.hibernate.engine.jdbc.batch.internal.BatchBuilderImpl;
+import org.hibernate.engine.jdbc.batch.internal.BatchBuilderInitiator;
+import org.hibernate.engine.jdbc.batch.internal.BatchingBatch;
+import org.hibernate.engine.jdbc.batch.spi.Batch;
+import org.hibernate.engine.jdbc.batch.spi.BatchKey;
+import org.hibernate.engine.jdbc.spi.JdbcCoordinator;
+import org.hibernate.test.common.JournalingBatchObserver;
+import org.hibernate.testing.junit.functional.FunctionalTestCase;
+import org.hibernate.testing.junit.functional.FunctionalTestClassTestSuite;
+
+import java.sql.PreparedStatement;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
/**
- * {@inheritDoc}
- *
* @author Steve Ebersole
*/
public class InsertOrderingTest extends FunctionalTestCase {
@@ -41,7 +40,7 @@ public class InsertOrderingTest extends FunctionalTestCase {
super.configure( cfg );
cfg.setProperty( Environment.ORDER_INSERTS, "true" );
cfg.setProperty( Environment.STATEMENT_BATCH_SIZE, "10" );
- cfg.setProperty( Environment.BATCH_STRATEGY, StatsBatchBuilder.class.getName() );
+ cfg.setProperty( BatchBuilderInitiator.BUILDER, StatsBatchBuilder.class.getName() );
}
public void testBatchOrdering() {
@@ -80,8 +79,8 @@ public class InsertOrderingTest extends FunctionalTestCase {
private static List batchSizes = new ArrayList();
private static int currentBatch = -1;
- public StatsBatch(Object key, SQLStatementLogger statementLogger, SQLExceptionHelper exceptionHelper, int jdbcBatchSize) {
- super( key, statementLogger, exceptionHelper, jdbcBatchSize );
+ public StatsBatch(BatchKey key, JdbcCoordinator jdbcCoordinator, int jdbcBatchSize) {
+ super( key, jdbcCoordinator, jdbcBatchSize );
}
static void reset() {
@@ -90,39 +89,34 @@ public class InsertOrderingTest extends FunctionalTestCase {
batchSQL = null;
}
- public void addBatchStatement(Object key, String sql, PreparedStatement ps) {
+ @Override
+ public PreparedStatement getBatchStatement(String sql, boolean callable) {
if ( batchSQL == null || ! batchSQL.equals( sql ) ) {
currentBatch++;
batchSQL = sql;
batchSizes.add( currentBatch, new Counter() );
- System.out.println( "--------------------------------------------------------" );
- System.out.println( "Preparing statement [" + sql + "]" );
}
- super.addBatchStatement( key, sql, ps );
+ return super.getBatchStatement( sql, callable );
}
- public void addToBatch(Object key, String sql, Expectation expectation) {
+ @Override
+ public void addToBatch() {
Counter counter = ( Counter ) batchSizes.get( currentBatch );
counter.count++;
- System.out.println( "Adding to batch [" + batchSQL + "]" );
- super.addToBatch( key, sql, expectation );
- }
-
- protected void doExecuteBatch() {
- System.out.println( "executing batch [" + batchSQL + "]" );
- System.out.println( "--------------------------------------------------------" );
- super.doExecuteBatch();
+ super.addToBatch();
}
}
- public static class StatsBatchBuilder extends BatchBuilder {
+ public static class StatsBatchBuilder extends BatchBuilderImpl {
private int jdbcBatchSize;
public void setJdbcBatchSize(int jdbcBatchSize) {
this.jdbcBatchSize = jdbcBatchSize;
}
- public Batch buildBatch(Object key, SQLStatementLogger statementLogger, SQLExceptionHelper exceptionHelper) {
- return new StatsBatch(key, statementLogger, exceptionHelper, jdbcBatchSize );
+
+ @Override
+ public Batch buildBatch(BatchKey key, JdbcCoordinator jdbcCoordinator) {
+ return new StatsBatch( key, jdbcCoordinator, jdbcBatchSize );
}
}
}
diff --git a/hibernate-core/src/test/java/org/hibernate/test/jdbc/proxies/AggressiveReleaseTest.java b/hibernate-core/src/test/java/org/hibernate/test/jdbc/proxies/AggressiveReleaseTest.java
index e32122b4ed..1acde23ec7 100644
--- a/hibernate-core/src/test/java/org/hibernate/test/jdbc/proxies/AggressiveReleaseTest.java
+++ b/hibernate-core/src/test/java/org/hibernate/test/jdbc/proxies/AggressiveReleaseTest.java
@@ -23,21 +23,20 @@
*/
package org.hibernate.test.jdbc.proxies;
+import org.hibernate.ConnectionReleaseMode;
+import org.hibernate.engine.jdbc.internal.LogicalConnectionImpl;
+import org.hibernate.engine.jdbc.internal.proxy.ProxyBuilder;
+import org.hibernate.test.common.BasicTestingJdbcServiceImpl;
+import org.hibernate.test.common.JournalingConnectionObserver;
+import org.hibernate.testing.junit.UnitTestCase;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Statement;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.hibernate.ConnectionReleaseMode;
-import org.hibernate.engine.jdbc.internal.LogicalConnectionImpl;
-import org.hibernate.engine.jdbc.spi.ConnectionObserver;
-import org.hibernate.engine.jdbc.internal.proxy.ProxyBuilder;
-import org.hibernate.test.common.BasicTestingJdbcServiceImpl;
-import org.hibernate.testing.junit.UnitTestCase;
-
/**
* TODO : javadoc
*
@@ -48,22 +47,6 @@ public class AggressiveReleaseTest extends UnitTestCase {
private static final Logger log = LoggerFactory.getLogger( AggressiveReleaseTest.class );
private BasicTestingJdbcServiceImpl services = new BasicTestingJdbcServiceImpl();
- private static class ConnectionCounter implements ConnectionObserver {
- public int obtainCount = 0;
- public int releaseCount = 0;
-
- public void physicalConnectionObtained(Connection connection) {
- obtainCount++;
- }
-
- public void physicalConnectionReleased() {
- releaseCount++;
- }
-
- public void logicalConnectionClosed() {
- }
- }
-
public AggressiveReleaseTest(String string) {
super( string );
}
@@ -130,14 +113,9 @@ public class AggressiveReleaseTest extends UnitTestCase {
}
public void testBasicRelease() {
- LogicalConnectionImpl logicalConnection = new LogicalConnectionImpl(
- null,
- ConnectionReleaseMode.AFTER_STATEMENT,
- services,
- null
- );
+ LogicalConnectionImpl logicalConnection = new LogicalConnectionImpl( null, ConnectionReleaseMode.AFTER_STATEMENT, services );
Connection proxiedConnection = ProxyBuilder.buildConnection( logicalConnection );
- ConnectionCounter observer = new ConnectionCounter();
+ JournalingConnectionObserver observer = new JournalingConnectionObserver();
logicalConnection.addObserver( observer );
try {
@@ -146,12 +124,12 @@ public class AggressiveReleaseTest extends UnitTestCase {
ps.setString( 2, "name" );
ps.execute();
assertTrue( logicalConnection.getResourceRegistry().hasRegisteredResources() );
- assertEquals( 1, observer.obtainCount );
- assertEquals( 0, observer.releaseCount );
+ assertEquals( 1, observer.getPhysicalConnectionObtainedCount() );
+ assertEquals( 0, observer.getPhysicalConnectionReleasedCount() );
ps.close();
assertFalse( logicalConnection.getResourceRegistry().hasRegisteredResources() );
- assertEquals( 1, observer.obtainCount );
- assertEquals( 1, observer.releaseCount );
+ assertEquals( 1, observer.getPhysicalConnectionObtainedCount() );
+ assertEquals( 1, observer.getPhysicalConnectionReleasedCount() );
}
catch ( SQLException sqle ) {
fail( "incorrect exception type : sqlexception" );
@@ -164,14 +142,9 @@ public class AggressiveReleaseTest extends UnitTestCase {
}
public void testReleaseCircumventedByHeldResources() {
- LogicalConnectionImpl logicalConnection = new LogicalConnectionImpl(
- null,
- ConnectionReleaseMode.AFTER_STATEMENT,
- services,
- null
- );
+ LogicalConnectionImpl logicalConnection = new LogicalConnectionImpl( null, ConnectionReleaseMode.AFTER_STATEMENT, services );
Connection proxiedConnection = ProxyBuilder.buildConnection( logicalConnection );
- ConnectionCounter observer = new ConnectionCounter();
+ JournalingConnectionObserver observer = new JournalingConnectionObserver();
logicalConnection.addObserver( observer );
try {
@@ -180,33 +153,32 @@ public class AggressiveReleaseTest extends UnitTestCase {
ps.setString( 2, "name" );
ps.execute();
assertTrue( logicalConnection.getResourceRegistry().hasRegisteredResources() );
- assertEquals( 1, observer.obtainCount );
- assertEquals( 0, observer.releaseCount );
+ assertEquals( 1, observer.getPhysicalConnectionObtainedCount() );
+ assertEquals( 0, observer.getPhysicalConnectionReleasedCount() );
ps.close();
assertFalse( logicalConnection.getResourceRegistry().hasRegisteredResources() );
- assertEquals( 1, observer.obtainCount );
- assertEquals( 1, observer.releaseCount );
+ assertEquals( 1, observer.getPhysicalConnectionObtainedCount() );
+ assertEquals( 1, observer.getPhysicalConnectionReleasedCount() );
// open a result set and hold it open...
ps = proxiedConnection.prepareStatement( "select * from SANDBOX_JDBC_TST" );
ps.executeQuery();
assertTrue( logicalConnection.getResourceRegistry().hasRegisteredResources() );
- assertTrue( logicalConnection.getResourceRegistry().hasRegisteredResources() );
- assertEquals( 2, observer.obtainCount );
- assertEquals( 1, observer.releaseCount );
+ assertEquals( 2, observer.getPhysicalConnectionObtainedCount() );
+ assertEquals( 1, observer.getPhysicalConnectionReleasedCount() );
// open a second result set
PreparedStatement ps2 = proxiedConnection.prepareStatement( "select * from SANDBOX_JDBC_TST" );
ps2.execute();
assertTrue( logicalConnection.getResourceRegistry().hasRegisteredResources() );
- assertEquals( 2, observer.obtainCount );
- assertEquals( 1, observer.releaseCount );
+ assertEquals( 2, observer.getPhysicalConnectionObtainedCount() );
+ assertEquals( 1, observer.getPhysicalConnectionReleasedCount() );
// and close it...
ps2.close();
// the release should be circumvented...
assertTrue( logicalConnection.getResourceRegistry().hasRegisteredResources() );
- assertEquals( 2, observer.obtainCount );
- assertEquals( 1, observer.releaseCount );
+ assertEquals( 2, observer.getPhysicalConnectionObtainedCount() );
+ assertEquals( 1, observer.getPhysicalConnectionReleasedCount() );
// let the close of the logical connection below release all resources (hopefully)...
}
@@ -218,19 +190,14 @@ public class AggressiveReleaseTest extends UnitTestCase {
}
assertFalse( logicalConnection.getResourceRegistry().hasRegisteredResources() );
- assertEquals( 2, observer.obtainCount );
- assertEquals( 2, observer.releaseCount );
+ assertEquals( 2, observer.getPhysicalConnectionObtainedCount() );
+ assertEquals( 2, observer.getPhysicalConnectionReleasedCount() );
}
public void testReleaseCircumventedManually() {
- LogicalConnectionImpl logicalConnection = new LogicalConnectionImpl(
- null,
- ConnectionReleaseMode.AFTER_STATEMENT,
- services,
- null
- );
+ LogicalConnectionImpl logicalConnection = new LogicalConnectionImpl( null, ConnectionReleaseMode.AFTER_STATEMENT, services );
Connection proxiedConnection = ProxyBuilder.buildConnection( logicalConnection );
- ConnectionCounter observer = new ConnectionCounter();
+ JournalingConnectionObserver observer = new JournalingConnectionObserver();
logicalConnection.addObserver( observer );
try {
@@ -239,12 +206,12 @@ public class AggressiveReleaseTest extends UnitTestCase {
ps.setString( 2, "name" );
ps.execute();
assertTrue( logicalConnection.getResourceRegistry().hasRegisteredResources() );
- assertEquals( 1, observer.obtainCount );
- assertEquals( 0, observer.releaseCount );
+ assertEquals( 1, observer.getPhysicalConnectionObtainedCount() );
+ assertEquals( 0, observer.getPhysicalConnectionReleasedCount() );
ps.close();
assertFalse( logicalConnection.getResourceRegistry().hasRegisteredResources() );
- assertEquals( 1, observer.obtainCount );
- assertEquals( 1, observer.releaseCount );
+ assertEquals( 1, observer.getPhysicalConnectionObtainedCount() );
+ assertEquals( 1, observer.getPhysicalConnectionReleasedCount() );
// disable releases...
logicalConnection.disableReleases();
@@ -253,14 +220,14 @@ public class AggressiveReleaseTest extends UnitTestCase {
ps = proxiedConnection.prepareStatement( "select * from SANDBOX_JDBC_TST" );
ps.executeQuery();
assertTrue( logicalConnection.getResourceRegistry().hasRegisteredResources() );
- assertEquals( 2, observer.obtainCount );
- assertEquals( 1, observer.releaseCount );
+ assertEquals( 2, observer.getPhysicalConnectionObtainedCount() );
+ assertEquals( 1, observer.getPhysicalConnectionReleasedCount() );
// and close it...
ps.close();
// the release should be circumvented...
assertFalse( logicalConnection.getResourceRegistry().hasRegisteredResources() );
- assertEquals( 2, observer.obtainCount );
- assertEquals( 1, observer.releaseCount );
+ assertEquals( 2, observer.getPhysicalConnectionObtainedCount() );
+ assertEquals( 1, observer.getPhysicalConnectionReleasedCount() );
// let the close of the logical connection below release all resources (hopefully)...
}
@@ -272,7 +239,7 @@ public class AggressiveReleaseTest extends UnitTestCase {
}
assertFalse( logicalConnection.getResourceRegistry().hasRegisteredResources() );
- assertEquals( 2, observer.obtainCount );
- assertEquals( 2, observer.releaseCount );
+ assertEquals( 2, observer.getPhysicalConnectionObtainedCount() );
+ assertEquals( 2, observer.getPhysicalConnectionReleasedCount() );
}
}
diff --git a/hibernate-core/src/test/java/org/hibernate/test/jdbc/proxies/BasicConnectionProxyTest.java b/hibernate-core/src/test/java/org/hibernate/test/jdbc/proxies/BasicConnectionProxyTest.java
index 8107c1ea0b..30ba84c132 100644
--- a/hibernate-core/src/test/java/org/hibernate/test/jdbc/proxies/BasicConnectionProxyTest.java
+++ b/hibernate-core/src/test/java/org/hibernate/test/jdbc/proxies/BasicConnectionProxyTest.java
@@ -61,8 +61,7 @@ public class BasicConnectionProxyTest extends UnitTestCase {
LogicalConnectionImpl logicalConnection = new LogicalConnectionImpl(
null,
ConnectionReleaseMode.AFTER_TRANSACTION,
- services,
- null
+ services
);
Connection proxiedConnection = ProxyBuilder.buildConnection( logicalConnection );
try {
@@ -89,8 +88,7 @@ public class BasicConnectionProxyTest extends UnitTestCase {
LogicalConnectionImpl logicalConnection = new LogicalConnectionImpl(
null,
ConnectionReleaseMode.AFTER_TRANSACTION,
- services,
- null
+ services
);
Connection proxiedConnection = ProxyBuilder.buildConnection( logicalConnection );
try {
@@ -111,8 +109,7 @@ public class BasicConnectionProxyTest extends UnitTestCase {
LogicalConnectionImpl logicalConnection = new LogicalConnectionImpl(
null,
ConnectionReleaseMode.AFTER_TRANSACTION,
- services,
- null
+ services
);
Connection proxiedConnection = ProxyBuilder.buildConnection( logicalConnection );
diff --git a/hibernate-core/src/test/java/org/hibernate/test/jdbc/proxies/BatchingTest.java b/hibernate-core/src/test/java/org/hibernate/test/jdbc/proxies/BatchingTest.java
new file mode 100644
index 0000000000..9fee757052
--- /dev/null
+++ b/hibernate-core/src/test/java/org/hibernate/test/jdbc/proxies/BatchingTest.java
@@ -0,0 +1,213 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2011, 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
+ */
+package org.hibernate.test.jdbc.proxies;
+
+import org.hibernate.engine.jdbc.batch.internal.BasicBatchKey;
+import org.hibernate.engine.jdbc.batch.internal.BatchBuilderImpl;
+import org.hibernate.engine.jdbc.batch.internal.BatchingBatch;
+import org.hibernate.engine.jdbc.batch.internal.NonBatchingBatch;
+import org.hibernate.engine.jdbc.batch.spi.Batch;
+import org.hibernate.engine.jdbc.batch.spi.BatchBuilder;
+import org.hibernate.engine.jdbc.batch.spi.BatchKey;
+import org.hibernate.engine.jdbc.spi.JdbcCoordinator;
+import org.hibernate.engine.jdbc.spi.LogicalConnectionImplementor;
+import org.hibernate.engine.transaction.internal.TransactionCoordinatorImpl;
+import org.hibernate.engine.transaction.spi.TransactionContext;
+import org.hibernate.engine.transaction.spi.TransactionImplementor;
+import org.hibernate.jdbc.Expectation;
+import org.hibernate.jdbc.Expectations;
+import org.hibernate.service.internal.ServiceRegistryImpl;
+import org.hibernate.service.spi.ServiceRegistry;
+import org.hibernate.service.spi.StandardServiceInitiators;
+import org.hibernate.test.common.ConnectionProviderBuilder;
+import org.hibernate.test.common.JournalingBatchObserver;
+import org.hibernate.test.common.JournalingTransactionObserver;
+import org.hibernate.test.common.TransactionContextImpl;
+import org.hibernate.test.common.TransactionEnvironmentImpl;
+import org.hibernate.testing.junit.UnitTestCase;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.Statement;
+
+/**
+ * @author Steve Ebersole
+ */
+public class BatchingTest extends UnitTestCase implements BatchKey {
+ private ServiceRegistry serviceRegistry;
+
+ public BatchingTest(String string) {
+ super( string );
+ }
+
+ public void setUp() throws Exception {
+ super.setUp();
+ serviceRegistry = new ServiceRegistryImpl(
+ StandardServiceInitiators.LIST,
+ ConnectionProviderBuilder.getConnectionProviderProperties()
+ );
+ }
+
+ public void tearDown() throws Exception {
+ ( (ServiceRegistryImpl) serviceRegistry).destroy();
+ super.tearDown();
+ }
+
+ @Override
+ public int getBatchedStatementCount() {
+ return 1;
+ }
+
+ @Override
+ public Expectation getExpectation() {
+ return Expectations.BASIC;
+ }
+
+ public void testNonBatchingUsage() throws Exception {
+ final TransactionContext transactionContext = new TransactionContextImpl( new TransactionEnvironmentImpl( serviceRegistry ) );
+
+ TransactionCoordinatorImpl transactionCoordinator = new TransactionCoordinatorImpl( null, transactionContext );
+ JournalingTransactionObserver observer = new JournalingTransactionObserver();
+ transactionCoordinator.addObserver( observer );
+
+ final JdbcCoordinator jdbcCoordinator = transactionCoordinator.getJdbcCoordinator();
+ LogicalConnectionImplementor logicalConnection = jdbcCoordinator.getLogicalConnection();
+ Connection connection = logicalConnection.getShareableConnectionProxy();
+
+ // set up some tables to use
+ Statement statement = connection.createStatement();
+ statement.execute( "drop table SANDBOX_JDBC_TST if exists" );
+ statement.execute( "create table SANDBOX_JDBC_TST ( ID integer, NAME varchar(100) )" );
+ assertTrue( logicalConnection.getResourceRegistry().hasRegisteredResources() );
+ assertTrue( logicalConnection.isPhysicallyConnected() );
+ statement.close();
+ assertFalse( logicalConnection.getResourceRegistry().hasRegisteredResources() );
+ assertTrue( logicalConnection.isPhysicallyConnected() ); // after_transaction specified
+
+ // ok, now we can get down to it...
+ TransactionImplementor txn = transactionCoordinator.getTransaction(); // same as Session#getTransaction
+ txn.begin();
+ assertEquals( 1, observer.getBegins() );
+
+ final String insertSql = "insert into SANDBOX_JDBC_TST( ID, NAME ) values ( ?, ? )";
+
+ final BatchBuilder batchBuilder = new BatchBuilderImpl( -1 );
+ final BatchKey batchKey = new BasicBatchKey( "this", Expectations.BASIC );
+ final Batch insertBatch = batchBuilder.buildBatch( batchKey, jdbcCoordinator );
+
+ final JournalingBatchObserver batchObserver = new JournalingBatchObserver();
+ insertBatch.addObserver( batchObserver );
+
+ assertTrue( "unexpected Batch impl", NonBatchingBatch.class.isInstance( insertBatch ) );
+ PreparedStatement insert = insertBatch.getBatchStatement( insertSql, false );
+ insert.setLong( 1, 1 );
+ insert.setString( 2, "name" );
+ assertEquals( 0, batchObserver.getExplicitExecutionCount() );
+ assertEquals( 0, batchObserver.getImplicitExecutionCount() );
+ insertBatch.addToBatch();
+ assertEquals( 0, batchObserver.getExplicitExecutionCount() );
+ assertEquals( 1, batchObserver.getImplicitExecutionCount() );
+ assertFalse( logicalConnection.getResourceRegistry().hasRegisteredResources() );
+
+ insertBatch.execute();
+ assertEquals( 1, batchObserver.getExplicitExecutionCount() );
+ assertEquals( 1, batchObserver.getImplicitExecutionCount() );
+ assertFalse( logicalConnection.getResourceRegistry().hasRegisteredResources() );
+
+ insertBatch.release();
+
+ txn.commit();
+ logicalConnection.close();
+ }
+
+ public void testBatchingUsage() throws Exception {
+ final TransactionContext transactionContext = new TransactionContextImpl( new TransactionEnvironmentImpl( serviceRegistry ) );
+
+ TransactionCoordinatorImpl transactionCoordinator = new TransactionCoordinatorImpl( null, transactionContext );
+ JournalingTransactionObserver transactionObserver = new JournalingTransactionObserver();
+ transactionCoordinator.addObserver( transactionObserver );
+
+ final JdbcCoordinator jdbcCoordinator = transactionCoordinator.getJdbcCoordinator();
+ LogicalConnectionImplementor logicalConnection = jdbcCoordinator.getLogicalConnection();
+ Connection connection = logicalConnection.getShareableConnectionProxy();
+
+ // set up some tables to use
+ Statement statement = connection.createStatement();
+ statement.execute( "drop table SANDBOX_JDBC_TST if exists" );
+ statement.execute( "create table SANDBOX_JDBC_TST ( ID integer, NAME varchar(100) )" );
+ assertTrue( logicalConnection.getResourceRegistry().hasRegisteredResources() );
+ assertTrue( logicalConnection.isPhysicallyConnected() );
+ statement.close();
+ assertFalse( logicalConnection.getResourceRegistry().hasRegisteredResources() );
+ assertTrue( logicalConnection.isPhysicallyConnected() ); // after_transaction specified
+
+ // ok, now we can get down to it...
+ TransactionImplementor txn = transactionCoordinator.getTransaction(); // same as Session#getTransaction
+ txn.begin();
+ assertEquals( 1, transactionObserver.getBegins() );
+
+ final BatchBuilder batchBuilder = new BatchBuilderImpl( 2 );
+ final BatchKey batchKey = new BasicBatchKey( "this", Expectations.BASIC );
+ final Batch insertBatch = batchBuilder.buildBatch( batchKey, jdbcCoordinator );
+ assertTrue( "unexpected Batch impl", BatchingBatch.class.isInstance( insertBatch ) );
+
+ final JournalingBatchObserver batchObserver = new JournalingBatchObserver();
+ insertBatch.addObserver( batchObserver );
+
+ final String insertSql = "insert into SANDBOX_JDBC_TST( ID, NAME ) values ( ?, ? )";
+
+ PreparedStatement insert = insertBatch.getBatchStatement( insertSql, false );
+ insert.setLong( 1, 1 );
+ insert.setString( 2, "name" );
+ assertEquals( 0, batchObserver.getExplicitExecutionCount() );
+ assertEquals( 0, batchObserver.getImplicitExecutionCount() );
+ insertBatch.addToBatch();
+ assertEquals( 0, batchObserver.getExplicitExecutionCount() );
+ assertEquals( 0, batchObserver.getImplicitExecutionCount() );
+ assertTrue( logicalConnection.getResourceRegistry().hasRegisteredResources() );
+
+ PreparedStatement insert2 = insertBatch.getBatchStatement( insertSql, false );
+ assertSame( insert, insert2 );
+ insert = insert2;
+ insert.setLong( 1, 2 );
+ insert.setString( 2, "another name" );
+ assertEquals( 0, batchObserver.getExplicitExecutionCount() );
+ assertEquals( 0, batchObserver.getImplicitExecutionCount() );
+ insertBatch.addToBatch();
+ assertEquals( 0, batchObserver.getExplicitExecutionCount() );
+ assertEquals( 1, batchObserver.getImplicitExecutionCount() );
+ assertTrue( logicalConnection.getResourceRegistry().hasRegisteredResources() );
+
+ insertBatch.execute();
+ assertEquals( 1, batchObserver.getExplicitExecutionCount() );
+ assertEquals( 1, batchObserver.getImplicitExecutionCount() );
+ assertFalse( logicalConnection.getResourceRegistry().hasRegisteredResources() );
+
+ insertBatch.release();
+
+ txn.commit();
+ logicalConnection.close();
+ }
+
+}
diff --git a/hibernate-core/src/test/java/org/hibernate/test/manytomany/batchload/BatchedManyToManyTest.java b/hibernate-core/src/test/java/org/hibernate/test/manytomany/batchload/BatchedManyToManyTest.java
index ca66ad9aa1..1ce6885626 100644
--- a/hibernate-core/src/test/java/org/hibernate/test/manytomany/batchload/BatchedManyToManyTest.java
+++ b/hibernate-core/src/test/java/org/hibernate/test/manytomany/batchload/BatchedManyToManyTest.java
@@ -21,27 +21,28 @@
*/
package org.hibernate.test.manytomany.batchload;
-import java.util.List;
-
-import junit.framework.Test;
import junit.framework.Assert;
+import junit.framework.Test;
-import org.hibernate.engine.jdbc.batch.internal.BatchBuilder;
-import org.hibernate.engine.jdbc.batch.internal.NonBatchingBatch;
-import org.hibernate.engine.jdbc.batch.spi.Batch;
-import org.hibernate.engine.jdbc.spi.SQLExceptionHelper;
-import org.hibernate.engine.jdbc.spi.SQLStatementLogger;
-import org.hibernate.testing.junit.functional.FunctionalTestCase;
-import org.hibernate.testing.junit.functional.FunctionalTestClassTestSuite;
-import org.hibernate.cfg.Configuration;
-import org.hibernate.cfg.Environment;
-import org.hibernate.Session;
+import org.hibernate.EmptyInterceptor;
import org.hibernate.Hibernate;
import org.hibernate.Interceptor;
-import org.hibernate.EmptyInterceptor;
-import org.hibernate.stat.CollectionStatistics;
+import org.hibernate.Session;
+import org.hibernate.cfg.Configuration;
+import org.hibernate.cfg.Environment;
+import org.hibernate.engine.jdbc.batch.internal.BatchBuilderImpl;
+import org.hibernate.engine.jdbc.batch.internal.NonBatchingBatch;
+import org.hibernate.engine.jdbc.batch.spi.Batch;
+import org.hibernate.engine.jdbc.batch.spi.BatchKey;
+import org.hibernate.engine.jdbc.spi.JdbcCoordinator;
+import org.hibernate.engine.jdbc.spi.JdbcServices;
import org.hibernate.loader.collection.BatchingCollectionInitializer;
import org.hibernate.persister.collection.AbstractCollectionPersister;
+import org.hibernate.stat.CollectionStatistics;
+import org.hibernate.testing.junit.functional.FunctionalTestCase;
+import org.hibernate.testing.junit.functional.FunctionalTestClassTestSuite;
+
+import java.util.List;
/**
* Tests loading of many-to-many collection which should trigger
@@ -68,20 +69,16 @@ public class BatchedManyToManyTest extends FunctionalTestCase {
cfg.setProperty( Environment.BATCH_STRATEGY, TestingBatchBuilder.class.getName() );
}
- public static class TestingBatchBuilder extends BatchBuilder {
- private int jdbcBatchSize;
-
- public void setJdbcBatchSize(int jdbcBatchSize) {
- this.jdbcBatchSize = jdbcBatchSize;
- }
- public Batch buildBatch(Object key, SQLStatementLogger statementLogger, SQLExceptionHelper exceptionHelper) {
- return new TestingBatch(key, statementLogger, exceptionHelper, jdbcBatchSize );
+ public static class TestingBatchBuilder extends BatchBuilderImpl {
+ @Override
+ public Batch buildBatch(BatchKey key, JdbcCoordinator jdbcCoordinator) {
+ return new TestingBatch( key, jdbcCoordinator );
}
}
public static class TestingBatch extends NonBatchingBatch {
- public TestingBatch(Object key, SQLStatementLogger statementLogger, SQLExceptionHelper exceptionHelper, int jdbcBatchSize) {
- super( key, statementLogger, exceptionHelper );
+ public TestingBatch(BatchKey key, JdbcCoordinator jdbcCoordinator) {
+ super( key, jdbcCoordinator );
}
}
diff --git a/hibernate-core/src/test/java/org/hibernate/test/nonflushedchanges/AbstractOperationTestCase.java b/hibernate-core/src/test/java/org/hibernate/test/nonflushedchanges/AbstractOperationTestCase.java
index 03bb8d760f..ffef92bea2 100644
--- a/hibernate-core/src/test/java/org/hibernate/test/nonflushedchanges/AbstractOperationTestCase.java
+++ b/hibernate-core/src/test/java/org/hibernate/test/nonflushedchanges/AbstractOperationTestCase.java
@@ -13,10 +13,10 @@ import org.hibernate.engine.EntityKey;
import org.hibernate.engine.NonFlushedChanges;
import org.hibernate.engine.SessionImplementor;
import org.hibernate.engine.StatefulPersistenceContext;
+import org.hibernate.engine.transaction.internal.jta.CMTTransactionFactory;
import org.hibernate.testing.junit.functional.FunctionalTestCase;
import org.hibernate.testing.tm.ConnectionProviderImpl;
import org.hibernate.testing.tm.TransactionManagerLookupImpl;
-import org.hibernate.transaction.CMTTransactionFactory;
import org.hibernate.util.SerializationHelper;
/**
diff --git a/hibernate-core/src/test/java/org/hibernate/test/ops/CreateTest.java b/hibernate-core/src/test/java/org/hibernate/test/ops/CreateTest.java
index 1f46942b64..7e1ca35733 100755
--- a/hibernate-core/src/test/java/org/hibernate/test/ops/CreateTest.java
+++ b/hibernate-core/src/test/java/org/hibernate/test/ops/CreateTest.java
@@ -124,7 +124,7 @@ public class CreateTest extends AbstractOperationTestCase {
s.persist(dupe);
try {
tx.commit();
- assertFalse(true);
+ fail( "Expecting constraint failure" );
}
catch (ConstraintViolationException cve) {
//verify that an exception is thrown!
diff --git a/hibernate-core/src/test/java/org/hibernate/test/readonly/ReadOnlyProxyTest.java b/hibernate-core/src/test/java/org/hibernate/test/readonly/ReadOnlyProxyTest.java
index 22e1b7a527..e2cba3b811 100644
--- a/hibernate-core/src/test/java/org/hibernate/test/readonly/ReadOnlyProxyTest.java
+++ b/hibernate-core/src/test/java/org/hibernate/test/readonly/ReadOnlyProxyTest.java
@@ -1495,7 +1495,6 @@ public class ReadOnlyProxyTest extends AbstractReadOnlyTest {
assertFalse( ( ( HibernateProxy ) dp ).getHibernateLazyInitializer().isReadOnlySettingAvailable() );
}
finally {
- s.beginTransaction();
s.delete( dp );
s.getTransaction().commit();
s.close();
@@ -1654,7 +1653,6 @@ public class ReadOnlyProxyTest extends AbstractReadOnlyTest {
assertFalse( ( ( HibernateProxy ) dp ).getHibernateLazyInitializer().isReadOnlySettingAvailable() );
}
finally {
- s.beginTransaction();
s.delete( dp );
s.getTransaction().commit();
s.close();
diff --git a/hibernate-core/src/test/java/org/hibernate/test/tm/CMTTest.java b/hibernate-core/src/test/java/org/hibernate/test/tm/CMTTest.java
index ee4c15e577..67c52d680e 100755
--- a/hibernate-core/src/test/java/org/hibernate/test/tm/CMTTest.java
+++ b/hibernate-core/src/test/java/org/hibernate/test/tm/CMTTest.java
@@ -1,12 +1,6 @@
//$Id: CMTTest.java 11303 2007-03-19 22:06:14Z steve.ebersole@jboss.com $
package org.hibernate.test.tm;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import javax.transaction.Transaction;
-
import junit.framework.Test;
import org.hibernate.ConnectionReleaseMode;
@@ -16,14 +10,21 @@ import org.hibernate.Session;
import org.hibernate.cfg.Configuration;
import org.hibernate.cfg.Environment;
import org.hibernate.criterion.Order;
+import org.hibernate.engine.transaction.internal.jta.CMTTransactionFactory;
+import org.hibernate.service.jta.platform.internal.JtaPlatformInitiator;
+import org.hibernate.service.jta.platform.spi.JtaPlatform;
+import org.hibernate.test.common.jta.AtomikosDataSourceConnectionProvider;
+import org.hibernate.test.common.jta.AtomikosJtaPlatform;
import org.hibernate.testing.junit.functional.FunctionalTestCase;
import org.hibernate.testing.junit.functional.FunctionalTestClassTestSuite;
-import org.hibernate.testing.tm.ConnectionProviderImpl;
-import org.hibernate.testing.tm.SimpleJtaTransactionManagerImpl;
-import org.hibernate.testing.tm.TransactionManagerLookupImpl;
-import org.hibernate.transaction.CMTTransactionFactory;
import org.hibernate.util.SerializationHelper;
+import javax.transaction.Transaction;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
/**
* @author Gavin King
*/
@@ -38,8 +39,8 @@ public class CMTTest extends FunctionalTestCase {
}
public void configure(Configuration cfg) {
- cfg.setProperty( Environment.CONNECTION_PROVIDER, ConnectionProviderImpl.class.getName() );
- cfg.setProperty( Environment.TRANSACTION_MANAGER_STRATEGY, TransactionManagerLookupImpl.class.getName() );
+ cfg.getProperties().put( JtaPlatformInitiator.JTA_PLATFORM, AtomikosJtaPlatform.class.getName() );
+ cfg.getProperties().put( Environment.CONNECTION_PROVIDER, AtomikosDataSourceConnectionProvider.class.getName() );
cfg.setProperty( Environment.TRANSACTION_STRATEGY, CMTTransactionFactory.class.getName() );
cfg.setProperty( Environment.AUTO_CLOSE_SESSION, "true" );
cfg.setProperty( Environment.FLUSH_BEFORE_COMPLETION, "true" );
@@ -62,7 +63,7 @@ public class CMTTest extends FunctionalTestCase {
assertNotNull( sfi().getEntityPersister( "Item" ).getCacheAccessStrategy() );
assertEquals( 0, getSessions().getStatistics().getEntityLoadCount() );
- SimpleJtaTransactionManagerImpl.getInstance().begin();
+ sfi().getServiceRegistry().getService( JtaPlatform.class ).retrieveTransactionManager().begin();
Session s = openSession();
Map foo = new HashMap();
foo.put( "name", "Foo" );
@@ -72,46 +73,46 @@ public class CMTTest extends FunctionalTestCase {
bar.put( "name", "Bar" );
bar.put( "description", "a small bar" );
s.persist( "Item", bar );
- SimpleJtaTransactionManagerImpl.getInstance().commit();
+ sfi().getServiceRegistry().getService( JtaPlatform.class ).retrieveTransactionManager().commit();
getSessions().evictEntity( "Item" );
- SimpleJtaTransactionManagerImpl.getInstance().begin();
+ sfi().getServiceRegistry().getService( JtaPlatform.class ).retrieveTransactionManager().begin();
Session s1 = openSession();
foo = ( Map ) s1.get( "Item", "Foo" );
//foo.put("description", "a big red foo");
//s1.flush();
- Transaction tx1 = SimpleJtaTransactionManagerImpl.getInstance().suspend();
+ Transaction tx1 = sfi().getServiceRegistry().getService( JtaPlatform.class ).retrieveTransactionManager().suspend();
- SimpleJtaTransactionManagerImpl.getInstance().begin();
+ sfi().getServiceRegistry().getService( JtaPlatform.class ).retrieveTransactionManager().begin();
Session s2 = openSession();
foo = ( Map ) s2.get( "Item", "Foo" );
- SimpleJtaTransactionManagerImpl.getInstance().commit();
+ sfi().getServiceRegistry().getService( JtaPlatform.class ).retrieveTransactionManager().commit();
- SimpleJtaTransactionManagerImpl.getInstance().resume( tx1 );
+ sfi().getServiceRegistry().getService( JtaPlatform.class ).retrieveTransactionManager().resume( tx1 );
tx1.commit();
getSessions().evictEntity( "Item" );
- SimpleJtaTransactionManagerImpl.getInstance().begin();
+ sfi().getServiceRegistry().getService( JtaPlatform.class ).retrieveTransactionManager().begin();
s1 = openSession();
s1.createCriteria( "Item" ).list();
//foo.put("description", "a big red foo");
//s1.flush();
- tx1 = SimpleJtaTransactionManagerImpl.getInstance().suspend();
+ tx1 = sfi().getServiceRegistry().getService( JtaPlatform.class ).retrieveTransactionManager().suspend();
- SimpleJtaTransactionManagerImpl.getInstance().begin();
+ sfi().getServiceRegistry().getService( JtaPlatform.class ).retrieveTransactionManager().begin();
s2 = openSession();
s2.createCriteria( "Item" ).list();
- SimpleJtaTransactionManagerImpl.getInstance().commit();
+ sfi().getServiceRegistry().getService( JtaPlatform.class ).retrieveTransactionManager().commit();
- SimpleJtaTransactionManagerImpl.getInstance().resume( tx1 );
+ sfi().getServiceRegistry().getService( JtaPlatform.class ).retrieveTransactionManager().resume( tx1 );
tx1.commit();
- SimpleJtaTransactionManagerImpl.getInstance().begin();
+ sfi().getServiceRegistry().getService( JtaPlatform.class ).retrieveTransactionManager().begin();
s2 = openSession();
s2.createCriteria( "Item" ).list();
- SimpleJtaTransactionManagerImpl.getInstance().commit();
+ sfi().getServiceRegistry().getService( JtaPlatform.class ).retrieveTransactionManager().commit();
assertEquals( 7, getSessions().getStatistics().getEntityLoadCount() );
assertEquals( 0, getSessions().getStatistics().getEntityFetchCount() );
@@ -119,15 +120,15 @@ public class CMTTest extends FunctionalTestCase {
assertEquals( 0, getSessions().getStatistics().getQueryCacheHitCount() );
assertEquals( 0, getSessions().getStatistics().getQueryCacheMissCount() );
- SimpleJtaTransactionManagerImpl.getInstance().begin();
+ sfi().getServiceRegistry().getService( JtaPlatform.class ).retrieveTransactionManager().begin();
s = openSession();
s.createQuery( "delete from Item" ).executeUpdate();
- SimpleJtaTransactionManagerImpl.getInstance().commit();
+ sfi().getServiceRegistry().getService( JtaPlatform.class ).retrieveTransactionManager().commit();
}
public void testConcurrentCachedQueries() throws Exception {
- SimpleJtaTransactionManagerImpl.getInstance().begin();
+ sfi().getServiceRegistry().getService( JtaPlatform.class ).retrieveTransactionManager().begin();
Session s = openSession();
Map foo = new HashMap();
foo.put( "name", "Foo" );
@@ -137,7 +138,7 @@ public class CMTTest extends FunctionalTestCase {
bar.put( "name", "Bar" );
bar.put( "description", "a small bar" );
s.persist( "Item", bar );
- SimpleJtaTransactionManagerImpl.getInstance().commit();
+ sfi().getServiceRegistry().getService( JtaPlatform.class ).retrieveTransactionManager().commit();
synchronized ( this ) {
wait( 1000 );
@@ -147,23 +148,23 @@ public class CMTTest extends FunctionalTestCase {
getSessions().evictEntity( "Item" );
- SimpleJtaTransactionManagerImpl.getInstance().begin();
+ sfi().getServiceRegistry().getService( JtaPlatform.class ).retrieveTransactionManager().begin();
Session s4 = openSession();
- Transaction tx4 = SimpleJtaTransactionManagerImpl.getInstance().suspend();
+ Transaction tx4 = sfi().getServiceRegistry().getService( JtaPlatform.class ).retrieveTransactionManager().suspend();
- SimpleJtaTransactionManagerImpl.getInstance().begin();
+ sfi().getServiceRegistry().getService( JtaPlatform.class ).retrieveTransactionManager().begin();
Session s1 = openSession();
List r1 = s1.createCriteria( "Item" ).addOrder( Order.asc( "description" ) )
.setCacheable( true ).list();
assertEquals( r1.size(), 2 );
- Transaction tx1 = SimpleJtaTransactionManagerImpl.getInstance().suspend();
+ Transaction tx1 = sfi().getServiceRegistry().getService( JtaPlatform.class ).retrieveTransactionManager().suspend();
- SimpleJtaTransactionManagerImpl.getInstance().begin();
+ sfi().getServiceRegistry().getService( JtaPlatform.class ).retrieveTransactionManager().begin();
Session s2 = openSession();
List r2 = s2.createCriteria( "Item" ).addOrder( Order.asc( "description" ) )
.setCacheable( true ).list();
assertEquals( r2.size(), 2 );
- SimpleJtaTransactionManagerImpl.getInstance().commit();
+ sfi().getServiceRegistry().getService( JtaPlatform.class ).retrieveTransactionManager().commit();
assertEquals( getSessions().getStatistics().getSecondLevelCacheHitCount(), 2 );
assertEquals( getSessions().getStatistics().getSecondLevelCacheMissCount(), 0 );
@@ -174,14 +175,14 @@ public class CMTTest extends FunctionalTestCase {
assertEquals( getSessions().getStatistics().getQueryCacheHitCount(), 1 );
assertEquals( getSessions().getStatistics().getQueryCacheMissCount(), 1 );
- SimpleJtaTransactionManagerImpl.getInstance().resume( tx1 );
+ sfi().getServiceRegistry().getService( JtaPlatform.class ).retrieveTransactionManager().resume( tx1 );
tx1.commit();
- SimpleJtaTransactionManagerImpl.getInstance().begin();
+ sfi().getServiceRegistry().getService( JtaPlatform.class ).retrieveTransactionManager().begin();
Session s3 = openSession();
s3.createCriteria( "Item" ).addOrder( Order.asc( "description" ) )
.setCacheable( true ).list();
- SimpleJtaTransactionManagerImpl.getInstance().commit();
+ sfi().getServiceRegistry().getService( JtaPlatform.class ).retrieveTransactionManager().commit();
assertEquals( getSessions().getStatistics().getSecondLevelCacheHitCount(), 4 );
assertEquals( getSessions().getStatistics().getSecondLevelCacheMissCount(), 0 );
@@ -192,7 +193,7 @@ public class CMTTest extends FunctionalTestCase {
assertEquals( getSessions().getStatistics().getQueryCacheHitCount(), 2 );
assertEquals( getSessions().getStatistics().getQueryCacheMissCount(), 1 );
- SimpleJtaTransactionManagerImpl.getInstance().resume( tx4 );
+ sfi().getServiceRegistry().getService( JtaPlatform.class ).retrieveTransactionManager().resume( tx4 );
List r4 = s4.createCriteria( "Item" ).addOrder( Order.asc( "description" ) )
.setCacheable( true ).list();
assertEquals( r4.size(), 2 );
@@ -207,10 +208,10 @@ public class CMTTest extends FunctionalTestCase {
assertEquals( getSessions().getStatistics().getQueryCacheHitCount(), 3 );
assertEquals( getSessions().getStatistics().getQueryCacheMissCount(), 1 );
- SimpleJtaTransactionManagerImpl.getInstance().begin();
+ sfi().getServiceRegistry().getService( JtaPlatform.class ).retrieveTransactionManager().begin();
s = openSession();
s.createQuery( "delete from Item" ).executeUpdate();
- SimpleJtaTransactionManagerImpl.getInstance().commit();
+ sfi().getServiceRegistry().getService( JtaPlatform.class ).retrieveTransactionManager().commit();
}
public void testConcurrentCachedDirtyQueries() throws Exception {
@@ -219,7 +220,7 @@ public class CMTTest extends FunctionalTestCase {
return;
}
- SimpleJtaTransactionManagerImpl.getInstance().begin();
+ sfi().getServiceRegistry().getService( JtaPlatform.class ).retrieveTransactionManager().begin();
Session s = openSession();
Map foo = new HashMap();
foo.put( "name", "Foo" );
@@ -229,7 +230,7 @@ public class CMTTest extends FunctionalTestCase {
bar.put( "name", "Bar" );
bar.put( "description", "a small bar" );
s.persist( "Item", bar );
- SimpleJtaTransactionManagerImpl.getInstance().commit();
+ sfi().getServiceRegistry().getService( JtaPlatform.class ).retrieveTransactionManager().commit();
synchronized ( this ) {
wait( 1000 );
@@ -239,11 +240,11 @@ public class CMTTest extends FunctionalTestCase {
getSessions().evictEntity( "Item" );
- SimpleJtaTransactionManagerImpl.getInstance().begin();
+ sfi().getServiceRegistry().getService( JtaPlatform.class ).retrieveTransactionManager().begin();
Session s4 = openSession();
- Transaction tx4 = SimpleJtaTransactionManagerImpl.getInstance().suspend();
+ Transaction tx4 = sfi().getServiceRegistry().getService( JtaPlatform.class ).retrieveTransactionManager().suspend();
- SimpleJtaTransactionManagerImpl.getInstance().begin();
+ sfi().getServiceRegistry().getService( JtaPlatform.class ).retrieveTransactionManager().begin();
Session s1 = openSession();
List r1 = s1.createCriteria( "Item" ).addOrder( Order.asc( "description" ) )
.setCacheable( true ).list();
@@ -251,14 +252,14 @@ public class CMTTest extends FunctionalTestCase {
foo = ( Map ) r1.get( 0 );
foo.put( "description", "a big red foo" );
s1.flush();
- Transaction tx1 = SimpleJtaTransactionManagerImpl.getInstance().suspend();
+ Transaction tx1 = sfi().getServiceRegistry().getService( JtaPlatform.class ).retrieveTransactionManager().suspend();
- SimpleJtaTransactionManagerImpl.getInstance().begin();
+ sfi().getServiceRegistry().getService( JtaPlatform.class ).retrieveTransactionManager().begin();
Session s2 = openSession();
List r2 = s2.createCriteria( "Item" ).addOrder( Order.asc( "description" ) )
.setCacheable( true ).list();
assertEquals( r2.size(), 2 );
- SimpleJtaTransactionManagerImpl.getInstance().commit();
+ sfi().getServiceRegistry().getService( JtaPlatform.class ).retrieveTransactionManager().commit();
assertEquals( getSessions().getStatistics().getSecondLevelCacheHitCount(), 0 );
assertEquals( getSessions().getStatistics().getSecondLevelCacheMissCount(), 0 );
@@ -269,14 +270,14 @@ public class CMTTest extends FunctionalTestCase {
assertEquals( getSessions().getStatistics().getQueryCacheHitCount(), 0 );
assertEquals( getSessions().getStatistics().getQueryCacheMissCount(), 2 );
- SimpleJtaTransactionManagerImpl.getInstance().resume( tx1 );
+ sfi().getServiceRegistry().getService( JtaPlatform.class ).retrieveTransactionManager().resume( tx1 );
tx1.commit();
- SimpleJtaTransactionManagerImpl.getInstance().begin();
+ sfi().getServiceRegistry().getService( JtaPlatform.class ).retrieveTransactionManager().begin();
Session s3 = openSession();
s3.createCriteria( "Item" ).addOrder( Order.asc( "description" ) )
.setCacheable( true ).list();
- SimpleJtaTransactionManagerImpl.getInstance().commit();
+ sfi().getServiceRegistry().getService( JtaPlatform.class ).retrieveTransactionManager().commit();
assertEquals( getSessions().getStatistics().getSecondLevelCacheHitCount(), 0 );
assertEquals( getSessions().getStatistics().getSecondLevelCacheMissCount(), 0 );
@@ -287,7 +288,7 @@ public class CMTTest extends FunctionalTestCase {
assertEquals( getSessions().getStatistics().getQueryCacheHitCount(), 0 );
assertEquals( getSessions().getStatistics().getQueryCacheMissCount(), 3 );
- SimpleJtaTransactionManagerImpl.getInstance().resume( tx4 );
+ sfi().getServiceRegistry().getService( JtaPlatform.class ).retrieveTransactionManager().resume( tx4 );
List r4 = s4.createCriteria( "Item" ).addOrder( Order.asc( "description" ) )
.setCacheable( true ).list();
assertEquals( r4.size(), 2 );
@@ -302,42 +303,42 @@ public class CMTTest extends FunctionalTestCase {
assertEquals( getSessions().getStatistics().getQueryCacheHitCount(), 1 );
assertEquals( getSessions().getStatistics().getQueryCacheMissCount(), 3 );
- SimpleJtaTransactionManagerImpl.getInstance().begin();
+ sfi().getServiceRegistry().getService( JtaPlatform.class ).retrieveTransactionManager().begin();
s = openSession();
s.createQuery( "delete from Item" ).executeUpdate();
- SimpleJtaTransactionManagerImpl.getInstance().commit();
+ sfi().getServiceRegistry().getService( JtaPlatform.class ).retrieveTransactionManager().commit();
}
public void testCMT() throws Exception {
getSessions().getStatistics().clear();
- SimpleJtaTransactionManagerImpl.getInstance().begin();
+ sfi().getServiceRegistry().getService( JtaPlatform.class ).retrieveTransactionManager().begin();
Session s = openSession();
- SimpleJtaTransactionManagerImpl.getInstance().getTransaction().commit();
+ sfi().getServiceRegistry().getService( JtaPlatform.class ).retrieveTransactionManager().commit();
assertFalse( s.isOpen() );
assertEquals( getSessions().getStatistics().getFlushCount(), 0 );
- SimpleJtaTransactionManagerImpl.getInstance().begin();
+ sfi().getServiceRegistry().getService( JtaPlatform.class ).retrieveTransactionManager().begin();
s = openSession();
- SimpleJtaTransactionManagerImpl.getInstance().getTransaction().rollback();
+ sfi().getServiceRegistry().getService( JtaPlatform.class ).retrieveTransactionManager().rollback();
assertFalse( s.isOpen() );
- SimpleJtaTransactionManagerImpl.getInstance().begin();
+ sfi().getServiceRegistry().getService( JtaPlatform.class ).retrieveTransactionManager().begin();
s = openSession();
Map item = new HashMap();
item.put( "name", "The Item" );
item.put( "description", "The only item we have" );
s.persist( "Item", item );
- SimpleJtaTransactionManagerImpl.getInstance().getTransaction().commit();
+ sfi().getServiceRegistry().getService( JtaPlatform.class ).retrieveTransactionManager().commit();
assertFalse( s.isOpen() );
- SimpleJtaTransactionManagerImpl.getInstance().begin();
+ sfi().getServiceRegistry().getService( JtaPlatform.class ).retrieveTransactionManager().begin();
s = openSession();
item = ( Map ) s.createQuery( "from Item" ).uniqueResult();
assertNotNull( item );
s.delete( item );
- SimpleJtaTransactionManagerImpl.getInstance().getTransaction().commit();
+ sfi().getServiceRegistry().getService( JtaPlatform.class ).retrieveTransactionManager().commit();
assertFalse( s.isOpen() );
assertEquals( getSessions().getStatistics().getTransactionCount(), 4 );
@@ -349,19 +350,19 @@ public class CMTTest extends FunctionalTestCase {
assertEquals( getSessions().getStatistics().getQueryExecutionCount(), 1 );
assertEquals( getSessions().getStatistics().getFlushCount(), 2 );
- SimpleJtaTransactionManagerImpl.getInstance().begin();
+ sfi().getServiceRegistry().getService( JtaPlatform.class ).retrieveTransactionManager().begin();
s = openSession();
s.createQuery( "delete from Item" ).executeUpdate();
- SimpleJtaTransactionManagerImpl.getInstance().commit();
+ sfi().getServiceRegistry().getService( JtaPlatform.class ).retrieveTransactionManager().commit();
}
public void testCurrentSession() throws Exception {
- SimpleJtaTransactionManagerImpl.getInstance().begin();
+ sfi().getServiceRegistry().getService( JtaPlatform.class ).retrieveTransactionManager().begin();
Session s = getSessions().getCurrentSession();
Session s2 = getSessions().getCurrentSession();
assertSame( s, s2 );
- SimpleJtaTransactionManagerImpl.getInstance().getTransaction().commit();
+ sfi().getServiceRegistry().getService( JtaPlatform.class ).retrieveTransactionManager().commit();
assertFalse( s.isOpen() );
// TODO : would be nice to automate-test that the SF internal map actually gets cleaned up
@@ -369,7 +370,7 @@ public class CMTTest extends FunctionalTestCase {
}
public void testCurrentSessionWithIterate() throws Exception {
- SimpleJtaTransactionManagerImpl.getInstance().begin();
+ sfi().getServiceRegistry().getService( JtaPlatform.class ).retrieveTransactionManager().begin();
Session s = openSession();
Map item1 = new HashMap();
item1.put( "name", "Item - 1" );
@@ -380,11 +381,11 @@ public class CMTTest extends FunctionalTestCase {
item2.put( "name", "Item - 2" );
item2.put( "description", "The second item" );
s.persist( "Item", item2 );
- SimpleJtaTransactionManagerImpl.getInstance().getTransaction().commit();
+ sfi().getServiceRegistry().getService( JtaPlatform.class ).retrieveTransactionManager().commit();
// First, test iterating the partial iterator; iterate to past
// the first, but not the second, item
- SimpleJtaTransactionManagerImpl.getInstance().begin();
+ sfi().getServiceRegistry().getService( JtaPlatform.class ).retrieveTransactionManager().begin();
s = getSessions().getCurrentSession();
Iterator itr = s.createQuery( "from Item" ).iterate();
if ( !itr.hasNext() ) {
@@ -394,10 +395,10 @@ public class CMTTest extends FunctionalTestCase {
if ( !itr.hasNext() ) {
fail( "Only one result in iterator" );
}
- SimpleJtaTransactionManagerImpl.getInstance().getTransaction().commit();
+ sfi().getServiceRegistry().getService( JtaPlatform.class ).retrieveTransactionManager().commit();
// Next, iterate the entire result
- SimpleJtaTransactionManagerImpl.getInstance().begin();
+ sfi().getServiceRegistry().getService( JtaPlatform.class ).retrieveTransactionManager().begin();
s = getSessions().getCurrentSession();
itr = s.createQuery( "from Item" ).iterate();
if ( !itr.hasNext() ) {
@@ -406,16 +407,16 @@ public class CMTTest extends FunctionalTestCase {
while ( itr.hasNext() ) {
itr.next();
}
- SimpleJtaTransactionManagerImpl.getInstance().getTransaction().commit();
+ sfi().getServiceRegistry().getService( JtaPlatform.class ).retrieveTransactionManager().commit();
- SimpleJtaTransactionManagerImpl.getInstance().begin();
+ sfi().getServiceRegistry().getService( JtaPlatform.class ).retrieveTransactionManager().begin();
s = openSession();
s.createQuery( "delete from Item" ).executeUpdate();
- SimpleJtaTransactionManagerImpl.getInstance().getTransaction().commit();
+ sfi().getServiceRegistry().getService( JtaPlatform.class ).retrieveTransactionManager().commit();
}
public void testCurrentSessionWithScroll() throws Exception {
- SimpleJtaTransactionManagerImpl.getInstance().begin();
+ sfi().getServiceRegistry().getService( JtaPlatform.class ).retrieveTransactionManager().begin();
Session s = getSessions().getCurrentSession();
Map item1 = new HashMap();
item1.put( "name", "Item - 1" );
@@ -426,50 +427,50 @@ public class CMTTest extends FunctionalTestCase {
item2.put( "name", "Item - 2" );
item2.put( "description", "The second item" );
s.persist( "Item", item2 );
- SimpleJtaTransactionManagerImpl.getInstance().getTransaction().commit();
+ sfi().getServiceRegistry().getService( JtaPlatform.class ).retrieveTransactionManager().commit();
// First, test partially scrolling the result with out closing
- SimpleJtaTransactionManagerImpl.getInstance().begin();
+ sfi().getServiceRegistry().getService( JtaPlatform.class ).retrieveTransactionManager().begin();
s = getSessions().getCurrentSession();
ScrollableResults results = s.createQuery( "from Item" ).scroll();
results.next();
- SimpleJtaTransactionManagerImpl.getInstance().getTransaction().commit();
+ sfi().getServiceRegistry().getService( JtaPlatform.class ).retrieveTransactionManager().commit();
// Next, test partially scrolling the result with closing
- SimpleJtaTransactionManagerImpl.getInstance().begin();
+ sfi().getServiceRegistry().getService( JtaPlatform.class ).retrieveTransactionManager().begin();
s = getSessions().getCurrentSession();
results = s.createQuery( "from Item" ).scroll();
results.next();
results.close();
- SimpleJtaTransactionManagerImpl.getInstance().getTransaction().commit();
+ sfi().getServiceRegistry().getService( JtaPlatform.class ).retrieveTransactionManager().commit();
// Next, scroll the entire result (w/o closing)
- SimpleJtaTransactionManagerImpl.getInstance().begin();
+ sfi().getServiceRegistry().getService( JtaPlatform.class ).retrieveTransactionManager().begin();
s = getSessions().getCurrentSession();
results = s.createQuery( "from Item" ).scroll();
while ( results.next() ) {
// do nothing
}
- SimpleJtaTransactionManagerImpl.getInstance().getTransaction().commit();
+ sfi().getServiceRegistry().getService( JtaPlatform.class ).retrieveTransactionManager().commit();
// Next, scroll the entire result (closing)
- SimpleJtaTransactionManagerImpl.getInstance().begin();
+ sfi().getServiceRegistry().getService( JtaPlatform.class ).retrieveTransactionManager().begin();
s = getSessions().getCurrentSession();
results = s.createQuery( "from Item" ).scroll();
while ( results.next() ) {
// do nothing
}
results.close();
- SimpleJtaTransactionManagerImpl.getInstance().getTransaction().commit();
+ sfi().getServiceRegistry().getService( JtaPlatform.class ).retrieveTransactionManager().commit();
- SimpleJtaTransactionManagerImpl.getInstance().begin();
+ sfi().getServiceRegistry().getService( JtaPlatform.class ).retrieveTransactionManager().begin();
s = getSessions().getCurrentSession();
s.createQuery( "delete from Item" ).executeUpdate();
- SimpleJtaTransactionManagerImpl.getInstance().getTransaction().commit();
+ sfi().getServiceRegistry().getService( JtaPlatform.class ).retrieveTransactionManager().commit();
}
public void testAggressiveReleaseWithExplicitDisconnectReconnect() throws Exception {
- SimpleJtaTransactionManagerImpl.getInstance().begin();
+ sfi().getServiceRegistry().getService( JtaPlatform.class ).retrieveTransactionManager().begin();
Session s = getSessions().getCurrentSession();
s.createQuery( "from Item" ).list();
@@ -481,11 +482,11 @@ public class CMTTest extends FunctionalTestCase {
s.createQuery( "from Item" ).list();
- SimpleJtaTransactionManagerImpl.getInstance().getTransaction().commit();
+ sfi().getServiceRegistry().getService( JtaPlatform.class ).retrieveTransactionManager().commit();
}
public void testAggressiveReleaseWithConnectionRetreival() throws Exception {
- SimpleJtaTransactionManagerImpl.getInstance().begin();
+ sfi().getServiceRegistry().getService( JtaPlatform.class ).retrieveTransactionManager().begin();
Session s = openSession();
Map item1 = new HashMap();
item1.put( "name", "Item - 1" );
@@ -496,20 +497,20 @@ public class CMTTest extends FunctionalTestCase {
item2.put( "name", "Item - 2" );
item2.put( "description", "The second item" );
s.save( "Item", item2 );
- SimpleJtaTransactionManagerImpl.getInstance().getTransaction().commit();
+ sfi().getServiceRegistry().getService( JtaPlatform.class ).retrieveTransactionManager().commit();
try {
- SimpleJtaTransactionManagerImpl.getInstance().begin();
+ sfi().getServiceRegistry().getService( JtaPlatform.class ).retrieveTransactionManager().begin();
s = getSessions().getCurrentSession();
s.createQuery( "from Item" ).scroll().next();
s.connection();
- SimpleJtaTransactionManagerImpl.getInstance().getTransaction().commit();
+ sfi().getServiceRegistry().getService( JtaPlatform.class ).retrieveTransactionManager().commit();
}
finally {
- SimpleJtaTransactionManagerImpl.getInstance().begin();
+ sfi().getServiceRegistry().getService( JtaPlatform.class ).retrieveTransactionManager().begin();
s = openSession();
s.createQuery( "delete from Item" ).executeUpdate();
- SimpleJtaTransactionManagerImpl.getInstance().getTransaction().commit();
+ sfi().getServiceRegistry().getService( JtaPlatform.class ).retrieveTransactionManager().commit();
}
}
diff --git a/hibernate-core/src/test/java/org/hibernate/test/transaction/jdbc/TestExpectedUsage.java b/hibernate-core/src/test/java/org/hibernate/test/transaction/jdbc/TestExpectedUsage.java
new file mode 100644
index 0000000000..871f544f9c
--- /dev/null
+++ b/hibernate-core/src/test/java/org/hibernate/test/transaction/jdbc/TestExpectedUsage.java
@@ -0,0 +1,139 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2011, 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
+ */
+package org.hibernate.test.transaction.jdbc;
+
+import org.hibernate.ConnectionReleaseMode;
+import org.hibernate.engine.jdbc.spi.LogicalConnectionImplementor;
+import org.hibernate.engine.transaction.internal.TransactionCoordinatorImpl;
+import org.hibernate.engine.transaction.spi.TransactionContext;
+import org.hibernate.engine.transaction.spi.TransactionImplementor;
+import org.hibernate.service.internal.ServiceRegistryImpl;
+import org.hibernate.service.spi.ServiceRegistry;
+import org.hibernate.service.spi.StandardServiceInitiators;
+import org.hibernate.test.common.ConnectionProviderBuilder;
+import org.hibernate.test.common.JournalingTransactionObserver;
+import org.hibernate.test.common.TransactionContextImpl;
+import org.hibernate.test.common.TransactionEnvironmentImpl;
+import org.hibernate.testing.junit.UnitTestCase;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.sql.Statement;
+
+/**
+ * TODO : javadoc
+ *
+ * @author Steve Ebersole
+ */
+public class TestExpectedUsage extends UnitTestCase {
+ private ServiceRegistry serviceRegistry;
+
+ public TestExpectedUsage(String string) {
+ super( string );
+ }
+
+ public void setUp() throws Exception {
+ super.setUp();
+ serviceRegistry = new ServiceRegistryImpl(
+ StandardServiceInitiators.LIST,
+ ConnectionProviderBuilder.getConnectionProviderProperties()
+ );
+ }
+
+ public void tearDown() throws Exception {
+ ( (ServiceRegistryImpl) serviceRegistry).destroy();
+ super.tearDown();
+ }
+
+ public void testBasicUsage() {
+ final TransactionContext transactionContext = new TransactionContextImpl( new TransactionEnvironmentImpl( serviceRegistry ) ) {
+ @Override
+ public ConnectionReleaseMode getConnectionReleaseMode() {
+ return ConnectionReleaseMode.AFTER_TRANSACTION;
+ }
+ };
+
+ TransactionCoordinatorImpl transactionCoordinator = new TransactionCoordinatorImpl( null, transactionContext );
+ JournalingTransactionObserver observer = new JournalingTransactionObserver();
+ transactionCoordinator.addObserver( observer );
+
+ LogicalConnectionImplementor logicalConnection = transactionCoordinator.getJdbcCoordinator().getLogicalConnection();
+ Connection connection = logicalConnection.getShareableConnectionProxy();
+
+ // set up some tables to use
+ try {
+ Statement statement = connection.createStatement();
+ statement.execute( "drop table SANDBOX_JDBC_TST if exists" );
+ statement.execute( "create table SANDBOX_JDBC_TST ( ID integer, NAME varchar(100) )" );
+ assertTrue( logicalConnection.getResourceRegistry().hasRegisteredResources() );
+ assertTrue( logicalConnection.isPhysicallyConnected() );
+ statement.close();
+ assertFalse( logicalConnection.getResourceRegistry().hasRegisteredResources() );
+ assertTrue( logicalConnection.isPhysicallyConnected() ); // after_transaction specified
+ }
+ catch ( SQLException sqle ) {
+ fail( "incorrect exception type : SQLException" );
+ }
+
+ // ok, now we can get down to it...
+ TransactionImplementor txn = transactionCoordinator.getTransaction(); // same as Session#getTransaction
+ txn.begin();
+ assertEquals( 1, observer.getBegins() );
+ try {
+ PreparedStatement ps = connection.prepareStatement( "insert into SANDBOX_JDBC_TST( ID, NAME ) values ( ?, ? )" );
+ ps.setLong( 1, 1 );
+ ps.setString( 2, "name" );
+ ps.execute();
+ assertTrue( logicalConnection.getResourceRegistry().hasRegisteredResources() );
+ ps.close();
+ assertFalse( logicalConnection.getResourceRegistry().hasRegisteredResources() );
+
+ ps = connection.prepareStatement( "select * from SANDBOX_JDBC_TST" );
+ ps.executeQuery();
+ connection.prepareStatement( "delete from SANDBOX_JDBC_TST" ).execute();
+ // lets forget to close these...
+ assertTrue( logicalConnection.getResourceRegistry().hasRegisteredResources() );
+
+ // and commit the transaction...
+ txn.commit();
+
+ // we should now have:
+ // 1) no resources because of after_transaction release mode
+ assertFalse( logicalConnection.getResourceRegistry().hasRegisteredResources() );
+ // 2) non-physically connected logical connection, again because of after_transaction release mode
+ assertFalse( logicalConnection.isPhysicallyConnected() );
+ // 3) transaction observer callbacks
+ assertEquals( 1, observer.getBeforeCompletions() );
+ assertEquals( 1, observer.getAfterCompletions() );
+ }
+ catch ( SQLException sqle ) {
+ fail( "incorrect exception type : SQLException" );
+ }
+ finally {
+ logicalConnection.close();
+ }
+ }
+
+}
diff --git a/hibernate-core/src/test/java/org/hibernate/test/transaction/jta/BasicDrivingTest.java b/hibernate-core/src/test/java/org/hibernate/test/transaction/jta/BasicDrivingTest.java
new file mode 100644
index 0000000000..d38a056c02
--- /dev/null
+++ b/hibernate-core/src/test/java/org/hibernate/test/transaction/jta/BasicDrivingTest.java
@@ -0,0 +1,162 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2011, 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
+ */
+package org.hibernate.test.transaction.jta;
+
+import org.hibernate.cfg.Environment;
+import org.hibernate.engine.jdbc.spi.LogicalConnectionImplementor;
+import org.hibernate.engine.transaction.internal.TransactionCoordinatorImpl;
+import org.hibernate.engine.transaction.internal.jta.JtaTransactionFactory;
+import org.hibernate.engine.transaction.spi.TransactionContext;
+import org.hibernate.engine.transaction.spi.TransactionImplementor;
+import org.hibernate.service.internal.ServiceProxy;
+import org.hibernate.service.internal.ServiceRegistryImpl;
+import org.hibernate.service.jta.platform.internal.JtaPlatformInitiator;
+import org.hibernate.service.jta.platform.spi.JtaPlatform;
+import org.hibernate.service.spi.ServiceRegistry;
+import org.hibernate.service.spi.StandardServiceInitiators;
+import org.hibernate.test.common.ConnectionProviderBuilder;
+import org.hibernate.test.common.JournalingTransactionObserver;
+import org.hibernate.test.common.TransactionContextImpl;
+import org.hibernate.test.common.TransactionEnvironmentImpl;
+import org.hibernate.test.common.jta.AtomikosDataSourceConnectionProvider;
+import org.hibernate.test.common.jta.AtomikosJtaPlatform;
+import org.hibernate.testing.junit.UnitTestCase;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Testing transaction handling when the JTA transaction facade is the driver.
+ *
+ * @author Steve Ebersole
+ */
+public class BasicDrivingTest extends UnitTestCase {
+ private ServiceRegistry serviceRegistry;
+
+ public BasicDrivingTest(String string) {
+ super( string );
+ }
+
+ public void setUp() throws Exception {
+ super.setUp();
+
+ Map configValues = new HashMap();
+ configValues.putAll( ConnectionProviderBuilder.getConnectionProviderProperties() );
+ configValues.put( Environment.TRANSACTION_STRATEGY, JtaTransactionFactory.class.getName() );
+ configValues.put( JtaPlatformInitiator.JTA_PLATFORM, AtomikosJtaPlatform.class.getName() );
+ configValues.put( Environment.CONNECTION_PROVIDER, AtomikosDataSourceConnectionProvider.class.getName() );
+ serviceRegistry = new ServiceRegistryImpl( StandardServiceInitiators.LIST, configValues );
+ }
+
+ public void tearDown() throws Exception {
+ ( (ServiceRegistryImpl) serviceRegistry).destroy();
+ super.tearDown();
+ }
+
+ public void testBasicUsage() throws Throwable {
+ final TransactionContext transactionContext = new TransactionContextImpl( new TransactionEnvironmentImpl( serviceRegistry ) );
+
+ TransactionCoordinatorImpl transactionCoordinator = new TransactionCoordinatorImpl( null, transactionContext );
+ JournalingTransactionObserver observer = new JournalingTransactionObserver();
+ transactionCoordinator.addObserver( observer );
+
+ LogicalConnectionImplementor logicalConnection = transactionCoordinator.getJdbcCoordinator().getLogicalConnection();
+ Connection connection = logicalConnection.getShareableConnectionProxy();
+
+ // set up some tables to use
+ try {
+ Statement statement = connection.createStatement();
+ statement.execute( "drop table SANDBOX_JDBC_TST if exists" );
+ statement.execute( "create table SANDBOX_JDBC_TST ( ID integer, NAME varchar(100) )" );
+ assertTrue( logicalConnection.getResourceRegistry().hasRegisteredResources() );
+ assertTrue( logicalConnection.isPhysicallyConnected() );
+ statement.close();
+ assertFalse( logicalConnection.getResourceRegistry().hasRegisteredResources() );
+ assertFalse( logicalConnection.isPhysicallyConnected() ); // after_statement specified
+ }
+ catch ( SQLException sqle ) {
+ fail( "incorrect exception type : SQLException" );
+ }
+
+ // ok, now we can get down to it...
+ TransactionImplementor txn = transactionCoordinator.getTransaction(); // same as Session#getTransaction
+ txn.begin();
+ assertEquals( 1, observer.getBegins() );
+ assertTrue( txn.isInitiator() );
+ try {
+ PreparedStatement ps = connection.prepareStatement( "insert into SANDBOX_JDBC_TST( ID, NAME ) values ( ?, ? )" );
+ ps.setLong( 1, 1 );
+ ps.setString( 2, "name" );
+ ps.execute();
+ assertTrue( logicalConnection.getResourceRegistry().hasRegisteredResources() );
+ ps.close();
+ assertFalse( logicalConnection.getResourceRegistry().hasRegisteredResources() );
+
+ ps = connection.prepareStatement( "select * from SANDBOX_JDBC_TST" );
+ ps.executeQuery();
+ connection.prepareStatement( "delete from SANDBOX_JDBC_TST" ).execute();
+ // lets forget to close these...
+ assertTrue( logicalConnection.getResourceRegistry().hasRegisteredResources() );
+ assertTrue( logicalConnection.isPhysicallyConnected() );
+
+ // and commit the transaction...
+ txn.commit();
+
+ // we should now have:
+ // 1) no resources because of after_transaction release mode
+ assertFalse( logicalConnection.getResourceRegistry().hasRegisteredResources() );
+ // 2) non-physically connected logical connection, again because of after_transaction release mode
+ assertFalse( logicalConnection.isPhysicallyConnected() );
+ // 3) transaction observer callbacks
+ assertEquals( 1, observer.getBeforeCompletions() );
+ assertEquals( 1, observer.getAfterCompletions() );
+ }
+ catch ( SQLException sqle ) {
+ try {
+ JtaPlatform instance = ( (ServiceProxy) serviceRegistry.getService( JtaPlatform.class ) ).getTargetInstance();
+ instance.retrieveTransactionManager().rollback();
+ }
+ catch (Exception ignore) {
+ }
+ fail( "incorrect exception type : SQLException" );
+ }
+ catch (Throwable reThrowable) {
+ try {
+ JtaPlatform instance = ( (ServiceProxy) serviceRegistry.getService( JtaPlatform.class ) ).getTargetInstance();
+ instance.retrieveTransactionManager().rollback();
+ }
+ catch (Exception ignore) {
+ }
+ throw reThrowable;
+ }
+ finally {
+ logicalConnection.close();
+ }
+ }
+
+}
diff --git a/hibernate-core/src/test/java/org/hibernate/test/transaction/jta/ManagedDrivingTest.java b/hibernate-core/src/test/java/org/hibernate/test/transaction/jta/ManagedDrivingTest.java
new file mode 100644
index 0000000000..746497f89a
--- /dev/null
+++ b/hibernate-core/src/test/java/org/hibernate/test/transaction/jta/ManagedDrivingTest.java
@@ -0,0 +1,178 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2011, 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
+ */
+package org.hibernate.test.transaction.jta;
+
+import org.hibernate.ConnectionReleaseMode;
+import org.hibernate.cfg.Environment;
+import org.hibernate.engine.jdbc.spi.LogicalConnectionImplementor;
+import org.hibernate.engine.transaction.internal.TransactionCoordinatorImpl;
+import org.hibernate.engine.transaction.internal.jta.CMTTransactionFactory;
+import org.hibernate.engine.transaction.spi.TransactionContext;
+import org.hibernate.engine.transaction.spi.TransactionImplementor;
+import org.hibernate.service.internal.ServiceProxy;
+import org.hibernate.service.internal.ServiceRegistryImpl;
+import org.hibernate.service.jta.platform.internal.JtaPlatformInitiator;
+import org.hibernate.service.jta.platform.spi.JtaPlatform;
+import org.hibernate.service.spi.ServiceRegistry;
+import org.hibernate.service.spi.StandardServiceInitiators;
+import org.hibernate.test.common.ConnectionProviderBuilder;
+import org.hibernate.test.common.JournalingTransactionObserver;
+import org.hibernate.test.common.TransactionContextImpl;
+import org.hibernate.test.common.TransactionEnvironmentImpl;
+import org.hibernate.test.common.jta.AtomikosDataSourceConnectionProvider;
+import org.hibernate.test.common.jta.AtomikosJtaPlatform;
+import org.hibernate.testing.junit.UnitTestCase;
+
+import javax.transaction.TransactionManager;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Testing transaction facacde handling when the transaction is being driven by somethign other than the facade.
+ *
+ * @author Steve Ebersole
+ */
+public class ManagedDrivingTest extends UnitTestCase {
+ private ServiceRegistry serviceRegistry;
+
+ public ManagedDrivingTest(String string) {
+ super( string );
+ }
+
+ public void setUp() throws Exception {
+ super.setUp();
+
+ Map configValues = new HashMap();
+ configValues.putAll( ConnectionProviderBuilder.getConnectionProviderProperties() );
+ configValues.put( Environment.TRANSACTION_STRATEGY, CMTTransactionFactory.class.getName() );
+ configValues.put( JtaPlatformInitiator.JTA_PLATFORM, AtomikosJtaPlatform.class.getName() );
+ configValues.put( Environment.CONNECTION_PROVIDER, AtomikosDataSourceConnectionProvider.class.getName() );
+
+ serviceRegistry = new ServiceRegistryImpl( StandardServiceInitiators.LIST, configValues );
+ }
+
+
+ public void tearDown() throws Exception {
+ ( (ServiceRegistryImpl) serviceRegistry).destroy();
+ super.tearDown();
+ }
+
+ public void testBasicUsage() throws Throwable {
+ final TransactionContext transactionContext = new TransactionContextImpl( new TransactionEnvironmentImpl( serviceRegistry ) ) {
+ @Override
+ public ConnectionReleaseMode getConnectionReleaseMode() {
+ return ConnectionReleaseMode.AFTER_STATEMENT;
+ }
+ };
+
+ final TransactionCoordinatorImpl transactionCoordinator = new TransactionCoordinatorImpl( null, transactionContext );
+ final JournalingTransactionObserver transactionObserver = new JournalingTransactionObserver();
+ transactionCoordinator.addObserver( transactionObserver );
+
+ final LogicalConnectionImplementor logicalConnection = transactionCoordinator.getJdbcCoordinator().getLogicalConnection();
+ Connection connection = logicalConnection.getShareableConnectionProxy();
+
+ // set up some tables to use
+ try {
+ Statement statement = connection.createStatement();
+ statement.execute( "drop table SANDBOX_JDBC_TST if exists" );
+ statement.execute( "create table SANDBOX_JDBC_TST ( ID integer, NAME varchar(100) )" );
+ assertTrue( logicalConnection.getResourceRegistry().hasRegisteredResources() );
+ assertTrue( logicalConnection.isPhysicallyConnected() );
+ statement.close();
+ assertFalse( logicalConnection.getResourceRegistry().hasRegisteredResources() );
+ assertFalse( logicalConnection.isPhysicallyConnected() ); // after_statement specified
+ }
+ catch ( SQLException sqle ) {
+ fail( "incorrect exception type : SQLException" );
+ }
+
+ JtaPlatform instance = ( (ServiceProxy) serviceRegistry.getService( JtaPlatform.class ) ).getTargetInstance();
+ TransactionManager transactionManager = instance.retrieveTransactionManager();
+
+ // start the cmt
+ transactionManager.begin();
+
+ // ok, now we can get down to it...
+ TransactionImplementor txn = transactionCoordinator.getTransaction(); // same as Session#getTransaction
+ txn.begin();
+ assertEquals( 1, transactionObserver.getBegins() );
+ assertFalse( txn.isInitiator() );
+ connection = logicalConnection.getShareableConnectionProxy();
+ try {
+ PreparedStatement ps = connection.prepareStatement( "insert into SANDBOX_JDBC_TST( ID, NAME ) values ( ?, ? )" );
+ ps.setLong( 1, 1 );
+ ps.setString( 2, "name" );
+ ps.execute();
+ assertTrue( logicalConnection.getResourceRegistry().hasRegisteredResources() );
+ ps.close();
+ assertFalse( logicalConnection.getResourceRegistry().hasRegisteredResources() );
+
+ ps = connection.prepareStatement( "select * from SANDBOX_JDBC_TST" );
+ ps.executeQuery();
+ connection.prepareStatement( "delete from SANDBOX_JDBC_TST" ).execute();
+ // lets forget to close these...
+ assertTrue( logicalConnection.getResourceRegistry().hasRegisteredResources() );
+ assertTrue( logicalConnection.isPhysicallyConnected() );
+
+ // and commit the transaction...
+ txn.commit();
+
+ // since txn is not a driver, nothing should have changed...
+ assertTrue( logicalConnection.getResourceRegistry().hasRegisteredResources() );
+ assertTrue( logicalConnection.isPhysicallyConnected() );
+ assertEquals( 0, transactionObserver.getBeforeCompletions() );
+ assertEquals( 0, transactionObserver.getAfterCompletions() );
+
+ transactionManager.commit();
+ assertFalse( logicalConnection.getResourceRegistry().hasRegisteredResources() );
+ assertFalse( logicalConnection.isPhysicallyConnected() );
+ assertEquals( 1, transactionObserver.getBeforeCompletions() );
+ assertEquals( 1, transactionObserver.getAfterCompletions() );
+ }
+ catch ( SQLException sqle ) {
+ try {
+ transactionManager.rollback();
+ }
+ catch (Exception ignore) {
+ }
+ fail( "incorrect exception type : SQLException" );
+ }
+ catch (Throwable reThrowable) {
+ try {
+ transactionManager.rollback();
+ }
+ catch (Exception ignore) {
+ }
+ throw reThrowable;
+ }
+ finally {
+ logicalConnection.close();
+ }
+ }
+}
diff --git a/hibernate-core/src/test/java/org/hibernate/testing/cache/BaseCacheProviderTestCase.java b/hibernate-core/src/test/java/org/hibernate/testing/cache/BaseCacheProviderTestCase.java
index 8b5dbff242..58f8f0b5e4 100644
--- a/hibernate-core/src/test/java/org/hibernate/testing/cache/BaseCacheProviderTestCase.java
+++ b/hibernate-core/src/test/java/org/hibernate/testing/cache/BaseCacheProviderTestCase.java
@@ -30,12 +30,12 @@ import org.hibernate.Transaction;
import org.hibernate.cache.ReadWriteCache;
import org.hibernate.cfg.Configuration;
import org.hibernate.cfg.Environment;
+import org.hibernate.engine.transaction.internal.jdbc.JdbcTransactionFactory;
import org.hibernate.testing.junit.functional.FunctionalTestCase;
import org.hibernate.stat.SecondLevelCacheStatistics;
import org.hibernate.stat.Statistics;
import org.hibernate.testing.tm.ConnectionProviderImpl;
import org.hibernate.testing.tm.TransactionManagerLookupImpl;
-import org.hibernate.transaction.JDBCTransactionFactory;
/**
* Common requirement testing for each {@link org.hibernate.cache.CacheProvider} impl.
@@ -78,7 +78,7 @@ public abstract class BaseCacheProviderTestCase extends FunctionalTestCase {
cfg.setProperty( Environment.TRANSACTION_MANAGER_STRATEGY, TransactionManagerLookupImpl.class.getName() );
}
else {
- cfg.setProperty( Environment.TRANSACTION_STRATEGY, JDBCTransactionFactory.class.getName() );
+ cfg.setProperty( Environment.TRANSACTION_STRATEGY, JdbcTransactionFactory.class.getName() );
}
}
diff --git a/hibernate-core/src/test/resources/log4j.properties b/hibernate-core/src/test/resources/log4j.properties
index cd9c5224cf..c13e5d4f48 100644
--- a/hibernate-core/src/test/resources/log4j.properties
+++ b/hibernate-core/src/test/resources/log4j.properties
@@ -17,3 +17,4 @@ log4j.logger.org.hibernate.hql.ast.SqlGenerator=trace
log4j.logger.org.hibernate.hql.ast.AST=trace
log4j.logger.org.hibernate.type.descriptor.sql.BasicBinder=trace
log4j.logger.org.hibernate.type.BasicTypeRegistry=trace
+
From b4a440e8d365c8cbc2bbce77cd9f89e009d761c4 Mon Sep 17 00:00:00 2001
From: Steve Ebersole
Date: Wed, 2 Mar 2011 16:46:08 -0600
Subject: [PATCH 04/19] HHH-5949 - Migrate, complete and integrate
TransactionFactory as a service
---
.../ejb/AbstractEntityManagerImpl.java | 307 +++++++++---------
.../org/hibernate/ejb/Ejb3Configuration.java | 4 +-
.../transaction/JoinableCMTTransaction.java | 83 ++---
.../JoinableCMTTransactionFactory.java | 56 ++--
.../AbstractDelegateSessionImplementor.java | 19 +-
.../tm/HibernateTransactionManagerLookup.java | 36 +-
...bstractEntityCollectionRegionTestCase.java | 8 +-
.../AbstractGeneralDataRegionTestCase.java | 8 +-
...ollectionRegionAccessStrategyTestCase.java | 7 +-
.../TransactionalExtraAPITestCase.java | 14 +-
...actEntityRegionAccessStrategyTestCase.java | 10 +-
.../entity/TransactionalExtraAPITestCase.java | 20 +-
.../BasicJdbcTransactionalTestCase.java | 6 +-
.../functional/SingleNodeTestCase.java | 6 +-
.../bulk/BulkOperationsTestCase.java | 4 +-
.../functional/cluster/DualNodeTestCase.java | 3 +-
.../query/QueryRegionImplTestCase.java | 4 +-
.../TimestampsRegionImplTestCase.java | 4 +-
.../tm/JBossStandaloneJtaExampleTest.java | 2 +-
.../cache/infinispan/util/CacheTestUtil.java | 19 +-
20 files changed, 279 insertions(+), 341 deletions(-)
diff --git a/hibernate-entitymanager/src/main/java/org/hibernate/ejb/AbstractEntityManagerImpl.java b/hibernate-entitymanager/src/main/java/org/hibernate/ejb/AbstractEntityManagerImpl.java
index aca398a737..ed1c48cc97 100755
--- a/hibernate-entitymanager/src/main/java/org/hibernate/ejb/AbstractEntityManagerImpl.java
+++ b/hibernate-entitymanager/src/main/java/org/hibernate/ejb/AbstractEntityManagerImpl.java
@@ -1,4 +1,3 @@
-// $Id$
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
@@ -24,15 +23,51 @@
*/
package org.hibernate.ejb;
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
+import org.hibernate.AssertionFailure;
+import org.hibernate.CacheMode;
+import org.hibernate.FlushMode;
+import org.hibernate.HibernateException;
+import org.hibernate.LockMode;
+import org.hibernate.LockOptions;
+import org.hibernate.MappingException;
+import org.hibernate.ObjectDeletedException;
+import org.hibernate.ObjectNotFoundException;
+import org.hibernate.QueryException;
+import org.hibernate.SQLQuery;
+import org.hibernate.Session;
+import org.hibernate.StaleObjectStateException;
+import org.hibernate.StaleStateException;
+import org.hibernate.TransientObjectException;
+import org.hibernate.TypeMismatchException;
+import org.hibernate.UnresolvableObjectException;
+import org.hibernate.cfg.Environment;
+import org.hibernate.ejb.criteria.CriteriaQueryCompiler;
+import org.hibernate.ejb.criteria.ValueHandlerFactory;
+import org.hibernate.ejb.criteria.expression.CompoundSelectionImpl;
+import org.hibernate.ejb.util.CacheModeHelper;
+import org.hibernate.ejb.util.ConfigurationHelper;
+import org.hibernate.ejb.util.LockModeTypeHelper;
+import org.hibernate.engine.NamedSQLQueryDefinition;
+import org.hibernate.engine.ResultSetMappingDefinition;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.engine.query.sql.NativeSQLQueryReturn;
+import org.hibernate.engine.query.sql.NativeSQLQueryRootReturn;
+import org.hibernate.engine.transaction.internal.jta.JtaStatusHelper;
+import org.hibernate.engine.transaction.spi.JoinStatus;
+import org.hibernate.engine.transaction.spi.TransactionCoordinator;
+import org.hibernate.engine.transaction.spi.TransactionImplementor;
+import org.hibernate.engine.transaction.synchronization.spi.AfterCompletionAction;
+import org.hibernate.engine.transaction.synchronization.spi.ExceptionMapper;
+import org.hibernate.engine.transaction.synchronization.spi.ManagedFlushChecker;
+import org.hibernate.engine.transaction.synchronization.spi.SynchronizationCallbackCoordinator;
+import org.hibernate.proxy.HibernateProxy;
+import org.hibernate.service.jta.platform.spi.JtaPlatform;
+import org.hibernate.transform.BasicTransformerAdapter;
+import org.hibernate.util.ReflectHelper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
import javax.persistence.CacheRetrieveMode;
import javax.persistence.CacheStoreMode;
import javax.persistence.EntityManager;
@@ -59,55 +94,17 @@ import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Selection;
import javax.persistence.metamodel.Metamodel;
import javax.persistence.spi.PersistenceUnitTransactionType;
-import javax.transaction.Status;
-import javax.transaction.Synchronization;
import javax.transaction.SystemException;
import javax.transaction.TransactionManager;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.hibernate.AssertionFailure;
-import org.hibernate.CacheMode;
-import org.hibernate.FlushMode;
-import org.hibernate.HibernateException;
-import org.hibernate.LockMode;
-import org.hibernate.LockOptions;
-import org.hibernate.MappingException;
-import org.hibernate.ObjectDeletedException;
-import org.hibernate.ObjectNotFoundException;
-import org.hibernate.QueryException;
-import org.hibernate.SQLQuery;
-import org.hibernate.Session;
-import org.hibernate.StaleObjectStateException;
-import org.hibernate.StaleStateException;
-import org.hibernate.Transaction;
-import org.hibernate.TransientObjectException;
-import org.hibernate.TypeMismatchException;
-import org.hibernate.UnresolvableObjectException;
-import org.hibernate.cfg.Environment;
-import org.hibernate.ejb.criteria.CriteriaQueryCompiler;
-import org.hibernate.ejb.criteria.ValueHandlerFactory;
-import org.hibernate.ejb.criteria.expression.CompoundSelectionImpl;
-import org.hibernate.ejb.transaction.JoinableCMTTransaction;
-import org.hibernate.ejb.util.CacheModeHelper;
-import org.hibernate.ejb.util.ConfigurationHelper;
-import org.hibernate.ejb.util.LockModeTypeHelper;
-import org.hibernate.engine.NamedSQLQueryDefinition;
-import org.hibernate.engine.ResultSetMappingDefinition;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.engine.query.sql.NativeSQLQueryReturn;
-import org.hibernate.engine.query.sql.NativeSQLQueryRootReturn;
-import org.hibernate.proxy.HibernateProxy;
-import org.hibernate.transaction.TransactionFactory;
-import org.hibernate.transaction.synchronization.AfterCompletionAction;
-import org.hibernate.transaction.synchronization.BeforeCompletionManagedFlushChecker;
-import org.hibernate.transaction.synchronization.CallbackCoordinator;
-import org.hibernate.transaction.synchronization.ExceptionMapper;
-import org.hibernate.transform.BasicTransformerAdapter;
-import org.hibernate.util.JTAHelper;
-import org.hibernate.util.ReflectHelper;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
/**
* @author Gavin King
@@ -944,6 +941,10 @@ public abstract class AbstractEntityManagerImpl implements HibernateEntityManage
return ( ( SessionImplementor ) getRawSession() ).isTransactionInProgress();
}
+ private SessionFactoryImplementor sfi() {
+ return ( SessionFactoryImplementor ) getRawSession().getSessionFactory();
+ }
+
protected void markAsRollback() {
log.debug( "mark transaction for rollback" );
if ( tx.isActive() ) {
@@ -952,8 +953,7 @@ public abstract class AbstractEntityManagerImpl implements HibernateEntityManage
else {
//no explicit use of the tx. boundaries methods
if ( PersistenceUnitTransactionType.JTA == transactionType ) {
- TransactionManager transactionManager =
- ( ( SessionFactoryImplementor ) getRawSession().getSessionFactory() ).getTransactionManager();
+ TransactionManager transactionManager = sfi().getServiceRegistry().getService( JtaPlatform.class ).retrieveTransactionManager();
if ( transactionManager == null ) {
throw new PersistenceException(
"Using a JTA persistence context wo setting hibernate.transaction.manager_lookup_class"
@@ -987,105 +987,52 @@ public abstract class AbstractEntityManagerImpl implements HibernateEntityManage
}
private void joinTransaction(boolean ignoreNotJoining) {
- //set the joined status
- getSession().isOpen(); //for sync
- if ( transactionType == PersistenceUnitTransactionType.JTA ) {
- try {
- log.debug( "Looking for a JTA transaction to join" );
- final Session session = getSession();
- final Transaction transaction = session.getTransaction();
- if ( transaction != null && transaction instanceof JoinableCMTTransaction ) {
- //can't handle it if not a joinnable transaction
- final JoinableCMTTransaction joinableCMTTransaction = ( JoinableCMTTransaction ) transaction;
-
- if ( joinableCMTTransaction.getStatus() == JoinableCMTTransaction.JoinStatus.JOINED ) {
- log.debug( "Transaction already joined" );
- return; //no-op
- }
- joinableCMTTransaction.markForJoined();
- session.isOpen(); //register to the Tx
- if ( joinableCMTTransaction.getStatus() == JoinableCMTTransaction.JoinStatus.NOT_JOINED ) {
- if ( ignoreNotJoining ) {
- log.debug( "No JTA transaction found" );
- return;
- }
- else {
- throw new TransactionRequiredException(
- "No active JTA transaction on joinTransaction call"
- );
- }
- }
- else if ( joinableCMTTransaction.getStatus() == JoinableCMTTransaction.JoinStatus.MARKED_FOR_JOINED ) {
- throw new AssertionFailure( "Transaction MARKED_FOR_JOINED after isOpen() call" );
- }
- //flush before completion and
- //register clear on rollback
- log.trace( "Adding flush() and close() synchronization" );
- CallbackCoordinator callbackCoordinator = ( (SessionImplementor ) getSession() ).getJDBCContext().getJtaSynchronizationCallbackCoordinator();
- if ( callbackCoordinator == null ) {
- throw new AssertionFailure( "Expecting CallbackCoordinator to be non-null" );
- }
- callbackCoordinator.setBeforeCompletionManagedFlushChecker(
- new BeforeCompletionManagedFlushChecker() {
- public boolean shouldDoManagedFlush(TransactionFactory.Context ctx, javax.transaction.Transaction jtaTransaction)
- throws SystemException {
- if ( transaction == null ) {
- log.warn( "Transaction not available on beforeCompletion: assuming valid" );
- }
- return !ctx.isFlushModeNever()
- && ( jtaTransaction == null || !JTAHelper.isRollback( jtaTransaction.getStatus() ) );
- }
- }
- );
- callbackCoordinator.setAfterCompletionAction(
- new AfterCompletionAction() {
- public void doAction(TransactionFactory.Context ctx, int status) {
- try {
- if ( !ctx.isClosed() ) {
- if ( Status.STATUS_ROLLEDBACK == status
- && transactionType == PersistenceUnitTransactionType.JTA ) {
- session.clear();
- }
- JoinableCMTTransaction joinable = ( JoinableCMTTransaction ) session.getTransaction();
- joinable.resetStatus();
- }
- }
- catch ( HibernateException e ) {
- throw convert( e );
- }
- }
- }
- );
- callbackCoordinator.setExceptionMapper(
- new ExceptionMapper() {
- public RuntimeException mapStatusCheckFailure(String message, SystemException systemException) {
- throw new PersistenceException( message, systemException );
- }
-
- public RuntimeException mapManagedFlushFailure(String message, RuntimeException failure) {
- if ( HibernateException.class.isInstance( failure ) ) {
- throw convert( failure );
- }
- if ( PersistenceException.class.isInstance( failure ) ) {
- throw failure;
- }
- throw new PersistenceException( message, failure );
- }
- }
- );
- }
- else {
- log.warn( "Cannot join transaction: do not override {}", Environment.TRANSACTION_STRATEGY );
- }
- }
- catch ( HibernateException he ) {
- throw convert( he );
- }
- }
- else {
+ if ( transactionType != PersistenceUnitTransactionType.JTA ) {
if ( !ignoreNotJoining ) {
log.warn( "Calling joinTransaction() on a non JTA EntityManager" );
}
+ return;
+ }
+
+ final SessionImplementor session = (SessionImplementor) getSession();
+ session.getTransactionCoordinator().pulse();
+
+ log.debug( "Looking for a JTA transaction to join" );
+ if ( ! session.getTransactionCoordinator().isTransactionJoinable() ) {
+ log.warn( "Cannot join transaction: do not override {}", Environment.TRANSACTION_STRATEGY );
+ }
+
+ try {
+ final TransactionImplementor transaction = session.getTransactionCoordinator().getTransaction();
+
+ if ( transaction.getJoinStatus() == JoinStatus.JOINED ) {
+ log.debug( "Transaction already joined" );
+ return; // noop
+ }
+
+ // join the transaction and then recheck the status
+ transaction.join();
+ if ( transaction.getJoinStatus() == JoinStatus.NOT_JOINED ) {
+ if ( ignoreNotJoining ) {
+ log.debug( "No JTA transaction found" );
+ return;
+ }
+ else {
+ throw new TransactionRequiredException( "No active JTA transaction on joinTransaction call" );
+ }
+ }
+ else if ( transaction.getJoinStatus() == JoinStatus.MARKED_FOR_JOINED ) {
+ throw new AssertionFailure( "Transaction MARKED_FOR_JOINED after isOpen() call" );
+ }
+
+ // register behavior changes
+ SynchronizationCallbackCoordinator callbackCoordinator = session.getTransactionCoordinator().getSynchronizationCallbackCoordinator();
+ callbackCoordinator.setManagedFlushChecker( new ManagedFlushCheckerImpl() );
+ callbackCoordinator.setExceptionMapper( new CallbackExceptionMapperImpl() );
+ callbackCoordinator.setAfterCompletionAction( new AfterCompletionActionImpl( session, transactionType ) );
+ }
+ catch ( HibernateException he ) {
+ throw convert( he );
}
}
@@ -1278,4 +1225,54 @@ public abstract class AbstractEntityManagerImpl implements HibernateEntityManage
}
return pe;
}
+
+ private static class AfterCompletionActionImpl implements AfterCompletionAction {
+ private final SessionImplementor session;
+ private final PersistenceUnitTransactionType transactionType;
+
+ private AfterCompletionActionImpl(SessionImplementor session, PersistenceUnitTransactionType transactionType) {
+ this.session = session;
+ this.transactionType = transactionType;
+ }
+
+ @Override
+ public void doAction(TransactionCoordinator transactionCoordinator, int status) {
+ if ( session.isClosed() ) {
+ log.trace( "Session was closed; nothing to do" );
+ return;
+ }
+
+ final boolean successful = JtaStatusHelper.isCommitted( status );
+ if ( !successful && transactionType == PersistenceUnitTransactionType.JTA ) {
+ ( (Session) session ).clear();
+ }
+ session.getTransactionCoordinator().resetJoinStatus();
+ }
+ }
+
+ private static class ManagedFlushCheckerImpl implements ManagedFlushChecker {
+ @Override
+ public boolean shouldDoManagedFlush(TransactionCoordinator coordinator, int jtaStatus) {
+ return ! coordinator.getTransactionContext().isFlushModeNever() &&
+ ! JtaStatusHelper.isRollback( jtaStatus );
+ }
+ }
+
+ private class CallbackExceptionMapperImpl implements ExceptionMapper {
+ @Override
+ public RuntimeException mapStatusCheckFailure(String message, SystemException systemException) {
+ throw new PersistenceException( message, systemException );
+ }
+
+ @Override
+ public RuntimeException mapManagedFlushFailure(String message, RuntimeException failure) {
+ if ( HibernateException.class.isInstance( failure ) ) {
+ throw convert( failure );
+ }
+ if ( PersistenceException.class.isInstance( failure ) ) {
+ throw failure;
+ }
+ throw new PersistenceException( message, failure );
+ }
+ }
}
diff --git a/hibernate-entitymanager/src/main/java/org/hibernate/ejb/Ejb3Configuration.java b/hibernate-entitymanager/src/main/java/org/hibernate/ejb/Ejb3Configuration.java
index c61d3a2a0a..07eaa01b90 100644
--- a/hibernate-entitymanager/src/main/java/org/hibernate/ejb/Ejb3Configuration.java
+++ b/hibernate-entitymanager/src/main/java/org/hibernate/ejb/Ejb3Configuration.java
@@ -87,6 +87,7 @@ import org.hibernate.ejb.util.ConfigurationHelper;
import org.hibernate.ejb.util.LogHelper;
import org.hibernate.ejb.util.NamingHelper;
import org.hibernate.engine.FilterDefinition;
+import org.hibernate.engine.transaction.internal.jdbc.JdbcTransactionFactory;
import org.hibernate.event.EventListeners;
import org.hibernate.mapping.AuxiliaryDatabaseObject;
import org.hibernate.mapping.PersistentClass;
@@ -95,7 +96,6 @@ import org.hibernate.proxy.EntityNotFoundDelegate;
import org.hibernate.secure.JACCConfiguration;
import org.hibernate.service.jdbc.connections.internal.ConnectionProviderInitiator;
import org.hibernate.service.spi.ServiceRegistry;
-import org.hibernate.transaction.JDBCTransactionFactory;
import org.hibernate.util.CollectionHelper;
import org.hibernate.util.ReflectHelper;
import org.hibernate.util.StringHelper;
@@ -1256,7 +1256,7 @@ public class Ejb3Configuration implements Serializable, Referenceable {
);
}
else if ( ! hasTxStrategy && transactionType == PersistenceUnitTransactionType.RESOURCE_LOCAL ) {
- preparedProperties.setProperty( Environment.TRANSACTION_STRATEGY, JDBCTransactionFactory.class.getName() );
+ preparedProperties.setProperty( Environment.TRANSACTION_STRATEGY, JdbcTransactionFactory.class.getName() );
}
if ( hasTxStrategy ) {
log.warn(
diff --git a/hibernate-entitymanager/src/main/java/org/hibernate/ejb/transaction/JoinableCMTTransaction.java b/hibernate-entitymanager/src/main/java/org/hibernate/ejb/transaction/JoinableCMTTransaction.java
index d4531a0739..19df58762c 100644
--- a/hibernate-entitymanager/src/main/java/org/hibernate/ejb/transaction/JoinableCMTTransaction.java
+++ b/hibernate-entitymanager/src/main/java/org/hibernate/ejb/transaction/JoinableCMTTransaction.java
@@ -21,79 +21,63 @@
*/
package org.hibernate.ejb.transaction;
-import javax.transaction.SystemException;
-import javax.transaction.Transaction;
-
import org.hibernate.HibernateException;
-import org.hibernate.TransactionException;
-import org.hibernate.engine.jdbc.spi.JDBCContext;
-import org.hibernate.transaction.CMTTransaction;
-import org.hibernate.transaction.TransactionFactory;
-import org.hibernate.util.JTAHelper;
+import org.hibernate.engine.transaction.internal.jta.CMTTransaction;
+import org.hibernate.engine.transaction.internal.jta.JtaStatusHelper;
+import org.hibernate.engine.transaction.spi.JoinStatus;
+import org.hibernate.engine.transaction.spi.TransactionCoordinator;
/**
* Implements a joinable transaction. Until the transaction is marked for joined, the TM.isTransactionInProgress()
* must return false
*
* @author Emmanuel Bernard
+ * @author Steve Ebersole
*/
public class JoinableCMTTransaction extends CMTTransaction {
- private JoinStatus status;
+ private JoinStatus joinStatus = JoinStatus.NOT_JOINED;
- public JoinableCMTTransaction(JDBCContext jdbcContext, TransactionFactory.Context transactionContext) {
- super( jdbcContext, transactionContext );
- //status = JoinStatus.MARKED_FOR_JOINED;
- //tryJoiningTransaction();
+ public JoinableCMTTransaction(TransactionCoordinator transactionCoordinator) {
+ super( transactionCoordinator );
}
- public boolean isTransactionInProgress(
- JDBCContext jdbcContext,
- TransactionFactory.Context transactionContext) {
- try {
- return status == JoinStatus.JOINED && isTransactionInProgress(
- transactionContext.getFactory().getTransactionManager().getTransaction()
- );
- }
- catch (SystemException se) {
- throw new TransactionException( "Unable to check transaction status", se );
- }
+ boolean isJoinable() {
+ return joinStatus == JoinStatus.JOINED && JtaStatusHelper.isActive( transactionManager() );
}
- private boolean isTransactionInProgress() {
- try {
- Transaction transaction = transactionContext.getFactory().getTransactionManager().getTransaction();
- return isTransactionInProgress(transaction);
- }
- catch (SystemException se) {
- throw new TransactionException( "Unable to check transaction status", se );
- }
+ public JoinStatus getJoinStatus() {
+ return joinStatus;
}
- private boolean isTransactionInProgress(Transaction tx) throws SystemException {
- return JTAHelper.isTransactionInProgress(tx) && ! JTAHelper.isRollback( tx.getStatus() );
- }
-
- void tryJoiningTransaction() {
- if ( status == JoinStatus.MARKED_FOR_JOINED ) {
- if ( isTransactionInProgress() ) {
- status = JoinStatus.JOINED;
+ @Override
+ public void join() {
+ if ( joinStatus == JoinStatus.MARKED_FOR_JOINED ) {
+ if ( JtaStatusHelper.isActive( transactionManager() ) ) {
+ joinStatus = JoinStatus.JOINED;
+ // register synchronization if needed
+ transactionCoordinator().pulse();
}
else {
- status = JoinStatus.NOT_JOINED;
+ joinStatus = JoinStatus.NOT_JOINED;
}
}
}
+ @Override
+ public void resetJoinStatus() {
+ joinStatus = JoinStatus.NOT_JOINED;
+ }
+
@Override
public void begin() throws HibernateException {
super.begin();
- status = JoinStatus.JOINED;
+ joinStatus = JoinStatus.JOINED;
}
@Override
public void commit() throws HibernateException {
/* this method is not supposed to be called
- * it breaks the flushBeforeCompletion flag optimizeation
+ * it breaks the flushBeforeCompletion flag optimization
* regarding flushing skip.
* In its current form, it will generate too much flush() calls
*/
@@ -102,20 +86,11 @@ public class JoinableCMTTransaction extends CMTTransaction {
public JoinStatus getStatus() {
- return status;
+ return joinStatus;
}
public void resetStatus() {
- status = JoinStatus.NOT_JOINED;
+ joinStatus = JoinStatus.NOT_JOINED;
}
- public void markForJoined() {
- if ( status != JoinStatus.JOINED ) status = JoinStatus.MARKED_FOR_JOINED;
- }
-
- public static enum JoinStatus {
- NOT_JOINED,
- MARKED_FOR_JOINED,
- JOINED
- }
}
diff --git a/hibernate-entitymanager/src/main/java/org/hibernate/ejb/transaction/JoinableCMTTransactionFactory.java b/hibernate-entitymanager/src/main/java/org/hibernate/ejb/transaction/JoinableCMTTransactionFactory.java
index b4f3239342..95832b763e 100644
--- a/hibernate-entitymanager/src/main/java/org/hibernate/ejb/transaction/JoinableCMTTransactionFactory.java
+++ b/hibernate-entitymanager/src/main/java/org/hibernate/ejb/transaction/JoinableCMTTransactionFactory.java
@@ -1,8 +1,10 @@
/*
- * Copyright (c) 2009, Red Hat Middleware LLC or third-party contributors as
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009-2011, 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 Middleware LLC.
+ * 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
@@ -21,34 +23,46 @@
*/
package org.hibernate.ejb.transaction;
-import org.hibernate.HibernateException;
-import org.hibernate.Transaction;
-import org.hibernate.engine.jdbc.spi.JDBCContext;
-import org.hibernate.transaction.CMTTransactionFactory;
+import org.hibernate.ConnectionReleaseMode;
+import org.hibernate.engine.transaction.spi.JoinStatus;
+import org.hibernate.engine.transaction.spi.TransactionCoordinator;
+import org.hibernate.engine.transaction.spi.TransactionFactory;
/**
* A transaction is in progress if the underlying JTA tx is in progress and if the Tx is marked as
* MARKED_FOR_JOINED
*
* @author Emmanuel Bernard
+ * @author Steve Ebersole
*/
-public class JoinableCMTTransactionFactory extends CMTTransactionFactory {
- public Transaction createTransaction(
- JDBCContext jdbcContext,
- Context transactionContext) throws HibernateException {
- return new JoinableCMTTransaction( jdbcContext, transactionContext );
+public class JoinableCMTTransactionFactory implements TransactionFactory {
+ @Override
+ public boolean compatibleWithJtaSynchronization() {
+ return true;
}
@Override
- public boolean isTransactionInProgress(
- JDBCContext jdbcContext,
- Context transactionContext,
- Transaction transaction) {
- if ( transaction == null ) {
- return false; //should not happen though
- }
- JoinableCMTTransaction joinableCMTTransaction = ( (JoinableCMTTransaction) transaction );
- joinableCMTTransaction.tryJoiningTransaction();
- return joinableCMTTransaction.isTransactionInProgress( jdbcContext, transactionContext );
+ public boolean canBeDriver() {
+ return false;
+ }
+
+ @Override
+ public JoinableCMTTransaction createTransaction(TransactionCoordinator transactionCoordinator) {
+ return new JoinableCMTTransaction( transactionCoordinator );
+ }
+
+ @Override
+ public boolean isJoinableJtaTransaction(TransactionCoordinator transactionCoordinator, JoinableCMTTransaction transaction) {
+ return transaction.isJoinable();
+ }
+
+ @Override
+ public JoinStatus getJoinStatus(TransactionCoordinator transactionCoordinator, JoinableCMTTransaction transaction) {
+ return transaction.getJoinStatus();
+ }
+
+ @Override
+ public ConnectionReleaseMode getDefaultReleaseMode() {
+ return ConnectionReleaseMode.AFTER_STATEMENT;
}
}
diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/lazy/AbstractDelegateSessionImplementor.java b/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/lazy/AbstractDelegateSessionImplementor.java
index 5de4173e21..8fa33710df 100644
--- a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/lazy/AbstractDelegateSessionImplementor.java
+++ b/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/lazy/AbstractDelegateSessionImplementor.java
@@ -46,8 +46,8 @@ import org.hibernate.engine.QueryParameters;
import org.hibernate.engine.SessionFactoryImplementor;
import org.hibernate.engine.SessionImplementor;
import org.hibernate.engine.NonFlushedChanges;
-import org.hibernate.engine.jdbc.spi.JDBCContext;
import org.hibernate.engine.query.sql.NativeSQLQuerySpecification;
+import org.hibernate.engine.transaction.spi.TransactionCoordinator;
import org.hibernate.event.EventListeners;
import org.hibernate.impl.CriteriaImpl;
import org.hibernate.loader.custom.CustomQuery;
@@ -140,14 +140,6 @@ public abstract class AbstractDelegateSessionImplementor implements SessionImple
return delegate.getEntityUsingInterceptor(key);
}
- public void afterTransactionCompletion(boolean successful, Transaction tx) {
- delegate.afterTransactionCompletion(successful, tx);
- }
-
- public void beforeTransactionCompletion(Transaction tx) {
- delegate.beforeTransactionCompletion(tx);
- }
-
public Serializable getContextEntityIdentifier(Object object) {
return delegate.getContextEntityIdentifier(object);
}
@@ -280,11 +272,12 @@ public abstract class AbstractDelegateSessionImplementor implements SessionImple
return delegate.getFetchProfile();
}
- public JDBCContext getJDBCContext() {
- return delegate.getJDBCContext();
- }
+ @Override
+ public TransactionCoordinator getTransactionCoordinator() {
+ return delegate.getTransactionCoordinator();
+ }
- public boolean isClosed() {
+ public boolean isClosed() {
return delegate.isClosed();
}
}
diff --git a/hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/tm/HibernateTransactionManagerLookup.java b/hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/tm/HibernateTransactionManagerLookup.java
index ea8d7b0993..ef80e7c300 100644
--- a/hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/tm/HibernateTransactionManagerLookup.java
+++ b/hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/tm/HibernateTransactionManagerLookup.java
@@ -21,12 +21,11 @@
*/
package org.hibernate.cache.infinispan.tm;
-import java.util.Properties;
+import org.hibernate.cfg.Settings;
+import org.hibernate.service.jta.platform.spi.JtaPlatform;
import javax.transaction.TransactionManager;
-
-import org.hibernate.cfg.Settings;
-import org.hibernate.transaction.TransactionManagerLookup;
+import java.util.Properties;
/**
* HibernateTransactionManagerLookup.
@@ -35,20 +34,19 @@ import org.hibernate.transaction.TransactionManagerLookup;
* @since 3.5
*/
public class HibernateTransactionManagerLookup implements org.infinispan.transaction.lookup.TransactionManagerLookup {
- private final TransactionManagerLookup hibernateLookup;
-
- private final Properties properties;
-
- public HibernateTransactionManagerLookup(Settings settings, Properties properties) {
- if (settings != null)
- this.hibernateLookup = settings.getTransactionManagerLookup();
- else
- this.hibernateLookup = null;
- this.properties = properties;
- }
-
- public TransactionManager getTransactionManager() throws Exception {
- return hibernateLookup == null ? null : hibernateLookup.getTransactionManager(properties);
- }
+ private final JtaPlatform jtaPlatform;
+
+ public HibernateTransactionManagerLookup(Settings settings, Properties properties) {
+ if ( settings != null ) {
+ jtaPlatform = settings.getJtaPlatform();
+ }
+ else {
+ jtaPlatform = null;
+ }
+ }
+
+ public TransactionManager getTransactionManager() throws Exception {
+ return jtaPlatform == null ? null : jtaPlatform.retrieveTransactionManager();
+ }
}
diff --git a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/AbstractEntityCollectionRegionTestCase.java b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/AbstractEntityCollectionRegionTestCase.java
index 2ce1305f9f..9d806489d5 100644
--- a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/AbstractEntityCollectionRegionTestCase.java
+++ b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/AbstractEntityCollectionRegionTestCase.java
@@ -65,7 +65,7 @@ public abstract class AbstractEntityCollectionRegionTestCase extends AbstractReg
String entityCfg = "entity";
cfg.setProperty(InfinispanRegionFactory.ENTITY_CACHE_RESOURCE_PROP, entityCfg);
InfinispanRegionFactory regionFactory = CacheTestUtil.startRegionFactory(
- getJdbcServices(), cfg, getCacheTestSupport()
+ getServiceRegistry(), cfg, getCacheTestSupport()
);
supportedAccessTypeTest(regionFactory, cfg.getProperties());
}
@@ -85,7 +85,7 @@ public abstract class AbstractEntityCollectionRegionTestCase extends AbstractReg
public void testIsTransactionAware() throws Exception {
Configuration cfg = CacheTestUtil.buildConfiguration("test", InfinispanRegionFactory.class, true, false);
InfinispanRegionFactory regionFactory = CacheTestUtil.startRegionFactory(
- getJdbcServices(), cfg, getCacheTestSupport()
+ getServiceRegistry(), cfg, getCacheTestSupport()
);
TransactionalDataRegion region = (TransactionalDataRegion) createRegion(regionFactory, "test/test", cfg.getProperties(), getCacheDataDescription());
assertTrue("Region is transaction-aware", region.isTransactionAware());
@@ -94,7 +94,7 @@ public abstract class AbstractEntityCollectionRegionTestCase extends AbstractReg
// Make it non-transactional
cfg.getProperties().remove(Environment.TRANSACTION_MANAGER_STRATEGY);
regionFactory = CacheTestUtil.startRegionFactory(
- getJdbcServices(), cfg, getCacheTestSupport()
+ getServiceRegistry(), cfg, getCacheTestSupport()
);
region = (TransactionalDataRegion) createRegion(regionFactory, "test/test", cfg.getProperties(), getCacheDataDescription());
assertFalse("Region is not transaction-aware", region.isTransactionAware());
@@ -104,7 +104,7 @@ public abstract class AbstractEntityCollectionRegionTestCase extends AbstractReg
public void testGetCacheDataDescription() throws Exception {
Configuration cfg = CacheTestUtil.buildConfiguration("test", InfinispanRegionFactory.class, true, false);
InfinispanRegionFactory regionFactory = CacheTestUtil.startRegionFactory(
- getJdbcServices(), cfg, getCacheTestSupport()
+ getServiceRegistry(), cfg, getCacheTestSupport()
);
TransactionalDataRegion region = (TransactionalDataRegion) createRegion(regionFactory, "test/test", cfg.getProperties(), getCacheDataDescription());
CacheDataDescription cdd = region.getCacheDataDescription();
diff --git a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/AbstractGeneralDataRegionTestCase.java b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/AbstractGeneralDataRegionTestCase.java
index 7f959ab380..eaa6a6ec7e 100644
--- a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/AbstractGeneralDataRegionTestCase.java
+++ b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/AbstractGeneralDataRegionTestCase.java
@@ -73,7 +73,7 @@ public abstract class AbstractGeneralDataRegionTestCase extends AbstractRegionIm
private void evictOrRemoveTest() throws Exception {
Configuration cfg = createConfiguration();
InfinispanRegionFactory regionFactory = CacheTestUtil.startRegionFactory(
- getJdbcServices(), cfg, getCacheTestSupport()
+ getServiceRegistry(), cfg, getCacheTestSupport()
);
CacheAdapter localCache = getInfinispanCache(regionFactory);
boolean invalidation = localCache.isClusteredInvalidation();
@@ -86,7 +86,7 @@ public abstract class AbstractGeneralDataRegionTestCase extends AbstractRegionIm
cfg = createConfiguration();
regionFactory = CacheTestUtil.startRegionFactory(
- getJdbcServices(), cfg, getCacheTestSupport()
+ getServiceRegistry(), cfg, getCacheTestSupport()
);
GeneralDataRegion remoteRegion = (GeneralDataRegion) createRegion(regionFactory,
@@ -126,7 +126,7 @@ public abstract class AbstractGeneralDataRegionTestCase extends AbstractRegionIm
private void evictOrRemoveAllTest(String configName) throws Exception {
Configuration cfg = createConfiguration();
InfinispanRegionFactory regionFactory = CacheTestUtil.startRegionFactory(
- getJdbcServices(), cfg, getCacheTestSupport()
+ getServiceRegistry(), cfg, getCacheTestSupport()
);
CacheAdapter localCache = getInfinispanCache(regionFactory);
@@ -138,7 +138,7 @@ public abstract class AbstractGeneralDataRegionTestCase extends AbstractRegionIm
cfg = createConfiguration();
regionFactory = CacheTestUtil.startRegionFactory(
- getJdbcServices(), cfg, getCacheTestSupport()
+ getServiceRegistry(), cfg, getCacheTestSupport()
);
CacheAdapter remoteCache = getInfinispanCache(regionFactory);
diff --git a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/collection/AbstractCollectionRegionAccessStrategyTestCase.java b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/collection/AbstractCollectionRegionAccessStrategyTestCase.java
index d63e697314..b92c7456f9 100644
--- a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/collection/AbstractCollectionRegionAccessStrategyTestCase.java
+++ b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/collection/AbstractCollectionRegionAccessStrategyTestCase.java
@@ -542,14 +542,11 @@ public abstract class AbstractCollectionRegionAccessStrategyTestCase extends Abs
serviceRegistry = ServiceRegistryBuilder.buildServiceRegistry( Environment.getProperties() );
localCfg = createConfiguration(configName, configResource);
- localRegionFactory = CacheTestUtil.startRegionFactory(
- serviceRegistry.getService( JdbcServices.class ),
- localCfg
- );
+ localRegionFactory = CacheTestUtil.startRegionFactory( serviceRegistry, localCfg );
remoteCfg = createConfiguration(configName, configResource);
remoteRegionFactory = CacheTestUtil.startRegionFactory(
- serviceRegistry.getService( JdbcServices.class ),
+ serviceRegistry,
remoteCfg
);
}
diff --git a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/collection/TransactionalExtraAPITestCase.java b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/collection/TransactionalExtraAPITestCase.java
index 70ce3a30c0..16bbbff6c0 100644
--- a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/collection/TransactionalExtraAPITestCase.java
+++ b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/collection/TransactionalExtraAPITestCase.java
@@ -55,7 +55,7 @@ public class TransactionalExtraAPITestCase extends AbstractNonFunctionalTestCase
if (getCollectionAccessStrategy() == null) {
Configuration cfg = createConfiguration();
InfinispanRegionFactory rf = CacheTestUtil.startRegionFactory(
- getJdbcServices(), cfg, getCacheTestSupport()
+ getServiceRegistry(), cfg, getCacheTestSupport()
);
// Sleep a bit to avoid concurrent FLUSH problem
@@ -93,30 +93,18 @@ public class TransactionalExtraAPITestCase extends AbstractNonFunctionalTestCase
localAccessStrategy = strategy;
}
- /**
- * Test method for {@link TransactionalAccess#lockItem(java.lang.Object, java.lang.Object)}.
- */
public void testLockItem() {
assertNull(getCollectionAccessStrategy().lockItem(KEY, new Integer(1)));
}
- /**
- * Test method for {@link TransactionalAccess#lockRegion()}.
- */
public void testLockRegion() {
assertNull(getCollectionAccessStrategy().lockRegion());
}
- /**
- * Test method for {@link TransactionalAccess#unlockItem(java.lang.Object, org.hibernate.cache.access.SoftLock)}.
- */
public void testUnlockItem() {
getCollectionAccessStrategy().unlockItem(KEY, new MockSoftLock());
}
- /**
- * Test method for {@link TransactionalAccess#unlockRegion(org.hibernate.cache.access.SoftLock)}.
- */
public void testUnlockRegion() {
getCollectionAccessStrategy().unlockItem(KEY, new MockSoftLock());
}
diff --git a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/entity/AbstractEntityRegionAccessStrategyTestCase.java b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/entity/AbstractEntityRegionAccessStrategyTestCase.java
index b70c41ffd6..f7197cdf3a 100644
--- a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/entity/AbstractEntityRegionAccessStrategyTestCase.java
+++ b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/entity/AbstractEntityRegionAccessStrategyTestCase.java
@@ -666,16 +666,10 @@ public abstract class AbstractEntityRegionAccessStrategyTestCase extends Abstrac
serviceRegistry = ServiceRegistryBuilder.buildServiceRegistry( Environment.getProperties() );
localCfg = createConfiguration(configName);
- localRegionFactory = CacheTestUtil.startRegionFactory(
- serviceRegistry.getService( JdbcServices.class ),
- localCfg
- );
+ localRegionFactory = CacheTestUtil.startRegionFactory( serviceRegistry, localCfg );
remoteCfg = createConfiguration(configName);
- remoteRegionFactory = CacheTestUtil.startRegionFactory(
- serviceRegistry.getService( JdbcServices.class ),
- remoteCfg
- );
+ remoteRegionFactory = CacheTestUtil.startRegionFactory( serviceRegistry, remoteCfg );
}
@Override
diff --git a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/entity/TransactionalExtraAPITestCase.java b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/entity/TransactionalExtraAPITestCase.java
index 0aac7c9792..bc04f1a625 100644
--- a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/entity/TransactionalExtraAPITestCase.java
+++ b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/entity/TransactionalExtraAPITestCase.java
@@ -61,7 +61,7 @@ public class TransactionalExtraAPITestCase extends AbstractNonFunctionalTestCase
if (getEntityAccessStrategy() == null) {
Configuration cfg = createConfiguration();
InfinispanRegionFactory rf = CacheTestUtil.startRegionFactory(
- getJdbcServices(), cfg, getCacheTestSupport()
+ getServiceRegistry(), cfg, getCacheTestSupport()
);
// Sleep a bit to avoid concurrent FLUSH problem
@@ -99,44 +99,26 @@ public class TransactionalExtraAPITestCase extends AbstractNonFunctionalTestCase
localAccessStrategy = strategy;
}
- /**
- * Test method for {@link TransactionalAccess#lockItem(java.lang.Object, java.lang.Object)}.
- */
public void testLockItem() {
assertNull(getEntityAccessStrategy().lockItem(KEY, new Integer(1)));
}
- /**
- * Test method for {@link TransactionalAccess#lockRegion()}.
- */
public void testLockRegion() {
assertNull(getEntityAccessStrategy().lockRegion());
}
- /**
- * Test method for {@link TransactionalAccess#unlockItem(java.lang.Object, org.hibernate.cache.access.SoftLock)}.
- */
public void testUnlockItem() {
getEntityAccessStrategy().unlockItem(KEY, new MockSoftLock());
}
- /**
- * Test method for {@link TransactionalAccess#unlockRegion(org.hibernate.cache.access.SoftLock)}.
- */
public void testUnlockRegion() {
getEntityAccessStrategy().unlockItem(KEY, new MockSoftLock());
}
- /**
- * Test method for {@link TransactionalAccess#afterInsert(java.lang.Object, java.lang.Object, java.lang.Object)}.
- */
public void testAfterInsert() {
assertFalse("afterInsert always returns false", getEntityAccessStrategy().afterInsert(KEY, VALUE1, new Integer(1)));
}
- /**
- * Test method for {@link TransactionalAccess#afterUpdate(java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object, org.hibernate.cache.access.SoftLock)}.
- */
public void testAfterUpdate() {
assertFalse("afterInsert always returns false", getEntityAccessStrategy().afterUpdate(KEY, VALUE2, new Integer(1), new Integer(2), new MockSoftLock()));
}
diff --git a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/BasicJdbcTransactionalTestCase.java b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/BasicJdbcTransactionalTestCase.java
index e04b63b49f..9413afc309 100644
--- a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/BasicJdbcTransactionalTestCase.java
+++ b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/BasicJdbcTransactionalTestCase.java
@@ -25,10 +25,10 @@ package org.hibernate.test.cache.infinispan.functional;
import java.util.Map;
import org.hibernate.Session;
+import org.hibernate.engine.transaction.internal.jdbc.JdbcTransactionFactory;
+import org.hibernate.engine.transaction.spi.TransactionFactory;
import org.hibernate.stat.SecondLevelCacheStatistics;
import org.hibernate.stat.Statistics;
-import org.hibernate.transaction.JDBCTransactionFactory;
-import org.hibernate.transaction.TransactionFactory;
import org.hibernate.transaction.TransactionManagerLookup;
import org.infinispan.util.logging.Log;
import org.infinispan.util.logging.LogFactory;
@@ -47,7 +47,7 @@ public class BasicJdbcTransactionalTestCase extends SingleNodeTestCase {
}
protected Class extends TransactionFactory> getTransactionFactoryClass() {
- return JDBCTransactionFactory.class;
+ return JdbcTransactionFactory.class;
}
protected Class extends TransactionManagerLookup> getTransactionManagerLookupClass() {
diff --git a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/SingleNodeTestCase.java b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/SingleNodeTestCase.java
index 88ad695cfb..e692ac149c 100644
--- a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/SingleNodeTestCase.java
+++ b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/SingleNodeTestCase.java
@@ -7,12 +7,10 @@ import org.hibernate.cache.RegionFactory;
import org.hibernate.cache.infinispan.InfinispanRegionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.cfg.Environment;
+import org.hibernate.engine.transaction.spi.TransactionFactory;
import org.hibernate.service.jdbc.connections.spi.ConnectionProvider;
import org.hibernate.testing.junit.functional.FunctionalTestCase;
-import org.hibernate.stat.SecondLevelCacheStatistics;
-import org.hibernate.stat.Statistics;
-import org.hibernate.transaction.CMTTransactionFactory;
-import org.hibernate.transaction.TransactionFactory;
+import org.hibernate.engine.transaction.internal.jta.CMTTransactionFactory;
import org.hibernate.transaction.TransactionManagerLookup;
import org.infinispan.util.logging.Log;
import org.infinispan.util.logging.LogFactory;
diff --git a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/bulk/BulkOperationsTestCase.java b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/bulk/BulkOperationsTestCase.java
index d737cd6c4c..1f11835053 100644
--- a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/bulk/BulkOperationsTestCase.java
+++ b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/bulk/BulkOperationsTestCase.java
@@ -34,13 +34,13 @@ import org.hibernate.cache.infinispan.InfinispanRegionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.cfg.Environment;
import org.hibernate.classic.Session;
+import org.hibernate.engine.transaction.internal.jta.CMTTransactionFactory;
+import org.hibernate.engine.transaction.spi.TransactionFactory;
import org.hibernate.service.jdbc.connections.spi.ConnectionProvider;
import org.hibernate.testing.junit.functional.FunctionalTestCase;
import org.hibernate.stat.SecondLevelCacheStatistics;
import org.hibernate.test.cache.infinispan.functional.Contact;
import org.hibernate.test.cache.infinispan.functional.Customer;
-import org.hibernate.transaction.CMTTransactionFactory;
-import org.hibernate.transaction.TransactionFactory;
import org.hibernate.transaction.TransactionManagerLookup;
import org.infinispan.util.logging.Log;
import org.infinispan.util.logging.LogFactory;
diff --git a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/cluster/DualNodeTestCase.java b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/cluster/DualNodeTestCase.java
index a63d0ea325..2aa7b0c741 100644
--- a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/cluster/DualNodeTestCase.java
+++ b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/cluster/DualNodeTestCase.java
@@ -30,9 +30,10 @@ import org.hibernate.cfg.Environment;
import org.hibernate.cfg.Mappings;
import org.hibernate.dialect.Dialect;
import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.engine.transaction.internal.jta.CMTTransactionFactory;
import org.hibernate.testing.junit.functional.ExecutionEnvironment;
import org.hibernate.testing.junit.functional.FunctionalTestCase;
-import org.hibernate.transaction.CMTTransactionFactory;
+
import org.infinispan.util.logging.Log;
import org.infinispan.util.logging.LogFactory;
diff --git a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/query/QueryRegionImplTestCase.java b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/query/QueryRegionImplTestCase.java
index e1180116d9..ed711b955b 100644
--- a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/query/QueryRegionImplTestCase.java
+++ b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/query/QueryRegionImplTestCase.java
@@ -91,7 +91,7 @@ public class QueryRegionImplTestCase extends AbstractGeneralDataRegionTestCase {
private void putDoesNotBlockGetTest() throws Exception {
Configuration cfg = createConfiguration();
InfinispanRegionFactory regionFactory = CacheTestUtil.startRegionFactory(
- getJdbcServices(), cfg, getCacheTestSupport());
+ getServiceRegistry(), cfg, getCacheTestSupport());
// Sleep a bit to avoid concurrent FLUSH problem
avoidConcurrentFlush();
@@ -177,7 +177,7 @@ public class QueryRegionImplTestCase extends AbstractGeneralDataRegionTestCase {
private void getDoesNotBlockPutTest() throws Exception {
Configuration cfg = createConfiguration();
InfinispanRegionFactory regionFactory = CacheTestUtil.startRegionFactory(
- getJdbcServices(), cfg, getCacheTestSupport()
+ getServiceRegistry(), cfg, getCacheTestSupport()
);
// Sleep a bit to avoid concurrent FLUSH problem
diff --git a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/timestamp/TimestampsRegionImplTestCase.java b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/timestamp/TimestampsRegionImplTestCase.java
index afd8dfc663..c27080f2f0 100644
--- a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/timestamp/TimestampsRegionImplTestCase.java
+++ b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/timestamp/TimestampsRegionImplTestCase.java
@@ -87,14 +87,14 @@ public class TimestampsRegionImplTestCase extends AbstractGeneralDataRegionTestC
public void testClearTimestampsRegionInIsolated() throws Exception {
Configuration cfg = createConfiguration();
InfinispanRegionFactory regionFactory = CacheTestUtil.startRegionFactory(
- getJdbcServices(), cfg, getCacheTestSupport()
+ getServiceRegistry(), cfg, getCacheTestSupport()
);
// Sleep a bit to avoid concurrent FLUSH problem
avoidConcurrentFlush();
Configuration cfg2 = createConfiguration();
InfinispanRegionFactory regionFactory2 = CacheTestUtil.startRegionFactory(
- getJdbcServices(), cfg2, getCacheTestSupport()
+ getServiceRegistry(), cfg2, getCacheTestSupport()
);
// Sleep a bit to avoid concurrent FLUSH problem
avoidConcurrentFlush();
diff --git a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/tm/JBossStandaloneJtaExampleTest.java b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/tm/JBossStandaloneJtaExampleTest.java
index 170655a2aa..cebf648378 100644
--- a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/tm/JBossStandaloneJtaExampleTest.java
+++ b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/tm/JBossStandaloneJtaExampleTest.java
@@ -226,7 +226,7 @@ public class JBossStandaloneJtaExampleTest extends TestCase {
}
private void bindUserTransaction() throws Exception {
- // also the UserTransaction must be registered on jndi: org.hibernate.transaction.JTATransactionFactory#getUserTransaction() requires this
+ // also the UserTransaction must be registered on jndi: org.hibernate.engine.transaction.internal.jta.JtaTransactionFactory#getUserTransaction() requires this
bind("UserTransaction", lookup.getUserTransaction(), lookup.getUserTransaction().getClass(), ctx);
}
diff --git a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/util/CacheTestUtil.java b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/util/CacheTestUtil.java
index 1db018c176..d53b95e9d1 100644
--- a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/util/CacheTestUtil.java
+++ b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/util/CacheTestUtil.java
@@ -37,6 +37,7 @@ import org.hibernate.cfg.Configuration;
import org.hibernate.cfg.Environment;
import org.hibernate.cfg.Settings;
import org.hibernate.engine.jdbc.spi.JdbcServices;
+import org.hibernate.service.spi.ServiceRegistry;
/**
* Utilities for cache testing.
@@ -72,11 +73,11 @@ public class CacheTestUtil {
return cfg;
}
- public static InfinispanRegionFactory startRegionFactory(JdbcServices jdbcServices,
- Configuration cfg)
- throws ClassNotFoundException, InstantiationException, IllegalAccessException {
+ public static InfinispanRegionFactory startRegionFactory(
+ ServiceRegistry serviceRegistry,
+ Configuration cfg) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
- Settings settings = cfg.buildSettings( jdbcServices );
+ Settings settings = cfg.buildSettings( serviceRegistry );
Properties properties = cfg.getProperties();
String factoryType = cfg.getProperty(Environment.CACHE_REGION_FACTORY);
@@ -88,11 +89,11 @@ public class CacheTestUtil {
return regionFactory;
}
- public static InfinispanRegionFactory startRegionFactory(JdbcServices jdbcServices,
- Configuration cfg,
- CacheTestSupport testSupport)
- throws ClassNotFoundException, InstantiationException, IllegalAccessException {
- InfinispanRegionFactory factory = startRegionFactory(jdbcServices, cfg);
+ public static InfinispanRegionFactory startRegionFactory(
+ ServiceRegistry serviceRegistry,
+ Configuration cfg,
+ CacheTestSupport testSupport) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
+ InfinispanRegionFactory factory = startRegionFactory( serviceRegistry, cfg );
testSupport.registerFactory(factory);
return factory;
}
From bf186e7a6e8d3ca03f0de0722d57533042bb9f97 Mon Sep 17 00:00:00 2001
From: Steve Ebersole
Date: Thu, 3 Mar 2011 11:53:20 -0600
Subject: [PATCH 05/19] HHH-5949 - Migrate, complete and integrate
TransactionFactory as a service
---
hibernate-core/hibernate-core.gradle | 7 ++++++-
hibernate-entitymanager/hibernate-entitymanager.gradle | 2 +-
.../src/test/java/org/hibernate/ejb/test/TestCase.java | 10 +++++-----
3 files changed, 12 insertions(+), 7 deletions(-)
diff --git a/hibernate-core/hibernate-core.gradle b/hibernate-core/hibernate-core.gradle
index 7263d71648..23defc1a7b 100644
--- a/hibernate-core/hibernate-core.gradle
+++ b/hibernate-core/hibernate-core.gradle
@@ -96,4 +96,9 @@ task installTesting(type:Upload, dependsOn: [testingJar,testingSourcesJar]) {
}
install.dependsOn installTesting
-uploadTesting.dependsOn installTesting
\ No newline at end of file
+uploadTesting.dependsOn installTesting
+
+// temporary
+test {
+ ignoreFailures = true
+}
\ No newline at end of file
diff --git a/hibernate-entitymanager/hibernate-entitymanager.gradle b/hibernate-entitymanager/hibernate-entitymanager.gradle
index b9fb474d99..52cac0e6cb 100644
--- a/hibernate-entitymanager/hibernate-entitymanager.gradle
+++ b/hibernate-entitymanager/hibernate-entitymanager.gradle
@@ -1,4 +1,4 @@
-import org.apache.tools.ant.filters.*
+import org.apache.tools.ant.filters.ReplaceTokens
apply plugin: 'java'
diff --git a/hibernate-entitymanager/src/test/java/org/hibernate/ejb/test/TestCase.java b/hibernate-entitymanager/src/test/java/org/hibernate/ejb/test/TestCase.java
index fceafbe65b..77526dec99 100644
--- a/hibernate-entitymanager/src/test/java/org/hibernate/ejb/test/TestCase.java
+++ b/hibernate-entitymanager/src/test/java/org/hibernate/ejb/test/TestCase.java
@@ -106,15 +106,15 @@ public abstract class TestCase extends HibernateTestCase {
}
protected void handleUnclosedResources() {
- cleanUnclosed( this.em );
- for ( Iterator iter = isolatedEms.iterator(); iter.hasNext(); ) {
- cleanUnclosed( ( EntityManager ) iter.next() );
- }
-
cfg = null;
}
protected void closeResources() {
+ cleanUnclosed( this.em );
+ for ( Object isolatedEm : isolatedEms ) {
+ cleanUnclosed( (EntityManager) isolatedEm );
+ }
+
if ( factory != null ) {
factory.close();
}
From 4d5b9f1ca13093325f05a1295449c3a92cc65463 Mon Sep 17 00:00:00 2001
From: Steve Ebersole
Date: Thu, 3 Mar 2011 14:16:58 -0600
Subject: [PATCH 06/19] HHH-5949 - Migrate, complete and integrate
TransactionFactory as a service
---
build.gradle | 2 +-
...bstractEntityCollectionRegionTestCase.java | 20 +++--
...ollectionRegionAccessStrategyTestCase.java | 27 +++---
.../functional/ConcurrentWriteTest.java | 14 +--
.../functional/SingleNodeTestCase.java | 48 +++++-----
.../bulk/BulkOperationsTestCase.java | 16 ++--
.../cluster/DualNodeJtaPlatformImpl.java | 87 +++++++++++++++++++
.../functional/cluster/DualNodeTestCase.java | 19 +---
.../cache/infinispan/tm/JtaPlatformImpl.java | 74 ++++++++++++++++
.../tm/XaTransactionManagerLookup.java | 52 -----------
.../infinispan/util/BatchModeJtaPlatform.java | 82 +++++++++++++++++
.../cache/infinispan/util/CacheTestUtil.java | 3 +-
12 files changed, 322 insertions(+), 122 deletions(-)
create mode 100644 hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/cluster/DualNodeJtaPlatformImpl.java
create mode 100644 hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/tm/JtaPlatformImpl.java
delete mode 100644 hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/tm/XaTransactionManagerLookup.java
create mode 100644 hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/util/BatchModeJtaPlatform.java
diff --git a/build.gradle b/build.gradle
index 5d250557a0..7929ef22b2 100644
--- a/build.gradle
+++ b/build.gradle
@@ -67,7 +67,7 @@ libraries = [
jcl: 'commons-logging:commons-logging:99.0-does-not-exist',
// testing
- atomikos: 'com.atomikos:transactions-jdbc:3.6.4',
+ atomikos: 'com.atomikos:transactions-jdbc:3.7.0',
junit: 'junit:junit:3.8.2',
testng: 'org.testng:testng:5.8:jdk15',
jpa_modelgen: 'org.hibernate:hibernate-jpamodelgen:1.1.0.Final',
diff --git a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/AbstractEntityCollectionRegionTestCase.java b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/AbstractEntityCollectionRegionTestCase.java
index 9d806489d5..590a7d844e 100644
--- a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/AbstractEntityCollectionRegionTestCase.java
+++ b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/AbstractEntityCollectionRegionTestCase.java
@@ -32,7 +32,9 @@ import org.hibernate.cache.access.AccessType;
import org.hibernate.cache.infinispan.InfinispanRegionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.cfg.Environment;
+import org.hibernate.service.jta.platform.internal.JtaPlatformInitiator;
import org.hibernate.test.cache.infinispan.util.CacheTestUtil;
+import org.hibernate.testing.ServiceRegistryBuilder;
/**
* Base class for tests of EntityRegion and CollectionRegion implementations.
@@ -65,7 +67,9 @@ public abstract class AbstractEntityCollectionRegionTestCase extends AbstractReg
String entityCfg = "entity";
cfg.setProperty(InfinispanRegionFactory.ENTITY_CACHE_RESOURCE_PROP, entityCfg);
InfinispanRegionFactory regionFactory = CacheTestUtil.startRegionFactory(
- getServiceRegistry(), cfg, getCacheTestSupport()
+ ServiceRegistryBuilder.buildServiceRegistry( cfg.getProperties() ),
+ cfg,
+ getCacheTestSupport()
);
supportedAccessTypeTest(regionFactory, cfg.getProperties());
}
@@ -85,16 +89,20 @@ public abstract class AbstractEntityCollectionRegionTestCase extends AbstractReg
public void testIsTransactionAware() throws Exception {
Configuration cfg = CacheTestUtil.buildConfiguration("test", InfinispanRegionFactory.class, true, false);
InfinispanRegionFactory regionFactory = CacheTestUtil.startRegionFactory(
- getServiceRegistry(), cfg, getCacheTestSupport()
+ ServiceRegistryBuilder.buildServiceRegistry( cfg.getProperties() ),
+ cfg,
+ getCacheTestSupport()
);
TransactionalDataRegion region = (TransactionalDataRegion) createRegion(regionFactory, "test/test", cfg.getProperties(), getCacheDataDescription());
assertTrue("Region is transaction-aware", region.isTransactionAware());
CacheTestUtil.stopRegionFactory(regionFactory, getCacheTestSupport());
cfg = CacheTestUtil.buildConfiguration("test", InfinispanRegionFactory.class, true, false);
// Make it non-transactional
- cfg.getProperties().remove(Environment.TRANSACTION_MANAGER_STRATEGY);
+ cfg.getProperties().remove( JtaPlatformInitiator.JTA_PLATFORM );
regionFactory = CacheTestUtil.startRegionFactory(
- getServiceRegistry(), cfg, getCacheTestSupport()
+ ServiceRegistryBuilder.buildServiceRegistry( cfg.getProperties() ),
+ cfg,
+ getCacheTestSupport()
);
region = (TransactionalDataRegion) createRegion(regionFactory, "test/test", cfg.getProperties(), getCacheDataDescription());
assertFalse("Region is not transaction-aware", region.isTransactionAware());
@@ -104,7 +112,9 @@ public abstract class AbstractEntityCollectionRegionTestCase extends AbstractReg
public void testGetCacheDataDescription() throws Exception {
Configuration cfg = CacheTestUtil.buildConfiguration("test", InfinispanRegionFactory.class, true, false);
InfinispanRegionFactory regionFactory = CacheTestUtil.startRegionFactory(
- getServiceRegistry(), cfg, getCacheTestSupport()
+ ServiceRegistryBuilder.buildServiceRegistry( cfg.getProperties() ),
+ cfg,
+ getCacheTestSupport()
);
TransactionalDataRegion region = (TransactionalDataRegion) createRegion(regionFactory, "test/test", cfg.getProperties(), getCacheDataDescription());
CacheDataDescription cdd = region.getCacheDataDescription();
diff --git a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/collection/AbstractCollectionRegionAccessStrategyTestCase.java b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/collection/AbstractCollectionRegionAccessStrategyTestCase.java
index b92c7456f9..d98f34b3ed 100644
--- a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/collection/AbstractCollectionRegionAccessStrategyTestCase.java
+++ b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/collection/AbstractCollectionRegionAccessStrategyTestCase.java
@@ -43,7 +43,6 @@ import org.hibernate.cache.infinispan.util.CacheAdapter;
import org.hibernate.cache.infinispan.util.FlagAdapter;
import org.hibernate.cfg.Configuration;
import org.hibernate.cfg.Environment;
-import org.hibernate.engine.jdbc.spi.JdbcServices;
import org.hibernate.service.spi.ServiceRegistry;
import org.hibernate.test.cache.infinispan.AbstractNonFunctionalTestCase;
import org.hibernate.test.cache.infinispan.functional.cluster.DualNodeJtaTransactionManagerImpl;
@@ -519,7 +518,9 @@ public abstract class AbstractCollectionRegionAccessStrategyTestCase extends Abs
private final String configResource;
private final String configName;
private String preferIPv4Stack;
- private ServiceRegistry serviceRegistry;
+
+ private ServiceRegistry localServiceRegistry;
+ private ServiceRegistry remoteServiceRegistry;
public AccessStrategyTestSetup(Test test, String configName) {
this(test, configName, null);
@@ -539,16 +540,13 @@ public abstract class AbstractCollectionRegionAccessStrategyTestCase extends Abs
preferIPv4Stack = System.getProperty(PREFER_IPV4STACK);
System.setProperty(PREFER_IPV4STACK, "true");
- serviceRegistry = ServiceRegistryBuilder.buildServiceRegistry( Environment.getProperties() );
+ localCfg = createConfiguration(configName, configResource);
+ localServiceRegistry = ServiceRegistryBuilder.buildServiceRegistry( localCfg.getProperties() );
+ localRegionFactory = CacheTestUtil.startRegionFactory( localServiceRegistry, localCfg );
- localCfg = createConfiguration(configName, configResource);
- localRegionFactory = CacheTestUtil.startRegionFactory( serviceRegistry, localCfg );
-
- remoteCfg = createConfiguration(configName, configResource);
- remoteRegionFactory = CacheTestUtil.startRegionFactory(
- serviceRegistry,
- remoteCfg
- );
+ remoteCfg = createConfiguration(configName, configResource);
+ remoteServiceRegistry = ServiceRegistryBuilder.buildServiceRegistry( remoteCfg.getProperties() );
+ remoteRegionFactory = CacheTestUtil.startRegionFactory( remoteServiceRegistry, remoteCfg );
}
@Override
@@ -570,8 +568,11 @@ public abstract class AbstractCollectionRegionAccessStrategyTestCase extends Abs
remoteRegionFactory.stop();
}
finally {
- if ( serviceRegistry != null ) {
- ServiceRegistryBuilder.destroy( serviceRegistry );
+ if ( localServiceRegistry != null ) {
+ ServiceRegistryBuilder.destroy( localServiceRegistry );
+ }
+ if ( remoteServiceRegistry != null ) {
+ ServiceRegistryBuilder.destroy( remoteServiceRegistry );
}
}
}
diff --git a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/ConcurrentWriteTest.java b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/ConcurrentWriteTest.java
index 9f165aaf11..ddc37bc383 100644
--- a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/ConcurrentWriteTest.java
+++ b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/ConcurrentWriteTest.java
@@ -47,12 +47,12 @@ import org.hibernate.cache.RegionFactory;
import org.hibernate.cache.infinispan.InfinispanRegionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.jdbc.connections.spi.ConnectionProvider;
+import org.hibernate.service.jta.platform.spi.JtaPlatform;
import org.hibernate.stat.SecondLevelCacheStatistics;
+import org.hibernate.test.cache.infinispan.functional.cluster.DualNodeJtaPlatformImpl;
import org.hibernate.test.cache.infinispan.functional.cluster.DualNodeTestCase;
import org.hibernate.test.cache.infinispan.functional.cluster.DualNodeConnectionProviderImpl;
import org.hibernate.test.cache.infinispan.functional.cluster.DualNodeJtaTransactionManagerImpl;
-import org.hibernate.test.cache.infinispan.functional.cluster.DualNodeTransactionManagerLookup;
-import org.hibernate.transaction.TransactionManagerLookup;
import org.infinispan.util.logging.Log;
import org.infinispan.util.logging.LogFactory;
@@ -104,12 +104,12 @@ public class ConcurrentWriteTest extends SingleNodeTestCase {
return DualNodeConnectionProviderImpl.class;
}
- @Override
- protected Class extends TransactionManagerLookup> getTransactionManagerLookupClass() {
- return DualNodeTransactionManagerLookup.class;
- }
+ @Override
+ protected Class extends JtaPlatform> getJtaPlatform() {
+ return DualNodeJtaPlatformImpl.class;
+ }
- /**
+ /**
* test that DB can be queried
*
* @throws java.lang.Exception
diff --git a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/SingleNodeTestCase.java b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/SingleNodeTestCase.java
index e692ac149c..2764c14ea6 100644
--- a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/SingleNodeTestCase.java
+++ b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/SingleNodeTestCase.java
@@ -9,9 +9,11 @@ import org.hibernate.cfg.Configuration;
import org.hibernate.cfg.Environment;
import org.hibernate.engine.transaction.spi.TransactionFactory;
import org.hibernate.service.jdbc.connections.spi.ConnectionProvider;
+import org.hibernate.service.jta.platform.internal.JtaPlatformInitiator;
+import org.hibernate.service.jta.platform.spi.JtaPlatform;
+import org.hibernate.test.cache.infinispan.tm.JtaPlatformImpl;
import org.hibernate.testing.junit.functional.FunctionalTestCase;
import org.hibernate.engine.transaction.internal.jta.CMTTransactionFactory;
-import org.hibernate.transaction.TransactionManagerLookup;
import org.infinispan.util.logging.Log;
import org.infinispan.util.logging.LogFactory;
@@ -28,19 +30,22 @@ public abstract class SingleNodeTestCase extends FunctionalTestCase {
tm = getTransactionManager();
}
- protected TransactionManager getTransactionManager() {
- try {
- if (getTransactionManagerLookupClass() == null)
- return null;
- else
- return getTransactionManagerLookupClass().newInstance().getTransactionManager(null);
- } catch (Exception e) {
- log.error("Error", e);
- throw new RuntimeException(e);
- }
- }
+ protected TransactionManager getTransactionManager() {
+ try {
+ Class extends JtaPlatform> jtaPlatformClass = getJtaPlatform();
+ if ( jtaPlatformClass == null ) {
+ return null;
+ }
+ else {
+ return jtaPlatformClass.newInstance().retrieveTransactionManager();
+ }
+ }
+ catch (Exception e) {
+ log.error("Error", e);
+ throw new RuntimeException(e);
+ }
+ }
-
public String[] getMappings() {
return new String[] {
"cache/infinispan/functional/Item.hbm.xml",
@@ -65,9 +70,9 @@ public abstract class SingleNodeTestCase extends FunctionalTestCase {
return org.hibernate.test.cache.infinispan.tm.XaConnectionProvider.class;
}
- protected Class extends TransactionManagerLookup> getTransactionManagerLookupClass() {
- return org.hibernate.test.cache.infinispan.tm.XaTransactionManagerLookup.class;
- }
+ protected Class extends JtaPlatform> getJtaPlatform() {
+ return JtaPlatformImpl.class;
+ }
protected boolean getUseQueryCache() {
return true;
@@ -79,11 +84,12 @@ public abstract class SingleNodeTestCase extends FunctionalTestCase {
cfg.setProperty(Environment.GENERATE_STATISTICS, "true");
cfg.setProperty(Environment.USE_QUERY_CACHE, String.valueOf(getUseQueryCache()));
cfg.setProperty(Environment.CACHE_REGION_FACTORY, getCacheRegionFactory().getName());
- cfg.setProperty(Environment.CONNECTION_PROVIDER, getConnectionProviderClass().getName());
- if (getTransactionManagerLookupClass() != null) {
- cfg.setProperty(Environment.TRANSACTION_MANAGER_STRATEGY, getTransactionManagerLookupClass().getName());
- }
- cfg.setProperty(Environment.TRANSACTION_STRATEGY, getTransactionFactoryClass().getName());
+
+ if ( getJtaPlatform() != null ) {
+ cfg.getProperties().put( JtaPlatformInitiator.JTA_PLATFORM, getJtaPlatform() );
+ }
+ cfg.setProperty( Environment.TRANSACTION_STRATEGY, getTransactionFactoryClass().getName() );
+ cfg.setProperty( Environment.CONNECTION_PROVIDER, getConnectionProviderClass().getName() );
}
protected void beginTx() throws Exception {
diff --git a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/bulk/BulkOperationsTestCase.java b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/bulk/BulkOperationsTestCase.java
index 1f11835053..344f626ef2 100644
--- a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/bulk/BulkOperationsTestCase.java
+++ b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/bulk/BulkOperationsTestCase.java
@@ -37,11 +37,13 @@ import org.hibernate.classic.Session;
import org.hibernate.engine.transaction.internal.jta.CMTTransactionFactory;
import org.hibernate.engine.transaction.spi.TransactionFactory;
import org.hibernate.service.jdbc.connections.spi.ConnectionProvider;
+import org.hibernate.service.jta.platform.internal.JtaPlatformInitiator;
+import org.hibernate.service.jta.platform.spi.JtaPlatform;
+import org.hibernate.test.cache.infinispan.tm.JtaPlatformImpl;
import org.hibernate.testing.junit.functional.FunctionalTestCase;
import org.hibernate.stat.SecondLevelCacheStatistics;
import org.hibernate.test.cache.infinispan.functional.Contact;
import org.hibernate.test.cache.infinispan.functional.Customer;
-import org.hibernate.transaction.TransactionManagerLookup;
import org.infinispan.util.logging.Log;
import org.infinispan.util.logging.LogFactory;
@@ -82,9 +84,9 @@ public class BulkOperationsTestCase extends FunctionalTestCase {
return org.hibernate.test.cache.infinispan.tm.XaConnectionProvider.class;
}
- protected Class extends TransactionManagerLookup> getTransactionManagerLookupClass() {
- return org.hibernate.test.cache.infinispan.tm.XaTransactionManagerLookup.class;
- }
+ protected JtaPlatform getJtaPlatform() {
+ return new JtaPlatformImpl();
+ }
public void configure(Configuration cfg) {
super.configure(cfg);
@@ -92,16 +94,16 @@ public class BulkOperationsTestCase extends FunctionalTestCase {
cfg.setProperty(Environment.GENERATE_STATISTICS, "true");
cfg.setProperty(Environment.USE_QUERY_CACHE, "false");
cfg.setProperty(Environment.CACHE_REGION_FACTORY, getCacheRegionFactory().getName());
- cfg.setProperty(Environment.CONNECTION_PROVIDER, getConnectionProviderClass().getName());
- cfg.setProperty(Environment.TRANSACTION_MANAGER_STRATEGY, getTransactionManagerLookupClass().getName());
cfg.setProperty(Environment.TRANSACTION_STRATEGY, getTransactionFactoryClass().getName());
+ cfg.getProperties().put( JtaPlatformInitiator.JTA_PLATFORM, getJtaPlatform() );
+ cfg.setProperty(Environment.CONNECTION_PROVIDER, getConnectionProviderClass().getName());
}
public void testBulkOperations() throws Throwable {
log.info("*** testBulkOperations()");
boolean cleanedUp = false;
try {
- tm = getTransactionManagerLookupClass().newInstance().getTransactionManager(null);
+ tm = getJtaPlatform().retrieveTransactionManager();
createContacts();
diff --git a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/cluster/DualNodeJtaPlatformImpl.java b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/cluster/DualNodeJtaPlatformImpl.java
new file mode 100644
index 0000000000..b376ef8148
--- /dev/null
+++ b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/cluster/DualNodeJtaPlatformImpl.java
@@ -0,0 +1,87 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2011, 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
+ */
+package org.hibernate.test.cache.infinispan.functional.cluster;
+
+import org.hibernate.HibernateException;
+import org.hibernate.TransactionException;
+import org.hibernate.engine.transaction.internal.jta.JtaStatusHelper;
+import org.hibernate.service.jta.platform.spi.JtaPlatform;
+import org.hibernate.service.spi.Configurable;
+
+import javax.transaction.Synchronization;
+import javax.transaction.SystemException;
+import javax.transaction.Transaction;
+import javax.transaction.TransactionManager;
+import javax.transaction.UserTransaction;
+import java.util.Map;
+
+/**
+ * @author Steve Ebersole
+ */
+public class DualNodeJtaPlatformImpl implements JtaPlatform, Configurable {
+ private String nodeId;
+
+ @Override
+ public void configure(Map configurationValues) {
+ nodeId = (String) configurationValues.get( DualNodeTestCase.NODE_ID_PROP );
+ if ( nodeId == null ) {
+ throw new HibernateException(DualNodeTestCase.NODE_ID_PROP + " not configured");
+ }
+ }
+
+ @Override
+ public TransactionManager retrieveTransactionManager() {
+ return DualNodeJtaTransactionManagerImpl.getInstance( nodeId );
+ }
+
+ @Override
+ public UserTransaction retrieveUserTransaction() {
+ throw new TransactionException( "UserTransaction not used in these tests" );
+ }
+
+ @Override
+ public Object getTransactionIdentifier(Transaction transaction) {
+ return transaction;
+ }
+
+ @Override
+ public boolean canRegisterSynchronization() {
+ return JtaStatusHelper.isActive( retrieveTransactionManager() );
+ }
+
+ @Override
+ public void registerSynchronization(Synchronization synchronization) {
+ try {
+ retrieveTransactionManager().getTransaction().registerSynchronization( synchronization );
+ }
+ catch (Exception e) {
+ throw new TransactionException( "Could not obtain transaction from TM" );
+ }
+ }
+
+ @Override
+ public int getCurrentStatus() throws SystemException {
+ return JtaStatusHelper.getStatus( retrieveTransactionManager() );
+ }
+}
diff --git a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/cluster/DualNodeTestCase.java b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/cluster/DualNodeTestCase.java
index 2aa7b0c741..773901e536 100644
--- a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/cluster/DualNodeTestCase.java
+++ b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/cluster/DualNodeTestCase.java
@@ -31,6 +31,7 @@ import org.hibernate.cfg.Mappings;
import org.hibernate.dialect.Dialect;
import org.hibernate.engine.SessionFactoryImplementor;
import org.hibernate.engine.transaction.internal.jta.CMTTransactionFactory;
+import org.hibernate.service.jta.platform.internal.JtaPlatformInitiator;
import org.hibernate.testing.junit.functional.ExecutionEnvironment;
import org.hibernate.testing.junit.functional.FunctionalTestCase;
@@ -134,20 +135,14 @@ public abstract class DualNodeTestCase extends FunctionalTestCase {
return DualNodeConnectionProviderImpl.class;
}
- protected Class getTransactionManagerLookupClass() {
- return DualNodeTransactionManagerLookup.class;
+ protected Class getJtaPlatformClass() {
+ return DualNodeJtaPlatformImpl.class;
}
protected Class getTransactionFactoryClass() {
return CMTTransactionFactory.class;
}
- /**
- * Apply any node-specific configurations to our first node.
- *
- * @param the
- * Configuration to update.
- */
protected void configureFirstNode(Configuration cfg) {
cfg.setProperty(NODE_ID_PROP, LOCAL);
}
@@ -156,12 +151,6 @@ public abstract class DualNodeTestCase extends FunctionalTestCase {
return Collections.singletonMap( NODE_ID_FIELD, LOCAL );
}
- /**
- * Apply any node-specific configurations to our second node.
- *
- * @param the
- * Configuration to update.
- */
protected void configureSecondNode(Configuration cfg) {
cfg.setProperty(NODE_ID_PROP, REMOTE);
}
@@ -187,7 +176,7 @@ public abstract class DualNodeTestCase extends FunctionalTestCase {
super.configure(cfg);
cfg.setProperty(Environment.CONNECTION_PROVIDER, getConnectionProviderClass().getName());
- cfg.setProperty(Environment.TRANSACTION_MANAGER_STRATEGY, getTransactionManagerLookupClass().getName());
+ cfg.setProperty( JtaPlatformInitiator.JTA_PLATFORM, getJtaPlatformClass().getName());
cfg.setProperty(Environment.TRANSACTION_STRATEGY, getTransactionFactoryClass().getName());
cfg.setProperty(Environment.CACHE_REGION_FACTORY, getCacheRegionFactory().getName());
cfg.setProperty(Environment.USE_QUERY_CACHE, String.valueOf(getUseQueryCache()));
diff --git a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/tm/JtaPlatformImpl.java b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/tm/JtaPlatformImpl.java
new file mode 100644
index 0000000000..265b052497
--- /dev/null
+++ b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/tm/JtaPlatformImpl.java
@@ -0,0 +1,74 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2011, 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
+ */
+package org.hibernate.test.cache.infinispan.tm;
+
+import org.hibernate.TransactionException;
+import org.hibernate.engine.transaction.internal.jta.JtaStatusHelper;
+import org.hibernate.service.jta.platform.spi.JtaPlatform;
+
+import javax.transaction.Synchronization;
+import javax.transaction.SystemException;
+import javax.transaction.Transaction;
+import javax.transaction.TransactionManager;
+import javax.transaction.UserTransaction;
+
+/**
+ * @author Steve Ebersole
+ */
+public class JtaPlatformImpl implements JtaPlatform {
+ @Override
+ public TransactionManager retrieveTransactionManager() {
+ return XaTransactionManagerImpl.getInstance();
+ }
+
+ @Override
+ public UserTransaction retrieveUserTransaction() {
+ throw new TransactionException( "UserTransaction not used in these tests" );
+ }
+
+ @Override
+ public Object getTransactionIdentifier(Transaction transaction) {
+ return transaction;
+ }
+
+ @Override
+ public boolean canRegisterSynchronization() {
+ return JtaStatusHelper.isActive( XaTransactionManagerImpl.getInstance() );
+ }
+
+ @Override
+ public void registerSynchronization(Synchronization synchronization) {
+ try {
+ XaTransactionManagerImpl.getInstance().getTransaction().registerSynchronization( synchronization );
+ }
+ catch (Exception e) {
+ throw new TransactionException( "Could not obtain transaction from TM" );
+ }
+ }
+
+ @Override
+ public int getCurrentStatus() throws SystemException {
+ return JtaStatusHelper.getStatus( XaTransactionManagerImpl.getInstance() );
+ }
+}
diff --git a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/tm/XaTransactionManagerLookup.java b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/tm/XaTransactionManagerLookup.java
deleted file mode 100644
index e6e2e5c3fb..0000000000
--- a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/tm/XaTransactionManagerLookup.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2009, Red Hat, Inc. and/or it's affiliates, and individual contributors
- * as indicated by the @author tags. See the copyright.txt file in the
- * distribution for a full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software 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 software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.hibernate.test.cache.infinispan.tm;
-
-import java.util.Properties;
-
-import javax.transaction.Transaction;
-import javax.transaction.TransactionManager;
-
-import org.hibernate.HibernateException;
-import org.hibernate.transaction.TransactionManagerLookup;
-
-/**
- * XaResourceCapableTransactionManagerLookup.
- *
- * @author Galder ZamarreƱo
- * @since 3.5
- */
-public class XaTransactionManagerLookup implements TransactionManagerLookup {
-
- public Object getTransactionIdentifier(Transaction transaction) {
- return transaction;
- }
-
- public TransactionManager getTransactionManager(Properties props) throws HibernateException {
- return XaTransactionManagerImpl.getInstance();
- }
-
- public String getUserTransactionName() {
- throw new UnsupportedOperationException( "jndi currently not implemented for these tests" );
- }
-
-}
diff --git a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/util/BatchModeJtaPlatform.java b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/util/BatchModeJtaPlatform.java
new file mode 100644
index 0000000000..a5daab66c8
--- /dev/null
+++ b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/util/BatchModeJtaPlatform.java
@@ -0,0 +1,82 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2011, 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
+ */
+package org.hibernate.test.cache.infinispan.util;
+
+import org.infinispan.transaction.tm.BatchModeTransactionManager;
+
+import org.hibernate.HibernateException;
+import org.hibernate.TransactionException;
+import org.hibernate.engine.transaction.internal.jta.JtaStatusHelper;
+import org.hibernate.service.jta.platform.spi.JtaPlatform;
+
+import javax.transaction.Synchronization;
+import javax.transaction.SystemException;
+import javax.transaction.Transaction;
+import javax.transaction.TransactionManager;
+import javax.transaction.UserTransaction;
+
+/**
+ * @author Steve Ebersole
+ */
+public class BatchModeJtaPlatform implements JtaPlatform {
+ @Override
+ public TransactionManager retrieveTransactionManager() {
+ try {
+ return BatchModeTransactionManager.getInstance();
+ }
+ catch (Exception e) {
+ throw new HibernateException("Failed getting BatchModeTransactionManager", e);
+ }
+ }
+
+ @Override
+ public UserTransaction retrieveUserTransaction() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Object getTransactionIdentifier(Transaction transaction) {
+ return transaction;
+ }
+
+ @Override
+ public boolean canRegisterSynchronization() {
+ return JtaStatusHelper.isActive( retrieveTransactionManager() );
+ }
+
+ @Override
+ public void registerSynchronization(Synchronization synchronization) {
+ try {
+ retrieveTransactionManager().getTransaction().registerSynchronization( synchronization );
+ }
+ catch (Exception e) {
+ throw new TransactionException( "Could not obtain transaction from TM" );
+ }
+ }
+
+ @Override
+ public int getCurrentStatus() throws SystemException {
+ return JtaStatusHelper.getStatus( retrieveTransactionManager() );
+ }
+}
diff --git a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/util/CacheTestUtil.java b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/util/CacheTestUtil.java
index d53b95e9d1..0d4ee1202a 100644
--- a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/util/CacheTestUtil.java
+++ b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/util/CacheTestUtil.java
@@ -37,6 +37,7 @@ import org.hibernate.cfg.Configuration;
import org.hibernate.cfg.Environment;
import org.hibernate.cfg.Settings;
import org.hibernate.engine.jdbc.spi.JdbcServices;
+import org.hibernate.service.jta.platform.internal.JtaPlatformInitiator;
import org.hibernate.service.spi.ServiceRegistry;
/**
@@ -50,7 +51,7 @@ public class CacheTestUtil {
Configuration cfg = new Configuration();
cfg.setProperty(Environment.GENERATE_STATISTICS, "true");
cfg.setProperty(Environment.USE_STRUCTURED_CACHE, "true");
- cfg.setProperty(Environment.TRANSACTION_MANAGER_STRATEGY, BatchModeTransactionManagerLookup.class.getName());
+ cfg.setProperty( JtaPlatformInitiator.JTA_PLATFORM, BatchModeJtaPlatform.class.getName() );
cfg.setProperty(Environment.CACHE_REGION_FACTORY, regionFactory.getName());
cfg.setProperty(Environment.CACHE_REGION_PREFIX, regionPrefix);
From 818987751e31fe8408d88291e5a3e119710a64c4 Mon Sep 17 00:00:00 2001
From: "David M. Carr"
Date: Thu, 24 Feb 2011 17:14:08 -0500
Subject: [PATCH 07/19] HHH-5977 Add a couple additional unit tests for when
you use a @JoinColumn with a secondary table specified.
---
.../annotations/manytoone/ManyToOneTest.java | 20 +++++++++++++++
.../test/annotations/manytoone/OrderLine.java | 13 ++++++++++
.../test/annotations/onetoone/Client.java | 13 ++++++++++
.../annotations/onetoone/OneToOneTest.java | 25 +++++++++++++++++++
4 files changed, 71 insertions(+)
diff --git a/hibernate-core/src/test/java/org/hibernate/test/annotations/manytoone/ManyToOneTest.java b/hibernate-core/src/test/java/org/hibernate/test/annotations/manytoone/ManyToOneTest.java
index f99a403405..de749ad461 100644
--- a/hibernate-core/src/test/java/org/hibernate/test/annotations/manytoone/ManyToOneTest.java
+++ b/hibernate-core/src/test/java/org/hibernate/test/annotations/manytoone/ManyToOneTest.java
@@ -269,6 +269,26 @@ public class ManyToOneTest extends TestCase {
s.close();
}
+ public void testManyToOneNonPkSecondaryTable() throws Exception {
+ Session s = openSession();
+ Transaction tx = s.beginTransaction();
+ Order order = new Order();
+ order.setOrderNbr( "123" );
+ s.persist( order );
+ OrderLine ol = new OrderLine();
+ ol.setItem( "Mouse" );
+ ol.setReplacementOrder( order );
+ s.persist( ol );
+ s.flush();
+ s.clear();
+ ol = (OrderLine) s.get( OrderLine.class, ol.getId() );
+ assertNotNull( ol.getReplacementOrder() );
+ assertEquals( "123", ol.getReplacementOrder().getOrderNbr() );
+ assertFalse( ol.getReplacementOrder().getOrderLines().contains( ol ) );
+ tx.rollback();
+ s.close();
+ }
+
public void testTwoManyToOneNonPk() throws Exception {
//2 many to one non pk pointing to the same referencedColumnName should not fail
Session s = openSession();
diff --git a/hibernate-core/src/test/java/org/hibernate/test/annotations/manytoone/OrderLine.java b/hibernate-core/src/test/java/org/hibernate/test/annotations/manytoone/OrderLine.java
index 22fc79374c..1b8ed9517a 100644
--- a/hibernate-core/src/test/java/org/hibernate/test/annotations/manytoone/OrderLine.java
+++ b/hibernate-core/src/test/java/org/hibernate/test/annotations/manytoone/OrderLine.java
@@ -6,15 +6,18 @@ import javax.persistence.Id;
import javax.persistence.GeneratedValue;
import javax.persistence.ManyToOne;
import javax.persistence.JoinColumn;
+import javax.persistence.SecondaryTable;
/**
* @author Emmanuel Bernard
*/
@Entity
+@SecondaryTable(name="OrderLine_Extension")
public class OrderLine {
private Integer id;
private String item;
private Order order;
+ private Order replacementOrder;
@Id @GeneratedValue
public Integer getId() {
@@ -42,4 +45,14 @@ public class OrderLine {
public void setOrder(Order order) {
this.order = order;
}
+
+ @ManyToOne
+ @JoinColumn(name="replacement_order_nbr", table="OrderLine_Extension", referencedColumnName = "order_nbr")
+ public Order getReplacementOrder() {
+ return replacementOrder;
+ }
+
+ public void setReplacementOrder(Order replacementOrder) {
+ this.replacementOrder = replacementOrder;
+ }
}
diff --git a/hibernate-core/src/test/java/org/hibernate/test/annotations/onetoone/Client.java b/hibernate-core/src/test/java/org/hibernate/test/annotations/onetoone/Client.java
index 44c0a2b456..79c64c1c00 100644
--- a/hibernate-core/src/test/java/org/hibernate/test/annotations/onetoone/Client.java
+++ b/hibernate-core/src/test/java/org/hibernate/test/annotations/onetoone/Client.java
@@ -7,16 +7,19 @@ import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
+import javax.persistence.SecondaryTable;
/**
* @author Emmanuel Bernard
*/
@Entity
+@SecondaryTable(name="CLIENT_EXTENSION")
public class Client {
private Integer id;
private String name;
private Address address;
+ private Address secondaryAddress;
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "ADDRESS_ID")
@@ -28,6 +31,16 @@ public class Client {
this.address = address;
}
+ @OneToOne(cascade = CascadeType.ALL)
+ @JoinColumn(name = "SECONDARY_ADDRESS_ID", table="CLIENT_EXTENSION")
+ public Address getSecondaryAddress() {
+ return secondaryAddress;
+ }
+
+ public void setSecondaryAddress(Address secondaryAddress) {
+ this.secondaryAddress = secondaryAddress;
+ }
+
@Id
@GeneratedValue
public Integer getId() {
diff --git a/hibernate-core/src/test/java/org/hibernate/test/annotations/onetoone/OneToOneTest.java b/hibernate-core/src/test/java/org/hibernate/test/annotations/onetoone/OneToOneTest.java
index a47bb96a90..7a97a0df75 100644
--- a/hibernate-core/src/test/java/org/hibernate/test/annotations/onetoone/OneToOneTest.java
+++ b/hibernate-core/src/test/java/org/hibernate/test/annotations/onetoone/OneToOneTest.java
@@ -108,6 +108,31 @@ public class OneToOneTest extends TestCase {
s.close();
}
+ public void testOneToOneWithExplicitSecondaryTableFk() throws Exception {
+ Client c = new Client();
+ Address a = new Address();
+ a.setCity( "Paris" );
+ c.setName( "Emmanuel" );
+ c.setSecondaryAddress( a );
+
+ Session s;
+ Transaction tx;
+ s = openSession();
+ tx = s.beginTransaction();
+ s.persist( c );
+ tx.commit();
+ s.close();
+
+ s = openSession();
+ tx = s.beginTransaction();
+ c = ( Client ) s.get( Client.class, c.getId() );
+ assertNotNull( c );
+ assertNotNull( c.getSecondaryAddress() );
+ assertEquals( "Paris", c.getSecondaryAddress().getCity() );
+ tx.commit();
+ s.close();
+ }
+
public void testUnidirectionalTrueOneToOne() throws Exception {
Body b = new Body();
Heart h = new Heart();
From 48c4db0b579ddd7966bf85b0a90cffcab3fb29c1 Mon Sep 17 00:00:00 2001
From: Strong Liu
Date: Fri, 4 Mar 2011 23:15:05 +0800
Subject: [PATCH 08/19] HHH-5707 Deprecated
DomainObjectCollection.allObjects(), TaskCollection.allTasks() and
PluginCollection.allPlugins(). These are replaced by
DomainObjectCollection.all().
---
.../hibernate/build/gradle/upload/AuthenticationHandler.java | 2 +-
.../build/gradle/upload/UploadAuthenticationManager.java | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/buildSrc/src/main/java/org/hibernate/build/gradle/upload/AuthenticationHandler.java b/buildSrc/src/main/java/org/hibernate/build/gradle/upload/AuthenticationHandler.java
index c9e0202443..955caf39d2 100644
--- a/buildSrc/src/main/java/org/hibernate/build/gradle/upload/AuthenticationHandler.java
+++ b/buildSrc/src/main/java/org/hibernate/build/gradle/upload/AuthenticationHandler.java
@@ -53,7 +53,7 @@ public class AuthenticationHandler extends DefaultTask {
@TaskAction
public void configureUploadAuthentication() {
// todo : unfortunately I have no idea how to apply this to non MavenDeployer-type repos...
- uploadTask.getRepositories().withType( MavenDeployer.class ).allObjects(
+ uploadTask.getRepositories().withType( MavenDeployer.class ).all(
new Action() {
public void execute(MavenDeployer deployer) {
final RemoteRepository repository = deployer.getRepository();
diff --git a/buildSrc/src/main/java/org/hibernate/build/gradle/upload/UploadAuthenticationManager.java b/buildSrc/src/main/java/org/hibernate/build/gradle/upload/UploadAuthenticationManager.java
index 73d29a1c10..2c8909fece 100644
--- a/buildSrc/src/main/java/org/hibernate/build/gradle/upload/UploadAuthenticationManager.java
+++ b/buildSrc/src/main/java/org/hibernate/build/gradle/upload/UploadAuthenticationManager.java
@@ -43,7 +43,7 @@ public class UploadAuthenticationManager implements Plugin {
// code for just that.
final AuthenticationProviderRegistry registry = new AuthenticationProviderRegistry();
- project.getTasks().withType( Upload.class ).allTasks(
+ project.getTasks().withType( Upload.class ).all(
new Action() {
@Override
public void execute(final Upload uploadTask) {
From 4f4f374daefc1c3d0901db542f157ec7192ce846 Mon Sep 17 00:00:00 2001
From: Steve Ebersole
Date: Fri, 4 Mar 2011 12:43:43 -0600
Subject: [PATCH 09/19] HHH-5981 - Clarify Session.disconnect() and
Session.reconnect() behavior
---
.../src/main/java/org/hibernate/Session.java | 36 +++++------------
.../jdbc/internal/LogicalConnectionImpl.java | 31 +++++++-------
.../hibernate/impl/AbstractSessionImpl.java | 3 +-
.../java/org/hibernate/impl/SessionImpl.java | 9 +----
.../connections/AggressiveReleaseTest.java | 2 +-
.../BasicConnectionProviderTest.java | 1 -
.../ConnectionManagementTestCase.java | 20 ++++++----
.../ThreadLocalCurrentSessionTest.java | 7 +++-
.../org/hibernate/test/legacy/FooBarTest.java | 40 +------------------
.../org/hibernate/test/legacy/FumTest.java | 35 +++++++++-------
.../org/hibernate/test/proxy/ProxyTest.java | 1 -
.../java/org/hibernate/test/tm/CMTTest.java | 18 +--------
12 files changed, 70 insertions(+), 133 deletions(-)
diff --git a/hibernate-core/src/main/java/org/hibernate/Session.java b/hibernate-core/src/main/java/org/hibernate/Session.java
index 003c55764f..5e3249da30 100644
--- a/hibernate-core/src/main/java/org/hibernate/Session.java
+++ b/hibernate-core/src/main/java/org/hibernate/Session.java
@@ -920,39 +920,25 @@ public interface Session extends Serializable {
public void doWork(Work work) throws HibernateException;
/**
- * Disconnect the Session from the current JDBC connection. If
- * the connection was obtained by Hibernate close it and return it to
- * the connection pool; otherwise, return it to the application.
+ * Disconnect the session from its underlying JDBC connection. This is intended for use in cases where the
+ * application has supplied the JDBC connection to the session and which require long-sessions (aka, conversations).
*
- * This is used by applications which supply JDBC connections to Hibernate
- * and which require long-sessions (or long-conversations)
+ * It is considered an error to call this method on a session which was not opened by supplying the JDBC connection
+ * and an exception will be thrown.
*
- * Note that disconnect() called on a session where the connection was
- * retrieved by Hibernate through its configured
- * {@link org.hibernate.service.jdbc.connections.spi.ConnectionProvider} has no effect,
- * provided {@link ConnectionReleaseMode#ON_CLOSE} is not in effect.
+ * For non-user-supplied scenarios, normal transaction management already handles disconnection and reconnection
+ * automatically.
*
- * @return the application-supplied connection or null
+ * @return the application-supplied connection or {@literal null}
+ *
+ * @see SessionFactory#openSession(java.sql.Connection)
+ * @see SessionFactory#openSession(java.sql.Connection, Interceptor)
* @see #reconnect(Connection)
- * @see #reconnect()
*/
Connection disconnect() throws HibernateException;
/**
- * Obtain a new JDBC connection. This is used by applications which
- * require long transactions and do not supply connections to the
- * session.
- *
- * @see #disconnect()
- * @deprecated Manual reconnection is only needed in the case of
- * application-supplied connections, in which case the
- * {@link #reconnect(java.sql.Connection)} for should be used.
- */
- void reconnect() throws HibernateException;
-
- /**
- * Reconnect to the given JDBC connection. This is used by applications
- * which require long transactions and use application-supplied connections.
+ * Reconnect to the given JDBC connection.
*
* @param connection a JDBC connection
* @see #disconnect()
diff --git a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/internal/LogicalConnectionImpl.java b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/internal/LogicalConnectionImpl.java
index 25a5c208f2..1b1d94f836 100644
--- a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/internal/LogicalConnectionImpl.java
+++ b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/internal/LogicalConnectionImpl.java
@@ -331,6 +331,15 @@ public class LogicalConnectionImpl implements LogicalConnectionImplementor {
releaseNonDurableObservers();
}
+ private void releaseNonDurableObservers() {
+ Iterator observers = this.observers.iterator();
+ while ( observers.hasNext() ) {
+ if ( NonDurableConnectionObserver.class.isInstance( observers.next() ) ) {
+ observers.remove();
+ }
+ }
+ }
+
@Override
public Connection manualDisconnect() {
if ( isClosed ) {
@@ -343,26 +352,20 @@ public class LogicalConnectionImpl implements LogicalConnectionImplementor {
return c;
}
- private void releaseNonDurableObservers() {
- Iterator observers = this.observers.iterator();
- while ( observers.hasNext() ) {
- if ( NonDurableConnectionObserver.class.isInstance( observers.next() ) ) {
- observers.remove();
- }
- }
- }
-
@Override
public void manualReconnect(Connection suppliedConnection) {
if ( isClosed ) {
throw new IllegalStateException( "cannot manually reconnect because logical connection is already closed" );
}
- if ( isUserSuppliedConnection ) {
+ if ( !isUserSuppliedConnection ) {
+ throw new IllegalStateException( "cannot manually reconnect unless Connection was originally supplied" );
+ }
+ else {
if ( suppliedConnection == null ) {
throw new IllegalArgumentException( "cannot reconnect a null user-supplied connection" );
}
else if ( suppliedConnection == physicalConnection ) {
- log.warn( "reconnecting the same connection that is already connected; should this connection have been disconnected?" );
+ log.debug( "reconnecting the same connection that is already connected; should this connection have been disconnected?" );
}
else if ( physicalConnection != null ) {
throw new IllegalArgumentException(
@@ -372,12 +375,6 @@ public class LogicalConnectionImpl implements LogicalConnectionImplementor {
physicalConnection = suppliedConnection;
log.debug( "reconnected JDBC connection" );
}
- else {
- if ( suppliedConnection != null ) {
- throw new IllegalStateException( "unexpected user-supplied connection" );
- }
- log.debug( "called reconnect() with null connection (not user-supplied)" );
- }
}
@Override
diff --git a/hibernate-core/src/main/java/org/hibernate/impl/AbstractSessionImpl.java b/hibernate-core/src/main/java/org/hibernate/impl/AbstractSessionImpl.java
index bc017b1a27..b2e9861415 100755
--- a/hibernate-core/src/main/java/org/hibernate/impl/AbstractSessionImpl.java
+++ b/hibernate-core/src/main/java/org/hibernate/impl/AbstractSessionImpl.java
@@ -41,6 +41,7 @@ import org.hibernate.engine.query.NativeSQLQueryPlan;
import org.hibernate.engine.transaction.spi.TransactionContext;
import org.hibernate.engine.transaction.spi.TransactionEnvironment;
+import java.io.Serializable;
import java.util.List;
/**
@@ -48,7 +49,7 @@ import java.util.List;
*
* @author Gavin King
*/
-public abstract class AbstractSessionImpl implements SessionImplementor, TransactionContext {
+public abstract class AbstractSessionImpl implements Serializable, SessionImplementor, TransactionContext {
protected transient SessionFactoryImpl factory;
private boolean closed = false;
diff --git a/hibernate-core/src/main/java/org/hibernate/impl/SessionImpl.java b/hibernate-core/src/main/java/org/hibernate/impl/SessionImpl.java
index 32749877d2..5e05492bc8 100644
--- a/hibernate-core/src/main/java/org/hibernate/impl/SessionImpl.java
+++ b/hibernate-core/src/main/java/org/hibernate/impl/SessionImpl.java
@@ -544,19 +544,14 @@ public final class SessionImpl
return !isClosed() && transactionCoordinator.isTransactionInProgress();
}
+ @Override
public Connection disconnect() throws HibernateException {
errorIfClosed();
log.debug( "disconnecting session" );
return transactionCoordinator.getJdbcCoordinator().getLogicalConnection().manualDisconnect();
}
- public void reconnect() throws HibernateException {
- errorIfClosed();
- log.debug( "reconnecting session" );
- checkTransactionSynchStatus();
- transactionCoordinator.getJdbcCoordinator().getLogicalConnection().manualReconnect( null );
- }
-
+ @Override
public void reconnect(Connection conn) throws HibernateException {
errorIfClosed();
log.debug( "reconnecting session" );
diff --git a/hibernate-core/src/test/java/org/hibernate/test/connections/AggressiveReleaseTest.java b/hibernate-core/src/test/java/org/hibernate/test/connections/AggressiveReleaseTest.java
index a5bb35f5c1..80b7805554 100644
--- a/hibernate-core/src/test/java/org/hibernate/test/connections/AggressiveReleaseTest.java
+++ b/hibernate-core/src/test/java/org/hibernate/test/connections/AggressiveReleaseTest.java
@@ -53,8 +53,8 @@ public class AggressiveReleaseTest extends ConnectionManagementTestCase {
return openSession();
}
+ @Override
protected void reconnect(Session session) {
- session.reconnect();
}
protected void prepare() throws Throwable {
diff --git a/hibernate-core/src/test/java/org/hibernate/test/connections/BasicConnectionProviderTest.java b/hibernate-core/src/test/java/org/hibernate/test/connections/BasicConnectionProviderTest.java
index 82d1795ada..88091760df 100644
--- a/hibernate-core/src/test/java/org/hibernate/test/connections/BasicConnectionProviderTest.java
+++ b/hibernate-core/src/test/java/org/hibernate/test/connections/BasicConnectionProviderTest.java
@@ -29,7 +29,6 @@ public class BasicConnectionProviderTest extends ConnectionManagementTestCase {
}
protected void reconnect(Session session) {
- session.reconnect();
}
public void configure(Configuration cfg) {
diff --git a/hibernate-core/src/test/java/org/hibernate/test/connections/ConnectionManagementTestCase.java b/hibernate-core/src/test/java/org/hibernate/test/connections/ConnectionManagementTestCase.java
index 4f6387169a..28c4300e7c 100644
--- a/hibernate-core/src/test/java/org/hibernate/test/connections/ConnectionManagementTestCase.java
+++ b/hibernate-core/src/test/java/org/hibernate/test/connections/ConnectionManagementTestCase.java
@@ -75,6 +75,10 @@ public abstract class ConnectionManagementTestCase extends FunctionalTestCase {
}
}
+ protected void disconnect(Session session) throws Throwable {
+ session.disconnect();
+ }
+
/**
* Perform any steps needed to reconnect a fixture session.
*
@@ -139,7 +143,7 @@ public abstract class ConnectionManagementTestCase extends FunctionalTestCase {
sessionUnderTest.enableFilter( "nameIsNull" );
assertNotNull( sessionUnderTest.getEnabledFilter( "nameIsNull" ) );
- sessionUnderTest.disconnect();
+ disconnect( sessionUnderTest );
assertNotNull( sessionUnderTest.getEnabledFilter( "nameIsNull" ) );
byte[] bytes = SerializationHelper.serialize( sessionUnderTest );
@@ -147,7 +151,7 @@ public abstract class ConnectionManagementTestCase extends FunctionalTestCase {
assertNotNull( sessionUnderTest.getEnabledFilter( "nameIsNull" ) );
reconnect( sessionUnderTest );
assertNotNull( sessionUnderTest.getEnabledFilter( "nameIsNull" ) );
- sessionUnderTest.disconnect();
+ disconnect( sessionUnderTest );
assertNotNull( sessionUnderTest.getEnabledFilter( "nameIsNull" ) );
Session s2 = ( Session ) SerializationHelper.deserialize( bytes );
@@ -156,7 +160,7 @@ public abstract class ConnectionManagementTestCase extends FunctionalTestCase {
reconnect( s2 );
assertNotNull( sessionUnderTest.getEnabledFilter( "nameIsNull" ) );
- s2.disconnect();
+ disconnect( s2 );
assertNotNull( sessionUnderTest.getEnabledFilter( "nameIsNull" ) );
reconnect( s2 );
assertNotNull( sessionUnderTest.getEnabledFilter( "nameIsNull" ) );
@@ -174,7 +178,7 @@ public abstract class ConnectionManagementTestCase extends FunctionalTestCase {
prepare();
Session sessionUnderTest = getSessionUnderTest();
- sessionUnderTest.disconnect();
+ disconnect( sessionUnderTest );
SerializationHelper.serialize( sessionUnderTest );
checkSerializedState( sessionUnderTest );
@@ -191,7 +195,7 @@ public abstract class ConnectionManagementTestCase extends FunctionalTestCase {
prepare();
Session sessionUnderTest = getSessionUnderTest();
- sessionUnderTest.disconnect();
+ disconnect( sessionUnderTest );
byte[] bytes = SerializationHelper.serialize( sessionUnderTest );
checkSerializedState( sessionUnderTest );
@@ -200,7 +204,7 @@ public abstract class ConnectionManagementTestCase extends FunctionalTestCase {
reconnect( s2 );
- s2.disconnect();
+ disconnect( s2 );
reconnect( s2 );
release( sessionUnderTest );
@@ -224,14 +228,14 @@ public abstract class ConnectionManagementTestCase extends FunctionalTestCase {
sessionUnderTest.createQuery( "from Silly" ).iterate();
- sessionUnderTest.disconnect();
+ disconnect( sessionUnderTest );
SerializationHelper.serialize( sessionUnderTest );
checkSerializedState( sessionUnderTest );
reconnect( sessionUnderTest );
sessionUnderTest.createQuery( "from Silly" ).scroll();
- sessionUnderTest.disconnect();
+ disconnect( sessionUnderTest );
SerializationHelper.serialize( sessionUnderTest );
checkSerializedState( sessionUnderTest );
diff --git a/hibernate-core/src/test/java/org/hibernate/test/connections/ThreadLocalCurrentSessionTest.java b/hibernate-core/src/test/java/org/hibernate/test/connections/ThreadLocalCurrentSessionTest.java
index a6d5691b65..bc09e2d3ef 100644
--- a/hibernate-core/src/test/java/org/hibernate/test/connections/ThreadLocalCurrentSessionTest.java
+++ b/hibernate-core/src/test/java/org/hibernate/test/connections/ThreadLocalCurrentSessionTest.java
@@ -8,6 +8,7 @@ import org.hibernate.cfg.Configuration;
import org.hibernate.cfg.Environment;
import org.hibernate.context.ThreadLocalSessionContext;
import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.engine.transaction.spi.LocalStatus;
import org.hibernate.testing.junit.functional.FunctionalTestClassTestSuite;
/**
@@ -36,6 +37,10 @@ public class ThreadLocalCurrentSessionTest extends ConnectionManagementTestCase
}
protected void release(Session session) {
+ if ( session.getTransaction().getLocalStatus() != LocalStatus.ACTIVE ) {
+ TestableThreadLocalContext.unbind( sfi() );
+ return;
+ }
long initialCount = getSessions().getStatistics().getSessionCloseCount();
session.getTransaction().commit();
long subsequentCount = getSessions().getStatistics().getSessionCloseCount();
@@ -45,8 +50,6 @@ public class ThreadLocalCurrentSessionTest extends ConnectionManagementTestCase
}
protected void reconnect(Session session) throws Throwable {
-// session.reconnect();
- session.beginTransaction();
}
protected void checkSerializedState(Session session) {
diff --git a/hibernate-core/src/test/java/org/hibernate/test/legacy/FooBarTest.java b/hibernate-core/src/test/java/org/hibernate/test/legacy/FooBarTest.java
index 390bd85459..b8660838f8 100644
--- a/hibernate-core/src/test/java/org/hibernate/test/legacy/FooBarTest.java
+++ b/hibernate-core/src/test/java/org/hibernate/test/legacy/FooBarTest.java
@@ -1358,9 +1358,7 @@ public class FooBarTest extends LegacyTestCase {
Object b = result[0];
assertTrue( s.getCurrentLockMode(b)==LockMode.WRITE && s.getCurrentLockMode( result[1] )==LockMode.WRITE );
tx.commit();
- s.disconnect();
- s.reconnect();
tx = s.beginTransaction();
assertTrue( s.getCurrentLockMode(b)==LockMode.NONE );
s.createQuery( "from Foo foo" ).list();
@@ -1371,9 +1369,7 @@ public class FooBarTest extends LegacyTestCase {
assertTrue( s.getCurrentLockMode(b)==LockMode.READ);
s.evict(baz);
tx.commit();
- s.disconnect();
-
- s.reconnect();
+
tx = s.beginTransaction();
assertTrue( s.getCurrentLockMode(b)==LockMode.NONE );
s.delete( s.load( Baz.class, baz.getCode() ) );
@@ -2575,12 +2571,9 @@ public class FooBarTest extends LegacyTestCase {
assertTrue( baz.getCascadingBars().size()==1 );
txn.commit();
- s.disconnect();
-
s2 = (Session) SerializationHelper.deserialize( SerializationHelper.serialize(s) );
s.close();
- s2.reconnect();
txn2 = s2.beginTransaction();
baz = (Baz) s2.load(Baz.class, baz.getCode());
assertTrue( ( (Long) s2.createQuery( "select count(*) from Bar" ).iterate().next() ).longValue()==3 );
@@ -3951,35 +3944,6 @@ public class FooBarTest extends LegacyTestCase {
}
}
- public void testDisconnect() throws Exception {
- Session s = openSession();
- s.beginTransaction();
- Foo foo = new Foo();
- Foo foo2 = new Foo();
- s.save(foo);
- s.save(foo2);
- foo2.setFoo(foo);
- s.getTransaction().commit();
-
- s.disconnect();
- s.reconnect();
-
- s.beginTransaction();
- s.delete(foo);
- foo2.setFoo(null);
- s.getTransaction().commit();
-
- s.disconnect();
- s.reconnect();
-
- s.beginTransaction();
- s.delete(foo2);
- s.getTransaction().commit();
- s.close();
- }
-
-
-
public void testOrderBy() throws Exception {
Session s = openSession();
s.beginTransaction();
@@ -4838,9 +4802,7 @@ public class FooBarTest extends LegacyTestCase {
t = s.beginTransaction();
Foo foo = (Foo) s.get(Foo.class, id);
t.commit();
- s.disconnect();
- s.reconnect();
t = s.beginTransaction();
s.flush();
t.commit();
diff --git a/hibernate-core/src/test/java/org/hibernate/test/legacy/FumTest.java b/hibernate-core/src/test/java/org/hibernate/test/legacy/FumTest.java
index 3f56af5366..b17bae7cf2 100644
--- a/hibernate-core/src/test/java/org/hibernate/test/legacy/FumTest.java
+++ b/hibernate-core/src/test/java/org/hibernate/test/legacy/FumTest.java
@@ -735,6 +735,7 @@ public class FumTest extends LegacyTestCase {
// Test insertions across serializations
Session s = getSessions().openSession();
s.setFlushMode(FlushMode.MANUAL);
+ s.beginTransaction();
Simple simple = new Simple();
simple.setAddress("123 Main St. Anytown USA");
@@ -745,11 +746,11 @@ public class FumTest extends LegacyTestCase {
s.save( simple, new Long(10) );
// Now, try to serialize session without flushing...
- s.disconnect();
+ s.getTransaction().commit();
Session s2 = spoofSerialization(s);
s.close();
s = s2;
- s.reconnect();
+ s.beginTransaction();
simple = (Simple) s.load( Simple.class, new Long(10) );
Simple other = new Simple();
@@ -759,7 +760,7 @@ public class FumTest extends LegacyTestCase {
simple.setOther(other);
s.flush();
- s.connection().commit();
+ s.getTransaction().commit();
s.close();
Simple check = simple;
@@ -767,6 +768,7 @@ public class FumTest extends LegacyTestCase {
// Test updates across serializations
s = getSessions().openSession();
s.setFlushMode(FlushMode.MANUAL);
+ s.beginTransaction();
simple = (Simple) s.get( Simple.class, new Long(10) );
assertTrue("Not same parent instances", check.getName().equals( simple.getName() ) );
@@ -774,14 +776,14 @@ public class FumTest extends LegacyTestCase {
simple.setName("My updated name");
- s.disconnect();
+ s.getTransaction().commit();
s2 = spoofSerialization(s);
s.close();
s = s2;
- s.reconnect();
+ s.beginTransaction();
s.flush();
- s.connection().commit();
+ s.getTransaction().commit();
s.close();
check = simple;
@@ -789,6 +791,7 @@ public class FumTest extends LegacyTestCase {
// Test deletions across serializations
s = getSessions().openSession();
s.setFlushMode(FlushMode.MANUAL);
+ s.beginTransaction();
simple = (Simple) s.get( Simple.class, new Long(10) );
assertTrue("Not same parent instances", check.getName().equals( simple.getName() ) );
@@ -797,20 +800,21 @@ public class FumTest extends LegacyTestCase {
// Now, lets delete across serialization...
s.delete(simple);
- s.disconnect();
+ s.getTransaction().commit();
s2 = spoofSerialization(s);
s.close();
s = s2;
- s.reconnect();
+ s.beginTransaction();
s.flush();
- s.connection().commit();
+ s.getTransaction().commit();
s.close();
///////////////////////////////////////////////////////////////////////////
// Test collection actions across serializations
s = getSessions().openSession();
s.setFlushMode(FlushMode.MANUAL);
+ s.beginTransaction();
Fum fum = new Fum( fumKey("uss-fum") );
fum.setFo( new Fum( fumKey("uss-fo") ) );
@@ -828,32 +832,33 @@ public class FumTest extends LegacyTestCase {
s.save( fum.getFo() );
s.save(fum);
- s.disconnect();
+ s.getTransaction().commit();
s2 = spoofSerialization(s);
s.close();
s = s2;
- s.reconnect();
+ s.beginTransaction();
s.flush();
- s.connection().commit();
+ s.getTransaction().commit();
s.close();
s = getSessions().openSession();
s.setFlushMode(FlushMode.MANUAL);
+ s.beginTransaction();
fum = (Fum) s.load( Fum.class, fum.getId() );
assertTrue("the Fum.friends did not get saved", fum.getFriends().size() == 2);
fum.setFriends(null);
- s.disconnect();
+ s.getTransaction().commit();
s2 = spoofSerialization(s);
s.close();
s = s2;
- s.reconnect();
+ s.beginTransaction();
s.flush();
- s.connection().commit();
+ s.getTransaction().commit();
s.close();
s = getSessions().openSession();
diff --git a/hibernate-core/src/test/java/org/hibernate/test/proxy/ProxyTest.java b/hibernate-core/src/test/java/org/hibernate/test/proxy/ProxyTest.java
index 63ce675366..422f39fbae 100755
--- a/hibernate-core/src/test/java/org/hibernate/test/proxy/ProxyTest.java
+++ b/hibernate-core/src/test/java/org/hibernate/test/proxy/ProxyTest.java
@@ -181,7 +181,6 @@ public class ProxyTest extends FunctionalTestCase {
//close the original:
s.close();
- sclone.reconnect();
t = sclone.beginTransaction();
DataPoint sdp = (DataPoint) sclone.load( DataPoint.class, new Long( dp.getId() ) );
diff --git a/hibernate-core/src/test/java/org/hibernate/test/tm/CMTTest.java b/hibernate-core/src/test/java/org/hibernate/test/tm/CMTTest.java
index 67c52d680e..cacab10634 100755
--- a/hibernate-core/src/test/java/org/hibernate/test/tm/CMTTest.java
+++ b/hibernate-core/src/test/java/org/hibernate/test/tm/CMTTest.java
@@ -11,6 +11,7 @@ import org.hibernate.cfg.Configuration;
import org.hibernate.cfg.Environment;
import org.hibernate.criterion.Order;
import org.hibernate.engine.transaction.internal.jta.CMTTransactionFactory;
+import org.hibernate.service.jdbc.connections.spi.ConnectionProvider;
import org.hibernate.service.jta.platform.internal.JtaPlatformInitiator;
import org.hibernate.service.jta.platform.spi.JtaPlatform;
import org.hibernate.test.common.jta.AtomikosDataSourceConnectionProvider;
@@ -20,6 +21,7 @@ import org.hibernate.testing.junit.functional.FunctionalTestClassTestSuite;
import org.hibernate.util.SerializationHelper;
import javax.transaction.Transaction;
+import java.sql.Connection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
@@ -469,22 +471,6 @@ public class CMTTest extends FunctionalTestCase {
sfi().getServiceRegistry().getService( JtaPlatform.class ).retrieveTransactionManager().commit();
}
- public void testAggressiveReleaseWithExplicitDisconnectReconnect() throws Exception {
- sfi().getServiceRegistry().getService( JtaPlatform.class ).retrieveTransactionManager().begin();
- Session s = getSessions().getCurrentSession();
-
- s.createQuery( "from Item" ).list();
-
- s.disconnect();
- byte[] bytes = SerializationHelper.serialize( s );
- s = ( Session ) SerializationHelper.deserialize( bytes );
- s.reconnect();
-
- s.createQuery( "from Item" ).list();
-
- sfi().getServiceRegistry().getService( JtaPlatform.class ).retrieveTransactionManager().commit();
- }
-
public void testAggressiveReleaseWithConnectionRetreival() throws Exception {
sfi().getServiceRegistry().getService( JtaPlatform.class ).retrieveTransactionManager().begin();
Session s = openSession();
From 747c2dd50d960aa861baaf64a3369dd6e89e6f33 Mon Sep 17 00:00:00 2001
From: Gail Badner
Date: Fri, 4 Mar 2011 11:18:34 -0800
Subject: [PATCH 10/19] HHH-5982 : Flush checker bugs
---
.../internal/SynchronizationCallbackCoordinatorImpl.java | 5 +++--
.../java/org/hibernate/ejb/AbstractEntityManagerImpl.java | 3 ++-
2 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/hibernate-core/src/main/java/org/hibernate/engine/transaction/synchronization/internal/SynchronizationCallbackCoordinatorImpl.java b/hibernate-core/src/main/java/org/hibernate/engine/transaction/synchronization/internal/SynchronizationCallbackCoordinatorImpl.java
index ff0ba26775..342f62e6ff 100644
--- a/hibernate-core/src/main/java/org/hibernate/engine/transaction/synchronization/internal/SynchronizationCallbackCoordinatorImpl.java
+++ b/hibernate-core/src/main/java/org/hibernate/engine/transaction/synchronization/internal/SynchronizationCallbackCoordinatorImpl.java
@@ -139,9 +139,10 @@ public class SynchronizationCallbackCoordinatorImpl implements SynchronizationCa
private static final ManagedFlushChecker STANDARD_MANAGED_FLUSH_CHECKER = new ManagedFlushChecker() {
@Override
public boolean shouldDoManagedFlush(TransactionCoordinator coordinator, int jtaStatus) {
- return coordinator.getTransactionContext().isFlushModeNever() &&
+ return ! coordinator.getTransactionContext().isClosed() &&
+ ! coordinator.getTransactionContext().isFlushModeNever() &&
coordinator.getTransactionContext().isFlushBeforeCompletionEnabled() &&
- !JtaStatusHelper.isRollback( jtaStatus );
+ ! JtaStatusHelper.isRollback( jtaStatus );
}
};
diff --git a/hibernate-entitymanager/src/main/java/org/hibernate/ejb/AbstractEntityManagerImpl.java b/hibernate-entitymanager/src/main/java/org/hibernate/ejb/AbstractEntityManagerImpl.java
index ed1c48cc97..447dc6b0c8 100755
--- a/hibernate-entitymanager/src/main/java/org/hibernate/ejb/AbstractEntityManagerImpl.java
+++ b/hibernate-entitymanager/src/main/java/org/hibernate/ejb/AbstractEntityManagerImpl.java
@@ -1253,7 +1253,8 @@ public abstract class AbstractEntityManagerImpl implements HibernateEntityManage
private static class ManagedFlushCheckerImpl implements ManagedFlushChecker {
@Override
public boolean shouldDoManagedFlush(TransactionCoordinator coordinator, int jtaStatus) {
- return ! coordinator.getTransactionContext().isFlushModeNever() &&
+ return ! coordinator.getTransactionContext().isClosed() &&
+ ! coordinator.getTransactionContext().isFlushModeNever() &&
! JtaStatusHelper.isRollback( jtaStatus );
}
}
From ddfcc44d760938578771cb6ce24c809c980c8b8b Mon Sep 17 00:00:00 2001
From: Steve Ebersole
Date: Fri, 4 Mar 2011 15:36:07 -0600
Subject: [PATCH 11/19] HHH-5916 - Add support for a programmatic way to define
a default EntityPersister and CollectionPersister class implementation
---
.../cfg/AnnotationConfiguration.java | 28 ---
.../java/org/hibernate/cfg/Configuration.java | 34 +---
.../java/org/hibernate/cfg/HbmBinder.java | 30 ---
.../main/java/org/hibernate/cfg/Mappings.java | 11 --
.../cfg/annotations/CollectionBinder.java | 13 --
.../cfg/annotations/EntityBinder.java | 10 -
.../hibernate/impl/SessionFactoryImpl.java | 18 +-
.../persister/PersisterClassProvider.java | 47 -----
.../hibernate/persister/PersisterFactory.java | 177 -----------------
.../PersisterClassResolverInitiator.java | 69 +++++++
.../internal/PersisterFactoryImpl.java | 183 ++++++++++++++++++
.../internal/PersisterFactoryInitiator.java | 69 +++++++
.../StandardPersisterClassResolver.java | 88 +++++++++
.../persister/spi/PersisterClassResolver.java | 54 ++++++
.../persister/spi/PersisterFactory.java | 89 +++++++++
.../spi/UnknownPersisterException.java | 41 ++++
.../spi/StandardServiceInitiators.java | 5 +
.../GoofyPersisterClassProvider.java | 11 +-
.../persister/PersisterClassProviderTest.java | 5 +-
.../org/hibernate/ejb/AvailableSettings.java | 2 +-
.../org/hibernate/ejb/Ejb3Configuration.java | 18 --
.../PersisterClassProviderTest.java | 16 +-
22 files changed, 633 insertions(+), 385 deletions(-)
delete mode 100644 hibernate-core/src/main/java/org/hibernate/persister/PersisterClassProvider.java
delete mode 100644 hibernate-core/src/main/java/org/hibernate/persister/PersisterFactory.java
create mode 100644 hibernate-core/src/main/java/org/hibernate/persister/internal/PersisterClassResolverInitiator.java
create mode 100644 hibernate-core/src/main/java/org/hibernate/persister/internal/PersisterFactoryImpl.java
create mode 100644 hibernate-core/src/main/java/org/hibernate/persister/internal/PersisterFactoryInitiator.java
create mode 100644 hibernate-core/src/main/java/org/hibernate/persister/internal/StandardPersisterClassResolver.java
create mode 100644 hibernate-core/src/main/java/org/hibernate/persister/spi/PersisterClassResolver.java
create mode 100644 hibernate-core/src/main/java/org/hibernate/persister/spi/PersisterFactory.java
create mode 100644 hibernate-core/src/main/java/org/hibernate/persister/spi/UnknownPersisterException.java
diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/AnnotationConfiguration.java b/hibernate-core/src/main/java/org/hibernate/cfg/AnnotationConfiguration.java
index 0195d31f3e..07cb7e0fab 100644
--- a/hibernate-core/src/main/java/org/hibernate/cfg/AnnotationConfiguration.java
+++ b/hibernate-core/src/main/java/org/hibernate/cfg/AnnotationConfiguration.java
@@ -26,37 +26,15 @@ package org.hibernate.cfg;
import java.io.File;
import java.io.InputStream;
import java.net.URL;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
import java.util.Properties;
-import javax.persistence.Embeddable;
-import javax.persistence.Entity;
-import javax.persistence.MappedSuperclass;
-import javax.persistence.MapsId;
import org.dom4j.Document;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.hibernate.AnnotationException;
-import org.hibernate.DuplicateMappingException;
import org.hibernate.HibernateException;
import org.hibernate.Interceptor;
import org.hibernate.MappingException;
-import org.hibernate.annotations.AnyMetaDef;
-import org.hibernate.annotations.common.reflection.ReflectionManager;
-import org.hibernate.annotations.common.reflection.XClass;
-import org.hibernate.engine.NamedQueryDefinition;
-import org.hibernate.engine.NamedSQLQueryDefinition;
-import org.hibernate.engine.ResultSetMappingDefinition;
-import org.hibernate.mapping.IdGenerator;
-import org.hibernate.mapping.Join;
-import org.hibernate.mapping.PersistentClass;
-import org.hibernate.mapping.Table;
-import org.hibernate.persister.PersisterClassProvider;
-import org.hibernate.util.CollectionHelper;
/**
* Similar to the {@link Configuration} object but handles EJB3 and Hibernate
@@ -264,12 +242,6 @@ public class AnnotationConfiguration extends Configuration {
return this;
}
- @Override
- public AnnotationConfiguration setPersisterClassProvider(PersisterClassProvider persisterClassProvider) {
- super.setPersisterClassProvider( persisterClassProvider );
- return this;
- }
-
@Deprecated
protected class ExtendedMappingsImpl extends MappingsImpl implements ExtendedMappings {
}
diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/Configuration.java b/hibernate-core/src/main/java/org/hibernate/cfg/Configuration.java
index ba64ce4900..e239c6b870 100644
--- a/hibernate-core/src/main/java/org/hibernate/cfg/Configuration.java
+++ b/hibernate-core/src/main/java/org/hibernate/cfg/Configuration.java
@@ -94,7 +94,6 @@ import org.hibernate.engine.Mapping;
import org.hibernate.engine.NamedQueryDefinition;
import org.hibernate.engine.NamedSQLQueryDefinition;
import org.hibernate.engine.ResultSetMappingDefinition;
-import org.hibernate.engine.jdbc.spi.JdbcServices;
import org.hibernate.event.AutoFlushEventListener;
import org.hibernate.event.DeleteEventListener;
import org.hibernate.event.DirtyCheckEventListener;
@@ -150,7 +149,6 @@ import org.hibernate.mapping.SimpleValue;
import org.hibernate.mapping.Table;
import org.hibernate.mapping.TypeDef;
import org.hibernate.mapping.UniqueKey;
-import org.hibernate.persister.PersisterClassProvider;
import org.hibernate.proxy.EntityNotFoundDelegate;
import org.hibernate.secure.JACCConfiguration;
import org.hibernate.service.spi.ServiceRegistry;
@@ -261,7 +259,6 @@ public class Configuration implements Serializable {
protected transient XMLHelper xmlHelper;
protected NamingStrategy namingStrategy;
- private PersisterClassProvider persisterClassProvider;
private SessionFactoryObserver sessionFactoryObserver;
private EventListeners eventListeners;
@@ -359,7 +356,6 @@ public class Configuration implements Serializable {
propertyRefResolver = new HashMap();
caches = new ArrayList();
namingStrategy = EJB3NamingStrategy.INSTANCE;
- persisterClassProvider = null;
setEntityResolver( new EJB3DTDEntityResolver() );
anyMetaDefs = new HashMap();
propertiesAnnotatedWithMapsId = new HashMap>();
@@ -1999,7 +1995,7 @@ public class Configuration implements Serializable {
/**
* Set the current {@link Interceptor}
*
- * @param interceptor The {@link Interceptor} to use for the {@link #buildSessionFactory() built}
+ * @param interceptor The {@link Interceptor} to use for the {@link #buildSessionFactory) built}
* {@link SessionFactory}.
*
* @return this for method chaining
@@ -2866,26 +2862,6 @@ public class Configuration implements Serializable {
return this;
}
- public PersisterClassProvider getPersisterClassProvider() {
- return persisterClassProvider;
- }
-
- /**
- * Defines a custom persister class provider.
- *
- * The persister class is chosen according to the following rules in decreasing priority:
- * - the persister class defined explicitly via annotation or XML
- * - the persister class returned by the PersisterClassProvider implementation (if not null)
- * - the default provider as chosen by Hibernate Core (best choice most of the time)
- *
- *
- * @param persisterClassProvider implementation
- */
- public Configuration setPersisterClassProvider(PersisterClassProvider persisterClassProvider) {
- this.persisterClassProvider = persisterClassProvider;
- return this;
- }
-
/**
* Retrieve the IdentifierGeneratorFactory in effect for this configuration.
*
@@ -3118,14 +3094,6 @@ public class Configuration implements Serializable {
Configuration.this.namingStrategy = namingStrategy;
}
- public PersisterClassProvider getPersisterClassProvider() {
- return persisterClassProvider;
- }
-
- public void setPersisterClassProvider(PersisterClassProvider persisterClassProvider) {
- Configuration.this.persisterClassProvider = persisterClassProvider;
- }
-
public TypeResolver getTypeResolver() {
return typeResolver;
}
diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/HbmBinder.java b/hibernate-core/src/main/java/org/hibernate/cfg/HbmBinder.java
index 473fc0b47b..e93dd0e60c 100644
--- a/hibernate-core/src/main/java/org/hibernate/cfg/HbmBinder.java
+++ b/hibernate-core/src/main/java/org/hibernate/cfg/HbmBinder.java
@@ -87,9 +87,6 @@ import org.hibernate.mapping.UnionSubclass;
import org.hibernate.mapping.UniqueKey;
import org.hibernate.mapping.Value;
import org.hibernate.mapping.FetchProfile;
-import org.hibernate.persister.PersisterClassProvider;
-import org.hibernate.persister.collection.CollectionPersister;
-import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.persister.entity.JoinedSubclassEntityPersister;
import org.hibernate.persister.entity.SingleTableEntityPersister;
import org.hibernate.persister.entity.UnionSubclassEntityPersister;
@@ -690,9 +687,6 @@ public final class HbmBinder {
entity.setMetaAttributes( getMetas( node, inheritedMetas ) );
// PERSISTER
- //persister node in XML has priority over
- //persisterClassProvider
- //if all fail, the default Hibernate persisters kick in
Attribute persisterNode = node.attribute( "persister" );
if ( persisterNode != null ) {
try {
@@ -704,17 +698,6 @@ public final class HbmBinder {
+ persisterNode.getValue() );
}
}
- else {
- final PersisterClassProvider persisterClassProvider = mappings.getPersisterClassProvider();
- if ( persisterClassProvider != null ) {
- final Class extends EntityPersister> persister = persisterClassProvider.getEntityPersisterClass(
- entity.getEntityName()
- );
- if ( persister != null ) {
- entity.setEntityPersisterClass( persister );
- }
- }
- }
// CUSTOM SQL
handleCustomSQL( node, entity );
@@ -1416,9 +1399,6 @@ public final class HbmBinder {
// PERSISTER
- //persister node in XML has priority over
- //persisterClassProvider
- //if all fail, the default Hibernate persisters kick in
Attribute persisterNode = node.attribute( "persister" );
if ( persisterNode != null ) {
try {
@@ -1430,16 +1410,6 @@ public final class HbmBinder {
+ persisterNode.getValue() );
}
}
- else {
- final PersisterClassProvider persisterClassProvider = mappings.getPersisterClassProvider();
- if ( persisterClassProvider != null ) {
- final Class extends CollectionPersister> persister =
- persisterClassProvider.getCollectionPersisterClass( collection.getRole() );
- if ( persister != null ) {
- collection.setCollectionPersisterClass( persister );
- }
- }
- }
Attribute typeNode = node.attribute( "collection-type" );
if ( typeNode != null ) {
diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/Mappings.java b/hibernate-core/src/main/java/org/hibernate/cfg/Mappings.java
index 7886b3f777..3e3bb128dd 100644
--- a/hibernate-core/src/main/java/org/hibernate/cfg/Mappings.java
+++ b/hibernate-core/src/main/java/org/hibernate/cfg/Mappings.java
@@ -51,7 +51,6 @@ import org.hibernate.mapping.TypeDef;
import org.hibernate.mapping.AuxiliaryDatabaseObject;
import org.hibernate.mapping.Column;
import org.hibernate.mapping.FetchProfile;
-import org.hibernate.persister.PersisterClassProvider;
import org.hibernate.type.TypeResolver;
/**
@@ -90,16 +89,6 @@ public interface Mappings {
*/
public void setNamingStrategy(NamingStrategy namingStrategy);
- /**
- * Get the current persister class provider implementation
- */
- public PersisterClassProvider getPersisterClassProvider();
-
- /**
- * Set the current persister class provider implementation
- */
- public void setPersisterClassProvider(PersisterClassProvider persisterClassProvider);
-
/**
* Returns the currently bound default schema name.
*
diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/annotations/CollectionBinder.java b/hibernate-core/src/main/java/org/hibernate/cfg/annotations/CollectionBinder.java
index 2922fc1203..e5cd290d93 100644
--- a/hibernate-core/src/main/java/org/hibernate/cfg/annotations/CollectionBinder.java
+++ b/hibernate-core/src/main/java/org/hibernate/cfg/annotations/CollectionBinder.java
@@ -111,7 +111,6 @@ import org.hibernate.mapping.Selectable;
import org.hibernate.mapping.SimpleValue;
import org.hibernate.mapping.SingleTableSubclass;
import org.hibernate.mapping.Table;
-import org.hibernate.persister.PersisterClassProvider;
import org.hibernate.persister.collection.CollectionPersister;
import org.hibernate.util.StringHelper;
@@ -402,22 +401,10 @@ public abstract class CollectionBinder {
OptimisticLock lockAnn = property.getAnnotation( OptimisticLock.class );
if ( lockAnn != null ) collection.setOptimisticLocked( !lockAnn.excluded() );
- //@Persister has priority over PersisterClassProvider
- //if all fail, left null and Hibernate defaults kick in
Persister persisterAnn = property.getAnnotation( Persister.class );
if ( persisterAnn != null ) {
collection.setCollectionPersisterClass( persisterAnn.impl() );
}
- else {
- final PersisterClassProvider persisterClassProvider = mappings.getPersisterClassProvider();
- if (persisterClassProvider != null) {
- final Class extends CollectionPersister> persister =
- persisterClassProvider.getCollectionPersisterClass( collection.getRole() );
- if (persister != null) {
- collection.setCollectionPersisterClass( persister );
- }
- }
- }
// set ordering
if ( orderBy != null ) collection.setOrderBy( orderBy );
diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/annotations/EntityBinder.java b/hibernate-core/src/main/java/org/hibernate/cfg/annotations/EntityBinder.java
index e0c988cf9a..fe0daf3e4d 100644
--- a/hibernate-core/src/main/java/org/hibernate/cfg/annotations/EntityBinder.java
+++ b/hibernate-core/src/main/java/org/hibernate/cfg/annotations/EntityBinder.java
@@ -83,7 +83,6 @@ import org.hibernate.mapping.SimpleValue;
import org.hibernate.mapping.Table;
import org.hibernate.mapping.TableOwner;
import org.hibernate.mapping.Value;
-import org.hibernate.persister.PersisterClassProvider;
import org.hibernate.util.ReflectHelper;
import org.hibernate.util.StringHelper;
@@ -251,9 +250,6 @@ public class EntityBinder {
persistentClass.setSelectBeforeUpdate( selectBeforeUpdate );
//set persister if needed
- //@Persister has precedence over @Entity.persister
- //in both fail we look for the PersisterClassProvider
- //if all fail, the persister is left null and the Hibernate defaults kick in
Persister persisterAnn = annotatedClass.getAnnotation( Persister.class );
Class persister = null;
if ( persisterAnn != null ) {
@@ -269,12 +265,6 @@ public class EntityBinder {
throw new AnnotationException( "Could not find persister class: " + persister );
}
}
- else {
- final PersisterClassProvider persisterClassProvider = mappings.getPersisterClassProvider();
- if ( persisterClassProvider != null ) {
- persister = persisterClassProvider.getEntityPersisterClass( persistentClass.getEntityName() );
- }
- }
}
if ( persister != null ) {
persistentClass.setEntityPersisterClass( persister );
diff --git a/hibernate-core/src/main/java/org/hibernate/impl/SessionFactoryImpl.java b/hibernate-core/src/main/java/org/hibernate/impl/SessionFactoryImpl.java
index 3a7dedf62d..323bfcf835 100644
--- a/hibernate-core/src/main/java/org/hibernate/impl/SessionFactoryImpl.java
+++ b/hibernate-core/src/main/java/org/hibernate/impl/SessionFactoryImpl.java
@@ -80,11 +80,12 @@ import org.hibernate.mapping.PersistentClass;
import org.hibernate.mapping.RootClass;
import org.hibernate.metadata.ClassMetadata;
import org.hibernate.metadata.CollectionMetadata;
-import org.hibernate.persister.PersisterFactory;
+import org.hibernate.persister.internal.PersisterFactoryImpl;
import org.hibernate.persister.collection.CollectionPersister;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.persister.entity.Loadable;
import org.hibernate.persister.entity.Queryable;
+import org.hibernate.persister.spi.PersisterFactory;
import org.hibernate.pretty.MessageHelper;
import org.hibernate.proxy.EntityNotFoundDelegate;
import org.hibernate.service.jdbc.connections.spi.ConnectionProvider;
@@ -109,7 +110,6 @@ import org.slf4j.LoggerFactory;
import javax.naming.NamingException;
import javax.naming.Reference;
import javax.naming.StringRefAddr;
-import javax.transaction.TransactionManager;
import java.io.IOException;
import java.io.InvalidObjectException;
import java.io.ObjectInputStream;
@@ -289,7 +289,12 @@ public final class SessionFactoryImpl
allCacheRegions.put( cacheRegionName, entityRegion );
}
}
- EntityPersister cp = PersisterFactory.createClassPersister( model, accessStrategy, this, mapping );
+ EntityPersister cp = serviceRegistry.getService( PersisterFactory.class ).createEntityPersister(
+ model,
+ accessStrategy,
+ this,
+ mapping
+ );
entityPersisters.put( model.getEntityName(), cp );
classMeta.put( model.getEntityName(), cp.getClassMetadata() );
}
@@ -310,7 +315,12 @@ public final class SessionFactoryImpl
entityAccessStrategies.put( cacheRegionName, accessStrategy );
allCacheRegions.put( cacheRegionName, collectionRegion );
}
- CollectionPersister persister = PersisterFactory.createCollectionPersister( cfg, model, accessStrategy, this) ;
+ CollectionPersister persister = serviceRegistry.getService( PersisterFactory.class ).createCollectionPersister(
+ cfg,
+ model,
+ accessStrategy,
+ this
+ ) ;
collectionPersisters.put( model.getRole(), persister.getCollectionMetadata() );
Type indexType = persister.getIndexType();
if ( indexType != null && indexType.isAssociationType() && !indexType.isAnyType() ) {
diff --git a/hibernate-core/src/main/java/org/hibernate/persister/PersisterClassProvider.java b/hibernate-core/src/main/java/org/hibernate/persister/PersisterClassProvider.java
deleted file mode 100644
index 029c4d0370..0000000000
--- a/hibernate-core/src/main/java/org/hibernate/persister/PersisterClassProvider.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Hibernate, Relational Persistence for Idiomatic Java
- *
- * JBoss, Home of Professional Open Source
- * Copyright 2011 Red Hat Inc. and/or its affiliates and other contributors
- * as indicated by the @authors tag. All rights reserved.
- * See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * 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, v. 2.1.
- * This program is distributed in the hope that it will be useful, but WITHOUT A
- * 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,
- * v.2.1 along with this distribution; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
- * MA 02110-1301, USA.
- */
-package org.hibernate.persister;
-
-import org.hibernate.persister.collection.CollectionPersister;
-import org.hibernate.persister.entity.EntityPersister;
-
-/**
- * Provides persister classes based on the entity or collection role.
- * The persister class is chosen according to the following rules in decreasing priority:
- * - the persister class defined explicitly via annotation or XML
- * - the persister class returned by the PersisterClassProvider implementation (if not null)
- * - the default provider as chosen by Hibernate Core (best choice most of the time)
- *
- * @author Emmanuel Bernard
- */
-public interface PersisterClassProvider {
- /**
- * Returns the entity persister class for a given entityName or null
- * if the entity persister class should be the default.
- */
- Class extends EntityPersister> getEntityPersisterClass(String entityName);
-
- /**
- * Returns the collection persister class for a given collection role or null
- * if the collection persister class should be the default.
- */
- Class extends CollectionPersister> getCollectionPersisterClass(String collectionPersister);
-}
diff --git a/hibernate-core/src/main/java/org/hibernate/persister/PersisterFactory.java b/hibernate-core/src/main/java/org/hibernate/persister/PersisterFactory.java
deleted file mode 100644
index e62c62f940..0000000000
--- a/hibernate-core/src/main/java/org/hibernate/persister/PersisterFactory.java
+++ /dev/null
@@ -1,177 +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.persister;
-
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
-
-import org.hibernate.HibernateException;
-import org.hibernate.MappingException;
-import org.hibernate.cache.access.EntityRegionAccessStrategy;
-import org.hibernate.cache.access.CollectionRegionAccessStrategy;
-import org.hibernate.cfg.Configuration;
-import org.hibernate.engine.Mapping;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.mapping.Collection;
-import org.hibernate.mapping.PersistentClass;
-import org.hibernate.persister.collection.BasicCollectionPersister;
-import org.hibernate.persister.collection.CollectionPersister;
-import org.hibernate.persister.collection.OneToManyPersister;
-import org.hibernate.persister.entity.EntityPersister;
-import org.hibernate.persister.entity.JoinedSubclassEntityPersister;
-import org.hibernate.persister.entity.SingleTableEntityPersister;
-import org.hibernate.persister.entity.UnionSubclassEntityPersister;
-
-/**
- * Factory for EntityPersister and CollectionPersister instances
- *
- * @author Gavin King
- */
-public final class PersisterFactory {
-
- //TODO: make EntityPersister *not* depend on SessionFactoryImplementor
- //interface, if possible
-
- // TODO : still need to make CollectionPersisters EntityMode-aware
-
- private PersisterFactory() {}
-
- private static final Class[] PERSISTER_CONSTRUCTOR_ARGS = new Class[] {
- PersistentClass.class, EntityRegionAccessStrategy.class, SessionFactoryImplementor.class, Mapping.class
- };
-
- // TODO: is it really neceassry to provide Configuration to CollectionPersisters ? Should it not be enough with associated class ?
- // or why does EntityPersister's not get access to configuration ?
- //
- // The only reason I could see that Configuration gets passed to collection persisters
- // is so that they can look up the dom4j node name of the entity element in case
- // no explicit node name was applied at the collection element level. Are you kidding me?
- // Trivial to fix then. Just store and expose the node name on the entity persister
- // (which the collection persister looks up anyway via other means...).
- private static final Class[] COLLECTION_PERSISTER_CONSTRUCTOR_ARGS = new Class[] {
- Collection.class, CollectionRegionAccessStrategy.class, Configuration.class, SessionFactoryImplementor.class
- };
-
- public static EntityPersister createClassPersister(
- PersistentClass model,
- EntityRegionAccessStrategy cacheAccessStrategy,
- SessionFactoryImplementor factory,
- Mapping cfg) throws HibernateException {
- Class persisterClass = model.getEntityPersisterClass();
- if ( persisterClass == null || persisterClass == SingleTableEntityPersister.class ) {
- return new SingleTableEntityPersister( model, cacheAccessStrategy, factory, cfg );
- }
- else if ( persisterClass == JoinedSubclassEntityPersister.class ) {
- return new JoinedSubclassEntityPersister( model, cacheAccessStrategy, factory, cfg );
- }
- else if ( persisterClass == UnionSubclassEntityPersister.class ) {
- return new UnionSubclassEntityPersister( model, cacheAccessStrategy, factory, cfg );
- }
- else {
- return create( persisterClass, model, cacheAccessStrategy, factory, cfg );
- }
- }
-
- public static CollectionPersister createCollectionPersister(
- Configuration cfg,
- Collection model,
- CollectionRegionAccessStrategy cacheAccessStrategy,
- SessionFactoryImplementor factory) throws HibernateException {
- Class persisterClass = model.getCollectionPersisterClass();
- if ( persisterClass == null ) {
- return model.isOneToMany()
- ? ( CollectionPersister ) new OneToManyPersister( model, cacheAccessStrategy, cfg, factory )
- : ( CollectionPersister ) new BasicCollectionPersister( model, cacheAccessStrategy, cfg, factory );
- }
- else {
- return create( persisterClass, cfg, model, cacheAccessStrategy, factory );
- }
-
- }
-
- private static EntityPersister create(
- Class persisterClass,
- PersistentClass model,
- EntityRegionAccessStrategy cacheAccessStrategy,
- SessionFactoryImplementor factory,
- Mapping cfg) throws HibernateException {
- Constructor pc;
- try {
- pc = persisterClass.getConstructor( PERSISTER_CONSTRUCTOR_ARGS );
- }
- catch ( Exception e ) {
- throw new MappingException( "Could not get constructor for " + persisterClass.getName(), e );
- }
-
- try {
- return (EntityPersister) pc.newInstance( new Object[] { model, cacheAccessStrategy, factory, cfg } );
- }
- catch (InvocationTargetException ite) {
- Throwable e = ite.getTargetException();
- if (e instanceof HibernateException) {
- throw (HibernateException) e;
- }
- else {
- throw new MappingException( "Could not instantiate persister " + persisterClass.getName(), e );
- }
- }
- catch (Exception e) {
- throw new MappingException( "Could not instantiate persister " + persisterClass.getName(), e );
- }
- }
-
- private static CollectionPersister create(
- Class persisterClass,
- Configuration cfg,
- Collection model,
- CollectionRegionAccessStrategy cacheAccessStrategy,
- SessionFactoryImplementor factory) throws HibernateException {
- Constructor pc;
- try {
- pc = persisterClass.getConstructor( COLLECTION_PERSISTER_CONSTRUCTOR_ARGS );
- }
- catch (Exception e) {
- throw new MappingException( "Could not get constructor for " + persisterClass.getName(), e );
- }
-
- try {
- return (CollectionPersister) pc.newInstance( new Object[] { model, cacheAccessStrategy, cfg, factory } );
- }
- catch (InvocationTargetException ite) {
- Throwable e = ite.getTargetException();
- if (e instanceof HibernateException) {
- throw (HibernateException) e;
- }
- else {
- throw new MappingException( "Could not instantiate collection persister " + persisterClass.getName(), e );
- }
- }
- catch (Exception e) {
- throw new MappingException( "Could not instantiate collection persister " + persisterClass.getName(), e );
- }
- }
-
-
-}
diff --git a/hibernate-core/src/main/java/org/hibernate/persister/internal/PersisterClassResolverInitiator.java b/hibernate-core/src/main/java/org/hibernate/persister/internal/PersisterClassResolverInitiator.java
new file mode 100644
index 0000000000..f61b48fd6a
--- /dev/null
+++ b/hibernate-core/src/main/java/org/hibernate/persister/internal/PersisterClassResolverInitiator.java
@@ -0,0 +1,69 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2011, 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
+ */
+package org.hibernate.persister.internal;
+
+import org.hibernate.persister.spi.PersisterClassResolver;
+import org.hibernate.service.classloading.spi.ClassLoaderService;
+import org.hibernate.service.spi.ServiceException;
+import org.hibernate.service.spi.ServiceInitiator;
+import org.hibernate.service.spi.ServiceRegistry;
+
+import java.util.Map;
+
+/**
+ * @author Steve Ebersole
+ */
+public class PersisterClassResolverInitiator implements ServiceInitiator {
+ public static final PersisterClassResolverInitiator INSTANCE = new PersisterClassResolverInitiator();
+ public static final String IMPL_NAME = "hibernate.persister.resolver";
+
+ @Override
+ public Class getServiceInitiated() {
+ return PersisterClassResolver.class;
+ }
+
+ @Override
+ @SuppressWarnings( {"unchecked"})
+ public PersisterClassResolver initiateService(Map configurationValues, ServiceRegistry registry) {
+ final Object customImpl = configurationValues.get( IMPL_NAME );
+ if ( customImpl == null ) {
+ return new StandardPersisterClassResolver();
+ }
+
+ if ( PersisterClassResolver.class.isInstance( customImpl ) ) {
+ return (PersisterClassResolver) customImpl;
+ }
+
+ final Class extends PersisterClassResolver> customImplClass = Class.class.isInstance( customImpl )
+ ? (Class extends PersisterClassResolver>) customImpl
+ : registry.getService( ClassLoaderService.class ).classForName( customImpl.toString() );
+
+ try {
+ return customImplClass.newInstance();
+ }
+ catch (Exception e) {
+ throw new ServiceException( "Could not initialize custom PersisterClassResolver impl [" + customImplClass.getName() + "]", e );
+ }
+ }
+}
diff --git a/hibernate-core/src/main/java/org/hibernate/persister/internal/PersisterFactoryImpl.java b/hibernate-core/src/main/java/org/hibernate/persister/internal/PersisterFactoryImpl.java
new file mode 100644
index 0000000000..c56523a9b9
--- /dev/null
+++ b/hibernate-core/src/main/java/org/hibernate/persister/internal/PersisterFactoryImpl.java
@@ -0,0 +1,183 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008-2011, 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
+ */
+package org.hibernate.persister.internal;
+
+import org.hibernate.HibernateException;
+import org.hibernate.MappingException;
+import org.hibernate.cache.access.CollectionRegionAccessStrategy;
+import org.hibernate.cache.access.EntityRegionAccessStrategy;
+import org.hibernate.cfg.Configuration;
+import org.hibernate.engine.Mapping;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.mapping.Collection;
+import org.hibernate.mapping.PersistentClass;
+import org.hibernate.persister.collection.CollectionPersister;
+import org.hibernate.persister.entity.EntityPersister;
+import org.hibernate.persister.spi.PersisterClassResolver;
+import org.hibernate.persister.spi.PersisterFactory;
+import org.hibernate.service.spi.ServiceRegistry;
+import org.hibernate.service.spi.ServiceRegistryAwareService;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+
+/**
+ * The standard Hibernate {@link PersisterFactory} implementation
+ *
+ * @author Gavin King
+ * @author Steve Ebersole
+ */
+public final class PersisterFactoryImpl implements PersisterFactory, ServiceRegistryAwareService {
+
+ /**
+ * The constructor signature for {@link EntityPersister} implementations
+ *
+ * @todo make EntityPersister *not* depend on {@link SessionFactoryImplementor} if possible.
+ */
+ public static final Class[] ENTITY_PERSISTER_CONSTRUCTOR_ARGS = new Class[] {
+ PersistentClass.class,
+ EntityRegionAccessStrategy.class,
+ SessionFactoryImplementor.class,
+ Mapping.class
+ };
+
+ /**
+ * The constructor signature for {@link CollectionPersister} implementations
+ *
+ * @todo still need to make collection persisters EntityMode-aware
+ * @todo make EntityPersister *not* depend on {@link SessionFactoryImplementor} if possible.
+ */
+ private static final Class[] COLLECTION_PERSISTER_CONSTRUCTOR_ARGS = new Class[] {
+ Collection.class,
+ CollectionRegionAccessStrategy.class,
+ Configuration.class,
+ SessionFactoryImplementor.class
+ };
+
+ private ServiceRegistry serviceRegistry;
+
+ @Override
+ public void injectServices(ServiceRegistry serviceRegistry) {
+ this.serviceRegistry = serviceRegistry;
+ }
+
+ @Override
+ @SuppressWarnings( {"unchecked"})
+ public EntityPersister createEntityPersister(
+ PersistentClass metadata,
+ EntityRegionAccessStrategy cacheAccessStrategy,
+ SessionFactoryImplementor factory,
+ Mapping cfg) {
+ Class extends EntityPersister> persisterClass = metadata.getEntityPersisterClass();
+ if ( persisterClass == null ) {
+ persisterClass = serviceRegistry.getService( PersisterClassResolver.class ).getEntityPersisterClass( metadata );
+ }
+ return create( persisterClass, metadata, cacheAccessStrategy, factory, cfg );
+ }
+
+ private static EntityPersister create(
+ Class extends EntityPersister> persisterClass,
+ PersistentClass metadata,
+ EntityRegionAccessStrategy cacheAccessStrategy,
+ SessionFactoryImplementor factory,
+ Mapping cfg) throws HibernateException {
+ try {
+ Constructor extends EntityPersister> constructor = persisterClass.getConstructor( ENTITY_PERSISTER_CONSTRUCTOR_ARGS );
+ try {
+ return constructor.newInstance( metadata, cacheAccessStrategy, factory, cfg );
+ }
+ catch (MappingException e) {
+ throw e;
+ }
+ catch (InvocationTargetException e) {
+ Throwable target = e.getTargetException();
+ if ( target instanceof HibernateException ) {
+ throw (HibernateException) target;
+ }
+ else {
+ throw new MappingException( "Could not instantiate persister " + persisterClass.getName(), target );
+ }
+ }
+ catch (Exception e) {
+ throw new MappingException( "Could not instantiate persister " + persisterClass.getName(), e );
+ }
+ }
+ catch (MappingException e) {
+ throw e;
+ }
+ catch (Exception e) {
+ throw new MappingException( "Could not get constructor for " + persisterClass.getName(), e );
+ }
+ }
+
+ @Override
+ @SuppressWarnings( {"unchecked"})
+ public CollectionPersister createCollectionPersister(
+ Configuration cfg,
+ Collection metadata,
+ CollectionRegionAccessStrategy cacheAccessStrategy,
+ SessionFactoryImplementor factory) throws HibernateException {
+ Class extends CollectionPersister> persisterClass = metadata.getCollectionPersisterClass();
+ if ( persisterClass == null ) {
+ persisterClass = serviceRegistry.getService( PersisterClassResolver.class ).getCollectionPersisterClass( metadata );
+ }
+
+ return create( persisterClass, cfg, metadata, cacheAccessStrategy, factory );
+ }
+
+ private static CollectionPersister create(
+ Class extends CollectionPersister> persisterClass,
+ Configuration cfg,
+ Collection metadata,
+ CollectionRegionAccessStrategy cacheAccessStrategy,
+ SessionFactoryImplementor factory) throws HibernateException {
+ try {
+ Constructor extends CollectionPersister> constructor = persisterClass.getConstructor( COLLECTION_PERSISTER_CONSTRUCTOR_ARGS );
+ try {
+ return constructor.newInstance( metadata, cacheAccessStrategy, cfg, factory );
+ }
+ catch (MappingException e) {
+ throw e;
+ }
+ catch (InvocationTargetException e) {
+ Throwable target = e.getTargetException();
+ if ( target instanceof HibernateException ) {
+ throw (HibernateException) target;
+ }
+ else {
+ throw new MappingException( "Could not instantiate collection persister " + persisterClass.getName(), target );
+ }
+ }
+ catch (Exception e) {
+ throw new MappingException( "Could not instantiate collection persister " + persisterClass.getName(), e );
+ }
+ }
+ catch (MappingException e) {
+ throw e;
+ }
+ catch (Exception e) {
+ throw new MappingException( "Could not get constructor for " + persisterClass.getName(), e );
+ }
+ }
+}
diff --git a/hibernate-core/src/main/java/org/hibernate/persister/internal/PersisterFactoryInitiator.java b/hibernate-core/src/main/java/org/hibernate/persister/internal/PersisterFactoryInitiator.java
new file mode 100644
index 0000000000..73df183a37
--- /dev/null
+++ b/hibernate-core/src/main/java/org/hibernate/persister/internal/PersisterFactoryInitiator.java
@@ -0,0 +1,69 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2011, 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
+ */
+package org.hibernate.persister.internal;
+
+import org.hibernate.persister.spi.PersisterFactory;
+import org.hibernate.service.classloading.spi.ClassLoaderService;
+import org.hibernate.service.spi.ServiceException;
+import org.hibernate.service.spi.ServiceInitiator;
+import org.hibernate.service.spi.ServiceRegistry;
+
+import java.util.Map;
+
+/**
+ * @author Steve Ebersole
+ */
+public class PersisterFactoryInitiator implements ServiceInitiator {
+ public static final PersisterFactoryInitiator INSTANCE = new PersisterFactoryInitiator();
+
+ public static final String IMPL_NAME = "hibernate.persister.factory";
+
+ @Override
+ public Class getServiceInitiated() {
+ return PersisterFactory.class;
+ }
+
+ @Override
+ @SuppressWarnings( {"unchecked"})
+ public PersisterFactory initiateService(Map configurationValues, ServiceRegistry registry) {
+ final Object customImpl = configurationValues.get( IMPL_NAME );
+ if ( customImpl == null ) {
+ return new PersisterFactoryImpl();
+ }
+
+ if ( PersisterFactory.class.isInstance( customImpl ) ) {
+ return (PersisterFactory) customImpl;
+ }
+
+ final Class extends PersisterFactory> customImplClass = Class.class.isInstance( customImpl )
+ ? ( Class extends PersisterFactory> ) customImpl
+ : registry.getService( ClassLoaderService.class ).classForName( customImpl.toString() );
+ try {
+ return customImplClass.newInstance();
+ }
+ catch (Exception e) {
+ throw new ServiceException( "Could not initialize custom PersisterFactory impl [" + customImplClass.getName() + "]", e );
+ }
+ }
+}
diff --git a/hibernate-core/src/main/java/org/hibernate/persister/internal/StandardPersisterClassResolver.java b/hibernate-core/src/main/java/org/hibernate/persister/internal/StandardPersisterClassResolver.java
new file mode 100644
index 0000000000..6261b85578
--- /dev/null
+++ b/hibernate-core/src/main/java/org/hibernate/persister/internal/StandardPersisterClassResolver.java
@@ -0,0 +1,88 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2011, 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
+ */
+package org.hibernate.persister.internal;
+
+import org.hibernate.mapping.Collection;
+import org.hibernate.mapping.JoinedSubclass;
+import org.hibernate.mapping.PersistentClass;
+import org.hibernate.mapping.RootClass;
+import org.hibernate.mapping.UnionSubclass;
+import org.hibernate.persister.collection.BasicCollectionPersister;
+import org.hibernate.persister.collection.CollectionPersister;
+import org.hibernate.persister.collection.OneToManyPersister;
+import org.hibernate.persister.entity.EntityPersister;
+import org.hibernate.persister.entity.JoinedSubclassEntityPersister;
+import org.hibernate.persister.entity.SingleTableEntityPersister;
+import org.hibernate.persister.entity.UnionSubclassEntityPersister;
+import org.hibernate.persister.spi.PersisterClassResolver;
+import org.hibernate.persister.spi.UnknownPersisterException;
+
+/**
+ * @author Steve Ebersole
+ */
+public class StandardPersisterClassResolver implements PersisterClassResolver {
+ @Override
+ public Class extends EntityPersister> getEntityPersisterClass(PersistentClass metadata) {
+ // todo : make sure this is based on an attribute kept on the metamodel in the new code, not the concrete PersistentClass impl found!
+ if ( RootClass.class.isInstance( metadata ) ) {
+ return singleTableEntityPersister();
+ }
+ else if ( JoinedSubclass.class.isInstance( metadata ) ) {
+ return joinedSubclassEntityPersister();
+ }
+ else if ( UnionSubclass.class.isInstance( metadata ) ) {
+ return unionSubclassEntityPersister();
+ }
+ else {
+ throw new UnknownPersisterException(
+ "Could not determine persister implementation for entity [" + metadata.getEntityName() + "]"
+ );
+ }
+ }
+
+ public Class extends EntityPersister> singleTableEntityPersister() {
+ return SingleTableEntityPersister.class;
+ }
+
+ public Class extends EntityPersister> joinedSubclassEntityPersister() {
+ return JoinedSubclassEntityPersister.class;
+ }
+
+ public Class extends EntityPersister> unionSubclassEntityPersister() {
+ return UnionSubclassEntityPersister.class;
+ }
+
+ @Override
+ public Class extends CollectionPersister> getCollectionPersisterClass(Collection metadata) {
+ return metadata.isOneToMany() ? oneToManyPersister() : basicCollectionPersister();
+ }
+
+ private Class oneToManyPersister() {
+ return OneToManyPersister.class;
+ }
+
+ private Class basicCollectionPersister() {
+ return BasicCollectionPersister.class;
+ }
+}
diff --git a/hibernate-core/src/main/java/org/hibernate/persister/spi/PersisterClassResolver.java b/hibernate-core/src/main/java/org/hibernate/persister/spi/PersisterClassResolver.java
new file mode 100644
index 0000000000..1137d12333
--- /dev/null
+++ b/hibernate-core/src/main/java/org/hibernate/persister/spi/PersisterClassResolver.java
@@ -0,0 +1,54 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2011, 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
+ */
+package org.hibernate.persister.spi;
+
+import org.hibernate.mapping.Collection;
+import org.hibernate.mapping.PersistentClass;
+import org.hibernate.persister.collection.CollectionPersister;
+import org.hibernate.persister.entity.EntityPersister;
+import org.hibernate.service.spi.Service;
+
+/**
+ * Provides persister classes based on the entity or collection role.
+ * The persister class is chosen according to the following rules in decreasing priority:
+ * - the persister class defined explicitly via annotation or XML
+ * - the persister class returned by the PersisterClassResolver implementation (if not null)
+ * - the default provider as chosen by Hibernate Core (best choice most of the time)
+ *
+ * @author Emmanuel Bernard
+ * @author Steve Ebersole
+ */
+public interface PersisterClassResolver extends Service {
+ /**
+ * Returns the entity persister class for a given entityName or null
+ * if the entity persister class should be the default.
+ */
+ Class extends EntityPersister> getEntityPersisterClass(PersistentClass metadata);
+
+ /**
+ * Returns the collection persister class for a given collection role or null
+ * if the collection persister class should be the default.
+ */
+ Class extends CollectionPersister> getCollectionPersisterClass(Collection metadata);
+}
diff --git a/hibernate-core/src/main/java/org/hibernate/persister/spi/PersisterFactory.java b/hibernate-core/src/main/java/org/hibernate/persister/spi/PersisterFactory.java
new file mode 100644
index 0000000000..1108fa1752
--- /dev/null
+++ b/hibernate-core/src/main/java/org/hibernate/persister/spi/PersisterFactory.java
@@ -0,0 +1,89 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2011, 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
+ */
+package org.hibernate.persister.spi;
+
+import org.hibernate.HibernateException;
+import org.hibernate.cache.access.CollectionRegionAccessStrategy;
+import org.hibernate.cache.access.EntityRegionAccessStrategy;
+import org.hibernate.cfg.Configuration;
+import org.hibernate.engine.Mapping;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.mapping.Collection;
+import org.hibernate.mapping.PersistentClass;
+import org.hibernate.persister.collection.CollectionPersister;
+import org.hibernate.persister.entity.EntityPersister;
+import org.hibernate.service.spi.Service;
+
+/**
+ * Contract for creating persister instances (both {@link EntityPersister} and {@link } varieties).
+ *
+ * @author Steve Ebersole
+ */
+public interface PersisterFactory extends Service {
+
+ // TODO: is it really neceassry to provide Configuration to CollectionPersisters ?
+ // Should it not be enough with associated class ? or why does EntityPersister's not get access to configuration ?
+ //
+ // The only reason I could see that Configuration gets passed to collection persisters
+ // is so that they can look up the dom4j node name of the entity element in case
+ // no explicit node name was applied at the collection element level. Are you kidding me?
+ // Trivial to fix then. Just store and expose the node name on the entity persister
+ // (which the collection persister looks up anyway via other means...).
+
+ /**
+ * Create an entity persister instance.
+ *
+ * @param model The O/R mapping metamodel definition for the entity
+ * @param cacheAccessStrategy The caching strategy for this entity
+ * @param factory The session factory
+ * @param cfg The overall mapping
+ *
+ * @return An appropriate entity persister instance.
+ *
+ * @throws HibernateException Indicates a problem building the persister.
+ */
+ public EntityPersister createEntityPersister(
+ PersistentClass model,
+ EntityRegionAccessStrategy cacheAccessStrategy,
+ SessionFactoryImplementor factory,
+ Mapping cfg) throws HibernateException;
+
+ /**
+ * Create a collection persister instance.
+ *
+ * @param cfg The configuration
+ * @param model The O/R mapping metamodel definition for the collection
+ * @param cacheAccessStrategy The caching strategy for this collection
+ * @param factory The session factory
+ *
+ * @return An appropriate collection persister instance.
+ *
+ * @throws HibernateException Indicates a problem building the persister.
+ */
+ public CollectionPersister createCollectionPersister(
+ Configuration cfg,
+ Collection model,
+ CollectionRegionAccessStrategy cacheAccessStrategy,
+ SessionFactoryImplementor factory) throws HibernateException;
+}
diff --git a/hibernate-core/src/main/java/org/hibernate/persister/spi/UnknownPersisterException.java b/hibernate-core/src/main/java/org/hibernate/persister/spi/UnknownPersisterException.java
new file mode 100644
index 0000000000..f5b67d6e84
--- /dev/null
+++ b/hibernate-core/src/main/java/org/hibernate/persister/spi/UnknownPersisterException.java
@@ -0,0 +1,41 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2011, 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
+ */
+package org.hibernate.persister.spi;
+
+import org.hibernate.HibernateException;
+
+/**
+ * Indicates that the persister to use is not known and couyld not be determined.
+ *
+ * @author Steve Ebersole
+ */
+public class UnknownPersisterException extends HibernateException {
+ public UnknownPersisterException(String s) {
+ super( s );
+ }
+
+ public UnknownPersisterException(String string, Throwable root) {
+ super( string, root );
+ }
+}
diff --git a/hibernate-core/src/main/java/org/hibernate/service/spi/StandardServiceInitiators.java b/hibernate-core/src/main/java/org/hibernate/service/spi/StandardServiceInitiators.java
index a6b8a545e7..f3d2eba700 100644
--- a/hibernate-core/src/main/java/org/hibernate/service/spi/StandardServiceInitiators.java
+++ b/hibernate-core/src/main/java/org/hibernate/service/spi/StandardServiceInitiators.java
@@ -26,6 +26,8 @@ package org.hibernate.service.spi;
import org.hibernate.engine.jdbc.batch.internal.BatchBuilderInitiator;
import org.hibernate.engine.jdbc.internal.JdbcServicesInitiator;
import org.hibernate.engine.transaction.internal.TransactionFactoryInitiator;
+import org.hibernate.persister.internal.PersisterClassResolverInitiator;
+import org.hibernate.persister.internal.PersisterFactoryInitiator;
import org.hibernate.service.classloading.internal.ClassLoaderServiceInitiator;
import org.hibernate.service.jdbc.connections.internal.ConnectionProviderInitiator;
import org.hibernate.service.jdbc.dialect.internal.DialectFactoryInitiator;
@@ -50,6 +52,9 @@ public class StandardServiceInitiators {
serviceInitiators.add( JndiServiceInitiator.INSTANCE );
serviceInitiators.add( JmxServiceInitiator.INSTANCE );
+ serviceInitiators.add( PersisterClassResolverInitiator.INSTANCE );
+ serviceInitiators.add( PersisterFactoryInitiator.INSTANCE );
+
serviceInitiators.add( ConnectionProviderInitiator.INSTANCE );
serviceInitiators.add( DialectResolverInitiator.INSTANCE );
serviceInitiators.add( DialectFactoryInitiator.INSTANCE );
diff --git a/hibernate-core/src/test/java/org/hibernate/test/cfg/persister/GoofyPersisterClassProvider.java b/hibernate-core/src/test/java/org/hibernate/test/cfg/persister/GoofyPersisterClassProvider.java
index 2cdcb817c2..9c09506736 100644
--- a/hibernate-core/src/test/java/org/hibernate/test/cfg/persister/GoofyPersisterClassProvider.java
+++ b/hibernate-core/src/test/java/org/hibernate/test/cfg/persister/GoofyPersisterClassProvider.java
@@ -41,9 +41,10 @@ import org.hibernate.engine.SessionImplementor;
import org.hibernate.engine.ValueInclusion;
import org.hibernate.id.IdentifierGenerator;
import org.hibernate.mapping.Collection;
+import org.hibernate.mapping.PersistentClass;
import org.hibernate.metadata.ClassMetadata;
import org.hibernate.metadata.CollectionMetadata;
-import org.hibernate.persister.PersisterClassProvider;
+import org.hibernate.persister.spi.PersisterClassResolver;
import org.hibernate.persister.collection.CollectionPersister;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.tuple.entity.EntityMetamodel;
@@ -54,12 +55,14 @@ import org.hibernate.type.VersionType;
/**
* @author Emmanuel Bernard
*/
-public class GoofyPersisterClassProvider implements PersisterClassProvider {
- public Class extends EntityPersister> getEntityPersisterClass(String entityName) {
+public class GoofyPersisterClassProvider implements PersisterClassResolver {
+ @Override
+ public Class extends EntityPersister> getEntityPersisterClass(PersistentClass metadata) {
return NoopEntityPersister.class;
}
- public Class extends CollectionPersister> getCollectionPersisterClass(String collectionPersister) {
+ @Override
+ public Class extends CollectionPersister> getCollectionPersisterClass(Collection metadata) {
return NoopCollectionPersister.class;
}
diff --git a/hibernate-core/src/test/java/org/hibernate/test/cfg/persister/PersisterClassProviderTest.java b/hibernate-core/src/test/java/org/hibernate/test/cfg/persister/PersisterClassProviderTest.java
index d94a8952ba..46211c597c 100644
--- a/hibernate-core/src/test/java/org/hibernate/test/cfg/persister/PersisterClassProviderTest.java
+++ b/hibernate-core/src/test/java/org/hibernate/test/cfg/persister/PersisterClassProviderTest.java
@@ -23,6 +23,7 @@ package org.hibernate.test.cfg.persister;
import org.hibernate.MappingException;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
+import org.hibernate.persister.spi.PersisterClassResolver;
import org.hibernate.service.spi.ServiceRegistry;
import org.hibernate.testing.ServiceRegistryBuilder;
import org.hibernate.testing.junit.UnitTestCase;
@@ -44,10 +45,9 @@ public class PersisterClassProviderTest extends UnitTestCase {
SessionFactory sessionFactory = cfg.buildSessionFactory( serviceRegistry );
sessionFactory.close();
-
+ serviceRegistry.registerService( PersisterClassResolver.class, new GoofyPersisterClassProvider() );
cfg = new Configuration();
cfg.addAnnotatedClass( Gate.class );
- cfg.setPersisterClassProvider( new GoofyPersisterClassProvider() );
try {
sessionFactory = cfg.buildSessionFactory( serviceRegistry );
sessionFactory.close();
@@ -63,7 +63,6 @@ public class PersisterClassProviderTest extends UnitTestCase {
cfg = new Configuration();
cfg.addAnnotatedClass( Portal.class );
cfg.addAnnotatedClass( Window.class );
- cfg.setPersisterClassProvider( new GoofyPersisterClassProvider() );
try {
sessionFactory = cfg.buildSessionFactory( serviceRegistry );
sessionFactory.close();
diff --git a/hibernate-entitymanager/src/main/java/org/hibernate/ejb/AvailableSettings.java b/hibernate-entitymanager/src/main/java/org/hibernate/ejb/AvailableSettings.java
index 92c64df0ad..e53a801690 100644
--- a/hibernate-entitymanager/src/main/java/org/hibernate/ejb/AvailableSettings.java
+++ b/hibernate-entitymanager/src/main/java/org/hibernate/ejb/AvailableSettings.java
@@ -247,7 +247,7 @@ public class AvailableSettings {
public static final String NAMING_STRATEGY = "hibernate.ejb.naming_strategy";
/**
- * PersisterClassProvider class name, the class has to gave a no-arg constructor
+ * PersisterClassResolver class name, the class has to gave a no-arg constructor
*/
public static final String PERSISTER_CLASS_PROVIDER = "hibernate.ejb.persister_class_provider";
diff --git a/hibernate-entitymanager/src/main/java/org/hibernate/ejb/Ejb3Configuration.java b/hibernate-entitymanager/src/main/java/org/hibernate/ejb/Ejb3Configuration.java
index 07eaa01b90..56a882f1d7 100644
--- a/hibernate-entitymanager/src/main/java/org/hibernate/ejb/Ejb3Configuration.java
+++ b/hibernate-entitymanager/src/main/java/org/hibernate/ejb/Ejb3Configuration.java
@@ -91,7 +91,6 @@ import org.hibernate.engine.transaction.internal.jdbc.JdbcTransactionFactory;
import org.hibernate.event.EventListeners;
import org.hibernate.mapping.AuxiliaryDatabaseObject;
import org.hibernate.mapping.PersistentClass;
-import org.hibernate.persister.PersisterClassProvider;
import org.hibernate.proxy.EntityNotFoundDelegate;
import org.hibernate.secure.JACCConfiguration;
import org.hibernate.service.jdbc.connections.internal.ConnectionProviderInitiator;
@@ -1049,18 +1048,6 @@ public class Ejb3Configuration implements Serializable, Referenceable {
cfg.setNamingStrategy( namingStrategy );
}
- final PersisterClassProvider persisterClassProvider = instantiateCustomClassFromConfiguration(
- preparedProperties,
- null,
- cfg.getPersisterClassProvider(),
- AvailableSettings.PERSISTER_CLASS_PROVIDER,
- "persister class provider",
- PersisterClassProvider.class
- );
- if ( persisterClassProvider != null ) {
- cfg.setPersisterClassProvider( persisterClassProvider );
- }
-
if ( jaccKeys.size() > 0 ) {
addSecurity( jaccKeys, preparedProperties, workingVars );
}
@@ -1581,11 +1568,6 @@ public class Ejb3Configuration implements Serializable, Referenceable {
return this;
}
- public Ejb3Configuration setPersisterClassProvider(PersisterClassProvider persisterClassProvider) {
- cfg.setPersisterClassProvider( persisterClassProvider );
- return this;
- }
-
public void setListeners(String type, String[] listenerClasses) {
cfg.setListeners( type, listenerClasses );
}
diff --git a/hibernate-entitymanager/src/test/java/org/hibernate/ejb/test/ejb3configuration/PersisterClassProviderTest.java b/hibernate-entitymanager/src/test/java/org/hibernate/ejb/test/ejb3configuration/PersisterClassProviderTest.java
index a3935788a1..16d07eaba7 100644
--- a/hibernate-entitymanager/src/test/java/org/hibernate/ejb/test/ejb3configuration/PersisterClassProviderTest.java
+++ b/hibernate-entitymanager/src/test/java/org/hibernate/ejb/test/ejb3configuration/PersisterClassProviderTest.java
@@ -40,8 +40,11 @@ import org.hibernate.engine.SessionFactoryImplementor;
import org.hibernate.engine.SessionImplementor;
import org.hibernate.engine.ValueInclusion;
import org.hibernate.id.IdentifierGenerator;
+import org.hibernate.mapping.Collection;
+import org.hibernate.mapping.PersistentClass;
import org.hibernate.metadata.ClassMetadata;
-import org.hibernate.persister.PersisterClassProvider;
+import org.hibernate.persister.internal.PersisterClassResolverInitiator;
+import org.hibernate.persister.spi.PersisterClassResolver;
import org.hibernate.persister.collection.CollectionPersister;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.tuple.entity.EntityMetamodel;
@@ -54,7 +57,7 @@ import org.hibernate.type.VersionType;
public class PersisterClassProviderTest extends junit.framework.TestCase {
public void testPersisterClassProvider() {
Ejb3Configuration conf = new Ejb3Configuration();
- conf.setPersisterClassProvider( new GoofyPersisterClassProvider() );
+ conf.getProperties().put( PersisterClassResolverInitiator.IMPL_NAME, GoofyPersisterClassProvider.class );
conf.addAnnotatedClass( Bell.class );
try {
final EntityManagerFactory entityManagerFactory = conf.buildEntityManagerFactory();
@@ -68,13 +71,14 @@ public class PersisterClassProviderTest extends junit.framework.TestCase {
}
}
- public static class GoofyPersisterClassProvider implements PersisterClassProvider {
-
- public Class extends EntityPersister> getEntityPersisterClass(String entityName) {
+ public static class GoofyPersisterClassProvider implements PersisterClassResolver {
+ @Override
+ public Class extends EntityPersister> getEntityPersisterClass(PersistentClass metadata) {
return GoofyProvider.class;
}
- public Class extends CollectionPersister> getCollectionPersisterClass(String collectionPersister) {
+ @Override
+ public Class extends CollectionPersister> getCollectionPersisterClass(Collection metadata) {
return null;
}
}
From 21cc90fbf448ff537e44d12e26679d6b0d49ed9f Mon Sep 17 00:00:00 2001
From: Steve Ebersole
Date: Fri, 4 Mar 2011 21:46:06 -0600
Subject: [PATCH 12/19] HHH-5985 - Remove TransactionHelper in preference of
IsolationDelegate
---
.../hibernate/engine/TransactionHelper.java | 74 ------
.../jdbc/internal/JdbcCoordinatorImpl.java | 24 ++
.../engine/jdbc/spi/JdbcCoordinator.java | 5 +
.../engine/jdbc/spi/SQLStatementLogger.java | 7 +-
.../internal/jdbc/JdbcIsolationDelegate.java | 65 ++++++
.../internal/jta/JtaIsolationDelegate.java | 109 +++++++++
.../transaction/spi/IsolationDelegate.java | 13 ++
.../id/MultipleHiLoPerTableGenerator.java | 154 +++++++------
.../id/PersistentIdentifierGenerator.java | 8 +-
.../java/org/hibernate/id/TableGenerator.java | 154 ++++++-------
.../hibernate/id/enhanced/TableGenerator.java | 218 +++++++++---------
.../hibernate/id/enhanced/TableStructure.java | 179 +++++++-------
.../org/hibernate/jdbc/ReturningWork.java | 46 ++++
13 files changed, 616 insertions(+), 440 deletions(-)
delete mode 100644 hibernate-core/src/main/java/org/hibernate/engine/TransactionHelper.java
create mode 100644 hibernate-core/src/main/java/org/hibernate/jdbc/ReturningWork.java
diff --git a/hibernate-core/src/main/java/org/hibernate/engine/TransactionHelper.java b/hibernate-core/src/main/java/org/hibernate/engine/TransactionHelper.java
deleted file mode 100644
index d820594a9a..0000000000
--- a/hibernate-core/src/main/java/org/hibernate/engine/TransactionHelper.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Hibernate, Relational Persistence for Idiomatic Java
- *
- * Copyright (c) 2008-2011, 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
- */
-package org.hibernate.engine;
-
-import org.hibernate.HibernateException;
-import org.hibernate.jdbc.Work;
-
-import java.io.Serializable;
-import java.sql.Connection;
-import java.sql.SQLException;
-
-/**
- * Allows work to be done outside the current transaction, by suspending it,
- * and performing work in a new transaction
- *
- * @author Emmanuel Bernard
- */
-public abstract class TransactionHelper {
-
- // todo : remove this and just have subclasses use IsolationDelegate directly...
-
- /**
- * The work to be done
- */
- protected abstract Serializable doWorkInCurrentTransaction(Connection conn, String sql) throws SQLException;
-
- /**
- * Suspend the current transaction and perform work in a new transaction
- */
- public Serializable doWorkInNewTransaction(final SessionImplementor session) throws HibernateException {
- class WorkToDo implements Work {
- Serializable generatedValue;
-
- @Override
- public void execute(Connection connection) throws SQLException {
- String sql = null;
- try {
- generatedValue = doWorkInCurrentTransaction( connection, sql );
- }
- catch( SQLException e ) {
- throw session.getFactory().getSQLExceptionHelper().convert(
- e,
- "could not get or update next value",
- sql
- );
- }
- }
- }
- WorkToDo work = new WorkToDo();
- session.getTransactionCoordinator().getTransaction().createIsolationDelegate().delegateWork( work, true );
- return work.generatedValue;
- }
-}
diff --git a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/internal/JdbcCoordinatorImpl.java b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/internal/JdbcCoordinatorImpl.java
index 241530c1a6..dbd92ad62b 100644
--- a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/internal/JdbcCoordinatorImpl.java
+++ b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/internal/JdbcCoordinatorImpl.java
@@ -36,6 +36,7 @@ import org.hibernate.engine.transaction.internal.TransactionCoordinatorImpl;
import org.hibernate.engine.transaction.spi.TransactionContext;
import org.hibernate.engine.transaction.spi.TransactionCoordinator;
import org.hibernate.engine.transaction.spi.TransactionEnvironment;
+import org.hibernate.jdbc.ReturningWork;
import org.hibernate.jdbc.Work;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -204,6 +205,29 @@ public class JdbcCoordinatorImpl implements JdbcCoordinator {
}
}
+ @Override
+ public T coordinateWork(ReturningWork work) {
+ Connection connection = getLogicalConnection().getDistinctConnectionProxy();
+ try {
+ T result = work.execute( connection );
+ getLogicalConnection().afterStatementExecution();
+ return result;
+ }
+ catch ( SQLException e ) {
+ throw sqlExceptionHelper().convert( e, "error executing work" );
+ }
+ finally {
+ try {
+ if ( ! connection.isClosed() ) {
+ connection.close();
+ }
+ }
+ catch (SQLException e) {
+ log.debug( "Error closing connection proxy", e );
+ }
+ }
+ }
+
public void executeBatch() {
if ( currentBatch != null ) {
currentBatch.execute();
diff --git a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/spi/JdbcCoordinator.java b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/spi/JdbcCoordinator.java
index d1d9a143de..b693081470 100644
--- a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/spi/JdbcCoordinator.java
+++ b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/spi/JdbcCoordinator.java
@@ -26,6 +26,8 @@ package org.hibernate.engine.jdbc.spi;
import org.hibernate.engine.jdbc.batch.spi.Batch;
import org.hibernate.engine.jdbc.batch.spi.BatchKey;
import org.hibernate.engine.transaction.spi.TransactionCoordinator;
+import org.hibernate.id.IntegralDataTypeHolder;
+import org.hibernate.jdbc.ReturningWork;
import org.hibernate.jdbc.Work;
import java.io.Serializable;
@@ -88,9 +90,12 @@ public interface JdbcCoordinator extends Serializable {
public void coordinateWork(Work work);
+ public T coordinateWork(ReturningWork work);
+
public void executeBatch();
public void cancelLastQuery();
public void setTransactionTimeOut(int timeout);
+
}
diff --git a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/spi/SQLStatementLogger.java b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/spi/SQLStatementLogger.java
index 141c14ce79..5be6dd39ce 100644
--- a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/spi/SQLStatementLogger.java
+++ b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/spi/SQLStatementLogger.java
@@ -27,6 +27,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.hibernate.jdbc.util.FormatStyle;
+import org.hibernate.jdbc.util.Formatter;
/**
* Centralize logging for SQL statements.
@@ -90,9 +91,13 @@ public class SQLStatementLogger {
*/
public void logStatement(String statement) {
// for now just assume a DML log for formatting
+ logStatement( statement, FormatStyle.BASIC.getFormatter() );
+ }
+
+ public void logStatement(String statement, Formatter formatter) {
if ( format ) {
if ( logToStdout || log.isDebugEnabled() ) {
- statement = FormatStyle.BASIC.getFormatter().format( statement );
+ statement = formatter.format( statement );
}
}
log.debug( statement );
diff --git a/hibernate-core/src/main/java/org/hibernate/engine/transaction/internal/jdbc/JdbcIsolationDelegate.java b/hibernate-core/src/main/java/org/hibernate/engine/transaction/internal/jdbc/JdbcIsolationDelegate.java
index 01a4e611d2..f00fbf55ca 100644
--- a/hibernate-core/src/main/java/org/hibernate/engine/transaction/internal/jdbc/JdbcIsolationDelegate.java
+++ b/hibernate-core/src/main/java/org/hibernate/engine/transaction/internal/jdbc/JdbcIsolationDelegate.java
@@ -34,6 +34,7 @@ import org.hibernate.HibernateException;
import org.hibernate.engine.jdbc.spi.SQLExceptionHelper;
import org.hibernate.engine.transaction.spi.IsolationDelegate;
import org.hibernate.engine.transaction.spi.TransactionCoordinator;
+import org.hibernate.jdbc.ReturningWork;
import org.hibernate.jdbc.Work;
import org.hibernate.service.jdbc.connections.spi.ConnectionProvider;
@@ -120,4 +121,68 @@ public class JdbcIsolationDelegate implements IsolationDelegate {
throw sqlExceptionHelper().convert( sqle, "unable to obtain isolated JDBC connection" );
}
}
+
+ @Override
+ public T delegateWork(ReturningWork work, boolean transacted) throws HibernateException {
+ boolean wasAutoCommit = false;
+ try {
+ // todo : should we use a connection proxy here?
+ Connection connection = connectionProvider().getConnection();
+ try {
+ if ( transacted ) {
+ if ( connection.getAutoCommit() ) {
+ wasAutoCommit = true;
+ connection.setAutoCommit( false );
+ }
+ }
+
+ T result = work.execute( connection );
+
+ if ( transacted ) {
+ connection.commit();
+ }
+
+ return result;
+ }
+ catch ( Exception e ) {
+ try {
+ if ( transacted && !connection.isClosed() ) {
+ connection.rollback();
+ }
+ }
+ catch ( Exception ignore ) {
+ log.info( "unable to rollback connection on exception [" + ignore + "]" );
+ }
+
+ if ( e instanceof HibernateException ) {
+ throw (HibernateException) e;
+ }
+ else if ( e instanceof SQLException ) {
+ throw sqlExceptionHelper().convert( (SQLException) e, "error performing isolated work" );
+ }
+ else {
+ throw new HibernateException( "error performing isolated work", e );
+ }
+ }
+ finally {
+ if ( transacted && wasAutoCommit ) {
+ try {
+ connection.setAutoCommit( true );
+ }
+ catch ( Exception ignore ) {
+ log.trace( "was unable to reset connection back to auto-commit" );
+ }
+ }
+ try {
+ connectionProvider().closeConnection( connection );
+ }
+ catch ( Exception ignore ) {
+ log.info( "Unable to release isolated connection [" + ignore + "]" );
+ }
+ }
+ }
+ catch ( SQLException sqle ) {
+ throw sqlExceptionHelper().convert( sqle, "unable to obtain isolated JDBC connection" );
+ }
+ }
}
diff --git a/hibernate-core/src/main/java/org/hibernate/engine/transaction/internal/jta/JtaIsolationDelegate.java b/hibernate-core/src/main/java/org/hibernate/engine/transaction/internal/jta/JtaIsolationDelegate.java
index 7e071428fe..42bcfa9966 100644
--- a/hibernate-core/src/main/java/org/hibernate/engine/transaction/internal/jta/JtaIsolationDelegate.java
+++ b/hibernate-core/src/main/java/org/hibernate/engine/transaction/internal/jta/JtaIsolationDelegate.java
@@ -37,6 +37,7 @@ import org.hibernate.HibernateException;
import org.hibernate.engine.jdbc.spi.SQLExceptionHelper;
import org.hibernate.engine.transaction.spi.IsolationDelegate;
import org.hibernate.engine.transaction.spi.TransactionCoordinator;
+import org.hibernate.jdbc.ReturningWork;
import org.hibernate.jdbc.Work;
import org.hibernate.service.jdbc.connections.spi.ConnectionProvider;
@@ -181,5 +182,113 @@ public class JtaIsolationDelegate implements IsolationDelegate {
}
}
+ @Override
+ public T delegateWork(ReturningWork work, boolean transacted) throws HibernateException {
+ TransactionManager transactionManager = transactionManager();
+
+ try {
+ // First we suspend any current JTA transaction
+ Transaction surroundingTransaction = transactionManager.suspend();
+ if ( log.isDebugEnabled() ) {
+ log.debug( "surrounding JTA transaction suspended [" + surroundingTransaction + "]" );
+ }
+
+ boolean hadProblems = false;
+ try {
+ // then perform the requested work
+ if ( transacted ) {
+ return doTheWorkInNewTransaction( work, transactionManager );
+ }
+ else {
+ return doTheWorkInNoTransaction( work );
+ }
+ }
+ catch ( HibernateException e ) {
+ hadProblems = true;
+ throw e;
+ }
+ finally {
+ try {
+ transactionManager.resume( surroundingTransaction );
+ if ( log.isDebugEnabled() ) {
+ log.debug( "surrounding JTA transaction resumed [" + surroundingTransaction + "]" );
+ }
+ }
+ catch( Throwable t ) {
+ // if the actually work had an error use that, otherwise error based on t
+ if ( !hadProblems ) {
+ //noinspection ThrowFromFinallyBlock
+ throw new HibernateException( "Unable to resume previously suspended transaction", t );
+ }
+ }
+ }
+ }
+ catch ( SystemException e ) {
+ throw new HibernateException( "Unable to suspend current JTA transaction", e );
+ }
+ }
+
+ private T doTheWorkInNewTransaction(ReturningWork work, TransactionManager transactionManager) {
+ T result = null;
+ try {
+ // start the new isolated transaction
+ transactionManager.begin();
+
+ try {
+ result = doTheWork( work );
+ // if everything went ok, commit the isolated transaction
+ transactionManager.commit();
+ }
+ catch ( Exception e ) {
+ try {
+ transactionManager.rollback();
+ }
+ catch ( Exception ignore ) {
+ log.info( "Unable to rollback isolated transaction on error [" + e + "] : [" + ignore + "]" );
+ }
+ }
+ }
+ catch ( SystemException e ) {
+ throw new HibernateException( "Unable to start isolated transaction", e );
+ }
+ catch ( NotSupportedException e ) {
+ throw new HibernateException( "Unable to start isolated transaction", e );
+ }
+ return result;
+ }
+
+ private T doTheWorkInNoTransaction(ReturningWork work) {
+ return doTheWork( work );
+ }
+
+ private T doTheWork(ReturningWork work) {
+ try {
+ // obtain our isolated connection
+ Connection connection = connectionProvider().getConnection();
+ try {
+ // do the actual work
+ return work.execute( connection );
+ }
+ catch ( HibernateException e ) {
+ throw e;
+ }
+ catch ( Exception e ) {
+ throw new HibernateException( "Unable to perform isolated work", e );
+ }
+ finally {
+ try {
+ // no matter what, release the connection (handle)
+ connectionProvider().closeConnection( connection );
+ }
+ catch ( Throwable ignore ) {
+ log.info( "Unable to release isolated connection [" + ignore + "]" );
+ }
+ }
+ }
+ catch ( SQLException e ) {
+ throw sqlExceptionHelper().convert( e, "unable to obtain isolated JDBC connection" );
+ }
+ }
+
}
diff --git a/hibernate-core/src/main/java/org/hibernate/engine/transaction/spi/IsolationDelegate.java b/hibernate-core/src/main/java/org/hibernate/engine/transaction/spi/IsolationDelegate.java
index 68935e95f4..e744b0d00a 100644
--- a/hibernate-core/src/main/java/org/hibernate/engine/transaction/spi/IsolationDelegate.java
+++ b/hibernate-core/src/main/java/org/hibernate/engine/transaction/spi/IsolationDelegate.java
@@ -24,6 +24,7 @@
package org.hibernate.engine.transaction.spi;
import org.hibernate.HibernateException;
+import org.hibernate.jdbc.ReturningWork;
import org.hibernate.jdbc.Work;
/**
@@ -41,4 +42,16 @@ public interface IsolationDelegate {
* @throws HibernateException Indicates a problem performing the work.
*/
public void delegateWork(Work work, boolean transacted) throws HibernateException;
+
+ /**
+ * Perform the given work in isolation from current transaction.
+ *
+ * @param work The work to be performed.
+ * @param transacted Should the work itself be done in a (isolated) transaction?
+ *
+ * @return The work result
+ *
+ * @throws HibernateException Indicates a problem performing the work.
+ */
+ public T delegateWork(ReturningWork work, boolean transacted) throws HibernateException;
}
diff --git a/hibernate-core/src/main/java/org/hibernate/id/MultipleHiLoPerTableGenerator.java b/hibernate-core/src/main/java/org/hibernate/id/MultipleHiLoPerTableGenerator.java
index bad7b90643..265c0ae216 100644
--- a/hibernate-core/src/main/java/org/hibernate/id/MultipleHiLoPerTableGenerator.java
+++ b/hibernate-core/src/main/java/org/hibernate/id/MultipleHiLoPerTableGenerator.java
@@ -23,6 +23,24 @@
*/
package org.hibernate.id;
+import org.hibernate.HibernateException;
+import org.hibernate.LockMode;
+import org.hibernate.MappingException;
+import org.hibernate.cfg.ObjectNameNormalizer;
+import org.hibernate.dialect.Dialect;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.engine.jdbc.spi.JdbcServices;
+import org.hibernate.engine.jdbc.spi.SQLStatementLogger;
+import org.hibernate.id.enhanced.AccessCallback;
+import org.hibernate.id.enhanced.OptimizerFactory;
+import org.hibernate.internal.util.config.ConfigurationHelper;
+import org.hibernate.jdbc.ReturningWork;
+import org.hibernate.jdbc.util.FormatStyle;
+import org.hibernate.mapping.Table;
+import org.hibernate.type.Type;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
import java.io.Serializable;
import java.sql.Connection;
import java.sql.PreparedStatement;
@@ -31,22 +49,6 @@ import java.sql.SQLException;
import java.sql.Types;
import java.util.Properties;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.hibernate.HibernateException;
-import org.hibernate.LockMode;
-import org.hibernate.MappingException;
-import org.hibernate.cfg.ObjectNameNormalizer;
-import org.hibernate.id.enhanced.AccessCallback;
-import org.hibernate.id.enhanced.OptimizerFactory;
-import org.hibernate.internal.util.config.ConfigurationHelper;
-import org.hibernate.jdbc.util.FormatStyle;
-import org.hibernate.dialect.Dialect;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.engine.TransactionHelper;
-import org.hibernate.mapping.Table;
-import org.hibernate.type.Type;
-
/**
*
* A hilo IdentifierGenerator that returns a Long, constructed using
@@ -78,11 +80,8 @@ import org.hibernate.type.Type;
* @author Emmanuel Bernard
* @author Klaus Richarz.
*/
-public class MultipleHiLoPerTableGenerator
- extends TransactionHelper
- implements PersistentIdentifierGenerator, Configurable {
-
- private static final Logger log = LoggerFactory.getLogger(MultipleHiLoPerTableGenerator.class);
+public class MultipleHiLoPerTableGenerator implements PersistentIdentifierGenerator, Configurable {
+ private static final Logger log = LoggerFactory.getLogger( MultipleHiLoPerTableGenerator.class );
public static final String ID_TABLE = "table";
public static final String PK_COLUMN_NAME = "primary_key_column";
@@ -146,66 +145,73 @@ public class MultipleHiLoPerTableGenerator
return tableName;
}
- public Serializable doWorkInCurrentTransaction(Connection conn, String sql) throws SQLException {
- IntegralDataTypeHolder value = IdentifierGeneratorHelper.getIntegralDataTypeHolder( returnClass );
- int rows;
- do {
- SQL_STATEMENT_LOGGER.logStatement( query, FormatStyle.BASIC );
- PreparedStatement qps = conn.prepareStatement( query );
- PreparedStatement ips = null;
- try {
- ResultSet rs = qps.executeQuery();
- boolean isInitialized = rs.next();
- if ( !isInitialized ) {
- value.initialize( 0 );
- SQL_STATEMENT_LOGGER.logStatement( insert, FormatStyle.BASIC );
- ips = conn.prepareStatement( insert );
- value.bind( ips, 1 );
- ips.execute();
- }
- else {
- value.initialize( rs, 0 );
- }
- rs.close();
- }
- catch (SQLException sqle) {
- log.error("could not read or init a hi value", sqle);
- throw sqle;
- }
- finally {
- if (ips != null) {
- ips.close();
- }
- qps.close();
- }
+ public synchronized Serializable generate(final SessionImplementor session, Object obj) {
+ final ReturningWork work = new ReturningWork() {
+ @Override
+ public IntegralDataTypeHolder execute(Connection connection) throws SQLException {
+ IntegralDataTypeHolder value = IdentifierGeneratorHelper.getIntegralDataTypeHolder( returnClass );
+ SQLStatementLogger statementLogger = session
+ .getFactory()
+ .getServiceRegistry()
+ .getService( JdbcServices.class )
+ .getSqlStatementLogger();
+ int rows;
+ do {
+ statementLogger.logStatement( query, FormatStyle.BASIC.getFormatter() );
+ PreparedStatement qps = connection.prepareStatement( query );
+ PreparedStatement ips = null;
+ try {
+ ResultSet rs = qps.executeQuery();
+ boolean isInitialized = rs.next();
+ if ( !isInitialized ) {
+ value.initialize( 0 );
+ statementLogger.logStatement( insert, FormatStyle.BASIC.getFormatter() );
+ ips = connection.prepareStatement( insert );
+ value.bind( ips, 1 );
+ ips.execute();
+ }
+ else {
+ value.initialize( rs, 0 );
+ }
+ rs.close();
+ }
+ catch (SQLException sqle) {
+ log.error("could not read or init a hi value", sqle);
+ throw sqle;
+ }
+ finally {
+ if (ips != null) {
+ ips.close();
+ }
+ qps.close();
+ }
- SQL_STATEMENT_LOGGER.logStatement( update, FormatStyle.BASIC );
- PreparedStatement ups = conn.prepareStatement( update );
- try {
- value.copy().increment().bind( ups, 1 );
- value.bind( ups, 2 );
- rows = ups.executeUpdate();
- }
- catch (SQLException sqle) {
- log.error("could not update hi value in: " + tableName, sqle);
- throw sqle;
- }
- finally {
- ups.close();
- }
- } while ( rows==0 );
+ statementLogger.logStatement( update, FormatStyle.BASIC.getFormatter() );
+ PreparedStatement ups = connection.prepareStatement( update );
+ try {
+ value.copy().increment().bind( ups, 1 );
+ value.bind( ups, 2 );
+ rows = ups.executeUpdate();
+ }
+ catch (SQLException sqle) {
+ log.error("could not update hi value in: " + tableName, sqle);
+ throw sqle;
+ }
+ finally {
+ ups.close();
+ }
+ } while ( rows==0 );
- return value;
- }
+ return value;
+ }
+ };
- public synchronized Serializable generate(final SessionImplementor session, Object obj)
- throws HibernateException {
// maxLo < 1 indicates a hilo generator with no hilo :?
if ( maxLo < 1 ) {
//keep the behavior consistent even for boundary usages
IntegralDataTypeHolder value = null;
while ( value == null || value.lt( 1 ) ) {
- value = (IntegralDataTypeHolder) doWorkInNewTransaction( session );
+ value = session.getTransactionCoordinator().getTransaction().createIsolationDelegate().delegateWork( work, true );
}
return value.makeValue();
}
@@ -213,7 +219,7 @@ public class MultipleHiLoPerTableGenerator
return hiloOptimizer.generate(
new AccessCallback() {
public IntegralDataTypeHolder getNextValue() {
- return (IntegralDataTypeHolder) doWorkInNewTransaction( session );
+ return session.getTransactionCoordinator().getTransaction().createIsolationDelegate().delegateWork( work, true );
}
}
);
diff --git a/hibernate-core/src/main/java/org/hibernate/id/PersistentIdentifierGenerator.java b/hibernate-core/src/main/java/org/hibernate/id/PersistentIdentifierGenerator.java
index 6a33796fba..44d4760607 100644
--- a/hibernate-core/src/main/java/org/hibernate/id/PersistentIdentifierGenerator.java
+++ b/hibernate-core/src/main/java/org/hibernate/id/PersistentIdentifierGenerator.java
@@ -1,10 +1,10 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
- * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * Copyright (c) 2008-2011, 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 Middleware LLC.
+ * 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
@@ -20,13 +20,11 @@
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
- *
*/
package org.hibernate.id;
import org.hibernate.HibernateException;
import org.hibernate.dialect.Dialect;
-import org.hibernate.jdbc.util.SQLStatementLogger;
/**
* An IdentifierGenerator that requires creation of database objects.
@@ -99,8 +97,6 @@ public interface PersistentIdentifierGenerator extends IdentifierGenerator {
*/
public Object generatorKey();
- static final SQLStatementLogger SQL_STATEMENT_LOGGER = new SQLStatementLogger( false, false );
-
}
diff --git a/hibernate-core/src/main/java/org/hibernate/id/TableGenerator.java b/hibernate-core/src/main/java/org/hibernate/id/TableGenerator.java
index 8cff01a2a3..1c8019b5df 100644
--- a/hibernate-core/src/main/java/org/hibernate/id/TableGenerator.java
+++ b/hibernate-core/src/main/java/org/hibernate/id/TableGenerator.java
@@ -1,10 +1,10 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
- * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * Copyright (c) 2008-2011, 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 Middleware LLC.
+ * 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
@@ -20,10 +20,24 @@
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
- *
*/
package org.hibernate.id;
+import org.hibernate.HibernateException;
+import org.hibernate.LockMode;
+import org.hibernate.cfg.ObjectNameNormalizer;
+import org.hibernate.dialect.Dialect;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.engine.jdbc.spi.JdbcServices;
+import org.hibernate.engine.jdbc.spi.SQLStatementLogger;
+import org.hibernate.internal.util.config.ConfigurationHelper;
+import org.hibernate.jdbc.ReturningWork;
+import org.hibernate.jdbc.util.FormatStyle;
+import org.hibernate.mapping.Table;
+import org.hibernate.type.Type;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
import java.io.Serializable;
import java.sql.Connection;
import java.sql.PreparedStatement;
@@ -32,19 +46,6 @@ import java.sql.SQLException;
import java.sql.Types;
import java.util.Properties;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.hibernate.HibernateException;
-import org.hibernate.LockMode;
-import org.hibernate.cfg.ObjectNameNormalizer;
-import org.hibernate.internal.util.config.ConfigurationHelper;
-import org.hibernate.jdbc.util.FormatStyle;
-import org.hibernate.dialect.Dialect;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.engine.TransactionHelper;
-import org.hibernate.mapping.Table;
-import org.hibernate.type.Type;
-
/**
* An IdentifierGenerator that uses a database
* table to store the last generated value. It is not
@@ -70,8 +71,7 @@ import org.hibernate.type.Type;
* @see TableHiLoGenerator
* @author Gavin King
*/
-public class TableGenerator extends TransactionHelper
- implements PersistentIdentifierGenerator, Configurable {
+public class TableGenerator implements PersistentIdentifierGenerator, Configurable {
/* COLUMN and TABLE should be renamed but it would break the public API */
/** The column parameter */
public static final String COLUMN = "column";
@@ -139,7 +139,63 @@ public class TableGenerator extends TransactionHelper
}
protected IntegralDataTypeHolder generateHolder(SessionImplementor session) {
- return (IntegralDataTypeHolder) doWorkInNewTransaction( session );
+ final SQLStatementLogger statementLogger = session
+ .getFactory()
+ .getServiceRegistry()
+ .getService( JdbcServices.class )
+ .getSqlStatementLogger();
+ return session.getTransactionCoordinator().getTransaction().createIsolationDelegate().delegateWork(
+ new ReturningWork() {
+ @Override
+ public IntegralDataTypeHolder execute(Connection connection) throws SQLException {
+ IntegralDataTypeHolder value = buildHolder();
+ int rows;
+ do {
+ // The loop ensures atomicity of the
+ // select + update even for no transaction
+ // or read committed isolation level
+
+ statementLogger.logStatement( query, FormatStyle.BASIC.getFormatter() );
+ PreparedStatement qps = connection.prepareStatement( query );
+ try {
+ ResultSet rs = qps.executeQuery();
+ if ( !rs.next() ) {
+ String err = "could not read a hi value - you need to populate the table: " + tableName;
+ log.error(err);
+ throw new IdentifierGenerationException(err);
+ }
+ value.initialize( rs, 1 );
+ rs.close();
+ }
+ catch (SQLException e) {
+ log.error("could not read a hi value", e);
+ throw e;
+ }
+ finally {
+ qps.close();
+ }
+
+ statementLogger.logStatement( update, FormatStyle.BASIC.getFormatter() );
+ PreparedStatement ups = connection.prepareStatement(update);
+ try {
+ value.copy().increment().bind( ups, 1 );
+ value.bind( ups, 2 );
+ rows = ups.executeUpdate();
+ }
+ catch (SQLException sqle) {
+ log.error("could not update hi value in: " + tableName, sqle);
+ throw sqle;
+ }
+ finally {
+ ups.close();
+ }
+ }
+ while (rows==0);
+ return value;
+ }
+ },
+ true
+ );
}
public String[] sqlCreateStrings(Dialect dialect) throws HibernateException {
@@ -165,66 +221,6 @@ public class TableGenerator extends TransactionHelper
return tableName;
}
- /**
- * Get the next value.
- *
- * @param conn The sql connection to use.
- * @param sql n/a
- *
- * @return Prior to 3.5 this method returned an {@link Integer}. Since 3.5 it now
- * returns a {@link IntegralDataTypeHolder}
- *
- * @throws SQLException
- */
- public Serializable doWorkInCurrentTransaction(Connection conn, String sql) throws SQLException {
- IntegralDataTypeHolder value = buildHolder();
- int rows;
- do {
- // The loop ensures atomicity of the
- // select + update even for no transaction
- // or read committed isolation level
-
- sql = query;
- SQL_STATEMENT_LOGGER.logStatement( sql, FormatStyle.BASIC );
- PreparedStatement qps = conn.prepareStatement(query);
- try {
- ResultSet rs = qps.executeQuery();
- if ( !rs.next() ) {
- String err = "could not read a hi value - you need to populate the table: " + tableName;
- log.error(err);
- throw new IdentifierGenerationException(err);
- }
- value.initialize( rs, 1 );
- rs.close();
- }
- catch (SQLException sqle) {
- log.error("could not read a hi value", sqle);
- throw sqle;
- }
- finally {
- qps.close();
- }
-
- sql = update;
- SQL_STATEMENT_LOGGER.logStatement( sql, FormatStyle.BASIC );
- PreparedStatement ups = conn.prepareStatement(update);
- try {
- value.copy().increment().bind( ups, 1 );
- value.bind( ups, 2 );
- rows = ups.executeUpdate();
- }
- catch (SQLException sqle) {
- log.error("could not update hi value in: " + tableName, sqle);
- throw sqle;
- }
- finally {
- ups.close();
- }
- }
- while (rows==0);
- return value;
- }
-
protected IntegralDataTypeHolder buildHolder() {
return IdentifierGeneratorHelper.getIntegralDataTypeHolder( identifierType.getReturnedClass() );
}
diff --git a/hibernate-core/src/main/java/org/hibernate/id/enhanced/TableGenerator.java b/hibernate-core/src/main/java/org/hibernate/id/enhanced/TableGenerator.java
index a1d4db56b4..b2bc06083d 100644
--- a/hibernate-core/src/main/java/org/hibernate/id/enhanced/TableGenerator.java
+++ b/hibernate-core/src/main/java/org/hibernate/id/enhanced/TableGenerator.java
@@ -23,37 +23,38 @@
*/
package org.hibernate.id.enhanced;
-import java.sql.Types;
-import java.sql.Connection;
-import java.sql.SQLException;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.util.Properties;
-import java.util.Collections;
-import java.util.Map;
-import java.io.Serializable;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
+import org.hibernate.HibernateException;
+import org.hibernate.LockMode;
+import org.hibernate.LockOptions;
+import org.hibernate.MappingException;
import org.hibernate.cfg.Environment;
-import org.hibernate.engine.TransactionHelper;
+import org.hibernate.cfg.ObjectNameNormalizer;
+import org.hibernate.dialect.Dialect;
import org.hibernate.engine.SessionImplementor;
+import org.hibernate.engine.jdbc.spi.JdbcServices;
+import org.hibernate.engine.jdbc.spi.SQLStatementLogger;
+import org.hibernate.id.Configurable;
import org.hibernate.id.IdentifierGeneratorHelper;
import org.hibernate.id.IntegralDataTypeHolder;
import org.hibernate.id.PersistentIdentifierGenerator;
-import org.hibernate.id.Configurable;
import org.hibernate.internal.util.config.ConfigurationHelper;
-import org.hibernate.type.Type;
-import org.hibernate.dialect.Dialect;
-import org.hibernate.HibernateException;
-import org.hibernate.MappingException;
-import org.hibernate.LockOptions;
-import org.hibernate.LockMode;
-import org.hibernate.cfg.ObjectNameNormalizer;
+import org.hibernate.jdbc.ReturningWork;
import org.hibernate.jdbc.util.FormatStyle;
import org.hibernate.mapping.Table;
+import org.hibernate.type.Type;
import org.hibernate.util.StringHelper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.Serializable;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Types;
+import java.util.Collections;
+import java.util.Map;
+import java.util.Properties;
/**
* An enhanced version of table-based id generation.
@@ -128,7 +129,7 @@ import org.hibernate.util.StringHelper;
*
* @author Steve Ebersole
*/
-public class TableGenerator extends TransactionHelper implements PersistentIdentifierGenerator, Configurable {
+public class TableGenerator implements PersistentIdentifierGenerator, Configurable {
private static final Logger log = LoggerFactory.getLogger( TableGenerator.class );
public static final String CONFIG_PREFER_SEGMENT_PER_ENTITY = "prefer_entity_table_as_segment_value";
@@ -176,9 +177,7 @@ public class TableGenerator extends TransactionHelper implements PersistentIdent
private Optimizer optimizer;
private long accessCount = 0;
- /**
- * {@inheritDoc}
- */
+ @Override
public Object generatorKey() {
return tableName;
}
@@ -283,9 +282,7 @@ public class TableGenerator extends TransactionHelper implements PersistentIdent
return accessCount;
}
- /**
- * {@inheritDoc}
- */
+ @Override
public void configure(Type type, Properties params, Dialect dialect) throws MappingException {
identifierType = type;
@@ -456,93 +453,96 @@ public class TableGenerator extends TransactionHelper implements PersistentIdent
return "insert into " + tableName + " (" + segmentColumnName + ", " + valueColumnName + ") " + " values (?,?)";
}
- /**
- * {@inheritDoc}
- */
+ @Override
public synchronized Serializable generate(final SessionImplementor session, Object obj) {
+ final SQLStatementLogger statementLogger = session
+ .getFactory()
+ .getServiceRegistry()
+ .getService( JdbcServices.class )
+ .getSqlStatementLogger();
return optimizer.generate(
new AccessCallback() {
+ @Override
public IntegralDataTypeHolder getNextValue() {
- return ( IntegralDataTypeHolder ) doWorkInNewTransaction( session );
+ return session.getTransactionCoordinator().getTransaction().createIsolationDelegate().delegateWork(
+ new ReturningWork() {
+ @Override
+ public IntegralDataTypeHolder execute(Connection connection) throws SQLException {
+ IntegralDataTypeHolder value = IdentifierGeneratorHelper.getIntegralDataTypeHolder( identifierType.getReturnedClass() );
+ int rows;
+ do {
+ statementLogger.logStatement( selectQuery, FormatStyle.BASIC.getFormatter() );
+ PreparedStatement selectPS = connection.prepareStatement( selectQuery );
+ try {
+ selectPS.setString( 1, segmentValue );
+ ResultSet selectRS = selectPS.executeQuery();
+ if ( !selectRS.next() ) {
+ value.initialize( initialValue );
+ PreparedStatement insertPS = null;
+ try {
+ statementLogger.logStatement( insertQuery, FormatStyle.BASIC.getFormatter() );
+ insertPS = connection.prepareStatement( insertQuery );
+ insertPS.setString( 1, segmentValue );
+ value.bind( insertPS, 2 );
+ insertPS.execute();
+ }
+ finally {
+ if ( insertPS != null ) {
+ insertPS.close();
+ }
+ }
+ }
+ else {
+ value.initialize( selectRS, 1 );
+ }
+ selectRS.close();
+ }
+ catch ( SQLException e ) {
+ log.error( "could not read or init a hi value", e );
+ throw e;
+ }
+ finally {
+ selectPS.close();
+ }
+
+ statementLogger.logStatement( updateQuery, FormatStyle.BASIC.getFormatter() );
+ PreparedStatement updatePS = connection.prepareStatement( updateQuery );
+ try {
+ final IntegralDataTypeHolder updateValue = value.copy();
+ if ( optimizer.applyIncrementSizeToSourceValues() ) {
+ updateValue.add( incrementSize );
+ }
+ else {
+ updateValue.increment();
+ }
+ updateValue.bind( updatePS, 1 );
+ value.bind( updatePS, 2 );
+ updatePS.setString( 3, segmentValue );
+ rows = updatePS.executeUpdate();
+ }
+ catch ( SQLException e ) {
+ log.error( "could not updateQuery hi value in: " + tableName, e );
+ throw e;
+ }
+ finally {
+ updatePS.close();
+ }
+ }
+ while ( rows == 0 );
+
+ accessCount++;
+
+ return value;
+ }
+ },
+ true
+ );
}
}
);
}
- /**
- * {@inheritDoc}
- */
- public Serializable doWorkInCurrentTransaction(Connection conn, String sql) throws SQLException {
- IntegralDataTypeHolder value = IdentifierGeneratorHelper.getIntegralDataTypeHolder( identifierType.getReturnedClass() );
- int rows;
- do {
- SQL_STATEMENT_LOGGER.logStatement( selectQuery, FormatStyle.BASIC );
- PreparedStatement selectPS = conn.prepareStatement( selectQuery );
- try {
- selectPS.setString( 1, segmentValue );
- ResultSet selectRS = selectPS.executeQuery();
- if ( !selectRS.next() ) {
- value.initialize( initialValue );
- PreparedStatement insertPS = null;
- try {
- SQL_STATEMENT_LOGGER.logStatement( insertQuery, FormatStyle.BASIC );
- insertPS = conn.prepareStatement( insertQuery );
- insertPS.setString( 1, segmentValue );
- value.bind( insertPS, 2 );
- insertPS.execute();
- }
- finally {
- if ( insertPS != null ) {
- insertPS.close();
- }
- }
- }
- else {
- value.initialize( selectRS, 1 );
- }
- selectRS.close();
- }
- catch ( SQLException sqle ) {
- log.error( "could not read or init a hi value", sqle );
- throw sqle;
- }
- finally {
- selectPS.close();
- }
-
- SQL_STATEMENT_LOGGER.logStatement( updateQuery, FormatStyle.BASIC );
- PreparedStatement updatePS = conn.prepareStatement( updateQuery );
- try {
- final IntegralDataTypeHolder updateValue = value.copy();
- if ( optimizer.applyIncrementSizeToSourceValues() ) {
- updateValue.add( incrementSize );
- }
- else {
- updateValue.increment();
- }
- updateValue.bind( updatePS, 1 );
- value.bind( updatePS, 2 );
- updatePS.setString( 3, segmentValue );
- rows = updatePS.executeUpdate();
- }
- catch ( SQLException sqle ) {
- log.error( "could not updateQuery hi value in: " + tableName, sqle );
- throw sqle;
- }
- finally {
- updatePS.close();
- }
- }
- while ( rows == 0 );
-
- accessCount++;
-
- return value;
- }
-
- /**
- * {@inheritDoc}
- */
+ @Override
public String[] sqlCreateStrings(Dialect dialect) throws HibernateException {
return new String[] {
new StringBuffer()
@@ -565,9 +565,7 @@ public class TableGenerator extends TransactionHelper implements PersistentIdent
};
}
- /**
- * {@inheritDoc}
- */
+ @Override
public String[] sqlDropStrings(Dialect dialect) throws HibernateException {
StringBuffer sqlDropString = new StringBuffer().append( "drop table " );
if ( dialect.supportsIfExistsBeforeTableName() ) {
diff --git a/hibernate-core/src/main/java/org/hibernate/id/enhanced/TableStructure.java b/hibernate-core/src/main/java/org/hibernate/id/enhanced/TableStructure.java
index 931128d136..cbad28cb17 100644
--- a/hibernate-core/src/main/java/org/hibernate/id/enhanced/TableStructure.java
+++ b/hibernate-core/src/main/java/org/hibernate/id/enhanced/TableStructure.java
@@ -1,10 +1,10 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
- * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * Copyright (c) 2008-2011, 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 Middleware LLC.
+ * 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
@@ -20,39 +20,36 @@
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
- *
*/
package org.hibernate.id.enhanced;
-import java.io.Serializable;
+import org.hibernate.HibernateException;
+import org.hibernate.LockMode;
+import org.hibernate.dialect.Dialect;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.engine.jdbc.spi.JdbcServices;
+import org.hibernate.engine.jdbc.spi.SQLStatementLogger;
+import org.hibernate.id.IdentifierGenerationException;
+import org.hibernate.id.IdentifierGeneratorHelper;
+import org.hibernate.id.IntegralDataTypeHolder;
+import org.hibernate.jdbc.ReturningWork;
+import org.hibernate.jdbc.util.FormatStyle;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.hibernate.HibernateException;
-import org.hibernate.LockMode;
-import org.hibernate.dialect.Dialect;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.engine.TransactionHelper;
-import org.hibernate.id.IdentifierGenerationException;
-import org.hibernate.id.IdentifierGeneratorHelper;
-import org.hibernate.id.IntegralDataTypeHolder;
-import org.hibernate.jdbc.util.FormatStyle;
-import org.hibernate.jdbc.util.SQLStatementLogger;
-
/**
* Describes a table used to mimic sequence behavior
*
* @author Steve Ebersole
*/
-public class TableStructure extends TransactionHelper implements DatabaseStructure {
+public class TableStructure implements DatabaseStructure {
private static final Logger log = LoggerFactory.getLogger( TableStructure.class );
- private static final SQLStatementLogger SQL_STATEMENT_LOGGER = new SQLStatementLogger( false, false );
private final String tableName;
private final String valueColumnName;
@@ -87,55 +84,98 @@ public class TableStructure extends TransactionHelper implements DatabaseStructu
" where " + valueColumnName + "=?";
}
- /**
- * {@inheritDoc}
- */
+ @Override
public String getName() {
return tableName;
}
- /**
- * {@inheritDoc}
- */
+ @Override
public int getInitialValue() {
return initialValue;
}
- /**
- * {@inheritDoc}
- */
+ @Override
public int getIncrementSize() {
return incrementSize;
}
- /**
- * {@inheritDoc}
- */
+ @Override
public int getTimesAccessed() {
return accessCounter;
}
- /**
- * {@inheritDoc}
- */
+ @Override
public void prepare(Optimizer optimizer) {
applyIncrementSizeToSourceValues = optimizer.applyIncrementSizeToSourceValues();
}
- /**
- * {@inheritDoc}
- */
+ @Override
public AccessCallback buildCallback(final SessionImplementor session) {
return new AccessCallback() {
+ @Override
public IntegralDataTypeHolder getNextValue() {
- return ( IntegralDataTypeHolder ) doWorkInNewTransaction( session );
+ return session.getTransactionCoordinator().getTransaction().createIsolationDelegate().delegateWork(
+ new ReturningWork() {
+ @Override
+ public IntegralDataTypeHolder execute(Connection connection) throws SQLException {
+ final SQLStatementLogger statementLogger = session
+ .getFactory()
+ .getServiceRegistry()
+ .getService( JdbcServices.class )
+ .getSqlStatementLogger();
+ IntegralDataTypeHolder value = IdentifierGeneratorHelper.getIntegralDataTypeHolder( numberType );
+ int rows;
+ do {
+ statementLogger.logStatement( selectQuery, FormatStyle.BASIC.getFormatter() );
+ PreparedStatement selectStatement = connection.prepareStatement( selectQuery );
+ try {
+ ResultSet selectRS = selectStatement.executeQuery();
+ if ( !selectRS.next() ) {
+ String err = "could not read a hi value - you need to populate the table: " + tableName;
+ log.error( err );
+ throw new IdentifierGenerationException( err );
+ }
+ value.initialize( selectRS, 1 );
+ selectRS.close();
+ }
+ catch ( SQLException sqle ) {
+ log.error( "could not read a hi value", sqle );
+ throw sqle;
+ }
+ finally {
+ selectStatement.close();
+ }
+
+ statementLogger.logStatement( updateQuery, FormatStyle.BASIC.getFormatter() );
+ PreparedStatement updatePS = connection.prepareStatement( updateQuery );
+ try {
+ final int increment = applyIncrementSizeToSourceValues ? incrementSize : 1;
+ final IntegralDataTypeHolder updateValue = value.copy().add( increment );
+ updateValue.bind( updatePS, 1 );
+ value.bind( updatePS, 2 );
+ rows = updatePS.executeUpdate();
+ }
+ catch ( SQLException e ) {
+ log.error( "could not updateQuery hi value in: " + tableName, e );
+ throw e;
+ }
+ finally {
+ updatePS.close();
+ }
+ } while ( rows == 0 );
+
+ accessCounter++;
+
+ return value;
+ }
+ },
+ true
+ );
}
};
}
- /**
- * {@inheritDoc}
- */
+ @Override
public String[] sqlCreateStrings(Dialect dialect) throws HibernateException {
return new String[] {
dialect.getCreateTableString() + " " + tableName + " ( " + valueColumnName + " " + dialect.getTypeName( Types.BIGINT ) + " )",
@@ -143,9 +183,7 @@ public class TableStructure extends TransactionHelper implements DatabaseStructu
};
}
- /**
- * {@inheritDoc}
- */
+ @Override
public String[] sqlDropStrings(Dialect dialect) throws HibernateException {
StringBuffer sqlDropString = new StringBuffer().append( "drop table " );
if ( dialect.supportsIfExistsBeforeTableName() ) {
@@ -157,55 +195,4 @@ public class TableStructure extends TransactionHelper implements DatabaseStructu
}
return new String[] { sqlDropString.toString() };
}
-
- /**
- * {@inheritDoc}
- */
- protected Serializable doWorkInCurrentTransaction(Connection conn, String sql) throws SQLException {
- IntegralDataTypeHolder value = IdentifierGeneratorHelper.getIntegralDataTypeHolder( numberType );
- int rows;
- do {
- SQL_STATEMENT_LOGGER.logStatement( selectQuery, FormatStyle.BASIC );
- PreparedStatement selectPS = conn.prepareStatement( selectQuery );
- try {
- ResultSet selectRS = selectPS.executeQuery();
- if ( !selectRS.next() ) {
- String err = "could not read a hi value - you need to populate the table: " + tableName;
- log.error( err );
- throw new IdentifierGenerationException( err );
- }
- value.initialize( selectRS, 1 );
- selectRS.close();
- }
- catch ( SQLException sqle ) {
- log.error( "could not read a hi value", sqle );
- throw sqle;
- }
- finally {
- selectPS.close();
- }
-
- SQL_STATEMENT_LOGGER.logStatement( updateQuery, FormatStyle.BASIC );
- PreparedStatement updatePS = conn.prepareStatement( updateQuery );
- try {
- final int increment = applyIncrementSizeToSourceValues ? incrementSize : 1;
- final IntegralDataTypeHolder updateValue = value.copy().add( increment );
- updateValue.bind( updatePS, 1 );
- value.bind( updatePS, 2 );
- rows = updatePS.executeUpdate();
- }
- catch ( SQLException sqle ) {
- log.error( "could not updateQuery hi value in: " + tableName, sqle );
- throw sqle;
- }
- finally {
- updatePS.close();
- }
- } while ( rows == 0 );
-
- accessCounter++;
-
- return value;
- }
-
}
diff --git a/hibernate-core/src/main/java/org/hibernate/jdbc/ReturningWork.java b/hibernate-core/src/main/java/org/hibernate/jdbc/ReturningWork.java
new file mode 100644
index 0000000000..83b9d4ced9
--- /dev/null
+++ b/hibernate-core/src/main/java/org/hibernate/jdbc/ReturningWork.java
@@ -0,0 +1,46 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2011, 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
+ */
+package org.hibernate.jdbc;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+
+/**
+ * A discrete piece of work following the lines of {@link Work} but returning a result.
+ *
+ * @author Steve Ebersole
+ */
+public interface ReturningWork {
+ /**
+ * Execute the discrete work encapsulated by this work instance using the supplied connection.
+ *
+ * @param connection The connection on which to perform the work.
+ *
+ * @return The work result
+ *
+ * @throws SQLException Thrown during execution of the underlying JDBC interaction.
+ * @throws org.hibernate.HibernateException Generally indicates a wrapped SQLException.
+ */
+ public T execute(Connection connection) throws SQLException;
+}
From 73e85ee761a455a12aab7132bfa308fa50c6680a Mon Sep 17 00:00:00 2001
From: Steve Ebersole
Date: Sat, 5 Mar 2011 08:06:21 -0600
Subject: [PATCH 13/19] HHH-5781 - Refactor code in org.hibernate.jdbc to
spi/internal and remove obsolete code
---
.../main/java/org/hibernate/cfg/Settings.java | 28 ----
.../org/hibernate/cfg/SettingsFactory.java | 10 --
.../engine/SessionFactoryImplementor.java | 10 +-
.../batch/internal/AbstractBatchImpl.java | 8 +-
.../jdbc/internal}/BasicFormatterImpl.java | 26 ++--
.../jdbc/internal}/DDLFormatterImpl.java | 7 +-
.../jdbc/internal}/FormatStyle.java | 33 +----
.../jdbc/internal}/Formatter.java | 14 +-
.../jdbc/internal/JdbcCoordinatorImpl.java | 4 +-
.../internal/JdbcResourceRegistryImpl.java | 6 +-
.../jdbc/internal/JdbcServicesImpl.java | 18 ++-
.../jdbc/internal/StatementPreparerImpl.java | 4 +-
.../jdbc/internal}/TypeInfo.java | 2 +-
.../jdbc/internal}/TypeInfoExtracter.java | 2 +-
.../jdbc/internal}/TypeNullability.java | 2 +-
.../jdbc/internal}/TypeSearchability.java | 2 +-
.../jdbc/spi/ExtractedDatabaseMetaData.java | 2 +-
.../engine/jdbc/spi/JdbcServices.java | 4 +-
...ionHelper.java => SqlExceptionHelper.java} | 8 +-
...entLogger.java => SqlStatementLogger.java} | 16 +--
.../internal/jdbc/JdbcIsolationDelegate.java | 4 +-
.../internal/jta/JtaIsolationDelegate.java | 4 +-
.../id/MultipleHiLoPerTableGenerator.java | 6 +-
.../java/org/hibernate/id/TableGenerator.java | 6 +-
.../hibernate/id/enhanced/TableGenerator.java | 6 +-
.../hibernate/id/enhanced/TableStructure.java | 6 +-
.../hibernate/impl/SessionFactoryImpl.java | 5 +-
.../main/java/org/hibernate/jdbc/package.html | 7 +-
.../jdbc/util/SQLStatementLogger.java | 120 ------------------
.../metamodel/relational/Datatype.java | 2 +-
.../AbstractCollectionPersister.java | 6 +-
.../hibernate/tool/hbm2ddl/SchemaExport.java | 8 +-
.../hibernate/tool/hbm2ddl/SchemaUpdate.java | 9 +-
.../jdbc/util/BasicFormatterTest.java | 2 +
.../common/BasicTestingJdbcServiceImpl.java | 18 +--
.../org/hibernate/test/jdbc/TypeInfoTest.java | 4 +-
36 files changed, 120 insertions(+), 299 deletions(-)
rename hibernate-core/src/main/java/org/hibernate/{jdbc/util => engine/jdbc/internal}/BasicFormatterImpl.java (89%)
rename hibernate-core/src/main/java/org/hibernate/{jdbc/util => engine/jdbc/internal}/DDLFormatterImpl.java (96%)
rename hibernate-core/src/main/java/org/hibernate/{jdbc/util => engine/jdbc/internal}/FormatStyle.java (65%)
rename hibernate-core/src/main/java/org/hibernate/{jdbc/util => engine/jdbc/internal}/Formatter.java (78%)
rename hibernate-core/src/main/java/org/hibernate/{internal/util/jdbc => engine/jdbc/internal}/TypeInfo.java (98%)
rename hibernate-core/src/main/java/org/hibernate/{internal/util/jdbc => engine/jdbc/internal}/TypeInfoExtracter.java (98%)
rename hibernate-core/src/main/java/org/hibernate/{internal/util/jdbc => engine/jdbc/internal}/TypeNullability.java (98%)
rename hibernate-core/src/main/java/org/hibernate/{internal/util/jdbc => engine/jdbc/internal}/TypeSearchability.java (98%)
rename hibernate-core/src/main/java/org/hibernate/engine/jdbc/spi/{SQLExceptionHelper.java => SqlExceptionHelper.java} (96%)
rename hibernate-core/src/main/java/org/hibernate/engine/jdbc/spi/{SQLStatementLogger.java => SqlStatementLogger.java} (86%)
delete mode 100644 hibernate-core/src/main/java/org/hibernate/jdbc/util/SQLStatementLogger.java
diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/Settings.java b/hibernate-core/src/main/java/org/hibernate/cfg/Settings.java
index fbc5e31eac..01ec78b7dc 100644
--- a/hibernate-core/src/main/java/org/hibernate/cfg/Settings.java
+++ b/hibernate-core/src/main/java/org/hibernate/cfg/Settings.java
@@ -29,7 +29,6 @@ import org.hibernate.cache.QueryCacheFactory;
import org.hibernate.cache.RegionFactory;
import org.hibernate.engine.jdbc.JdbcSupport;
import org.hibernate.hql.QueryTranslatorFactory;
-import org.hibernate.jdbc.util.SQLStatementLogger;
import org.hibernate.service.jta.platform.spi.JtaPlatform;
import org.hibernate.tuple.entity.EntityTuplizerFactory;
@@ -42,9 +41,6 @@ import java.util.Map;
*/
public final class Settings {
-// private boolean showSql;
-// private boolean formatSql;
- private SQLStatementLogger sqlStatementLogger;
private Integer maximumFetchDepth;
private Map querySubstitutions;
private int jdbcBatchSize;
@@ -99,14 +95,6 @@ public final class Settings {
// public getters ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// public boolean isShowSqlEnabled() {
-// return showSql;
-// }
-//
-// public boolean isFormatSqlEnabled() {
-// return formatSql;
-// }
-
public String getImportFiles() {
return importFiles;
}
@@ -115,10 +103,6 @@ public final class Settings {
this.importFiles = importFiles;
}
- public SQLStatementLogger getSqlStatementLogger() {
- return sqlStatementLogger;
- }
-
public String getDefaultSchemaName() {
return defaultSchemaName;
}
@@ -282,18 +266,6 @@ public final class Settings {
// package protected setters ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// void setShowSqlEnabled(boolean b) {
-// showSql = b;
-// }
-//
-// void setFormatSqlEnabled(boolean b) {
-// formatSql = b;
-// }
-
- void setSqlStatementLogger(SQLStatementLogger sqlStatementLogger) {
- this.sqlStatementLogger = sqlStatementLogger;
- }
-
void setDefaultSchemaName(String string) {
defaultSchemaName = string;
}
diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/SettingsFactory.java b/hibernate-core/src/main/java/org/hibernate/cfg/SettingsFactory.java
index 73801f2b98..b6944c84d0 100644
--- a/hibernate-core/src/main/java/org/hibernate/cfg/SettingsFactory.java
+++ b/hibernate-core/src/main/java/org/hibernate/cfg/SettingsFactory.java
@@ -44,7 +44,6 @@ import org.hibernate.engine.jdbc.spi.JdbcServices;
import org.hibernate.engine.transaction.spi.TransactionFactory;
import org.hibernate.hql.QueryTranslatorFactory;
import org.hibernate.internal.util.config.ConfigurationHelper;
-import org.hibernate.jdbc.util.SQLStatementLogger;
import org.hibernate.service.jta.platform.spi.JtaPlatform;
import org.hibernate.service.spi.ServiceRegistry;
import org.hibernate.util.ReflectHelper;
@@ -214,15 +213,6 @@ public class SettingsFactory implements Serializable {
//Statistics and logging:
- boolean showSql = ConfigurationHelper.getBoolean(Environment.SHOW_SQL, properties);
- if (showSql) log.info("Echoing all SQL to stdout");
-// settings.setShowSqlEnabled(showSql);
-
- boolean formatSql = ConfigurationHelper.getBoolean(Environment.FORMAT_SQL, properties);
-// settings.setFormatSqlEnabled(formatSql);
-
- settings.setSqlStatementLogger( new SQLStatementLogger( showSql, formatSql ) );
-
boolean useStatistics = ConfigurationHelper.getBoolean(Environment.GENERATE_STATISTICS, properties);
log.info( "Statistics: " + enabledDisabled(useStatistics) );
settings.setStatisticsEnabled(useStatistics);
diff --git a/hibernate-core/src/main/java/org/hibernate/engine/SessionFactoryImplementor.java b/hibernate-core/src/main/java/org/hibernate/engine/SessionFactoryImplementor.java
index a72b2aee50..8c876a7041 100644
--- a/hibernate-core/src/main/java/org/hibernate/engine/SessionFactoryImplementor.java
+++ b/hibernate-core/src/main/java/org/hibernate/engine/SessionFactoryImplementor.java
@@ -29,15 +29,13 @@ import java.util.Properties;
import java.util.Set;
import java.sql.Connection;
-import javax.transaction.TransactionManager;
-
import org.hibernate.HibernateException;
import org.hibernate.Interceptor;
import org.hibernate.MappingException;
import org.hibernate.SessionFactory;
import org.hibernate.ConnectionReleaseMode;
import org.hibernate.engine.jdbc.spi.JdbcServices;
-import org.hibernate.engine.jdbc.spi.SQLExceptionHelper;
+import org.hibernate.engine.jdbc.spi.SqlExceptionHelper;
import org.hibernate.proxy.EntityNotFoundDelegate;
import org.hibernate.engine.query.QueryPlanCache;
import org.hibernate.engine.profile.FetchProfile;
@@ -202,12 +200,12 @@ public interface SessionFactoryImplementor extends Mapping, SessionFactory {
// TODO: deprecate???
/**
- * Retrieves the SQLExceptionHelper in effect for this SessionFactory.
+ * Retrieves the SqlExceptionHelper in effect for this SessionFactory.
*
- * @return The SQLExceptionHelper for this SessionFactory.
+ * @return The SqlExceptionHelper for this SessionFactory.
*
*/
- public SQLExceptionHelper getSQLExceptionHelper();
+ public SqlExceptionHelper getSQLExceptionHelper();
public Settings getSettings();
diff --git a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/batch/internal/AbstractBatchImpl.java b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/batch/internal/AbstractBatchImpl.java
index a0c4bd2b97..41560f003b 100644
--- a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/batch/internal/AbstractBatchImpl.java
+++ b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/batch/internal/AbstractBatchImpl.java
@@ -27,8 +27,8 @@ import org.hibernate.engine.jdbc.batch.spi.Batch;
import org.hibernate.engine.jdbc.batch.spi.BatchKey;
import org.hibernate.engine.jdbc.batch.spi.BatchObserver;
import org.hibernate.engine.jdbc.spi.JdbcCoordinator;
-import org.hibernate.engine.jdbc.spi.SQLExceptionHelper;
-import org.hibernate.engine.jdbc.spi.SQLStatementLogger;
+import org.hibernate.engine.jdbc.spi.SqlExceptionHelper;
+import org.hibernate.engine.jdbc.spi.SqlStatementLogger;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -74,7 +74,7 @@ public abstract class AbstractBatchImpl implements Batch {
*
* @return The underlying SQLException helper.
*/
- protected SQLExceptionHelper sqlExceptionHelper() {
+ protected SqlExceptionHelper sqlExceptionHelper() {
return jdbcCoordinator.getTransactionCoordinator()
.getTransactionContext()
.getTransactionEnvironment()
@@ -87,7 +87,7 @@ public abstract class AbstractBatchImpl implements Batch {
*
* @return The underlying JDBC services.
*/
- protected SQLStatementLogger sqlStatementLogger() {
+ protected SqlStatementLogger sqlStatementLogger() {
return jdbcCoordinator.getTransactionCoordinator()
.getTransactionContext()
.getTransactionEnvironment()
diff --git a/hibernate-core/src/main/java/org/hibernate/jdbc/util/BasicFormatterImpl.java b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/internal/BasicFormatterImpl.java
similarity index 89%
rename from hibernate-core/src/main/java/org/hibernate/jdbc/util/BasicFormatterImpl.java
rename to hibernate-core/src/main/java/org/hibernate/engine/jdbc/internal/BasicFormatterImpl.java
index 68f6a8d89f..8f85174cfd 100755
--- a/hibernate-core/src/main/java/org/hibernate/jdbc/util/BasicFormatterImpl.java
+++ b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/internal/BasicFormatterImpl.java
@@ -22,7 +22,7 @@
* Boston, MA 02110-1301 USA
*
*/
-package org.hibernate.jdbc.util;
+package org.hibernate.engine.jdbc.internal;
import java.util.HashSet;
import java.util.LinkedList;
@@ -39,12 +39,12 @@ import org.hibernate.util.StringHelper;
*/
public class BasicFormatterImpl implements Formatter {
- private static final Set BEGIN_CLAUSES = new HashSet();
- private static final Set END_CLAUSES = new HashSet();
- private static final Set LOGICAL = new HashSet();
- private static final Set QUANTIFIERS = new HashSet();
- private static final Set DML = new HashSet();
- private static final Set MISC = new HashSet();
+ private static final Set BEGIN_CLAUSES = new HashSet();
+ private static final Set END_CLAUSES = new HashSet();
+ private static final Set LOGICAL = new HashSet();
+ private static final Set QUANTIFIERS = new HashSet();
+ private static final Set DML = new HashSet();
+ private static final Set MISC = new HashSet();
static {
BEGIN_CLAUSES.add( "left" );
@@ -101,8 +101,8 @@ public class BasicFormatterImpl implements Formatter {
boolean afterInsert = false;
int inFunction = 0;
int parensSinceSelect = 0;
- private LinkedList parenCounts = new LinkedList();
- private LinkedList afterByOrFromOrSelects = new LinkedList();
+ private LinkedList parenCounts = new LinkedList();
+ private LinkedList afterByOrFromOrSelects = new LinkedList();
int indent = 1;
@@ -273,11 +273,12 @@ public class BasicFormatterImpl implements Formatter {
}
}
+ @SuppressWarnings( {"UnnecessaryBoxing"})
private void select() {
out();
indent++;
newline();
- parenCounts.addLast( new Integer( parensSinceSelect ) );
+ parenCounts.addLast( Integer.valueOf( parensSinceSelect ) );
afterByOrFromOrSelects.addLast( Boolean.valueOf( afterByOrSetOrFromOrSelect ) );
parensSinceSelect = 0;
afterByOrSetOrFromOrSelect = true;
@@ -330,12 +331,13 @@ public class BasicFormatterImpl implements Formatter {
afterValues = true;
}
+ @SuppressWarnings( {"UnnecessaryUnboxing"})
private void closeParen() {
parensSinceSelect--;
if ( parensSinceSelect < 0 ) {
indent--;
- parensSinceSelect = ( ( Integer ) parenCounts.removeLast() ).intValue();
- afterByOrSetOrFromOrSelect = ( ( Boolean ) afterByOrFromOrSelects.removeLast() ).booleanValue();
+ parensSinceSelect = parenCounts.removeLast().intValue();
+ afterByOrSetOrFromOrSelect = afterByOrFromOrSelects.removeLast().booleanValue();
}
if ( inFunction > 0 ) {
inFunction--;
diff --git a/hibernate-core/src/main/java/org/hibernate/jdbc/util/DDLFormatterImpl.java b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/internal/DDLFormatterImpl.java
similarity index 96%
rename from hibernate-core/src/main/java/org/hibernate/jdbc/util/DDLFormatterImpl.java
rename to hibernate-core/src/main/java/org/hibernate/engine/jdbc/internal/DDLFormatterImpl.java
index e3a06dbaf3..52ba4fc71a 100755
--- a/hibernate-core/src/main/java/org/hibernate/jdbc/util/DDLFormatterImpl.java
+++ b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/internal/DDLFormatterImpl.java
@@ -1,10 +1,10 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
- * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * Copyright (c) 2008-2011, 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 Middleware LLC.
+ * 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
@@ -20,9 +20,8 @@
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
- *
*/
-package org.hibernate.jdbc.util;
+package org.hibernate.engine.jdbc.internal;
import java.util.StringTokenizer;
diff --git a/hibernate-core/src/main/java/org/hibernate/jdbc/util/FormatStyle.java b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/internal/FormatStyle.java
similarity index 65%
rename from hibernate-core/src/main/java/org/hibernate/jdbc/util/FormatStyle.java
rename to hibernate-core/src/main/java/org/hibernate/engine/jdbc/internal/FormatStyle.java
index 00da9d4e50..260d4c601a 100644
--- a/hibernate-core/src/main/java/org/hibernate/jdbc/util/FormatStyle.java
+++ b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/internal/FormatStyle.java
@@ -1,10 +1,10 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
- * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * Copyright (c) 2008-2011, 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 Middleware LLC.
+ * 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
@@ -20,19 +20,18 @@
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
- *
*/
-package org.hibernate.jdbc.util;
+package org.hibernate.engine.jdbc.internal;
/**
* Represents the the understood types or styles of formatting.
*
* @author Steve Ebersole
*/
-public class FormatStyle {
- public static final FormatStyle BASIC = new FormatStyle( "basic", new BasicFormatterImpl() );
- public static final FormatStyle DDL = new FormatStyle( "ddl", new DDLFormatterImpl() );
- public static final FormatStyle NONE = new FormatStyle( "none", new NoFormatImpl() );
+public enum FormatStyle {
+ BASIC( "basic", new BasicFormatterImpl() ),
+ DDL( "ddl", new DDLFormatterImpl() ),
+ NONE( "none", new NoFormatImpl() );
private final String name;
private final Formatter formatter;
@@ -50,24 +49,6 @@ public class FormatStyle {
return formatter;
}
- public boolean equals(Object o) {
- if ( this == o ) {
- return true;
- }
- if ( o == null || getClass() != o.getClass() ) {
- return false;
- }
-
- FormatStyle that = ( FormatStyle ) o;
-
- return name.equals( that.name );
-
- }
-
- public int hashCode() {
- return name.hashCode();
- }
-
private static class NoFormatImpl implements Formatter {
public String format(String source) {
return source;
diff --git a/hibernate-core/src/main/java/org/hibernate/jdbc/util/Formatter.java b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/internal/Formatter.java
similarity index 78%
rename from hibernate-core/src/main/java/org/hibernate/jdbc/util/Formatter.java
rename to hibernate-core/src/main/java/org/hibernate/engine/jdbc/internal/Formatter.java
index 2e43de74c7..3d9248c876 100644
--- a/hibernate-core/src/main/java/org/hibernate/jdbc/util/Formatter.java
+++ b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/internal/Formatter.java
@@ -1,10 +1,10 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
- * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * Copyright (c) 2008-2011, 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 Middleware LLC.
+ * 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
@@ -20,9 +20,8 @@
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
- *
*/
-package org.hibernate.jdbc.util;
+package org.hibernate.engine.jdbc.internal;
/**
* Formatter contract
@@ -30,5 +29,12 @@ package org.hibernate.jdbc.util;
* @author Steve Ebersole
*/
public interface Formatter {
+ /**
+ * Format the source SQL string.
+ *
+ * @param source The original SQL string
+ *
+ * @return The formatted version
+ */
public String format(String source);
}
diff --git a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/internal/JdbcCoordinatorImpl.java b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/internal/JdbcCoordinatorImpl.java
index dbd92ad62b..3a217786e7 100644
--- a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/internal/JdbcCoordinatorImpl.java
+++ b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/internal/JdbcCoordinatorImpl.java
@@ -30,7 +30,7 @@ import org.hibernate.engine.jdbc.batch.spi.BatchBuilder;
import org.hibernate.engine.jdbc.batch.spi.BatchKey;
import org.hibernate.engine.jdbc.spi.JdbcCoordinator;
import org.hibernate.engine.jdbc.spi.LogicalConnectionImplementor;
-import org.hibernate.engine.jdbc.spi.SQLExceptionHelper;
+import org.hibernate.engine.jdbc.spi.SqlExceptionHelper;
import org.hibernate.engine.jdbc.spi.StatementPreparer;
import org.hibernate.engine.transaction.internal.TransactionCoordinatorImpl;
import org.hibernate.engine.transaction.spi.TransactionContext;
@@ -100,7 +100,7 @@ public class JdbcCoordinatorImpl implements JdbcCoordinator {
return sessionFactory().getServiceRegistry().getService( BatchBuilder.class );
}
- private SQLExceptionHelper sqlExceptionHelper() {
+ private SqlExceptionHelper sqlExceptionHelper() {
return transactionEnvironment().getJdbcServices().getSqlExceptionHelper();
}
diff --git a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/internal/JdbcResourceRegistryImpl.java b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/internal/JdbcResourceRegistryImpl.java
index bcace088a0..69a5edf3ec 100644
--- a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/internal/JdbcResourceRegistryImpl.java
+++ b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/internal/JdbcResourceRegistryImpl.java
@@ -36,7 +36,7 @@ import org.slf4j.LoggerFactory;
import org.hibernate.HibernateException;
import org.hibernate.engine.jdbc.spi.JdbcWrapper;
-import org.hibernate.engine.jdbc.spi.SQLExceptionHelper;
+import org.hibernate.engine.jdbc.spi.SqlExceptionHelper;
import org.hibernate.engine.jdbc.spi.JdbcResourceRegistry;
import org.hibernate.engine.jdbc.spi.InvalidatableWrapper;
@@ -50,11 +50,11 @@ public class JdbcResourceRegistryImpl implements JdbcResourceRegistry {
private final HashMap> xref = new HashMap>();
private final Set unassociatedResultSets = new HashSet();
- private final SQLExceptionHelper exceptionHelper;
+ private final SqlExceptionHelper exceptionHelper;
private Statement lastQuery;
- public JdbcResourceRegistryImpl(SQLExceptionHelper exceptionHelper) {
+ public JdbcResourceRegistryImpl(SqlExceptionHelper exceptionHelper) {
this.exceptionHelper = exceptionHelper;
}
diff --git a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/internal/JdbcServicesImpl.java b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/internal/JdbcServicesImpl.java
index e5585eab4d..a32cd6560d 100644
--- a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/internal/JdbcServicesImpl.java
+++ b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/internal/JdbcServicesImpl.java
@@ -38,19 +38,17 @@ import org.slf4j.LoggerFactory;
import org.hibernate.cfg.Environment;
import org.hibernate.dialect.Dialect;
+import org.hibernate.engine.jdbc.spi.SqlStatementLogger;
import org.hibernate.service.jdbc.connections.spi.ConnectionProvider;
import org.hibernate.service.jdbc.dialect.spi.DialectFactory;
import org.hibernate.engine.jdbc.spi.ExtractedDatabaseMetaData;
import org.hibernate.engine.jdbc.spi.JdbcServices;
-import org.hibernate.engine.jdbc.spi.SQLExceptionHelper;
-import org.hibernate.engine.jdbc.spi.SQLStatementLogger;
+import org.hibernate.engine.jdbc.spi.SqlExceptionHelper;
import org.hibernate.engine.jdbc.spi.SchemaNameResolver;
import org.hibernate.internal.util.config.ConfigurationHelper;
-import org.hibernate.internal.util.jdbc.TypeInfo;
import org.hibernate.service.spi.Configurable;
import org.hibernate.service.spi.InjectService;
import org.hibernate.util.ReflectHelper;
-import org.hibernate.internal.util.jdbc.TypeInfoExtracter;
/**
* Standard implementation of the {@link JdbcServices} contract
@@ -75,8 +73,8 @@ public class JdbcServicesImpl implements JdbcServices, Configurable {
}
private Dialect dialect;
- private SQLStatementLogger sqlStatementLogger;
- private SQLExceptionHelper sqlExceptionHelper;
+ private SqlStatementLogger sqlStatementLogger;
+ private SqlExceptionHelper sqlExceptionHelper;
private ExtractedDatabaseMetaData extractedMetaDataSupport;
public void configure(Map configValues) {
@@ -167,8 +165,8 @@ public class JdbcServicesImpl implements JdbcServices, Configurable {
final boolean formatSQL = ConfigurationHelper.getBoolean( Environment.FORMAT_SQL, configValues, false );
this.dialect = dialect;
- this.sqlStatementLogger = new SQLStatementLogger( showSQL, formatSQL );
- this.sqlExceptionHelper = new SQLExceptionHelper( dialect.buildSQLExceptionConverter() );
+ this.sqlStatementLogger = new SqlStatementLogger( showSQL, formatSQL );
+ this.sqlExceptionHelper = new SqlExceptionHelper( dialect.buildSQLExceptionConverter() );
this.extractedMetaDataSupport = new ExtractedDatabaseMetaDataImpl(
metaSupportsScrollable,
metaSupportsGetGeneratedKeys,
@@ -321,11 +319,11 @@ public class JdbcServicesImpl implements JdbcServices, Configurable {
return connectionProvider;
}
- public SQLStatementLogger getSqlStatementLogger() {
+ public SqlStatementLogger getSqlStatementLogger() {
return sqlStatementLogger;
}
- public SQLExceptionHelper getSqlExceptionHelper() {
+ public SqlExceptionHelper getSqlExceptionHelper() {
return sqlExceptionHelper;
}
diff --git a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/internal/StatementPreparerImpl.java b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/internal/StatementPreparerImpl.java
index ed4fa259b0..ff26f46259 100644
--- a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/internal/StatementPreparerImpl.java
+++ b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/internal/StatementPreparerImpl.java
@@ -28,7 +28,7 @@ import org.hibernate.ScrollMode;
import org.hibernate.TransactionException;
import org.hibernate.cfg.Settings;
import org.hibernate.engine.jdbc.spi.LogicalConnectionImplementor;
-import org.hibernate.engine.jdbc.spi.SQLExceptionHelper;
+import org.hibernate.engine.jdbc.spi.SqlExceptionHelper;
import org.hibernate.engine.jdbc.spi.StatementPreparer;
import java.sql.Connection;
@@ -59,7 +59,7 @@ class StatementPreparerImpl implements StatementPreparer {
return jdbcCoordinator.getLogicalConnection();
}
- protected final SQLExceptionHelper sqlExceptionHelper() {
+ protected final SqlExceptionHelper sqlExceptionHelper() {
return jdbcCoordinator.getTransactionCoordinator()
.getTransactionContext()
.getTransactionEnvironment()
diff --git a/hibernate-core/src/main/java/org/hibernate/internal/util/jdbc/TypeInfo.java b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/internal/TypeInfo.java
similarity index 98%
rename from hibernate-core/src/main/java/org/hibernate/internal/util/jdbc/TypeInfo.java
rename to hibernate-core/src/main/java/org/hibernate/engine/jdbc/internal/TypeInfo.java
index 543913df56..b84fe7b5dd 100644
--- a/hibernate-core/src/main/java/org/hibernate/internal/util/jdbc/TypeInfo.java
+++ b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/internal/TypeInfo.java
@@ -21,7 +21,7 @@
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
-package org.hibernate.internal.util.jdbc;
+package org.hibernate.engine.jdbc.internal;
/**
* Models type info extracted from {@link java.sql.DatabaseMetaData#getTypeInfo()}
diff --git a/hibernate-core/src/main/java/org/hibernate/internal/util/jdbc/TypeInfoExtracter.java b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/internal/TypeInfoExtracter.java
similarity index 98%
rename from hibernate-core/src/main/java/org/hibernate/internal/util/jdbc/TypeInfoExtracter.java
rename to hibernate-core/src/main/java/org/hibernate/engine/jdbc/internal/TypeInfoExtracter.java
index e39cd086eb..cac3401e4e 100644
--- a/hibernate-core/src/main/java/org/hibernate/internal/util/jdbc/TypeInfoExtracter.java
+++ b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/internal/TypeInfoExtracter.java
@@ -21,7 +21,7 @@
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
-package org.hibernate.internal.util.jdbc;
+package org.hibernate.engine.jdbc.internal;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
diff --git a/hibernate-core/src/main/java/org/hibernate/internal/util/jdbc/TypeNullability.java b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/internal/TypeNullability.java
similarity index 98%
rename from hibernate-core/src/main/java/org/hibernate/internal/util/jdbc/TypeNullability.java
rename to hibernate-core/src/main/java/org/hibernate/engine/jdbc/internal/TypeNullability.java
index 2dad8be345..cdbfb04e7c 100644
--- a/hibernate-core/src/main/java/org/hibernate/internal/util/jdbc/TypeNullability.java
+++ b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/internal/TypeNullability.java
@@ -21,7 +21,7 @@
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
-package org.hibernate.internal.util.jdbc;
+package org.hibernate.engine.jdbc.internal;
import java.sql.DatabaseMetaData;
diff --git a/hibernate-core/src/main/java/org/hibernate/internal/util/jdbc/TypeSearchability.java b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/internal/TypeSearchability.java
similarity index 98%
rename from hibernate-core/src/main/java/org/hibernate/internal/util/jdbc/TypeSearchability.java
rename to hibernate-core/src/main/java/org/hibernate/engine/jdbc/internal/TypeSearchability.java
index 555524f62f..96aef2e42d 100644
--- a/hibernate-core/src/main/java/org/hibernate/internal/util/jdbc/TypeSearchability.java
+++ b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/internal/TypeSearchability.java
@@ -21,7 +21,7 @@
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
-package org.hibernate.internal.util.jdbc;
+package org.hibernate.engine.jdbc.internal;
import java.sql.DatabaseMetaData;
diff --git a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/spi/ExtractedDatabaseMetaData.java b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/spi/ExtractedDatabaseMetaData.java
index 2a9cda5a1d..10bfe61040 100644
--- a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/spi/ExtractedDatabaseMetaData.java
+++ b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/spi/ExtractedDatabaseMetaData.java
@@ -26,7 +26,7 @@ package org.hibernate.engine.jdbc.spi;
import java.util.LinkedHashSet;
import java.util.Set;
-import org.hibernate.internal.util.jdbc.TypeInfo;
+import org.hibernate.engine.jdbc.internal.TypeInfo;
/**
* Information extracted from {@link java.sql.DatabaseMetaData} regarding what the JDBC driver reports as
diff --git a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/spi/JdbcServices.java b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/spi/JdbcServices.java
index 9a5747996d..6a25234082 100644
--- a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/spi/JdbcServices.java
+++ b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/spi/JdbcServices.java
@@ -55,14 +55,14 @@ public interface JdbcServices extends Service {
*
* @return The SQL statement logger.
*/
- public SQLStatementLogger getSqlStatementLogger();
+ public SqlStatementLogger getSqlStatementLogger();
/**
* Obtain service for dealing with exceptions.
*
* @return The exception helper service.
*/
- public SQLExceptionHelper getSqlExceptionHelper();
+ public SqlExceptionHelper getSqlExceptionHelper();
/**
* Obtain infomration about supported behavior reported by the JDBC driver.
diff --git a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/spi/SQLExceptionHelper.java b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/spi/SqlExceptionHelper.java
similarity index 96%
rename from hibernate-core/src/main/java/org/hibernate/engine/jdbc/spi/SQLExceptionHelper.java
rename to hibernate-core/src/main/java/org/hibernate/engine/jdbc/spi/SqlExceptionHelper.java
index 0db12c826b..69885d8f53 100644
--- a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/spi/SQLExceptionHelper.java
+++ b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/spi/SqlExceptionHelper.java
@@ -42,8 +42,8 @@ import org.hibernate.util.StringHelper;
*
* @author Steve Ebersole
*/
-public class SQLExceptionHelper implements Serializable {
- private static final Logger log = LoggerFactory.getLogger( SQLExceptionHelper.class );
+public class SqlExceptionHelper implements Serializable {
+ private static final Logger log = LoggerFactory.getLogger( SqlExceptionHelper.class );
public static final String DEFAULT_EXCEPTION_MSG = "SQL Exception";
public static final String DEFAULT_WARNING_MSG = "SQL Warning";
@@ -61,7 +61,7 @@ public class SQLExceptionHelper implements Serializable {
/**
* Create an exception helper with a default exception converter.
*/
- public SQLExceptionHelper() {
+ public SqlExceptionHelper() {
sqlExceptionConverter = DEFAULT_CONVERTER;
}
@@ -70,7 +70,7 @@ public class SQLExceptionHelper implements Serializable {
*
* @param sqlExceptionConverter The exception converter to use.
*/
- public SQLExceptionHelper(SQLExceptionConverter sqlExceptionConverter) {
+ public SqlExceptionHelper(SQLExceptionConverter sqlExceptionConverter) {
this.sqlExceptionConverter = sqlExceptionConverter;
}
diff --git a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/spi/SQLStatementLogger.java b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/spi/SqlStatementLogger.java
similarity index 86%
rename from hibernate-core/src/main/java/org/hibernate/engine/jdbc/spi/SQLStatementLogger.java
rename to hibernate-core/src/main/java/org/hibernate/engine/jdbc/spi/SqlStatementLogger.java
index 5be6dd39ce..be469d9bb7 100644
--- a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/spi/SQLStatementLogger.java
+++ b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/spi/SqlStatementLogger.java
@@ -26,34 +26,34 @@ package org.hibernate.engine.jdbc.spi;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.hibernate.jdbc.util.FormatStyle;
-import org.hibernate.jdbc.util.Formatter;
+import org.hibernate.engine.jdbc.internal.FormatStyle;
+import org.hibernate.engine.jdbc.internal.Formatter;
/**
* Centralize logging for SQL statements.
*
* @author Steve Ebersole
*/
-public class SQLStatementLogger {
- private static final Logger log = LoggerFactory.getLogger( SQLStatementLogger.class );
+public class SqlStatementLogger {
+ private static final Logger log = LoggerFactory.getLogger( SqlStatementLogger.class );
private boolean logToStdout;
private boolean format;
/**
- * Constructs a new SQLStatementLogger instance.
+ * Constructs a new SqlStatementLogger instance.
*/
- public SQLStatementLogger() {
+ public SqlStatementLogger() {
this( false, false );
}
/**
- * Constructs a new SQLStatementLogger instance.
+ * Constructs a new SqlStatementLogger instance.
*
* @param logToStdout Should we log to STDOUT in addition to our internal logger.
* @param format Should we format the statements prior to logging
*/
- public SQLStatementLogger(boolean logToStdout, boolean format) {
+ public SqlStatementLogger(boolean logToStdout, boolean format) {
this.logToStdout = logToStdout;
this.format = format;
}
diff --git a/hibernate-core/src/main/java/org/hibernate/engine/transaction/internal/jdbc/JdbcIsolationDelegate.java b/hibernate-core/src/main/java/org/hibernate/engine/transaction/internal/jdbc/JdbcIsolationDelegate.java
index f00fbf55ca..36269665ce 100644
--- a/hibernate-core/src/main/java/org/hibernate/engine/transaction/internal/jdbc/JdbcIsolationDelegate.java
+++ b/hibernate-core/src/main/java/org/hibernate/engine/transaction/internal/jdbc/JdbcIsolationDelegate.java
@@ -31,7 +31,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.hibernate.HibernateException;
-import org.hibernate.engine.jdbc.spi.SQLExceptionHelper;
+import org.hibernate.engine.jdbc.spi.SqlExceptionHelper;
import org.hibernate.engine.transaction.spi.IsolationDelegate;
import org.hibernate.engine.transaction.spi.TransactionCoordinator;
import org.hibernate.jdbc.ReturningWork;
@@ -56,7 +56,7 @@ public class JdbcIsolationDelegate implements IsolationDelegate {
return transactionCoordinator.getJdbcCoordinator().getLogicalConnection().getJdbcServices().getConnectionProvider();
}
- protected SQLExceptionHelper sqlExceptionHelper() {
+ protected SqlExceptionHelper sqlExceptionHelper() {
return transactionCoordinator.getJdbcCoordinator().getLogicalConnection().getJdbcServices().getSqlExceptionHelper();
}
diff --git a/hibernate-core/src/main/java/org/hibernate/engine/transaction/internal/jta/JtaIsolationDelegate.java b/hibernate-core/src/main/java/org/hibernate/engine/transaction/internal/jta/JtaIsolationDelegate.java
index 42bcfa9966..aeab29e538 100644
--- a/hibernate-core/src/main/java/org/hibernate/engine/transaction/internal/jta/JtaIsolationDelegate.java
+++ b/hibernate-core/src/main/java/org/hibernate/engine/transaction/internal/jta/JtaIsolationDelegate.java
@@ -34,7 +34,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.hibernate.HibernateException;
-import org.hibernate.engine.jdbc.spi.SQLExceptionHelper;
+import org.hibernate.engine.jdbc.spi.SqlExceptionHelper;
import org.hibernate.engine.transaction.spi.IsolationDelegate;
import org.hibernate.engine.transaction.spi.TransactionCoordinator;
import org.hibernate.jdbc.ReturningWork;
@@ -69,7 +69,7 @@ public class JtaIsolationDelegate implements IsolationDelegate {
.getConnectionProvider();
}
- protected SQLExceptionHelper sqlExceptionHelper() {
+ protected SqlExceptionHelper sqlExceptionHelper() {
return transactionCoordinator.getTransactionContext()
.getTransactionEnvironment()
.getJdbcServices()
diff --git a/hibernate-core/src/main/java/org/hibernate/id/MultipleHiLoPerTableGenerator.java b/hibernate-core/src/main/java/org/hibernate/id/MultipleHiLoPerTableGenerator.java
index 265c0ae216..f70535534b 100644
--- a/hibernate-core/src/main/java/org/hibernate/id/MultipleHiLoPerTableGenerator.java
+++ b/hibernate-core/src/main/java/org/hibernate/id/MultipleHiLoPerTableGenerator.java
@@ -29,13 +29,13 @@ import org.hibernate.MappingException;
import org.hibernate.cfg.ObjectNameNormalizer;
import org.hibernate.dialect.Dialect;
import org.hibernate.engine.SessionImplementor;
+import org.hibernate.engine.jdbc.internal.FormatStyle;
import org.hibernate.engine.jdbc.spi.JdbcServices;
-import org.hibernate.engine.jdbc.spi.SQLStatementLogger;
+import org.hibernate.engine.jdbc.spi.SqlStatementLogger;
import org.hibernate.id.enhanced.AccessCallback;
import org.hibernate.id.enhanced.OptimizerFactory;
import org.hibernate.internal.util.config.ConfigurationHelper;
import org.hibernate.jdbc.ReturningWork;
-import org.hibernate.jdbc.util.FormatStyle;
import org.hibernate.mapping.Table;
import org.hibernate.type.Type;
import org.slf4j.Logger;
@@ -150,7 +150,7 @@ public class MultipleHiLoPerTableGenerator implements PersistentIdentifierGenera
@Override
public IntegralDataTypeHolder execute(Connection connection) throws SQLException {
IntegralDataTypeHolder value = IdentifierGeneratorHelper.getIntegralDataTypeHolder( returnClass );
- SQLStatementLogger statementLogger = session
+ SqlStatementLogger statementLogger = session
.getFactory()
.getServiceRegistry()
.getService( JdbcServices.class )
diff --git a/hibernate-core/src/main/java/org/hibernate/id/TableGenerator.java b/hibernate-core/src/main/java/org/hibernate/id/TableGenerator.java
index 1c8019b5df..fa2790142a 100644
--- a/hibernate-core/src/main/java/org/hibernate/id/TableGenerator.java
+++ b/hibernate-core/src/main/java/org/hibernate/id/TableGenerator.java
@@ -28,11 +28,11 @@ import org.hibernate.LockMode;
import org.hibernate.cfg.ObjectNameNormalizer;
import org.hibernate.dialect.Dialect;
import org.hibernate.engine.SessionImplementor;
+import org.hibernate.engine.jdbc.internal.FormatStyle;
import org.hibernate.engine.jdbc.spi.JdbcServices;
-import org.hibernate.engine.jdbc.spi.SQLStatementLogger;
+import org.hibernate.engine.jdbc.spi.SqlStatementLogger;
import org.hibernate.internal.util.config.ConfigurationHelper;
import org.hibernate.jdbc.ReturningWork;
-import org.hibernate.jdbc.util.FormatStyle;
import org.hibernate.mapping.Table;
import org.hibernate.type.Type;
import org.slf4j.Logger;
@@ -139,7 +139,7 @@ public class TableGenerator implements PersistentIdentifierGenerator, Configurab
}
protected IntegralDataTypeHolder generateHolder(SessionImplementor session) {
- final SQLStatementLogger statementLogger = session
+ final SqlStatementLogger statementLogger = session
.getFactory()
.getServiceRegistry()
.getService( JdbcServices.class )
diff --git a/hibernate-core/src/main/java/org/hibernate/id/enhanced/TableGenerator.java b/hibernate-core/src/main/java/org/hibernate/id/enhanced/TableGenerator.java
index b2bc06083d..3c704095eb 100644
--- a/hibernate-core/src/main/java/org/hibernate/id/enhanced/TableGenerator.java
+++ b/hibernate-core/src/main/java/org/hibernate/id/enhanced/TableGenerator.java
@@ -32,14 +32,14 @@ import org.hibernate.cfg.ObjectNameNormalizer;
import org.hibernate.dialect.Dialect;
import org.hibernate.engine.SessionImplementor;
import org.hibernate.engine.jdbc.spi.JdbcServices;
-import org.hibernate.engine.jdbc.spi.SQLStatementLogger;
+import org.hibernate.engine.jdbc.spi.SqlStatementLogger;
import org.hibernate.id.Configurable;
import org.hibernate.id.IdentifierGeneratorHelper;
import org.hibernate.id.IntegralDataTypeHolder;
import org.hibernate.id.PersistentIdentifierGenerator;
import org.hibernate.internal.util.config.ConfigurationHelper;
+import org.hibernate.engine.jdbc.internal.FormatStyle;
import org.hibernate.jdbc.ReturningWork;
-import org.hibernate.jdbc.util.FormatStyle;
import org.hibernate.mapping.Table;
import org.hibernate.type.Type;
import org.hibernate.util.StringHelper;
@@ -455,7 +455,7 @@ public class TableGenerator implements PersistentIdentifierGenerator, Configurab
@Override
public synchronized Serializable generate(final SessionImplementor session, Object obj) {
- final SQLStatementLogger statementLogger = session
+ final SqlStatementLogger statementLogger = session
.getFactory()
.getServiceRegistry()
.getService( JdbcServices.class )
diff --git a/hibernate-core/src/main/java/org/hibernate/id/enhanced/TableStructure.java b/hibernate-core/src/main/java/org/hibernate/id/enhanced/TableStructure.java
index cbad28cb17..2464d8858d 100644
--- a/hibernate-core/src/main/java/org/hibernate/id/enhanced/TableStructure.java
+++ b/hibernate-core/src/main/java/org/hibernate/id/enhanced/TableStructure.java
@@ -28,12 +28,12 @@ import org.hibernate.LockMode;
import org.hibernate.dialect.Dialect;
import org.hibernate.engine.SessionImplementor;
import org.hibernate.engine.jdbc.spi.JdbcServices;
-import org.hibernate.engine.jdbc.spi.SQLStatementLogger;
+import org.hibernate.engine.jdbc.spi.SqlStatementLogger;
import org.hibernate.id.IdentifierGenerationException;
import org.hibernate.id.IdentifierGeneratorHelper;
import org.hibernate.id.IntegralDataTypeHolder;
import org.hibernate.jdbc.ReturningWork;
-import org.hibernate.jdbc.util.FormatStyle;
+import org.hibernate.engine.jdbc.internal.FormatStyle;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -118,7 +118,7 @@ public class TableStructure implements DatabaseStructure {
new ReturningWork() {
@Override
public IntegralDataTypeHolder execute(Connection connection) throws SQLException {
- final SQLStatementLogger statementLogger = session
+ final SqlStatementLogger statementLogger = session
.getFactory()
.getServiceRegistry()
.getService( JdbcServices.class )
diff --git a/hibernate-core/src/main/java/org/hibernate/impl/SessionFactoryImpl.java b/hibernate-core/src/main/java/org/hibernate/impl/SessionFactoryImpl.java
index 323bfcf835..9209d8cbe7 100644
--- a/hibernate-core/src/main/java/org/hibernate/impl/SessionFactoryImpl.java
+++ b/hibernate-core/src/main/java/org/hibernate/impl/SessionFactoryImpl.java
@@ -63,7 +63,7 @@ import org.hibernate.engine.NamedSQLQueryDefinition;
import org.hibernate.engine.ResultSetMappingDefinition;
import org.hibernate.engine.SessionFactoryImplementor;
import org.hibernate.engine.jdbc.spi.JdbcServices;
-import org.hibernate.engine.jdbc.spi.SQLExceptionHelper;
+import org.hibernate.engine.jdbc.spi.SqlExceptionHelper;
import org.hibernate.engine.profile.Association;
import org.hibernate.engine.profile.Fetch;
import org.hibernate.engine.profile.FetchProfile;
@@ -80,7 +80,6 @@ import org.hibernate.mapping.PersistentClass;
import org.hibernate.mapping.RootClass;
import org.hibernate.metadata.ClassMetadata;
import org.hibernate.metadata.CollectionMetadata;
-import org.hibernate.persister.internal.PersisterFactoryImpl;
import org.hibernate.persister.collection.CollectionPersister;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.persister.entity.Loadable;
@@ -737,7 +736,7 @@ public final class SessionFactoryImpl
return getSQLExceptionHelper().getSqlExceptionConverter();
}
- public SQLExceptionHelper getSQLExceptionHelper() {
+ public SqlExceptionHelper getSQLExceptionHelper() {
return getJdbcServices().getSqlExceptionHelper();
}
diff --git a/hibernate-core/src/main/java/org/hibernate/jdbc/package.html b/hibernate-core/src/main/java/org/hibernate/jdbc/package.html
index 8b9aeb146c..e8e3d0d377 100755
--- a/hibernate-core/src/main/java/org/hibernate/jdbc/package.html
+++ b/hibernate-core/src/main/java/org/hibernate/jdbc/package.html
@@ -27,12 +27,7 @@
- This package abstracts the mechanism for dispatching SQL statements
- to the database, and implements interaction with JDBC.
-
-
- Concrete implementations of the Batcher interface may be
- selected by specifying hibernate.jdbc.factory_class.
+ Essentially defines {@link Work}, {@link ReturningWork} and {@link Expectation} as well as some exceptions