Merge remote branch 'upstream/master' into 4.0

This commit is contained in:
Alex Snaps 2011-04-07 16:39:20 +02:00
commit cf12382292
26 changed files with 356 additions and 246 deletions

View File

@ -71,13 +71,12 @@ libraries = [
logging: 'org.jboss.logging:jboss-logging:3.0.0.Beta5',
logging_tools: 'org.jboss.logging:jboss-logging-tools:1.0.0.Beta4',
slf4j_api: 'org.slf4j:slf4j-api:' + slf4jVersion,
slf4j_simple: 'org.slf4j:slf4j-simple:' + slf4jVersion,
slf4j_log4j12: 'org.slf4j:slf4j-log4j12:' + slf4jVersion,
jcl_slf4j: 'org.slf4j:jcl-over-slf4j:' + slf4jVersion,
jcl_api: 'commons-logging:commons-logging-api:99.0-does-not-exist',
jcl: 'commons-logging:commons-logging:99.0-does-not-exist',
// testing
atomikos: 'com.atomikos:transactions-jdbc:3.7.0',
junit: 'junit:junit:4.8.2',
jpa_modelgen: 'org.hibernate:hibernate-jpamodelgen:1.1.1.Final',
shrinkwrap_api: 'org.jboss.shrinkwrap:shrinkwrap-api:1.0.0-alpha-6',
@ -121,9 +120,8 @@ subprojects { subProject ->
dependencies {
compile( libraries.logging )
testCompile( libraries.junit )
testCompile( libraries.atomikos )
testRuntime( libraries.slf4j_api )
testRuntime( libraries.slf4j_simple )
testRuntime( libraries.slf4j_log4j12 )
testRuntime( libraries.jcl_slf4j )
testRuntime( libraries.jcl_api )
testRuntime( libraries.jcl )

View File

@ -5,6 +5,67 @@ match the actual issue resolution (i.e. a bug might not be a bug). Please
refer to the particular case on JIRA using the issue tracking number to learn
more about each case.
Changes in version 4.0.0.Alpha2 (2011.04.06)
------------------------------------------------------------------------------------------------------------------------
** Bug
* [HHH-4999] - createSQLQuery(query).list() result screw up when when columns in different tables have same name
* [HHH-5803] - Better handling of implicit literal numeric expression typing
* [HHH-5940] - @MapKeyJoinColumns always throws an exception
* [HHH-5989] - Add tests of JPA-style transaction joining
* [HHH-5996] - Wire in JdbcServices into SchemaUpdateTask, SchemaExportTask, SchemaValidatorTask, HibernateService.dropSchema(), HibernateService.createSchema()
* [HHH-6001] - Add a top-level directory inside the release bundle archives
* [HHH-6002] - Use today's year when building copyright footer for aggregated javadocs
* [HHH-6028] - Remove o.h.classic stuff
* [HHH-6057] - hibernate.cfg.xml references wrong hbm.xml files and doesn't include reference to DTD file
* [HHH-6058] - Error in mapping file in Event.hbm.xml file for documentation in download
* [HHH-6061] - ValidatoryFactory type checking
* [HHH-6076] - query with setFirstResult throws Exception on derby
** Improvement
* [HHH-2680] - Blobs not updated on Session.merge() for detached instances
* [HHH-2860] - Consolidate Session creation options/parameters
* [HHH-4362] - @RowId
* [HHH-5244] - Flesh out H2Dialect temp table support
* [HHH-5284] - Allow Type to dictate the default length/scale/precision
* [HHH-5562] - Introduce a locator pattern for integrators to be able to leverage to more easily integrate with Hibernate
* [HHH-5947] - Improve error message, documentation and tests on @UniqueConstraint
* [HHH-5993] - Expose SessionFactoryObserver to Hibernate EntityManager configuration
* [HHH-6053] - Create an interface for centralizing the contract that is shared between Session and StatelessSession
** New Feature
* [HHH-5697] - Support for multi-tenancy
** Patch
* [HHH-3646] - implement Criteria API querying of collection-of-component (David Mansfield)
* [HHH-5348] - support for TypedQuery jpaql/hql "scalar" queries
** Task
* [HHH-5650] - Pull documentation building into 'release' module
* [HHH-5682] - Modify service infrastructure to leverage CDI annotations
* [HHH-5683] - Create Weld-specific ServiceRegistry
* [HHH-5913] - Implement set of event listeners as a service
* [HHH-5942] - Migrate to JUnit 4
* [HHH-5966] - Finish up loose ends for overriding a SqlTypeDescriptor
* [HHH-6010] - Remove duplication in code involving Work and ReturningWork
* [HHH-6013] - Consolidate on single JTA impl for testing
* [HHH-6015] - Investigate hibernate-infinispan test failures since migration to JUnit4
* [HHH-6016] - Migrate version injection plugin to Gradle
* [HHH-6025] - Remove cglib dependencies
* [HHH-6026] - Migrate bytecode provider integrations to api/spi/internal split
* [HHH-6027] - Migrate o.h.action pakcage to api/spi/internal split
* [HHH-6033] - Migrate stats to api/spi/internal split
* [HHH-6036] - integration documentation generation
* [HHH-6038] - Migrate to use newly separated gradle-upload-auth-plugin
* [HHH-6047] - allow nesting of ServiceRegistry
* [HHH-6050] - Remove direct compile-time dependencies to slf4j from build
* [HHH-6051] - Create a SessionFactory scoped ServiceRegistry
* [HHH-6052] - Make statistics a service
* [HHH-6073] - Dialects cannot use the Thread Context ClassLoader with AS7, please change to use the
* [HHH-6081] - Finish up Integrator
* [HHH-6088] - Move to slf4j-log4j12 for test logging
Changes in version 4.0.0.Alpha1 (2011.03.09)
------------------------------------------------------------------------------------------------------------------------
http://opensource.atlassian.com/projects/hibernate/browse/HHH/fixforversion/11161

View File

@ -1858,4 +1858,12 @@ public interface HibernateLogger extends BasicLogger {
@LogMessage( level = WARN )
@Message( value = "Setting entity-identifier value binding where one already existed : %s.", id = 429 )
void entityIdentifierValueBindingExists(String name);
@LogMessage( level = WARN )
@Message( value = "The DerbyDialect dialect has been deprecated; use one of the version-specific dialects instead", id = 430 )
void deprecatedDerbyDialect();
@LogMessage( level = WARN )
@Message( value = "Unable to determine H2 database version, certain features may not work", id = 431 )
void undeterminedH2Version();
}

View File

@ -37,7 +37,7 @@ import org.hibernate.HibernateLogger;
import org.hibernate.cfg.Configuration;
import org.hibernate.cfg.Environment;
import org.hibernate.engine.SessionFactoryImplementor;
import org.hibernate.impl.Integrator;
import org.hibernate.spi.Integrator;
import org.hibernate.internal.util.config.ConfigurationHelper;
import org.hibernate.service.classloading.spi.ClassLoaderService;
import org.hibernate.service.event.spi.EventListenerRegistry;
@ -49,6 +49,8 @@ import org.hibernate.service.spi.SessionFactoryServiceRegistry;
public class BeanValidationIntegrator implements Integrator {
private static final HibernateLogger LOG = Logger.getMessageLogger(HibernateLogger.class, BeanValidationIntegrator.class.getName());
public static final String APPLY_CONSTRAINTS = "hibernate.validator.apply_to_ddl";
public static final String BV_CHECK_CLASS = "javax.validation.Validation";
public static final String MODE_PROPERTY = "javax.persistence.validation.mode";
@ -149,7 +151,7 @@ public class BeanValidationIntegrator implements Integrator {
boolean beanValidationAvailable,
Class typeSafeActivatorClass,
Configuration configuration) {
if ( ! ConfigurationHelper.getBoolean( LegacyHibernateValidationIntegrator.APPLY_CONSTRAINTS, configuration.getProperties(), true ) ){
if ( ! ConfigurationHelper.getBoolean( APPLY_CONSTRAINTS, configuration.getProperties(), true ) ){
LOG.debug( "Skipping application of relational constraints from legacy Hibernate Validator" );
return;
}
@ -287,4 +289,8 @@ public class BeanValidationIntegrator implements Integrator {
}
}
@Override
public void disintegrate(SessionFactoryImplementor sessionFactory, SessionFactoryServiceRegistry serviceRegistry) {
// nothing to do here afaik
}
}

View File

@ -1,155 +0,0 @@
/*
* 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.cfg.beanvalidation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.Map;
import java.util.ResourceBundle;
import org.jboss.logging.Logger;
import org.hibernate.AnnotationException;
import org.hibernate.HibernateLogger;
import org.hibernate.annotations.common.reflection.ReflectionManager;
import org.hibernate.cfg.Configuration;
import org.hibernate.engine.SessionFactoryImplementor;
import org.hibernate.event.EventType;
import org.hibernate.event.PreInsertEventListener;
import org.hibernate.event.PreUpdateEventListener;
import org.hibernate.impl.Integrator;
import org.hibernate.internal.util.ReflectHelper;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.internal.util.config.ConfigurationHelper;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.service.classloading.spi.ClassLoaderService;
import org.hibernate.service.event.spi.EventListenerRegistry;
import org.hibernate.service.spi.SessionFactoryServiceRegistry;
/**
* @author Steve Ebersole
*/
public class LegacyHibernateValidationIntegrator implements Integrator {
private static final HibernateLogger LOG = Logger.getMessageLogger( HibernateLogger.class, LegacyHibernateValidationIntegrator.class.getName() );
public static final String APPLY_CONSTRAINTS = "hibernate.validator.apply_to_ddl";
public static final String CLASS_VALIDATOR_CLASS = "org.hibernate.validator.ClassValidator";
public static final String MSG_INTERPOLATOR_CLASS = "org.hibernate.validator.MessageInterpolator";
public static final String AUTO_REGISTER = "hibernate.validator.autoregister_listeners";
public static final String LISTENER_CLASS_NAME = "org.hibernate.validator.event.ValidateEventListener";
// this code mostly all copied and pasted from various spots...
@Override
public void integrate(
Configuration configuration,
SessionFactoryImplementor sessionFactory,
SessionFactoryServiceRegistry serviceRegistry) {
applyRelationalConstraints( configuration, serviceRegistry );
applyListeners( configuration, serviceRegistry );
}
@SuppressWarnings( {"unchecked"})
private void applyRelationalConstraints(Configuration configuration, SessionFactoryServiceRegistry serviceRegistry) {
if ( ! ConfigurationHelper.getBoolean( APPLY_CONSTRAINTS, configuration.getProperties(), true ) ){
LOG.debug( "Skipping application of relational constraints from legacy Hibernate Validator" );
return;
}
Constructor validatorCtr = null;
Method applyMethod = null;
try {
final ClassLoaderService classLoaderService = serviceRegistry.getService( ClassLoaderService.class );
final Class classValidator = classLoaderService.classForName( CLASS_VALIDATOR_CLASS );
final Class messageInterpolator = classLoaderService.classForName( MSG_INTERPOLATOR_CLASS );
validatorCtr = classValidator.getDeclaredConstructor(
Class.class, ResourceBundle.class, messageInterpolator, Map.class, ReflectionManager.class
);
applyMethod = classValidator.getMethod( "apply", PersistentClass.class );
}
catch ( NoSuchMethodException e ) {
throw new AnnotationException( e );
}
catch ( Exception e ) {
LOG.debug( "Legacy Hibernate Validator classes not found, ignoring" );
}
if ( applyMethod != null ) {
Iterable<PersistentClass> persistentClasses = ( (Map<String,PersistentClass>) configuration.createMappings().getClasses() ).values();
for ( PersistentClass persistentClass : persistentClasses ) {
// integrate the validate framework
String className = persistentClass.getClassName();
if ( StringHelper.isNotEmpty( className ) ) {
try {
Object validator = validatorCtr.newInstance(
ReflectHelper.classForName( className ), null, null, null, configuration.getReflectionManager()
);
applyMethod.invoke( validator, persistentClass );
}
catch ( Exception e ) {
LOG.unableToApplyConstraints(className, e);
}
}
}
}
}
private void applyListeners(Configuration configuration, SessionFactoryServiceRegistry serviceRegistry) {
final boolean registerListeners = ConfigurationHelper.getBoolean( AUTO_REGISTER, configuration.getProperties(), false );
if ( !registerListeners ) {
LOG.debug( "Skipping legacy validator auto registration" );
return;
}
final Class listenerClass = loadListenerClass( serviceRegistry );
if ( listenerClass == null ) {
LOG.debug( "Skipping legacy validator auto registration - could not locate listener" );
return;
}
final Object validateEventListener;
try {
validateEventListener = listenerClass.newInstance();
}
catch ( Exception e ) {
throw new AnnotationException( "Unable to instantiate Validator event listener", e );
}
EventListenerRegistry listenerRegistry = serviceRegistry.getService( EventListenerRegistry.class );
// todo : duplication strategy
listenerRegistry.appendListeners( EventType.PRE_INSERT, (PreInsertEventListener) validateEventListener );
listenerRegistry.appendListeners( EventType.PRE_UPDATE, (PreUpdateEventListener) validateEventListener );
}
private Class loadListenerClass(SessionFactoryServiceRegistry serviceRegistry) {
try {
return serviceRegistry.getService( ClassLoaderService.class ).classForName( LISTENER_CLASS_NAME );
}
catch (Exception e) {
return null;
}
}
}

View File

@ -36,7 +36,7 @@ import org.hibernate.event.PostCollectionUpdateEventListener;
import org.hibernate.event.PostDeleteEventListener;
import org.hibernate.event.PostInsertEventListener;
import org.hibernate.event.PostUpdateEventListener;
import org.hibernate.impl.Integrator;
import org.hibernate.spi.Integrator;
import org.hibernate.internal.util.config.ConfigurationHelper;
import org.hibernate.service.classloading.spi.ClassLoaderService;
import org.hibernate.service.event.spi.DuplicationStrategy;
@ -126,4 +126,9 @@ public class HibernateSearchIntegrator implements Integrator {
return Action.KEEP_ORIGINAL;
}
}
@Override
public void disintegrate(SessionFactoryImplementor sessionFactory, SessionFactoryServiceRegistry serviceRegistry) {
// nothing to do here afaik
}
}

View File

@ -40,7 +40,10 @@ import org.jboss.logging.Logger;
* http://www.jroller.com/comments/kenlars99/Weblog/cloudscape_soon_to_be_derby
*
* @author Simon Johnston
*
* @deprecated HHH-6073
*/
@Deprecated
public class DerbyDialect extends DB2Dialect {
private static final HibernateLogger LOG = Logger.getMessageLogger(HibernateLogger.class, DerbyDialect.class.getName());
@ -50,6 +53,7 @@ public class DerbyDialect extends DB2Dialect {
public DerbyDialect() {
super();
LOG.deprecatedDerbyDialect();
registerFunction( "concat", new DerbyConcatFunction() );
registerFunction( "trim", new AnsiTrimFunction() );
determineDriverVersion();

View File

@ -0,0 +1,60 @@
/*
* 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.dialect;
import org.hibernate.dialect.function.AnsiTrimFunction;
import org.hibernate.dialect.function.DerbyConcatFunction;
/**
* Hibernate Dialect for Cloudscape 10 - aka Derby. This implements both an
* override for the identity column generator as well as for the case statement
* issue documented at:
* http://www.jroller.com/comments/kenlars99/Weblog/cloudscape_soon_to_be_derby
*
* @author Simon Johnston
* @author Scott Marlow
*/
public class DerbyTenFiveDialect extends DerbyDialect {
public DerbyTenFiveDialect() {
super();
registerFunction( "concat", new DerbyConcatFunction() );
registerFunction( "trim", new AnsiTrimFunction() );
}
@Override
public boolean supportsSequences() {
return false;
}
@Override
public boolean supportsLimit() {
return true;
}
@Override
public boolean supportsLimitOffset() {
return true;
}
}

View File

@ -0,0 +1,44 @@
/*
* 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.dialect;
/**
* Hibernate Dialect for Cloudscape 10 - aka Derby. This implements both an
* override for the identity column generator as well as for the case statement
* issue documented at:
* http://www.jroller.com/comments/kenlars99/Weblog/cloudscape_soon_to_be_derby
*
* @author Simon Johnston
* @author Scott Marlow
*/
public class DerbyTenSixDialect extends DerbyTenFiveDialect {
public DerbyTenSixDialect() {
super();
}
@Override
public boolean supportsSequences() {
return true;
}
}

View File

@ -46,29 +46,33 @@ public class H2Dialect extends Dialect {
private static final HibernateLogger LOG = Logger.getMessageLogger(HibernateLogger.class, H2Dialect.class.getName());
private String querySequenceString;
private final String querySequenceString;
public H2Dialect() {
super();
querySequenceString = "select sequence_name from information_schema.sequences";
String querySequenceString = "select sequence_name from information_schema.sequences";
try {
// HHH-2300
final Class constants = ReflectHelper.classForName( "org.h2.engine.Constants" );
final int majorVersion = ( Integer ) constants.getDeclaredField( "VERSION_MAJOR" ).get( null );
final int minorVersion = ( Integer ) constants.getDeclaredField( "VERSION_MINOR" ).get( null );
final int buildId = ( Integer ) constants.getDeclaredField( "BUILD_ID" ).get( null );
final Class h2ConstantsClass = ReflectHelper.classForName( "org.h2.engine.Constants" );
final int majorVersion = ( Integer ) h2ConstantsClass.getDeclaredField( "VERSION_MAJOR" ).get( null );
final int minorVersion = ( Integer ) h2ConstantsClass.getDeclaredField( "VERSION_MINOR" ).get( null );
final int buildId = ( Integer ) h2ConstantsClass.getDeclaredField( "BUILD_ID" ).get( null );
if ( buildId < 32 ) {
querySequenceString = "select name from information_schema.sequences";
}
if (!(majorVersion > 1 || minorVersion > 2 || buildId >= 139)) LOG.unsupportedMultiTableBulkHqlJpaql(majorVersion,
minorVersion,
buildId);
if ( ! ( majorVersion > 1 || minorVersion > 2 || buildId >= 139 ) ) {
LOG.unsupportedMultiTableBulkHqlJpaql( majorVersion, minorVersion, buildId );
}
}
catch ( Exception e ) {
// ignore (probably H2 not in the classpath)
// probably H2 not in the classpath, though in certain app server environments it might just mean we are
// not using the correct classloader
LOG.undeterminedH2Version();
}
this.querySequenceString = querySequenceString;
registerColumnType( Types.BOOLEAN, "boolean" );
registerColumnType( Types.BIGINT, "bigint" );
registerColumnType( Types.BINARY, "binary" );
@ -297,8 +301,17 @@ public class H2Dialect extends Dialect {
return "create local temporary table if not exists";
}
@Override
public String getCreateTemporaryTablePostfix() {
// actually 2 different options are specified here:
// 1) [on commit drop] - says to drop the table on transaction commit
// 2) [transactional] - says to not perform an implicit commit of any current transaction
return "on commit drop transactional";
}
@Override
public Boolean performTemporaryTableDDLInIsolation() {
// explicitly create the table using the same connection and transaction
return Boolean.FALSE;
}

View File

@ -100,7 +100,7 @@ public class SqlStatementLogger {
statement = formatter.format( statement );
}
}
LOG.debugf(statement);
LOG.debug( statement );
if ( logToStdout ) {
System.out.println( "Hibernate: " + statement );
}

View File

@ -249,7 +249,7 @@ public class QueryTranslatorImpl implements FilterTranslator {
if (LOG.isDebugEnabled()) {
ASTPrinter printer = new ASTPrinter( SqlTokenTypes.class );
LOG.debugf(printer.showAsString(w.getAST(), "--- SQL AST ---"));
LOG.debug( printer.showAsString( w.getAST(), "--- SQL AST ---" ) );
}
w.getParseErrorHandler().throwQueryException();
@ -280,7 +280,7 @@ public class QueryTranslatorImpl implements FilterTranslator {
void showHqlAst(AST hqlAst) {
if (LOG.isDebugEnabled()) {
ASTPrinter printer = new ASTPrinter( HqlTokenTypes.class );
LOG.debugf(printer.showAsString(hqlAst, "--- HQL AST ---"));
LOG.debug( printer.showAsString( hqlAst, "--- HQL AST ---" ) );
}
}

View File

@ -27,13 +27,11 @@ import javax.naming.NamingException;
import javax.naming.Reference;
import javax.naming.StringRefAddr;
import java.io.IOException;
import java.io.InputStream;
import java.io.InvalidObjectException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.ObjectStreamException;
import java.io.Serializable;
import java.net.URL;
import java.sql.Connection;
import java.util.ArrayList;
import java.util.Collections;
@ -44,6 +42,7 @@ import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.ServiceLoader;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
@ -82,7 +81,6 @@ import org.hibernate.cfg.Configuration;
import org.hibernate.cfg.Environment;
import org.hibernate.cfg.Settings;
import org.hibernate.cfg.beanvalidation.BeanValidationIntegrator;
import org.hibernate.cfg.beanvalidation.LegacyHibernateValidationIntegrator;
import org.hibernate.cfg.search.HibernateSearchIntegrator;
import org.hibernate.context.CurrentSessionContext;
import org.hibernate.context.JTASessionContext;
@ -125,12 +123,12 @@ import org.hibernate.persister.spi.PersisterFactory;
import org.hibernate.pretty.MessageHelper;
import org.hibernate.proxy.EntityNotFoundDelegate;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.classloading.spi.ClassLoaderService;
import org.hibernate.service.jdbc.connections.spi.ConnectionProvider;
import org.hibernate.service.jta.platform.spi.JtaPlatform;
import org.hibernate.service.spi.ServiceRegistryImplementor;
import org.hibernate.service.spi.SessionFactoryServiceRegistry;
import org.hibernate.service.spi.SessionFactoryServiceRegistryFactory;
import org.hibernate.spi.Integrator;
import org.hibernate.stat.Statistics;
import org.hibernate.stat.spi.StatisticsImplementor;
import org.hibernate.tool.hbm2ddl.SchemaExport;
@ -245,8 +243,26 @@ public final class SessionFactoryImpl
// todo : everything above here consider implementing as standard SF service. specifically: stats, caches, types, function-reg
class IntegratorObserver implements SessionFactoryObserver {
private ArrayList<Integrator> integrators = new ArrayList<Integrator>();
@Override
public void sessionFactoryCreated(SessionFactory factory) {
}
@Override
public void sessionFactoryClosed(SessionFactory factory) {
for ( Integrator integrator : integrators ) {
integrator.disintegrate( SessionFactoryImpl.this, SessionFactoryImpl.this.serviceRegistry );
}
}
}
final IntegratorObserver integratorObserver = new IntegratorObserver();
this.observer.addObserver( integratorObserver );
for ( Integrator integrator : locateIntegrators( this.serviceRegistry ) ) {
integrator.integrate( cfg, this, (SessionFactoryServiceRegistry) this.serviceRegistry );
integrator.integrate( cfg, this, this.serviceRegistry );
integratorObserver.integrators.add( integrator );
}
//Generators:
@ -490,43 +506,14 @@ public final class SessionFactoryImpl
private Iterable<Integrator> locateIntegrators(ServiceRegistryImplementor serviceRegistry) {
List<Integrator> integrators = new ArrayList<Integrator>();
// todo : Envers needs to bbe handled by discovery to be because it is in a separate project
integrators.add( new LegacyHibernateValidationIntegrator() );
// todo : Envers needs to be handled by discovery to be because it is in a separate project
integrators.add( new BeanValidationIntegrator() );
integrators.add( new HibernateSearchIntegrator() );
final Properties properties = new Properties();
for ( Integrator integrator : ServiceLoader.load( Integrator.class ) ) {
integrators.add( integrator );
}
ClassLoaderService classLoader = serviceRegistry.getService( ClassLoaderService.class );
List<URL> urls = classLoader.locateResources( "META-INF/hibernate/org.hibernate.impl.Integrator" );
for ( URL url : urls ) {
try {
final InputStream propertyStream = url.openStream();
try {
properties.clear();
properties.load( propertyStream );
// for now we only understand 'implClass' as key
final String implClass = properties.getProperty( "implClass" );
Class integratorClass = classLoader.classForName( implClass );
try {
integrators.add( (Integrator) integratorClass.newInstance() );
}
catch (Exception e) {
throw new HibernateException( "Unable to instantiate specified Integrator class [" + implClass + "]", e );
}
}
finally {
try {
propertyStream.close();
}
catch (IOException ignore) {
}
}
}
catch ( IOException ioe ) {
LOG.debugf( ioe, "Unable to process Integrator service file [%s], skipping" , url.toExternalForm() );
}
}
return integrators;
}

View File

@ -1685,6 +1685,18 @@ public abstract class Loader {
return dialect.supportsLimit() && hasMaxRows( selection );
}
private ScrollMode getScrollMode(boolean scroll, boolean hasFirstRow, boolean useLimitOffSet, QueryParameters queryParameters) {
final boolean canScroll = getFactory().getSettings().isScrollableResultSetsEnabled();
if ( canScroll ) {
if ( scroll ) {
return queryParameters.getScrollMode();
}
if ( hasFirstRow && !useLimitOffSet ) {
return ScrollMode.SCROLL_INSENSITIVE;
}
}
return null;
}
/**
* Obtain a <tt>PreparedStatement</tt> with all parameters pre-bound.
* Bind JDBC-style <tt>?</tt> parameters, named parameters, and
@ -1701,24 +1713,23 @@ public abstract class Loader {
final RowSelection selection = queryParameters.getRowSelection();
boolean useLimit = useLimit( selection, dialect );
boolean hasFirstRow = getFirstRow( selection ) > 0;
boolean useOffset = hasFirstRow && useLimit && dialect.supportsLimitOffset();
boolean useLimitOffset = hasFirstRow && useLimit && dialect.supportsLimitOffset();
boolean callable = queryParameters.isCallable();
final boolean canScroll = getFactory().getSettings().isScrollableResultSetsEnabled();
final boolean useScrollableResultSetToSkip = hasFirstRow &&
!useOffset &&
getFactory().getSettings().isScrollableResultSetsEnabled();
final ScrollMode scrollMode =
canScroll
? scroll || useScrollableResultSetToSkip
? queryParameters.getScrollMode()
: ScrollMode.SCROLL_INSENSITIVE
: null;
!useLimitOffset && canScroll;
final ScrollMode scrollMode = getScrollMode( scroll, hasFirstRow, useLimit, queryParameters );
//
// if(canScroll && ( scroll || useScrollableResultSetToSkip )){
// scrollMode = scroll ? queryParameters.getScrollMode() : ScrollMode.SCROLL_INSENSITIVE;
// }else{
// scrollMode = null;
// }
if ( useLimit ) {
sql = dialect.getLimitString(
sql.trim(), //use of trim() here is ugly?
useOffset ? getFirstRow(selection) : 0,
useLimitOffset ? getFirstRow(selection) : 0,
getMaxOrLimit(selection, dialect)
);
}

View File

@ -27,6 +27,8 @@ import java.sql.SQLException;
import org.hibernate.HibernateLogger;
import org.hibernate.dialect.DB2Dialect;
import org.hibernate.dialect.DerbyDialect;
import org.hibernate.dialect.DerbyTenFiveDialect;
import org.hibernate.dialect.DerbyTenSixDialect;
import org.hibernate.dialect.Dialect;
import org.hibernate.dialect.H2Dialect;
import org.hibernate.dialect.HSQLDialect;
@ -78,8 +80,17 @@ public class StandardDialectResolver extends AbstractDialectResolver {
}
if ( "Apache Derby".equals( databaseName ) ) {
final int databaseMinorVersion = metaData.getDatabaseMinorVersion();
if ( databaseMajorVersion > 10 || ( databaseMajorVersion == 10 && databaseMinorVersion >= 6 ) ) {
return new DerbyTenSixDialect();
}
else if ( databaseMajorVersion == 10 && databaseMinorVersion == 5 ) {
return new DerbyTenFiveDialect();
}
else {
return new DerbyDialect();
}
}
if ( "ingres".equalsIgnoreCase( databaseName ) ) {
switch( databaseMajorVersion ) {

View File

@ -21,7 +21,7 @@
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.impl;
package org.hibernate.spi;
import org.hibernate.cfg.Configuration;
import org.hibernate.engine.SessionFactoryImplementor;
@ -40,6 +40,7 @@ import org.hibernate.service.spi.SessionFactoryServiceRegistry;
* @author Steve Ebersole
* @since 4.0
* @jira HHH-5562
* @jira HHH-6081
*/
public interface Integrator {
/**
@ -53,4 +54,12 @@ public interface Integrator {
Configuration configuration,
SessionFactoryImplementor sessionFactory,
SessionFactoryServiceRegistry serviceRegistry);
/**
* Tongue-in-cheek name for a shutdown callback.
*
* @param sessionFactory The session factory being closed.
* @param serviceRegistry That session factory's service registry
*/
public void disintegrate(SessionFactoryImplementor sessionFactory, SessionFactoryServiceRegistry serviceRegistry);
}

View File

@ -22,6 +22,7 @@
* Boston, MA 02110-1301 USA
*/
package org.hibernate.dialect;
import javax.persistence.criteria.CriteriaBuilder;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
@ -35,8 +36,12 @@ import java.sql.SQLException;
@SuppressWarnings( {"UnnecessaryBoxing"})
public class Mocks {
public static Connection createConnection(String dbName, int version) {
DatabaseMetaDataHandler metadataHandler = new DatabaseMetaDataHandler( dbName, version );
public static Connection createConnection(String databaseName, int majorVersion) {
return createConnection( databaseName, majorVersion, -9999 );
}
public static Connection createConnection(String databaseName, int majorVersion, int minorVersion) {
DatabaseMetaDataHandler metadataHandler = new DatabaseMetaDataHandler( databaseName, majorVersion, minorVersion );
ConnectionHandler connectionHandler = new ConnectionHandler();
DatabaseMetaData metadataProxy = ( DatabaseMetaData ) Proxy.newProxyInstance(
@ -90,6 +95,7 @@ public class Mocks {
private static class DatabaseMetaDataHandler implements InvocationHandler {
private final String databaseName;
private final int majorVersion;
private final int minorVersion;
private Connection connectionProxy;
@ -98,8 +104,13 @@ public class Mocks {
}
private DatabaseMetaDataHandler(String databaseName, int majorVersion) {
this( databaseName, majorVersion, -9999 );
}
private DatabaseMetaDataHandler(String databaseName, int majorVersion, int minorVersion) {
this.databaseName = databaseName;
this.majorVersion = majorVersion;
this.minorVersion = minorVersion;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
@ -112,6 +123,10 @@ public class Mocks {
return Integer.valueOf( majorVersion );
}
if ( "getDatabaseMinorVersion".equals( methodName ) ) {
return Integer.valueOf( minorVersion );
}
if ( "getConnection".equals( methodName ) ) {
return connectionProxy;
}

View File

@ -33,6 +33,8 @@ import org.hibernate.HibernateException;
import org.hibernate.cfg.Environment;
import org.hibernate.dialect.DB2Dialect;
import org.hibernate.dialect.DerbyDialect;
import org.hibernate.dialect.DerbyTenFiveDialect;
import org.hibernate.dialect.DerbyTenSixDialect;
import org.hibernate.dialect.H2Dialect;
import org.hibernate.dialect.HSQLDialect;
import org.hibernate.dialect.InformixDialect;
@ -123,7 +125,10 @@ public class DialectFactoryTest extends BaseUnitTestCase {
testDetermination( "H2", H2Dialect.class, resolver );
testDetermination( "MySQL", MySQLDialect.class, resolver );
testDetermination( "PostgreSQL", PostgreSQLDialect.class, resolver );
testDetermination( "Apache Derby", DerbyDialect.class, resolver );
testDetermination( "Apache Derby", 10, 4, DerbyDialect.class, resolver );
testDetermination( "Apache Derby", 10, 5, DerbyTenFiveDialect.class, resolver );
testDetermination( "Apache Derby", 10, 6, DerbyTenSixDialect.class, resolver );
testDetermination( "Apache Derby", 11, 5, DerbyTenSixDialect.class, resolver );
testDetermination( "Ingres", IngresDialect.class, resolver );
testDetermination( "ingres", IngresDialect.class, resolver );
testDetermination( "INGRES", IngresDialect.class, resolver );
@ -197,9 +202,14 @@ public class DialectFactoryTest extends BaseUnitTestCase {
}
private void testDetermination(String databaseName, int databaseMajorVersion, Class clazz, DialectResolver resolver) {
testDetermination( databaseName, databaseMajorVersion, -9999, clazz, resolver );
}
private void testDetermination(String databaseName, int majorVersion, int minorVersion, Class clazz, DialectResolver resolver) {
dialectFactory.setDialectResolver( resolver );
Properties properties = new Properties();
Connection conn = Mocks.createConnection( databaseName, databaseMajorVersion );
Connection conn = Mocks.createConnection( databaseName, majorVersion, minorVersion );
assertEquals( clazz, dialectFactory.buildDialect( properties, conn ).getClass() );
}
}

View File

@ -91,6 +91,23 @@ public class PaginationTest extends BaseCoreFunctionalTestCase {
cleanupTestData();
}
@Test
public void testOffset(){
prepareTestData();
Session session = openSession();
session.beginTransaction();
List result;
result = generateBaseHQLQuery( session )
.setFirstResult( 3 )
.list();
result = generateBaseCriteria( session )
.setFirstResult( 3 )
.list();
session.getTransaction().commit();
session.close();
cleanupTestData();
}
@Test
@RequiresDialectFeature(

View File

@ -6,15 +6,5 @@ log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n
log4j.rootLogger=info, stdout
log4j.logger.org.hibernate.test=info
log4j.logger.org.hibernate.tool.hbm2ddl=debug
log4j.logger.org.hibernate.engine.jdbc.internal=trace
log4j.logger.org.hibernate.engine.jdbc.internal.proxy=trace
log4j.logger.org.hibernate.engine.jdbc.batch.internal=trace
log4j.logger.org.hibernate.hql.ast.QueryTranslatorImpl=trace
log4j.logger.org.hibernate.hql.ast.HqlSqlWalker=trace
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

View File

@ -30,7 +30,7 @@ import org.hibernate.cfg.Configuration;
import org.hibernate.engine.SessionFactoryImplementor;
import org.hibernate.envers.configuration.AuditConfiguration;
import org.hibernate.event.EventType;
import org.hibernate.impl.Integrator;
import org.hibernate.spi.Integrator;
import org.hibernate.internal.util.config.ConfigurationHelper;
import org.hibernate.service.event.spi.EventListenerRegistry;
import org.hibernate.service.spi.SessionFactoryServiceRegistry;
@ -70,4 +70,9 @@ public class EnversIntegrator implements Integrator {
listenerRegistry.appendListeners( EventType.PRE_COLLECTION_UPDATE, new EnversPreCollectionUpdateEventListenerImpl( enversConfiguration ) );
}
}
@Override
public void disintegrate(SessionFactoryImplementor sessionFactory, SessionFactoryServiceRegistry serviceRegistry) {
// nothing to do afaik
}
}

View File

@ -1 +0,0 @@
implClass = org.hibernate.envers.event.EnversIntegrator

View File

@ -0,0 +1 @@
org.hibernate.envers.event.EnversIntegrator

View File

@ -49,8 +49,5 @@ test {
systemProperties['jgroups.bind_addr'] = 'localhost'
// systemProperties['log4j.configuration'] = 'file:/log4j/log4j-infinispan.xml'
enabled = true
afterTest { desc, result ->
println "Executing test ${desc.name} [${desc.className}] with result: ${result.resultType}"
}
}

View File

@ -38,6 +38,8 @@ import org.hibernate.stat.Statistics;
import org.junit.Test;
import org.hibernate.testing.FailureExpected;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
@ -318,6 +320,7 @@ public class BasicTransactionalTestCase extends SingleNodeTestCase {
}
@Test
@FailureExpected( jiraKey = "HHH-6094" )
public void testQueryCache() throws Exception {
Statistics stats = sessionFactory().getStatistics();
stats.clear();
@ -375,6 +378,7 @@ public class BasicTransactionalTestCase extends SingleNodeTestCase {
}
@Test
@FailureExpected( jiraKey = "HHH-6094" )
public void testQueryCacheHitInSameTransaction() throws Exception {
Statistics stats = sessionFactory().getStatistics();
stats.clear();

View File

@ -165,7 +165,17 @@ public class CustomRunner extends BlockJUnit4ClassRunner {
}
}
private static Dialect dialect = Dialect.getDialect();
private static Dialect dialect = determineDialect();
private static Dialect determineDialect() {
try {
return Dialect.getDialect();
}
catch( Exception e ) {
return new Dialect() {
};
}
}
protected Ignore convertSkipToIgnore(FrameworkMethod frameworkMethod) {
// @Skip