merge master

This commit is contained in:
Strong Liu 2013-05-13 18:55:37 +08:00
commit 96ce0d2742
132 changed files with 3514 additions and 2783 deletions

View File

@ -21,6 +21,7 @@ buildscript {
} }
dependencies { dependencies {
classpath 'org.hibernate.build.gradle:gradle-maven-publish-auth:2.0.1' classpath 'org.hibernate.build.gradle:gradle-maven-publish-auth:2.0.1'
classpath 'org.hibernate.build.gradle:hibernate-matrix-testing:1.0.0-SNAPSHOT'
} }
} }
@ -28,7 +29,7 @@ ext.hibernateTargetVersion = '5.0.0-SNAPSHOT'
ext.javaLanguageLevel = "1.6" ext.javaLanguageLevel = "1.6"
task wrapper(type: Wrapper) { task wrapper(type: Wrapper) {
gradleVersion = '1.5' gradleVersion = '1.6'
} }
idea { idea {
@ -103,6 +104,8 @@ subprojects { subProject ->
configurations { configurations {
all*.exclude group: 'xml-apis', module: 'xml-apis' all*.exclude group: 'xml-apis', module: 'xml-apis'
} }
animalSniffer
javaApiSignature
} }
// appropriately inject the common dependencies into each sub-project // appropriately inject the common dependencies into each sub-project
@ -133,6 +136,8 @@ subprojects { subProject ->
jaxb( libraries.jaxb2_ant ) jaxb( libraries.jaxb2_ant )
jaxb( libraries.jaxb2_jaxb ) jaxb( libraries.jaxb2_jaxb )
jaxb( libraries.jaxb2_jaxb_xjc ) jaxb( libraries.jaxb2_jaxb_xjc )
animalSniffer ( libraries.animal_sniffer )
javaApiSignature ( libraries.java16_signature )
} }
// mac-specific stuff ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // mac-specific stuff ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -172,7 +177,9 @@ subprojects { subProject ->
"-encoding", "UTF-8", "-encoding", "UTF-8",
"-processor", "org.jboss.logging.processor.apt.LoggingToolsProcessor", "-processor", "org.jboss.logging.processor.apt.LoggingToolsProcessor",
"-s", "$sourceSets.main.generatedLoggingSrcDir.absolutePath", "-s", "$sourceSets.main.generatedLoggingSrcDir.absolutePath",
"-AloggingVersion=3.0", // "-AloggingVersion=3.0",
"-Adebug=true",
"-AskipTranslations=true",
"-source", rootProject.javaLanguageLevel, "-source", rootProject.javaLanguageLevel,
"-target", rootProject.javaLanguageLevel, "-target", rootProject.javaLanguageLevel,
"-AtranslationFilesPath=${project.rootDir}/src/main/resources" "-AtranslationFilesPath=${project.rootDir}/src/main/resources"
@ -316,6 +323,23 @@ subprojects { subProject ->
// eclipseClasspath will not add sources to classpath unless the dirs actually exist. // eclipseClasspath will not add sources to classpath unless the dirs actually exist.
eclipseClasspath.dependsOn("generateSources") eclipseClasspath.dependsOn("generateSources")
task copyJavaApiSignature(type: Copy) {
from configurations.javaApiSignature
into "$buildDir/javaApiSignature/"
rename '.*signature', 'javaApi.signature'
}
// checks that only types of the target Java version are used
task checkJavaApiSignature << {
ant.taskdef(name: 'animalSniffer', classname: 'org.codehaus.mojo.animal_sniffer.ant.CheckSignatureTask', classpath: configurations.animalSniffer.asPath)
ant.animalSniffer(signature: "$buildDir/javaApiSignature/javaApi.signature", classpath: configurations.compile.asPath + System.properties.'path.separator' + configurations.provided.asPath) {
path(path: "$buildDir/classes/main")
}
}
checkJavaApiSignature.dependsOn compileJava
checkJavaApiSignature.dependsOn copyJavaApiSignature
check.dependsOn checkJavaApiSignature
// specialized API/SPI checkstyle tasks ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // specialized API/SPI checkstyle tasks ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
task checkstylePublicSources(type: Checkstyle) { task checkstylePublicSources(type: Checkstyle) {
checkstyleClasspath = checkstyleMain.checkstyleClasspath checkstyleClasspath = checkstyleMain.checkstyleClasspath
@ -387,30 +411,49 @@ subprojects { subProject ->
} }
pom.withXml { pom.withXml {
def root = asNode(); // append additional metadata
root.appendNode( 'name', subProject.pomName() ) asNode().children().last() + {
root.appendNode( 'description', subProject.pomDescription() ) resolveStrategy = Closure.DELEGATE_FIRST
root.appendNode( 'url', 'http://hibernate.org' )
def org = root.appendNode( 'organization' ) name subProject.pomName()
org.appendNode( 'name', 'Hibernate.org' ) description subProject.pomDescription()
org.appendNode( 'url', 'http://hibernate.org' ) url 'http://hibernate.org'
def jira = root.appendNode( 'issueManagement' ) organization {
jira.appendNode( 'system', 'jira' ) name 'Hibernate.org'
jira.appendNode( 'url', 'https://hibernate.atlassian.net/browse/HHH' ) url 'http://hibernate.org'
def scm = root.appendNode( 'scm' ) }
scm.appendNode( 'url', 'http://github.com/hibernate/hibernate-orm' ) issueManagement {
scm.appendNode( 'connection', 'scm:git:http://github.com/hibernate/hibernate-orm.git' ) system 'jira'
scm.appendNode( 'developerConnection', 'scm:git:git@github.com:hibernate/hibernate-orm.git' ) url 'https://hibernate.atlassian.net/browse/HHH'
def license = root.appendNode( 'licenses' ).appendNode( 'license' ); }
license.appendNode( 'name', 'GNU Lesser General Public License' ) scm {
license.appendNode( 'url', 'http://www.gnu.org/licenses/lgpl-2.1.html' ) url 'http://github.com/hibernate/hibernate-orm'
license.appendNode( 'comments', 'See discussion at http://hibernate.org/license for more details.' ) connection 'scm:git:http://github.com/hibernate/hibernate-orm.git'
license.appendNode( 'distribution', 'repo' ) developerConnection 'scm:git:git@github.com:hibernate/hibernate-orm.git'
def dev = root.appendNode( 'developers' ).appendNode( 'developer' ); }
dev.appendNode( 'id', 'hibernate-team' ) licenses {
dev.appendNode( 'name', 'The Hibernate Development Team' ) license {
dev.appendNode( 'organization', 'Hibernate.org' ) name 'GNU Lesser General Public License'
dev.appendNode( 'organizationUrl', 'http://hibernate.org' ) url 'http://www.gnu.org/licenses/lgpl-2.1.html'
comments 'See discussion at http://hibernate.org/license for more details.'
distribution 'repo'
}
}
developers {
developer {
id 'hibernate-team'
name 'The Hibernate Development Team'
organization 'Hibernate.org'
organizationUrl 'http://hibernate.org'
}
}
}
// TEMPORARY : currently Gradle Publishing feature is exporting dependencies as 'runtime' scope,
// rather than 'compile'; fix that.
asNode().dependencies[0].dependency.each {
it.scope[0].value = 'compile'
}
} }
} }
} }

View File

@ -1,184 +0,0 @@
##Hibernate Matrix Testing
### Goal
The idea of matrix testing is to allow testing in a varied set of configurations. Specifically for Hibernate, this
correlates to running the same set of tests against against multiple databases. This goal is achieved through
2 Gradle plugins.
Note that the second plugin (org.hibernate.build.gradle.testing.matrix.MatrixTestingPlugin) applies the first
one (org.hibernate.build.gradle.testing.database.DatabaseProfilePlugin) automatically, so generally scripts would
not even reference it. The reason for the split is historical and these 2 may get merged later...
### org.hibernate.build.gradle.testing.database.DatabaseProfilePlugin
This plugin is responsible for determining which databases are available for testing in the given environment. It
does this by performing a directory search. Well actually it can perform up to 2 directory searches:
* The standard profile directory is named _databases_ at the base directory of the root project
* A custom profile directory, which can be named by setting a system property named _hibernate-matrix-databases_
These directories are searched recursively. We leverage this in Hibernate to allow the standard _databases_ directory
to hold local profiles too. That is achieved by a _.gitignore_ which says to ignore any directory named
_local_ under the directory _databases_. So one option to provide custom profiles is to drop them in there. That
has the benefit of not having to specify _hibernate-matrix-databases_
Within these directories, the plugin looks for sub-directories which either:
* contain a file named _matrix.gradle_. _matrix.gradle_ is a limited DSL Gradle file which currently understands
just a specialized org.gradle.api.artifacts.Configuration reference named _jdbcDependency_. All that is a fancy
way to say that _matrix.gradle_ allows you to specify some dependencies this database profile needs (JDBC drivers,
etc). Any dependency artifacts named here get resolved using whatever resolvers (Maven, etc) are associated with
the build. For example
jdbcDependency {
"mysql:mysql-connector-java:5.1.17"
}
* contain a directory named _jdbc_ which is assumed to hold jar file(s) needed for the profile.
Such directories become the basis of a database profile made available to the build. The name of the profile
(which becomes important when we discuss the next plugin) is taken from the directory name. Database profiles can
also contain a _resources_ directory.
An example layout using _matrix.gradle_ might be
├── mysql50
│ ├── jdbc
│ │ └── mysql-connector-java-5.1.9.jar
│ └── resources
│ └── hibernate.properties
Or
├── mysql50
│ ├── matrix.gradle
│ └── resources
│ └── hibernate.properties
Either would result in a database profile named _mysql50_
Profiles can be ignored using the *hibernate-matrix-ignore* setting which accepts either
* a comma-separated list of the database profile names to be skipped
* the magic value **all** which indicates to ignore all profiles
### org.hibernate.build.gradle.testing.matrix.MatrixTestingPlugin
The MatrixTestingPlugin essentially generates a bunch of Gradle tasks dynamically and adds them to your build. It does
this based on all the database profiles found. Running `gradle tasks --all` will list all tasks available to the build
including these generated ones.
For each database profile the plugin will generate a task named *matrix_{profile}* that executes the tests against
that particular database profile. It also generates a task named *matrix* that groups together all the
profile-specific tasks so that running `gradle matrix` will run all the profiles.
*see section below discussing SourceSet separation*
### Database Allocator (JBoss internally, VPN required)
For developers on the Red Hat VPN, one option is to use the databases in the JBoss QA lab for testing. Note that
this tends to result in **very** slow builds but the obvious trade off is not having to install and manage these
databases locally.
The JBoss QA team developed a servlet to allow management of "database allocations" including requesting an
allocation be set up. The MatrixTestingPlugin is able to play with that feature allowing you to ask the build
to allocate the database for you. This feature is disabled by default, to enable it, you need this system property
named _hibernate-matrix-dballcoation_ which accepts either
* a comma-separate list of profile names
* the magic value **all** which indicates to allocate for all **supported** databases (see
org.hibernate.build.qalab.DatabaseAllocator.SUPPORTED_DB_NAMES for details)
For example, if you want to run matrix test on PostgreSQL 8.4, knowing that the database name for that is
_postgresql84_, you can use this command:
gradle matrix_postgresql84 -Dhibernate-matrix-dballocation=postgresql84
which would
1. talk to the database allocator service and make a database instance available
2. use the information returned from the allocator service to properly set up the connection information
Hibernate would need to connect to that instance.
3. run the tests against the postgresql84 profile
For some databases we need adjust the connection url with some options after get it from the database allocator. In
these cases we can use the system property _hibernate-matrix-dballocation-url-postfix-${dbname}_. For example
`-Dhibernate-matrix-dballocation-url-postfix-sybase155="?SQLINITSTRING=set quoted_identifier on&amp;DYNAMIC_PREPARE=true"`
A useful parameter to the allocator service when allocating a database is the _requester_ which is basically just a
string meant to identify who is making the request. By default the Hibernate build uses _hibernate_. But you can
specify an alternate requester using the system property _hibernate-matrix-dballocation-requestee_
### Testing SourceSets
If you are not familiar with Gradle's notion of
[SourceSet](http://gradle.org/current/docs/javadoc/org/gradle/api/tasks/SourceSet.html), you should be :)
The Hibernate build defines 2 different testing related SourceSets in a number of modules (currently hibernate-core,
hibernate-entitymanager and hibernate-envers):
* _test_ - tests that **should not** be run against the profiles from the MatrixTestingPlugin
* _matrix_ - tests that **should** be run against the profiles from the MatrixTestingPlugin
Tests in _test_ include unit tests as well as a few functional tests which use a database but where the particular
database should not at all affect the outcome. Tests in _matrix_ are functional tests where the outcome of the tests
are highly dependent on the database being used (how pessimistic locks are acquired, etc).
As always, Wikipedia is a great source of information
* [Functional Testing](http://en.wikipedia.org/wiki/Functional_testing)
* [Unit Testing](http://en.wikipedia.org/wiki/Unit_testing)
hibernate-core directory layout (for discussion):
hibernate-core
├── hibernate-core.gradle
├── src
├── main
│ ├── antlr
│ ├── java
│ ├── javadoc
│ ├── resources
│ └── xjb
├── matrix
│ └── java
└── test
├── java
└── resources
The directories of interest include
* matrix/java
all functional tests go into this directory
* test/java
all unit tests go into this directory
* test/resources
all resources for **functional tests and unit tests**. Yes, resource files in this directory are shared for both, so you don't need to copy one file to both place, for example, log4j.properties.
To make _idea plugin_ (similar entries for _eclipse plugin_) works, we also have this defined in hibernate-core.gradle:
sourceSets {
matrix {
java {
srcDir 'src/matrix/java'
}
resources {
srcDir 'src/matrix/resources'
}
}
}
ideaModule {
sourceDirs += file( '$buildDir/generated-src/antlr/main' )
testSourceDirs += file( 'src/matrix/java')
testSourceDirs += file( 'src/matrix/resources')
}

View File

@ -1,126 +0,0 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2012, 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.build.gradle.testing.database;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import org.gradle.api.Project;
import org.gradle.api.artifacts.Configuration;
import org.gradle.api.logging.Logging;
import org.slf4j.Logger;
import org.hibernate.build.qalab.DatabaseAllocation;
import org.hibernate.build.qalab.DatabaseAllocator;
/**
* Basic support for {@link DatabaseProfile} implementations
*
* @author Steve Ebersole
* @author Strong Liu
*/
public abstract class AbstractDatabaseProfileImpl implements DatabaseProfile {
private static final Logger log = Logging.getLogger( AbstractDatabaseProfileImpl.class );
private final String name;
private final File profileDirectory;
private final Project project;
private final Map<String,String> hibernateProperties;
private final DatabaseAllocation databaseAllocation;
@SuppressWarnings( {"unchecked"})
protected AbstractDatabaseProfileImpl(File profileDirectory, Project project) {
this.profileDirectory = profileDirectory;
this.name = profileDirectory.getName();
this.project = project;
this.hibernateProperties = new HashMap<String, String>();
final File hibernatePropertiesFile = new File(
new File( profileDirectory, "resources" ),
"hibernate.properties"
);
if ( hibernatePropertiesFile.exists() ) {
Properties props = new Properties();
try {
FileInputStream stream = new FileInputStream( hibernatePropertiesFile );
try {
props.load( stream );
}
finally {
try {
stream.close();
}
catch (IOException ignore) {
}
}
}
catch (IOException e) {
log.warn( "Unable to read Hibernate properties for database profile [" + name + "]", e );
}
for ( String propName : props.stringPropertyNames() ) {
hibernateProperties.put( propName, props.getProperty( propName ) );
}
}
this.databaseAllocation = DatabaseAllocator.locate( project ).getAllocation( this );
}
@Override
public String getName() {
return name;
}
@Override
public File getDirectory() {
return profileDirectory;
}
@Override
public Map<String, String> getHibernateProperties() {
return hibernateProperties;
}
@Override
public DatabaseAllocation getDatabaseAllocation() {
return databaseAllocation;
}
protected Configuration prepareConfiguration(String name) {
Configuration configuration = getOrCreateConfiguration( name );
configuration.setDescription( "The JDBC dependency configuration for the [" + name + "] profile" );
return configuration;
}
protected Configuration getOrCreateConfiguration(String name) {
Configuration configuration = project.getConfigurations().findByName( name );
if ( configuration == null ) {
configuration = project.getConfigurations().add( name );
}
return configuration;
}
}

View File

@ -1,53 +0,0 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2012, 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.build.gradle.testing.database;
import java.util.HashSet;
import java.util.Set;
import org.gradle.BuildAdapter;
import org.gradle.BuildResult;
import org.hibernate.build.qalab.DatabaseAllocation;
/**
* A Gradle {@link org.gradle.BuildListener} used to release all databases allocated when the build is finished.
*
* @author Steve Ebersole
*/
public class DatabaseAllocationCleanUp extends BuildAdapter {
private Set<DatabaseAllocation> databaseAllocations = new HashSet<DatabaseAllocation>();
public void addDatabaseAllocation(DatabaseAllocation databaseAllocation) {
databaseAllocations.add( databaseAllocation );
}
@Override
public void buildFinished(BuildResult result) {
super.buildFinished( result );
for ( DatabaseAllocation databaseAllocation : databaseAllocations ) {
databaseAllocation.release();
}
}
}

View File

@ -1,169 +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.build.gradle.testing.database;
import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.gradle.api.Plugin;
import org.gradle.api.Project;
import org.gradle.api.logging.Logger;
import org.gradle.api.logging.Logging;
/**
* Plugin used to apply notion of database profiles, which are consumed by the matrix testing plugin.
*
* @author Steve Ebersole
* @author Strong Liu
*/
public class DatabaseProfilePlugin implements Plugin<Project> {
/**
* The directory containing standard database profiles.
*/
public static final String STANDARD_DATABASES_DIRECTORY = "databases";
/**
* Names a system setting key that can be set to point to a directory containing additional, custom
* database profiles.
*/
public static final String CUSTOM_DATABASES_DIRECTORY_KEY = "hibernate-matrix-databases";
public static final String HIBERNATE_MATRIX_IGNORE = "hibernate-matrix-ignore";
private static final String MATRIX_BUILD_FILE = "matrix.gradle";
private static final String JDBC_DIR = "jdbc";
private static final Logger log = Logging.getLogger( DatabaseProfilePlugin.class );
private Project project;
private List<DatabaseProfile> profiles;
public void apply(Project project) {
this.project = project;
final LinkedHashMap<String, DatabaseProfile> profileMap = new LinkedHashMap<String, DatabaseProfile>();
processStandardProfiles( profileMap );
processCustomProfiles( profileMap );
this.profiles = new ArrayList<DatabaseProfile>();
DatabaseAllocationCleanUp listener = new DatabaseAllocationCleanUp();
project.getGradle().addBuildListener( listener );
for ( DatabaseProfile profile : profileMap.values() ) {
this.profiles.add( profile );
listener.addDatabaseAllocation( profile.getDatabaseAllocation() );
}
}
private void processStandardProfiles(Map<String, DatabaseProfile> profileMap) {
final File standardDatabasesDirectory = project.file( STANDARD_DATABASES_DIRECTORY );
if ( standardDatabasesDirectory == null || ! standardDatabasesDirectory.exists() ) {
log.debug( "Standard databases directory [{}] did not exist", STANDARD_DATABASES_DIRECTORY );
return;
}
if ( ! standardDatabasesDirectory.isDirectory() ) {
log.warn( "Located standard databases directory [{}] was not a directory", STANDARD_DATABASES_DIRECTORY );
return;
}
processProfiles( standardDatabasesDirectory, profileMap );
}
private void processProfiles(File directory, Map<String, DatabaseProfile> profileMap) {
// the directory itself is a "database directory" if it contains either:
// 1) a file named 'matrix.gradle'
// 2) a directory named 'jdbc'
DatabaseProfile databaseProfile = null;
final File matrixDotGradleFile = new File( directory, MATRIX_BUILD_FILE );
if ( matrixDotGradleFile.exists() && matrixDotGradleFile.isFile() ) {
log.debug( "Found matrix.gradle file : " + matrixDotGradleFile );
databaseProfile = new MatrixDotGradleProfile( matrixDotGradleFile, project );
}
final File jdbcDirectory = new File( directory, JDBC_DIR );
if ( jdbcDirectory.exists() && jdbcDirectory.isDirectory() ) {
databaseProfile = new JdbcDirectoryProfile( jdbcDirectory, project );
}
if ( databaseProfile == null ) {
// we determined this directory is not a database directory, check its sub-directories
for ( File subDirectory : directory.listFiles() ) {
if ( subDirectory.isDirectory() ) {
processProfiles( subDirectory, profileMap );
}
}
return; // EARLY EXIT!!!
}
final String profileName = databaseProfile.getName();
if ( ignored().contains( profileName ) ) {
log.debug( "Skipping ignored database profile [{}]", profileName );
return;
}
DatabaseProfile previousEntry = profileMap.put( profileName, databaseProfile );
if ( previousEntry != null ) {
log.lifecycle(
"Found duplicate profile definitions [name={}], [{}] taking precedence over [{}]",
profileName,
databaseProfile.getDirectory().getAbsolutePath(),
previousEntry.getDirectory().getAbsolutePath()
);
}
}
private Set<String> ignored;
private Set<String> ignored() {
if ( ignored == null ) {
final String values = System.getProperty( HIBERNATE_MATRIX_IGNORE );
if ( values == null || values.length() == 0 ) {
ignored = Collections.emptySet();
}
else {
ignored = new HashSet<String>();
Collections.addAll( ignored, values.split( "," ) );
}
}
return ignored;
}
private void processCustomProfiles(Map<String, DatabaseProfile> profileMap) {
final String customDatabaseDirectoryPath = System.getProperty( CUSTOM_DATABASES_DIRECTORY_KEY );
if ( customDatabaseDirectoryPath != null && customDatabaseDirectoryPath.length() > 0 ) {
final File customDatabaseDirectory = new File( customDatabaseDirectoryPath );
if ( customDatabaseDirectory.exists() && customDatabaseDirectory.isDirectory() ) {
processProfiles( customDatabaseDirectory, profileMap );
}
}
}
public Iterable<DatabaseProfile> getDatabaseProfiles() {
return profiles;
}
}

View File

@ -1,39 +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.build.gradle.testing.database;
import org.hibernate.build.gradle.util.BuildException;
/**
* Indicates that we found multiple database profiles having the same name.
*
* @author Strong Liu
* @author Steve Ebersole
*/
public class DuplicateDatabaseProfileException extends BuildException {
public DuplicateDatabaseProfileException(String message) {
super( message );
}
}

View File

@ -1,48 +0,0 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2012, 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.build.gradle.testing.database;
import org.gradle.api.Project;
import org.gradle.api.artifacts.Configuration;
/**
* Database profile as defined by a directory named {@code jdbc} containing JDBC drivers.
*
* @author Steve Ebersole
* @author Strong Liu
*/
public class JdbcDirectoryProfile extends AbstractDatabaseProfileImpl {
private final Configuration jdbcDependencies;
public JdbcDirectoryProfile(File jdbcDirectory, Project project) {
super( jdbcDirectory.getParentFile(), project );
jdbcDependencies = prepareConfiguration( getName() );
project.dependencies.add(getName(), project.files(jdbcDirectory.listFiles()))
}
@Override
public Configuration getTestingRuntimeConfiguration() {
return jdbcDependencies;
}
}

View File

@ -1,82 +0,0 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2012, 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.build.gradle.testing.database;
import java.io.File;
import java.util.Collections;
import groovy.lang.Closure;
import org.gradle.api.Project;
import org.gradle.api.artifacts.Configuration;
/**
* Database profile as defined by a {@code matrix.gradle} file
*
* @author Steve Ebersole
* @author Strong Liu
*/
public class MatrixDotGradleProfile extends AbstractDatabaseProfileImpl {
private static final String MATRIX_NODE_CONVENTION_KEY = "matrixNode";
private final Configuration jdbcDependencies;
protected MatrixDotGradleProfile(File matrixDotGradleFile, Project project) {
super( matrixDotGradleFile.getParentFile(), project );
jdbcDependencies = prepareConfiguration( getName() );
final ConventionImpl convention = new ConventionImpl( jdbcDependencies, project );
project.getConvention().getPlugins().put( MATRIX_NODE_CONVENTION_KEY, convention );
try {
project.apply( Collections.singletonMap( "from", matrixDotGradleFile ) );
}
finally {
project.getConvention().getPlugins().remove( MATRIX_NODE_CONVENTION_KEY );
}
}
@Override
public Configuration getTestingRuntimeConfiguration() {
return jdbcDependencies;
}
private class ConventionImpl {
private final Configuration jdbcDependencies;
private final Project project;
private ConventionImpl(Configuration jdbcDependencies, Project project) {
this.jdbcDependencies = jdbcDependencies;
this.project = project;
}
@SuppressWarnings( {"UnusedDeclaration"})
public void jdbcDependency(Object dependencyNotation, Closure closure) {
project.getDependencies().add( jdbcDependencies.getName(), dependencyNotation, closure );
}
@SuppressWarnings( {"UnusedDeclaration"})
public void jdbcDependency(Object dependencyNotation) {
project.getDependencies().add( jdbcDependencies.getName(), dependencyNotation );
}
}
}

View File

@ -1,79 +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.build.gradle.testing.matrix;
import java.io.File;
import org.gradle.api.Project;
import org.hibernate.build.gradle.testing.database.DatabaseProfile;
import org.hibernate.build.gradle.util.Jdk;
import org.hibernate.build.qalab.*;
import org.hibernate.build.qalab.DatabaseAllocation;
/**
* A testing matrix node combines a database profile and a jdk (eventually) along with managing "db allocation"
* information.
*
* @author Steve Ebersole
* @author Strong Liu
*/
public class MatrixNode {
private final DatabaseProfile databaseProfile;
private final Jdk jdk;
private final File baseOutputDirectory;
private final DatabaseAllocation databaseAllocation;
@SuppressWarnings( {"ResultOfMethodCallIgnored"})
public MatrixNode(Project project, DatabaseProfile databaseProfile, Jdk jdk) {
this.databaseProfile = databaseProfile;
this.jdk = jdk;
baseOutputDirectory = new File( new File( project.getBuildDir(), "matrix" ), databaseProfile.getName() );
baseOutputDirectory.mkdirs();
this.databaseAllocation = DatabaseAllocator.locate( project ).getAllocation( databaseProfile );
}
public String getName() {
return databaseProfile.getName();
}
public DatabaseProfile getDatabaseProfile() {
return databaseProfile;
}
public Jdk getJdk() {
return jdk;
}
public File getBaseOutputDirectory() {
return baseOutputDirectory;
}
public DatabaseAllocation getDatabaseAllocation() {
return databaseAllocation;
}
}

View File

@ -1,159 +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.build.gradle.testing.matrix;
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.Task
import org.gradle.api.artifacts.Configuration
import org.gradle.api.logging.Logger
import org.gradle.api.logging.Logging
import org.gradle.api.plugins.JavaPluginConvention
import org.gradle.api.tasks.SourceSet
import org.gradle.api.tasks.testing.Test
import org.hibernate.build.gradle.testing.database.DatabaseProfile
import org.hibernate.build.gradle.testing.database.DatabaseProfilePlugin
import org.hibernate.build.gradle.util.Jdk
import static org.gradle.api.plugins.JavaPlugin.COMPILE_CONFIGURATION_NAME
import static org.gradle.api.plugins.JavaPlugin.RUNTIME_CONFIGURATION_NAME
import static org.gradle.api.plugins.JavaPlugin.TEST_COMPILE_CONFIGURATION_NAME
import static org.gradle.api.plugins.JavaPlugin.TEST_RUNTIME_CONFIGURATION_NAME
/**
* TODO : 1) add a base configuration of common attribute across all matrix node tasks (convention)
* TODO : 2) somehow allow applying just a single database to a project (non matrix testing).
*
* @author Steve Ebersole
* @author Strong Liu
*/
public class MatrixTestingPlugin implements Plugin<Project> {
private static final Logger log = Logging.getLogger(MatrixTestingPlugin.class);
public static final String MATRIX_COMPILE_CONFIG_NAME = "matrixCompile";
public static final String MATRIX_RUNTIME_CONFIG_NAME = "matrixRuntime";
public static final String MATRIX_TASK_NAME = "matrix";
private Project project;
private SourceSet testSourceSet;
private Configuration matrixCompileConfig;
private Configuration matrixRuntimeConfig;
private Task matrixTask;
// currently, only the build jdk is supported
private Jdk theJdk = new Jdk();
public void apply(Project project) {
this.project = project;
project.rootProject.plugins.apply( DatabaseProfilePlugin );
List<MatrixNode> matrixNodes = locateMatrixNodes();
if ( matrixNodes == null || matrixNodes.isEmpty() ) {
// no db profiles defined
return;
}
matrixCompileConfig = prepareCompileConfiguration();
matrixRuntimeConfig = prepareRuntimeConfiguration();
testSourceSet = project.convention.getPlugin( JavaPluginConvention ).sourceSets
.getByName( SourceSet.TEST_SOURCE_SET_NAME );
matrixTask = prepareGroupingTask();
for ( MatrixNode matrixNode: matrixNodes ) {
Task matrixNodeTask = prepareNodeTask( matrixNode );
matrixTask.dependsOn( matrixNodeTask );
}
}
private List<MatrixNode> locateMatrixNodes() {
List<MatrixNode> matrixNodes = new ArrayList<MatrixNode>();
Iterable<DatabaseProfile> profiles = project.rootProject.plugins[DatabaseProfilePlugin].databaseProfiles;
if ( profiles != null ) {
for ( DatabaseProfile profile : profiles ) {
matrixNodes.add( new MatrixNode( project, profile, theJdk ) );
}
}
return matrixNodes;
}
/**
* Prepare compile configuration for matrix source set.
*/
private Configuration prepareCompileConfiguration() {
return project.configurations.add( MATRIX_COMPILE_CONFIG_NAME )
.setDescription( "Dependencies used to compile the matrix tests" )
.extendsFrom( project.configurations.getByName( COMPILE_CONFIGURATION_NAME ) )
.extendsFrom( project.configurations.getByName( TEST_COMPILE_CONFIGURATION_NAME ) );
}
/**
* Prepare runtime configuration for matrix source set.
*/
private Configuration prepareRuntimeConfiguration() {
return project.configurations.add( MATRIX_RUNTIME_CONFIG_NAME )
.setDescription( "Dependencies (baseline) used to run the matrix tests" )
.extendsFrom( matrixCompileConfig )
.extendsFrom( project.configurations.getByName( RUNTIME_CONFIGURATION_NAME ) )
.extendsFrom( project.configurations.getByName( TEST_RUNTIME_CONFIGURATION_NAME ) );
}
private Task prepareGroupingTask() {
Task matrixTask = project.tasks.add( MATRIX_TASK_NAME );
matrixTask.group = "Verification"
matrixTask.description = "Runs the unit tests on Database Matrix"
return matrixTask;
}
private void generateNodeTasks(List<MatrixNode> matrixNodes) {
// For now we just hard code this to locate the databases processed by
// org.hibernate.build.gradle.testing.database.DatabaseProfilePlugin. But long term would be much better to
// abstract this idea via the MatrixNode/MatrixNodeProvider interfaces; this would allow the jvm variance
// needed for jdbc3/jdbc4 testing for example. Not to mention its much more generally applicable
//
// Also the notion that the plugin as a MatrixNodeProducer might not be appropriate. probably a split there
// is in order too (config producer and jvm producer and somehow they get wired into a matrix).
//
// but again this is just a start.
}
private Task prepareNodeTask(MatrixNode node) {
String taskName = MATRIX_TASK_NAME + '_' + node.name
log.debug( "Adding Matrix Testing task $taskName" );
final Test nodeTask = project.tasks.add( taskName, Test );
nodeTask.description = "Runs the matrix against ${node.name}"
nodeTask.classpath = node.databaseProfile.testingRuntimeConfiguration + testSourceSet.runtimeClasspath
nodeTask.testClassesDir = testSourceSet.output.classesDir
nodeTask.ignoreFailures = true
nodeTask.workingDir = node.baseOutputDirectory
nodeTask.testReportDir = new File(node.baseOutputDirectory, "reports")
nodeTask.testResultsDir = new File(node.baseOutputDirectory, "results")
nodeTask.dependsOn( project.tasks.getByName( testSourceSet.classesTaskName ) );
nodeTask.systemProperties = node.databaseAllocation.properties
nodeTask.systemProperties['hibernate.test.validatefailureexpected'] = true
nodeTask.jvmArgs = ['-Xms1024M', '-Xmx1024M']//, '-XX:MaxPermSize=512M', '-Xss4096k', '-Xverify:none', '-XX:+UseFastAccessorMethods', '-XX:+DisableExplicitGC']
nodeTask.maxHeapSize = "1024M"
return nodeTask;
}
}

View File

@ -1,39 +0,0 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2012, 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.build.qalab;
import java.util.Map;
/**
* Represents a database instances allocated in the JBoss/Red Hat Qe Lab via {@link DatabaseAllocator}
*
* @author mvecera
* @author Strong Liu
* @author Steve Ebersole
*/
public interface DatabaseAllocation {
public Map<String,String> getProperties();
public void release();
}

View File

@ -1,101 +0,0 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2012, 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.build.qalab
import org.gradle.api.Project
import org.gradle.api.logging.Logger
import org.gradle.api.logging.Logging
import org.hibernate.build.gradle.testing.database.DatabaseProfile
/**
* Helper for dealing with the "DB Allocator" service set up in the JBoss/Red Hat QE lab.
*
* Use the <code>hibernate-matrix-dballocation</code> setting to control db allocation. By default,
* no allocations are performed. <code>hibernate-matrix-dballocation</code> could be either:<ul>
* <li><b>all</b> - allocate all non-ignored databases</li>
* <li><b>profile1{,profile2,...}</b> - allocate only the named profiles, provided the name is also one of the supported names</li>
* </ul>
*
* @author mvecera
* @author Strong Liu
* @author Steve Ebersole
*/
class DatabaseAllocator {
private static final Logger log = Logging.getLogger( DatabaseAllocator.class );
public static final String ALLOCATION_ENABLED = "hibernate-matrix-dballocation";
public static final String REQUESTEE = "hibernate-matrix-dballocation-requestee";
public static final String DB_ALLOCATOR_KEY = "dbAllocator";
public static def SUPPORTED_DB_NAMES = [
"oracle9i", "oracle10g", "oracle11gR1", "oracle11gR2", "oracle11gR2RAC", "oracle11gR1RAC",
"postgresql82", "postgresql83", "postgresql84", "postgresql91", "postgresql92",
"postgresplus92",
"mysql50", "mysql51","mysql55",
"db2-91", "db2-97", "db2-10",
"mssql2005", "mssql2008R1", "mssql2008R2", "mssql2012",
"sybase155", "sybase157"
];
private Map<String,DatabaseAllocation> databaseAllocationMap = new HashMap<String, DatabaseAllocation>();
private final Project rootProject;
DatabaseAllocator(Project rootProject) {
this.rootProject = rootProject
}
public DatabaseAllocation getAllocation(DatabaseProfile profile) {
DatabaseAllocation databaseAllocation = databaseAllocationMap.get( profile.name );
if ( databaseAllocation == null ) {
databaseAllocation = createAllocation( profile );
databaseAllocationMap.put( profile.name, databaseAllocation );
}
return databaseAllocation;
}
private DatabaseAllocation createAllocation(DatabaseProfile profile) {
if ( isAllocationEnabled( profile.name ) ) {
log.lifecycle( "using Allocator to get database [${profile.name}] connection info" );
final File outputDirectory = new File( new File( rootProject.getBuildDir(), "matrix" ), profile.getName() )
return new EnabledDatabaseAllocation( rootProject.getAnt(), profile, outputDirectory );
}
return new DisabledDatabaseAllocation( profile );
}
private boolean isAllocationEnabled(String name) {
if ( !SUPPORTED_DB_NAMES.contains(name) ) {
return false
};
String value = System.properties[ALLOCATION_ENABLED]
return value != null && (value.contains(name) || value.equals("all"));
}
public static DatabaseAllocator locate(Project project) {
if ( ! project.rootProject.hasProperty( DB_ALLOCATOR_KEY ) ) {
project.rootProject.ext.setProperty( DB_ALLOCATOR_KEY, new DatabaseAllocator( project.rootProject ) );
}
return (DatabaseAllocator) project.rootProject.properties[ DB_ALLOCATOR_KEY ];
}
}

View File

@ -1,47 +0,0 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2012, 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.build.qalab
import org.hibernate.build.gradle.testing.database.DatabaseProfile
/**
* @author Steve Ebersole
*/
class DisabledDatabaseAllocation implements DatabaseAllocation {
private final DatabaseProfile databaseProfile;
DisabledDatabaseAllocation(DatabaseProfile databaseProfile) {
this.databaseProfile = databaseProfile;
}
@Override
Map<String, String> getProperties() {
return databaseProfile.hibernateProperties;
}
@Override
void release() {
// nothing to do
}
}

View File

@ -1,150 +0,0 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2012, 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.build.qalab
import org.gradle.api.Project
import org.hibernate.build.gradle.testing.database.DatabaseProfile
import org.hibernate.build.gradle.util.BuildException
import org.gradle.api.logging.Logging
import org.gradle.api.logging.Logger
/**
* @author Steve Ebersole
*/
class EnabledDatabaseAllocation implements DatabaseAllocation {
private static final Logger log = Logging.getLogger( DatabaseAllocator.class );
private static final String DB_ALLOCATOR_URL = "http://dballocator.mw.lab.eng.bos.redhat.com:8080/Allocator/AllocatorServlet";
private static final String ALLOCATOR_OUTPUT_FILE_NAME = "allocated-db.properties";
private static final String DB_ALLOCATION_URL_POSTFIX = "hibernate-matrix-dballocation-url-postfix";
private static final String DRIVER_PROP = "hibernate.connection.driver_class";
private static final String URL_PROP = "hibernate.connection.url";
private static final String USERNAME_PROP = "hibernate.connection.username";
private static final String PASSWORD_PROP = "hibernate.connection.password";
private static final int RETRIES = 30
private static final int EXPIRY = 300;
private final DatabaseProfile databaseProfile
private final AntBuilder ant;
private final File allocatorOutputFile;
private final String requester;
private final String uuid;
private final File tmpFile;
private final Map<String,String> properties;
EnabledDatabaseAllocation(AntBuilder ant, DatabaseProfile databaseProfile, File outputDirectory) {
this.ant = ant;
this.databaseProfile = databaseProfile;
outputDirectory.mkdirs()
this.allocatorOutputFile = new File( outputDirectory, ALLOCATOR_OUTPUT_FILE_NAME );
this.tmpFile = new File( outputDirectory, "tmpfile" );
if ( System.properties.containsKey("hibernate-matrix-dballocation-requestee") ) {
requester = System.properties["hibernate-matrix-dballocation-requestee"]
}
else {
requester = "hibernate"
}
if ( allocatorOutputFile.exists() ) {
allocatorOutputFile.delete()
}
int attempts = 0;
while ( !(allocatorOutputFile.exists() && allocatorOutputFile.length() > 0) ) {
if ( attempts >= RETRIES ) {
throw new BuildException( 'Database unavailable' );
}
if ( attempts > 0 ) {
log.lifecycle( "Trouble accessing Allocator servlet; waiting before trying again" );
Thread.sleep( 60000 );
}
def allocatorUrl = DB_ALLOCATOR_URL +
"?operation=alloc&label=${databaseProfile.name}&requestee=${requester}&expiry=${EXPIRY}"
ant.get(
src: allocatorUrl,
dest: allocatorOutputFile.absolutePath,
ignoreerrors: 'true'
);
attempts++
}
def allocatorProps = new Properties();
allocatorProps.load( new FileInputStream( allocatorOutputFile ) );
this.uuid = allocatorProps['uuid']
log.lifecycle( "Finished allocating for DB instance [${databaseProfile.name}], uuid is [${uuid}]" );
properties = new HashMap<String, String>();
properties.putAll( databaseProfile.hibernateProperties );
properties[DRIVER_PROP] = allocatorProps["db.jdbc_class"]
properties[URL_PROP] = allocatorProps["db.jdbc_url"] + getURLPostfix(databaseProfile.name)
properties[USERNAME_PROP] = allocatorProps["db.username"]
properties[PASSWORD_PROP] = allocatorProps["db.password"]
properties["uuid"] = allocatorProps["uuid"];
clean();
}
private String getURLPostfix(String dbName) {
for ( String key: System.properties.keySet() ) {
if ( key.startsWith(DB_ALLOCATION_URL_POSTFIX) ) {
String db = key.substring(DB_ALLOCATION_URL_POSTFIX.length() + 1, key.length())
if ( db.equalsIgnoreCase(dbName) ) {
String postfix = System.properties[key];
log.debug("found URL postfix[%s] for DB[%s]", postfix, db );
return postfix;
}
}
}
return ""
}
void clean() {
log.lifecycle( "Cleaning DB [${databaseProfile.name}]..." );
final String allocatorUrl = DB_ALLOCATOR_URL + "?operation=erase&uuid=${uuid}";
ant.get( src: allocatorUrl, dest: tmpFile.absolutePath );
}
@Override
Map<String, String> getProperties() {
return properties;
}
@Override
void release() {
log.lifecycle( "De-allocating DB [${databaseProfile.name}]..." );
final String allocatorUrl = DB_ALLOCATOR_URL + "?operation=dealloc&uuid=${uuid}";
ant.get( src: allocatorUrl, dest: tmpFile.absolutePath );
}
}

View File

@ -1,3 +0,0 @@
#Ignore any sub directory named 'local'. these are used to define custom database profiles local
# to the developer's machine
/local

View File

@ -1,25 +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
*/
jdbcDependency "org.apache.derby:derby:10.8.2.2"

View File

@ -1,40 +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
#
hibernate.dialect org.hibernate.dialect.DerbyTenSevenDialect
hibernate.connection.driver_class org.apache.derby.jdbc.EmbeddedDriver
hibernate.connection.url jdbc:derby:testdb;create=true
hibernate.connection.username sa
hibernate.connection.pool_size 5
hibernate.show_sql true
hibernate.format_sql true
hibernate.max_fetch_depth 5
hibernate.cache.region_prefix hibernate.test
hibernate.cache.region.factory_class org.hibernate.testing.cache.CachingRegionFactory

View File

@ -1,25 +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
*/
jdbcDependency "mysql:mysql-connector-java:5.1.17"

View File

@ -1,42 +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
#
hibernate.dialect org.hibernate.dialect.MySQL5InnoDBDialect
hibernate.connection.driver_class com.mysql.jdbc.Driver
hibernate.connection.url jdbc:mysql://vmg08.mw.lab.eng.bos.redhat.com:3306/dballo01
hibernate.connection.username dballo01
hibernate.connection.password dballo01
hibernate.connection.pool_size 5
hibernate.show_sql true
hibernate.format_sql true
hibernate.max_fetch_depth 5
hibernate.cache.region_prefix hibernate.test
hibernate.cache.region.factory_class org.hibernate.testing.cache.CachingRegionFactory

View File

@ -1,25 +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
*/
jdbcDependency "mysql:mysql-connector-java:5.1.17"

View File

@ -1,46 +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
#
hibernate.dialect org.hibernate.dialect.MySQL5InnoDBDialect
hibernate.connection.driver_class com.mysql.jdbc.Driver
#hibernate.connection.url jdbc:mysql://vmg02.mw.lab.eng.bos.redhat.com:3306/dballo01
#hibernate.connection.username dballo01
#hibernate.connection.password dballo01
hibernate.connection.url jdbc:mysql://127.0.0.1:3306/hibernate
hibernate.connection.username hibernate
hibernate.connection.password hibernate
hibernate.connection.pool_size 5
hibernate.show_sql true
hibernate.format_sql true
hibernate.max_fetch_depth 5
hibernate.cache.region_prefix hibernate.test
hibernate.cache.region.factory_class org.hibernate.testing.cache.CachingRegionFactory

View File

@ -1,24 +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
*/
jdbcDependency "postgresql:postgresql:8.4-701.jdbc4"

View File

@ -1,42 +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
#
hibernate.dialect org.hibernate.dialect.PostgreSQLDialect
hibernate.connection.driver_class org.postgresql.Driver
hibernate.connection.url jdbc:postgresql://postgresql01.mw.lab.eng.bos.redhat.com:5432/dballo03
hibernate.connection.username dballo03
hibernate.connection.password dballo03
hibernate.connection.pool_size 5
hibernate.show_sql true
hibernate.format_sql true
hibernate.max_fetch_depth 5
hibernate.cache.region_prefix hibernate.test
hibernate.cache.region.factory_class org.hibernate.testing.cache.CachingRegionFactory

View File

@ -1,24 +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
*/
jdbcDependency "postgresql:postgresql:8.4-701.jdbc4"

View File

@ -1,43 +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
#
hibernate.dialect org.hibernate.dialect.PostgreSQLDialect
hibernate.connection.driver_class org.postgresql.Driver
hibernate.connection.url jdbc:postgresql://postgresql03.mw.lab.eng.bos.redhat.com:5432/dballo03
hibernate.connection.username dballo03
hibernate.connection.password dballo03
hibernate.connection.pool_size 5
hibernate.show_sql true
hibernate.format_sql true
hibernate.max_fetch_depth 5
hibernate.cache.region_prefix hibernate.test
hibernate.cache.region.factory_class org.hibernate.testing.cache.CachingRegionFactory

View File

@ -1,24 +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
*/
jdbcDependency "postgresql:postgresql:9.1-901.jdbc4"

View File

@ -1,42 +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
#
hibernate.dialect org.hibernate.dialect.PostgreSQL82Dialect
hibernate.connection.driver_class org.postgresql.Driver
hibernate.connection.url jdbc:postgresql://127.0.0.1/hibernate
hibernate.connection.username hibernate
hibernate.connection.password hibernate
hibernate.connection.pool_size 5
hibernate.show_sql true
hibernate.format_sql true
hibernate.max_fetch_depth 5
hibernate.cache.region_prefix hibernate.test
hibernate.cache.region.factory_class org.hibernate.testing.cache.CachingRegionFactory

Binary file not shown.

View File

@ -1,6 +1,6 @@
#Thu Apr 04 13:01:06 CDT 2013 #Thu May 09 20:32:29 CDT 2013
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists
distributionUrl=http\://services.gradle.org/distributions/gradle-1.5-bin.zip distributionUrl=http\://services.gradle.org/distributions/gradle-1.6-bin.zip

View File

@ -168,7 +168,7 @@ public class C3P0ConnectionProvider
} }
final String key = (String) o; final String key = (String) o;
if ( key.startsWith( "hibernate.c3p0." ) ) { if ( key.startsWith( "hibernate.c3p0." ) ) {
String newKey = key.substring( 15 ); final String newKey = key.substring( 15 );
if ( props.containsKey( newKey ) ) { if ( props.containsKey( newKey ) ) {
warnPropertyConflict( key, newKey ); warnPropertyConflict( key, newKey );
} }
@ -267,6 +267,7 @@ public class C3P0ConnectionProvider
* *
* @deprecated Use {@link #stop} instead * @deprecated Use {@link #stop} instead
*/ */
@SuppressWarnings("UnusedDeclaration")
@Deprecated @Deprecated
public void close() { public void close() {
stop(); stop();

View File

@ -1,6 +1,8 @@
apply plugin: 'antlr' apply plugin: 'antlr'
apply plugin: 'hibernate-matrix-testing'
apply plugin: org.hibernate.build.gradle.inject.InjectionPlugin apply plugin: org.hibernate.build.gradle.inject.InjectionPlugin
apply plugin: org.hibernate.build.gradle.testing.matrix.MatrixTestingPlugin
dependencies { dependencies {
compile( libraries.jta ) compile( libraries.jta )
@ -30,7 +32,7 @@ dependencies {
testRuntime( 'jaxen:jaxen:1.1' ) testRuntime( 'jaxen:jaxen:1.1' )
testRuntime( libraries.javassist ) testRuntime( libraries.javassist )
testRuntime( libraries.unified_el )
} }
def pomName() { def pomName() {

View File

@ -26,6 +26,7 @@ package org.hibernate;
import java.io.Serializable; import java.io.Serializable;
import org.hibernate.procedure.ProcedureCall; import org.hibernate.procedure.ProcedureCall;
import org.hibernate.procedure.ProcedureCallMemento;
/** /**
* Contract methods shared between {@link Session} and {@link StatelessSession}. * Contract methods shared between {@link Session} and {@link StatelessSession}.
@ -86,6 +87,17 @@ public interface SharedSessionContract extends Serializable {
*/ */
public SQLQuery createSQLQuery(String queryString); public SQLQuery createSQLQuery(String queryString);
/**
* Gets a ProcedureCall based on a named template
*
* @param name The name given to the template
*
* @return The ProcedureCall
*
* @see javax.persistence.NamedStoredProcedureQuery
*/
public ProcedureCall getNamedProcedureCall(String name);
/** /**
* Creates a call to a stored procedure. * Creates a call to a stored procedure.
* *
@ -154,5 +166,4 @@ public interface SharedSessionContract extends Serializable {
* @return The criteria instance for manipulation and execution * @return The criteria instance for manipulation and execution
*/ */
public Criteria createCriteria(String entityName, String alias); public Criteria createCriteria(String entityName, String alias);
} }

View File

@ -35,6 +35,7 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Properties; import java.util.Properties;
import java.util.Set; import java.util.Set;
import javax.persistence.Basic; import javax.persistence.Basic;
import javax.persistence.Cacheable; import javax.persistence.Cacheable;
import javax.persistence.CollectionTable; import javax.persistence.CollectionTable;
@ -67,6 +68,8 @@ import javax.persistence.NamedNativeQueries;
import javax.persistence.NamedNativeQuery; import javax.persistence.NamedNativeQuery;
import javax.persistence.NamedQueries; import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery; import javax.persistence.NamedQuery;
import javax.persistence.NamedStoredProcedureQueries;
import javax.persistence.NamedStoredProcedureQuery;
import javax.persistence.OneToMany; import javax.persistence.OneToMany;
import javax.persistence.OneToOne; import javax.persistence.OneToOne;
import javax.persistence.OrderColumn; import javax.persistence.OrderColumn;
@ -81,8 +84,6 @@ import javax.persistence.TableGenerator;
import javax.persistence.UniqueConstraint; import javax.persistence.UniqueConstraint;
import javax.persistence.Version; import javax.persistence.Version;
import org.jboss.logging.Logger;
import org.hibernate.AnnotationException; import org.hibernate.AnnotationException;
import org.hibernate.AssertionFailure; import org.hibernate.AssertionFailure;
import org.hibernate.EntityMode; import org.hibernate.EntityMode;
@ -151,7 +152,6 @@ import org.hibernate.cfg.annotations.QueryBinder;
import org.hibernate.cfg.annotations.SimpleValueBinder; import org.hibernate.cfg.annotations.SimpleValueBinder;
import org.hibernate.cfg.annotations.TableBinder; import org.hibernate.cfg.annotations.TableBinder;
import org.hibernate.engine.OptimisticLockStyle; import org.hibernate.engine.OptimisticLockStyle;
import org.hibernate.engine.internal.Versioning;
import org.hibernate.engine.spi.FilterDefinition; import org.hibernate.engine.spi.FilterDefinition;
import org.hibernate.id.MultipleHiLoPerTableGenerator; import org.hibernate.id.MultipleHiLoPerTableGenerator;
import org.hibernate.id.PersistentIdentifierGenerator; import org.hibernate.id.PersistentIdentifierGenerator;
@ -159,9 +159,9 @@ import org.hibernate.id.SequenceHiLoGenerator;
import org.hibernate.id.TableHiLoGenerator; import org.hibernate.id.TableHiLoGenerator;
import org.hibernate.id.enhanced.SequenceStyleGenerator; import org.hibernate.id.enhanced.SequenceStyleGenerator;
import org.hibernate.internal.CoreMessageLogger; import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.mapping.Any; import org.hibernate.mapping.Any;
import org.hibernate.mapping.Component; import org.hibernate.mapping.Component;
import org.hibernate.mapping.Constraint;
import org.hibernate.mapping.DependantValue; import org.hibernate.mapping.DependantValue;
import org.hibernate.mapping.IdGenerator; import org.hibernate.mapping.IdGenerator;
import org.hibernate.mapping.Join; import org.hibernate.mapping.Join;
@ -175,6 +175,7 @@ import org.hibernate.mapping.SingleTableSubclass;
import org.hibernate.mapping.Subclass; import org.hibernate.mapping.Subclass;
import org.hibernate.mapping.ToOne; import org.hibernate.mapping.ToOne;
import org.hibernate.mapping.UnionSubclass; import org.hibernate.mapping.UnionSubclass;
import org.jboss.logging.Logger;
/** /**
* JSR 175 annotation binder which reads the annotations from classes, applies the * JSR 175 annotation binder which reads the annotations from classes, applies the
@ -254,6 +255,28 @@ public final class AnnotationBinder {
} }
} }
} }
{
final List<NamedStoredProcedureQuery> annotations =
(List<NamedStoredProcedureQuery>) defaults.get( NamedStoredProcedureQuery.class );
if ( annotations != null ) {
for ( NamedStoredProcedureQuery annotation : annotations ) {
QueryBinder.bindNamedStoredProcedureQuery( annotation, mappings );
}
}
}
{
final List<NamedStoredProcedureQueries> annotations =
(List<NamedStoredProcedureQueries>) defaults.get( NamedStoredProcedureQueries.class );
if ( annotations != null ) {
for ( NamedStoredProcedureQueries annotation : annotations ) {
for ( NamedStoredProcedureQuery queryAnnotation : annotation.value() ) {
QueryBinder.bindNamedStoredProcedureQuery( queryAnnotation, mappings );
}
}
}
}
} }
public static void bindPackage(String packageName, Mappings mappings) { public static void bindPackage(String packageName, Mappings mappings) {
@ -359,6 +382,24 @@ public final class AnnotationBinder {
); );
QueryBinder.bindNativeQueries( ann, mappings ); QueryBinder.bindNativeQueries( ann, mappings );
} }
// NamedStoredProcedureQuery handling ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
{
final NamedStoredProcedureQuery annotation = annotatedElement.getAnnotation( NamedStoredProcedureQuery.class );
if ( annotation != null ) {
QueryBinder.bindNamedStoredProcedureQuery( annotation, mappings );
}
}
// NamedStoredProcedureQueries handling ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
{
final NamedStoredProcedureQueries annotation = annotatedElement.getAnnotation( NamedStoredProcedureQueries.class );
if ( annotation != null ) {
for ( NamedStoredProcedureQuery queryAnnotation : annotation.value() ) {
QueryBinder.bindNamedStoredProcedureQuery( queryAnnotation, mappings );
}
}
}
} }
private static IdGenerator buildIdGenerator(java.lang.annotation.Annotation ann, Mappings mappings) { private static IdGenerator buildIdGenerator(java.lang.annotation.Annotation ann, Mappings mappings) {
@ -2097,16 +2138,22 @@ public final class AnnotationBinder {
} }
} }
// Natural ID columns must reside in one single UniqueKey within the Table.
// For now, simply ensure consistent naming.
// TODO: AFAIK, there really isn't a reason for these UKs to be created
// on the secondPass. This whole area should go away...
NaturalId naturalIdAnn = property.getAnnotation( NaturalId.class ); NaturalId naturalIdAnn = property.getAnnotation( NaturalId.class );
if ( naturalIdAnn != null ) { if ( naturalIdAnn != null ) {
if ( joinColumns != null ) { if ( joinColumns != null ) {
for ( Ejb3Column column : joinColumns ) { for ( Ejb3Column column : joinColumns ) {
column.addUniqueKey( column.getTable().getNaturalIdUniqueKeyName(), inSecondPass ); String keyName = "UK_" + Constraint.hashedName( column.getTable().getName() + "_NaturalID" );
column.addUniqueKey( keyName, inSecondPass );
} }
} }
else { else {
for ( Ejb3Column column : columns ) { for ( Ejb3Column column : columns ) {
column.addUniqueKey( column.getTable().getNaturalIdUniqueKeyName(), inSecondPass ); String keyName = "UK_" + Constraint.hashedName( column.getTable().getName() + "_NaturalID" );
column.addUniqueKey( keyName, inSecondPass );
} }
} }
} }

View File

@ -84,6 +84,7 @@ import org.hibernate.annotations.common.reflection.java.JavaReflectionManager;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder; import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService; import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
import org.hibernate.boot.registry.internal.StandardServiceRegistryImpl; import org.hibernate.boot.registry.internal.StandardServiceRegistryImpl;
import org.hibernate.cfg.annotations.NamedProcedureCallDefinition;
import org.hibernate.cfg.annotations.reflection.JPAMetadataProvider; import org.hibernate.cfg.annotations.reflection.JPAMetadataProvider;
import org.hibernate.context.spi.CurrentTenantIdentifierResolver; import org.hibernate.context.spi.CurrentTenantIdentifierResolver;
import org.hibernate.dialect.Dialect; import org.hibernate.dialect.Dialect;
@ -122,6 +123,7 @@ import org.hibernate.jaxb.spi.SourceType;
import org.hibernate.mapping.AuxiliaryDatabaseObject; import org.hibernate.mapping.AuxiliaryDatabaseObject;
import org.hibernate.mapping.Collection; import org.hibernate.mapping.Collection;
import org.hibernate.mapping.Column; import org.hibernate.mapping.Column;
import org.hibernate.mapping.Constraint;
import org.hibernate.mapping.DenormalizedTable; import org.hibernate.mapping.DenormalizedTable;
import org.hibernate.mapping.FetchProfile; import org.hibernate.mapping.FetchProfile;
import org.hibernate.mapping.ForeignKey; import org.hibernate.mapping.ForeignKey;
@ -213,6 +215,7 @@ public class Configuration implements Serializable {
protected Map<String, NamedQueryDefinition> namedQueries; protected Map<String, NamedQueryDefinition> namedQueries;
protected Map<String, NamedSQLQueryDefinition> namedSqlQueries; protected Map<String, NamedSQLQueryDefinition> namedSqlQueries;
protected Map<String, NamedProcedureCallDefinition> namedProcedureCallMap;
protected Map<String, ResultSetMappingDefinition> sqlResultSetMappings; protected Map<String, ResultSetMappingDefinition> sqlResultSetMappings;
protected Map<String, TypeDef> typeDefs; protected Map<String, TypeDef> typeDefs;
@ -1398,22 +1401,14 @@ public class Configuration implements Serializable {
final Table table = tableListEntry.getKey(); final Table table = tableListEntry.getKey();
final List<UniqueConstraintHolder> uniqueConstraints = tableListEntry.getValue(); final List<UniqueConstraintHolder> uniqueConstraints = tableListEntry.getValue();
for ( UniqueConstraintHolder holder : uniqueConstraints ) { for ( UniqueConstraintHolder holder : uniqueConstraints ) {
final String keyName = StringHelper.isEmpty( holder.getName() ) buildUniqueKeyFromColumnNames( table, holder.getName(), holder.getColumns() );
? StringHelper.randomFixedLengthHex("UK_")
: holder.getName();
buildUniqueKeyFromColumnNames( table, keyName, holder.getColumns() );
} }
} }
for(Table table : jpaIndexHoldersByTable.keySet()){ for(Table table : jpaIndexHoldersByTable.keySet()){
final List<JPAIndexHolder> jpaIndexHolders = jpaIndexHoldersByTable.get( table ); final List<JPAIndexHolder> jpaIndexHolders = jpaIndexHoldersByTable.get( table );
int uniqueIndexPerTable = 0;
for ( JPAIndexHolder holder : jpaIndexHolders ) { for ( JPAIndexHolder holder : jpaIndexHolders ) {
uniqueIndexPerTable++; buildUniqueKeyFromColumnNames( table, holder.getName(), holder.getColumns(), holder.getOrdering(), holder.isUnique() );
final String keyName = StringHelper.isEmpty( holder.getName() )
? "idx_"+table.getName()+"_" + uniqueIndexPerTable
: holder.getName();
buildUniqueKeyFromColumnNames( table, keyName, holder.getColumns(), holder.getOrdering(), holder.isUnique() );
} }
} }
@ -1576,8 +1571,6 @@ public class Configuration implements Serializable {
} }
private void buildUniqueKeyFromColumnNames(Table table, String keyName, String[] columnNames, String[] orderings, boolean unique) { private void buildUniqueKeyFromColumnNames(Table table, String keyName, String[] columnNames, String[] orderings, boolean unique) {
keyName = normalizer.normalizeIdentifierQuoting( keyName );
int size = columnNames.length; int size = columnNames.length;
Column[] columns = new Column[size]; Column[] columns = new Column[size];
Set<Column> unbound = new HashSet<Column>(); Set<Column> unbound = new HashSet<Column>();
@ -1594,6 +1587,12 @@ public class Configuration implements Serializable {
unboundNoLogical.add( new Column( column ) ); unboundNoLogical.add( new Column( column ) );
} }
} }
if ( StringHelper.isEmpty( keyName ) ) {
keyName = Constraint.generateName( "UK_", table, columns );
}
keyName = normalizer.normalizeIdentifierQuoting( keyName );
if ( unique ) { if ( unique ) {
UniqueKey uk = table.getOrCreateUniqueKey( keyName ); UniqueKey uk = table.getOrCreateUniqueKey( keyName );
for ( int i = 0; i < columns.length; i++ ) { for ( int i = 0; i < columns.length; i++ ) {
@ -1775,6 +1774,10 @@ public class Configuration implements Serializable {
return namedQueries; return namedQueries;
} }
public Map<String, NamedProcedureCallDefinition> getNamedProcedureCallMap() {
return namedProcedureCallMap;
}
/** /**
* Create a {@link SessionFactory} using the properties and mappings in this configuration. The * Create a {@link SessionFactory} using the properties and mappings in this configuration. The
* {@link SessionFactory} will be immutable, so changes made to {@code this} {@link Configuration} after * {@link SessionFactory} will be immutable, so changes made to {@code this} {@link Configuration} after
@ -2873,6 +2876,16 @@ public class Configuration implements Serializable {
namedSqlQueries.put( name.intern(), query ); namedSqlQueries.put( name.intern(), query );
} }
@Override
public void addNamedProcedureCallDefinition(NamedProcedureCallDefinition definition)
throws DuplicateMappingException {
final String name = definition.getRegisteredName();
final NamedProcedureCallDefinition previous = namedProcedureCallMap.put( name, definition );
if ( previous != null ) {
throw new DuplicateMappingException( "named stored procedure query", name );
}
}
public void addDefaultSQLQuery(String name, NamedSQLQueryDefinition query) { public void addDefaultSQLQuery(String name, NamedSQLQueryDefinition query) {
applySQLQuery( name, query ); applySQLQuery( name, query );
defaultNamedNativeQueryNames.add( name ); defaultNamedNativeQueryNames.add( name );

View File

@ -59,6 +59,7 @@ import org.hibernate.mapping.Bag;
import org.hibernate.mapping.Collection; import org.hibernate.mapping.Collection;
import org.hibernate.mapping.Column; import org.hibernate.mapping.Column;
import org.hibernate.mapping.Component; import org.hibernate.mapping.Component;
import org.hibernate.mapping.Constraint;
import org.hibernate.mapping.DependantValue; import org.hibernate.mapping.DependantValue;
import org.hibernate.mapping.FetchProfile; import org.hibernate.mapping.FetchProfile;
import org.hibernate.mapping.Fetchable; import org.hibernate.mapping.Fetchable;
@ -2211,7 +2212,6 @@ public final class HbmBinder {
} }
else if ( "natural-id".equals( name ) ) { else if ( "natural-id".equals( name ) ) {
UniqueKey uk = new UniqueKey(); UniqueKey uk = new UniqueKey();
uk.setName(StringHelper.randomFixedLengthHex("UK_"));
uk.setTable(table); uk.setTable(table);
//by default, natural-ids are "immutable" (constant) //by default, natural-ids are "immutable" (constant)
boolean mutableId = "true".equals( subnode.attributeValue("mutable") ); boolean mutableId = "true".equals( subnode.attributeValue("mutable") );
@ -2225,6 +2225,8 @@ public final class HbmBinder {
false, false,
true true
); );
uk.setName( Constraint.generateName( uk.generatedConstraintNamePrefix(),
table, uk.getColumns() ) );
table.addUniqueKey(uk); table.addUniqueKey(uk);
} }
else if ( "query".equals(name) ) { else if ( "query".equals(name) ) {

View File

@ -36,6 +36,7 @@ import org.hibernate.MappingException;
import org.hibernate.annotations.AnyMetaDef; import org.hibernate.annotations.AnyMetaDef;
import org.hibernate.annotations.common.reflection.ReflectionManager; import org.hibernate.annotations.common.reflection.ReflectionManager;
import org.hibernate.annotations.common.reflection.XClass; import org.hibernate.annotations.common.reflection.XClass;
import org.hibernate.cfg.annotations.NamedProcedureCallDefinition;
import org.hibernate.engine.ResultSetMappingDefinition; import org.hibernate.engine.ResultSetMappingDefinition;
import org.hibernate.engine.spi.FilterDefinition; import org.hibernate.engine.spi.FilterDefinition;
import org.hibernate.engine.spi.NamedQueryDefinition; import org.hibernate.engine.spi.NamedQueryDefinition;
@ -337,6 +338,15 @@ public interface Mappings {
*/ */
public void addSQLQuery(String name, NamedSQLQueryDefinition query) throws DuplicateMappingException; public void addSQLQuery(String name, NamedSQLQueryDefinition query) throws DuplicateMappingException;
/**
* Adds metadata for a named stored procedure call to this repository.
*
* @param definition The procedure call information
*
* @throws DuplicateMappingException If a query already exists with that name.
*/
public void addNamedProcedureCallDefinition(NamedProcedureCallDefinition definition) throws DuplicateMappingException;
/** /**
* Get the metadata for a named SQL result set mapping. * Get the metadata for a named SQL result set mapping.
* *

View File

@ -32,6 +32,7 @@ import org.hibernate.annotations.common.reflection.XClass;
import org.hibernate.cfg.annotations.PropertyBinder; import org.hibernate.cfg.annotations.PropertyBinder;
import org.hibernate.internal.util.StringHelper; import org.hibernate.internal.util.StringHelper;
import org.hibernate.mapping.Column; import org.hibernate.mapping.Column;
import org.hibernate.mapping.Component;
import org.hibernate.mapping.DependantValue; import org.hibernate.mapping.DependantValue;
import org.hibernate.mapping.Join; import org.hibernate.mapping.Join;
import org.hibernate.mapping.ManyToOne; import org.hibernate.mapping.ManyToOne;
@ -211,7 +212,23 @@ public class OneToOneSecondPass implements SecondPass {
propertyHolder.addProperty( prop, inferredData.getDeclaringClass() ); propertyHolder.addProperty( prop, inferredData.getDeclaringClass() );
} }
value.setReferencedPropertyName( mappedBy ); // HHH-6813
// If otherSide's id is derived, do not set EntityType#uniqueKeyPropertyName.
// EntityType#isReferenceToPrimaryKey() assumes that, if it's set,
// a PK is not referenced. Example:
//
// Foo: @Id long id, @OneToOne(mappedBy="foo") Bar bar
// Bar: @Id @OneToOne Foo foo
boolean referencesDerivedId = false;
try {
referencesDerivedId = otherSide.getIdentifier() instanceof Component
&& ( (Component) otherSide.getIdentifier() ).getProperty( mappedBy ) != null;
}
catch ( MappingException e ) {
// ignore
}
String referencedPropertyName = referencesDerivedId ? null : mappedBy;
value.setReferencedPropertyName( referencedPropertyName );
String propertyRef = value.getReferencedPropertyName(); String propertyRef = value.getReferencedPropertyName();
if ( propertyRef != null ) { if ( propertyRef != null ) {

View File

@ -1416,12 +1416,9 @@ public abstract class CollectionBinder {
private String extractHqlOrderBy(javax.persistence.OrderBy jpaOrderBy) { private String extractHqlOrderBy(javax.persistence.OrderBy jpaOrderBy) {
if ( jpaOrderBy != null ) { if ( jpaOrderBy != null ) {
final String jpaOrderByFragment = jpaOrderBy.value(); return jpaOrderBy.value(); // Null not possible. In case of empty expression, apply default ordering.
return StringHelper.isNotEmpty( jpaOrderByFragment )
? jpaOrderByFragment
: null;
} }
return null; return null; // @OrderBy not found.
} }
private static void checkFilterConditions(Collection collValue) { private static void checkFilterConditions(Collection collValue) {

View File

@ -0,0 +1,237 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2013, 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.annotations;
import javax.persistence.NamedStoredProcedureQuery;
import javax.persistence.ParameterMode;
import javax.persistence.QueryHint;
import javax.persistence.StoredProcedureParameter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.hibernate.LockMode;
import org.hibernate.MappingException;
import org.hibernate.engine.ResultSetMappingDefinition;
import org.hibernate.engine.query.spi.sql.NativeSQLQueryReturn;
import org.hibernate.engine.query.spi.sql.NativeSQLQueryRootReturn;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.internal.SessionFactoryImpl;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.procedure.ProcedureCallMemento;
import org.hibernate.procedure.internal.ParameterStrategy;
import org.hibernate.procedure.internal.ProcedureCallMementoImpl;
import org.hibernate.procedure.internal.Util;
import static org.hibernate.procedure.internal.ProcedureCallMementoImpl.ParameterMemento;
/**
* Holds all the information needed from a named procedure call declaration in order to create a
* {@link org.hibernate.procedure.internal.ProcedureCallImpl}
*
* @author Steve Ebersole
*
* @see javax.persistence.NamedStoredProcedureQuery
*/
public class NamedProcedureCallDefinition {
private final String registeredName;
private final String procedureName;
private final Class[] resultClasses;
private final String[] resultSetMappings;
private final ParameterDefinitions parameterDefinitions;
private final Map<String,Object> hints;
NamedProcedureCallDefinition(NamedStoredProcedureQuery annotation) {
this.registeredName = annotation.name();
this.procedureName = annotation.procedureName();
this.resultClasses = annotation.resultClasses();
this.resultSetMappings = annotation.resultSetMappings();
this.parameterDefinitions = new ParameterDefinitions( annotation.parameters() );
this.hints = extract( annotation.hints() );
final boolean specifiesResultClasses = resultClasses != null && resultClasses.length > 0;
final boolean specifiesResultSetMappings = resultSetMappings != null && resultSetMappings.length > 0;
if ( specifiesResultClasses && specifiesResultSetMappings ) {
throw new MappingException(
String.format(
"NamedStoredProcedureQuery [%s] specified both resultClasses and resultSetMappings",
registeredName
)
);
}
}
private Map<String, Object> extract(QueryHint[] hints) {
if ( hints == null || hints.length == 0 ) {
return Collections.emptyMap();
}
final Map<String,Object> hintsMap = new HashMap<String, Object>();
for ( QueryHint hint : hints ) {
hintsMap.put( hint.name(), hint.value() );
}
return hintsMap;
}
public String getRegisteredName() {
return registeredName;
}
public String getProcedureName() {
return procedureName;
}
public ProcedureCallMemento toMemento(
final SessionFactoryImpl sessionFactory,
final Map<String,ResultSetMappingDefinition> resultSetMappingDefinitions) {
final List<NativeSQLQueryReturn> collectedQueryReturns = new ArrayList<NativeSQLQueryReturn>();
final Set<String> collectedQuerySpaces = new HashSet<String>();
final boolean specifiesResultClasses = resultClasses != null && resultClasses.length > 0;
final boolean specifiesResultSetMappings = resultSetMappings != null && resultSetMappings.length > 0;
if ( specifiesResultClasses ) {
Util.resolveResultClasses(
new Util.ResultClassesResolutionContext() {
@Override
public SessionFactoryImplementor getSessionFactory() {
return sessionFactory;
}
@Override
public void addQueryReturns(NativeSQLQueryReturn... queryReturns) {
Collections.addAll( collectedQueryReturns, queryReturns );
}
@Override
public void addQuerySpaces(String... spaces) {
Collections.addAll( collectedQuerySpaces, spaces );
}
},
resultClasses
);
}
else if ( specifiesResultSetMappings ) {
Util.resolveResultSetMappings(
new Util.ResultSetMappingResolutionContext() {
@Override
public SessionFactoryImplementor getSessionFactory() {
return sessionFactory;
}
@Override
public ResultSetMappingDefinition findResultSetMapping(String name) {
return resultSetMappingDefinitions.get( name );
}
@Override
public void addQueryReturns(NativeSQLQueryReturn... queryReturns) {
Collections.addAll( collectedQueryReturns, queryReturns );
}
@Override
public void addQuerySpaces(String... spaces) {
Collections.addAll( collectedQuerySpaces, spaces );
}
},
resultSetMappings
);
}
return new ProcedureCallMementoImpl(
procedureName,
collectedQueryReturns.toArray( new NativeSQLQueryReturn[ collectedQueryReturns.size() ] ),
parameterDefinitions.getParameterStrategy(),
parameterDefinitions.toMementos( sessionFactory ),
collectedQuerySpaces,
hints
);
}
static class ParameterDefinitions {
private final ParameterStrategy parameterStrategy;
private final ParameterDefinition[] parameterDefinitions;
ParameterDefinitions(StoredProcedureParameter[] parameters) {
if ( parameters == null || parameters.length == 0 ) {
parameterStrategy = ParameterStrategy.POSITIONAL;
parameterDefinitions = new ParameterDefinition[0];
}
else {
parameterStrategy = StringHelper.isNotEmpty( parameters[0].name() )
? ParameterStrategy.NAMED
: ParameterStrategy.POSITIONAL;
parameterDefinitions = new ParameterDefinition[ parameters.length ];
for ( int i = 0; i < parameters.length; i++ ) {
parameterDefinitions[i] = new ParameterDefinition( i, parameters[i] );
}
}
}
public ParameterStrategy getParameterStrategy() {
return parameterStrategy;
}
public List<ParameterMemento> toMementos(SessionFactoryImpl sessionFactory) {
final List<ParameterMemento> mementos = new ArrayList<ParameterMemento>();
for ( ParameterDefinition definition : parameterDefinitions ) {
definition.toMemento( sessionFactory );
}
return mementos;
}
}
static class ParameterDefinition {
private final Integer position;
private final String name;
private final ParameterMode parameterMode;
private final Class type;
ParameterDefinition(int position, StoredProcedureParameter annotation) {
this.position = position;
this.name = normalize( annotation.name() );
this.parameterMode = annotation.mode();
this.type = annotation.type();
}
public ParameterMemento toMemento(SessionFactoryImpl sessionFactory) {
return new ParameterMemento(
position,
name,
parameterMode,
type,
sessionFactory.getTypeResolver().heuristicType( type.getName() )
);
}
}
private static String normalize(String name) {
return StringHelper.isNotEmpty( name ) ? name : null;
}
}

View File

@ -29,6 +29,7 @@ import javax.persistence.NamedNativeQueries;
import javax.persistence.NamedNativeQuery; import javax.persistence.NamedNativeQuery;
import javax.persistence.NamedQueries; import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery; import javax.persistence.NamedQuery;
import javax.persistence.NamedStoredProcedureQuery;
import javax.persistence.QueryHint; import javax.persistence.QueryHint;
import javax.persistence.SqlResultSetMapping; import javax.persistence.SqlResultSetMapping;
import javax.persistence.SqlResultSetMappings; import javax.persistence.SqlResultSetMappings;
@ -331,6 +332,20 @@ public abstract class QueryBinder {
} }
} }
public static void bindNamedStoredProcedureQuery(NamedStoredProcedureQuery annotation, Mappings mappings) {
if ( annotation == null ) {
return;
}
if ( BinderHelper.isEmptyAnnotationValue( annotation.name() ) ) {
throw new AnnotationException( "A named query must have a name when used in class or package level" );
}
final NamedProcedureCallDefinition def = new NamedProcedureCallDefinition( annotation );
mappings.addNamedProcedureCallDefinition( def );
LOG.debugf( "Bound named stored procedure query : %s => %s", def.getRegisteredName(), def.getProcedureName() );
}
public static void bindSqlResultsetMappings(SqlResultSetMappings ann, Mappings mappings, boolean isDefault) { public static void bindSqlResultsetMappings(SqlResultSetMappings ann, Mappings mappings, boolean isDefault) {
if ( ann == null ) return; if ( ann == null ) return;
for (SqlResultSetMapping rs : ann.value()) { for (SqlResultSetMapping rs : ann.value()) {

View File

@ -268,6 +268,9 @@ public class ConnectionProviderInitiator implements StandardServiceInitiator<Con
); );
} }
} }
else if ( CONDITIONAL_PROPERTIES.containsKey( key ) ) {
result.setProperty( CONDITIONAL_PROPERTIES.get( key ), value );
}
} }
return result; return result;
} }
@ -283,6 +286,16 @@ public class ConnectionProviderInitiator implements StandardServiceInitiator<Con
SPECIAL_PROPERTIES.add( Environment.ISOLATION ); SPECIAL_PROPERTIES.add( Environment.ISOLATION );
SPECIAL_PROPERTIES.add( Environment.DRIVER ); SPECIAL_PROPERTIES.add( Environment.DRIVER );
SPECIAL_PROPERTIES.add( Environment.USER ); SPECIAL_PROPERTIES.add( Environment.USER );
}
// Connection properties (map value) that automatically need set if the
// Hibernate property (map key) is available. Makes the assumption that
// both settings use the same value type.
private static final Map<String, String> CONDITIONAL_PROPERTIES;
static {
CONDITIONAL_PROPERTIES = new HashMap<String, String>();
// Oracle requires that includeSynonyms=true in order for getColumns to work using a table synonym name.
CONDITIONAL_PROPERTIES.put( Environment.ENABLE_SYNONYMS, "includeSynonyms" );
} }
} }

View File

@ -380,22 +380,31 @@ public class SessionDelegatorBaseImpl implements SessionImplementor, Session {
// Delegates to Session // Delegates to Session
@Override
public Transaction beginTransaction() { public Transaction beginTransaction() {
return session.beginTransaction(); return session.beginTransaction();
} }
@Override
public Transaction getTransaction() { public Transaction getTransaction() {
return session.getTransaction(); return session.getTransaction();
} }
@Override
public Query createQuery(String queryString) { public Query createQuery(String queryString) {
return session.createQuery( queryString ); return session.createQuery( queryString );
} }
@Override
public SQLQuery createSQLQuery(String queryString) { public SQLQuery createSQLQuery(String queryString) {
return session.createSQLQuery( queryString ); return session.createSQLQuery( queryString );
} }
@Override
public ProcedureCall getNamedProcedureCall(String name) {
return session.getNamedProcedureCall( name );
}
@Override @Override
public ProcedureCall createStoredProcedureCall(String procedureName) { public ProcedureCall createStoredProcedureCall(String procedureName) {
return session.createStoredProcedureCall( procedureName ); return session.createStoredProcedureCall( procedureName );
@ -411,298 +420,372 @@ public class SessionDelegatorBaseImpl implements SessionImplementor, Session {
return session.createStoredProcedureCall( procedureName, resultSetMappings ); return session.createStoredProcedureCall( procedureName, resultSetMappings );
} }
@Override
public Criteria createCriteria(Class persistentClass) { public Criteria createCriteria(Class persistentClass) {
return session.createCriteria( persistentClass ); return session.createCriteria( persistentClass );
} }
@Override
public Criteria createCriteria(Class persistentClass, String alias) { public Criteria createCriteria(Class persistentClass, String alias) {
return session.createCriteria( persistentClass, alias ); return session.createCriteria( persistentClass, alias );
} }
@Override
public Criteria createCriteria(String entityName) { public Criteria createCriteria(String entityName) {
return session.createCriteria( entityName ); return session.createCriteria( entityName );
} }
@Override
public Criteria createCriteria(String entityName, String alias) { public Criteria createCriteria(String entityName, String alias) {
return session.createCriteria( entityName, alias ); return session.createCriteria( entityName, alias );
} }
@Override
public SharedSessionBuilder sessionWithOptions() { public SharedSessionBuilder sessionWithOptions() {
return session.sessionWithOptions(); return session.sessionWithOptions();
} }
@Override
public SessionFactory getSessionFactory() { public SessionFactory getSessionFactory() {
return session.getSessionFactory(); return session.getSessionFactory();
} }
@Override
public Connection close() throws HibernateException { public Connection close() throws HibernateException {
return session.close(); return session.close();
} }
@Override
public void cancelQuery() throws HibernateException { public void cancelQuery() throws HibernateException {
session.cancelQuery(); session.cancelQuery();
} }
@Override
public boolean isDirty() throws HibernateException { public boolean isDirty() throws HibernateException {
return session.isDirty(); return session.isDirty();
} }
@Override
public boolean isDefaultReadOnly() { public boolean isDefaultReadOnly() {
return session.isDefaultReadOnly(); return session.isDefaultReadOnly();
} }
@Override
public void setDefaultReadOnly(boolean readOnly) { public void setDefaultReadOnly(boolean readOnly) {
session.setDefaultReadOnly( readOnly ); session.setDefaultReadOnly( readOnly );
} }
@Override
public Serializable getIdentifier(Object object) { public Serializable getIdentifier(Object object) {
return session.getIdentifier( object ); return session.getIdentifier( object );
} }
@Override
public boolean contains(Object object) { public boolean contains(Object object) {
return session.contains( object ); return session.contains( object );
} }
@Override
public void evict(Object object) { public void evict(Object object) {
session.evict( object ); session.evict( object );
} }
@Override
public Object load(Class theClass, Serializable id, LockMode lockMode) { public Object load(Class theClass, Serializable id, LockMode lockMode) {
return session.load( theClass, id, lockMode ); return session.load( theClass, id, lockMode );
} }
@Override
public Object load(Class theClass, Serializable id, LockOptions lockOptions) { public Object load(Class theClass, Serializable id, LockOptions lockOptions) {
return session.load( theClass, id, lockOptions ); return session.load( theClass, id, lockOptions );
} }
@Override
public Object load(String entityName, Serializable id, LockMode lockMode) { public Object load(String entityName, Serializable id, LockMode lockMode) {
return session.load( entityName, id, lockMode ); return session.load( entityName, id, lockMode );
} }
@Override
public Object load(String entityName, Serializable id, LockOptions lockOptions) { public Object load(String entityName, Serializable id, LockOptions lockOptions) {
return session.load( entityName, id, lockOptions ); return session.load( entityName, id, lockOptions );
} }
@Override
public Object load(Class theClass, Serializable id) { public Object load(Class theClass, Serializable id) {
return session.load( theClass, id ); return session.load( theClass, id );
} }
@Override
public Object load(String entityName, Serializable id) { public Object load(String entityName, Serializable id) {
return session.load( entityName, id ); return session.load( entityName, id );
} }
@Override
public void load(Object object, Serializable id) { public void load(Object object, Serializable id) {
session.load( object, id ); session.load( object, id );
} }
@Override
public void replicate(Object object, ReplicationMode replicationMode) { public void replicate(Object object, ReplicationMode replicationMode) {
session.replicate( object, replicationMode ); session.replicate( object, replicationMode );
} }
@Override
public void replicate(String entityName, Object object, ReplicationMode replicationMode) { public void replicate(String entityName, Object object, ReplicationMode replicationMode) {
session.replicate( entityName, object, replicationMode ); session.replicate( entityName, object, replicationMode );
} }
@Override
public Serializable save(Object object) { public Serializable save(Object object) {
return session.save( object ); return session.save( object );
} }
@Override
public Serializable save(String entityName, Object object) { public Serializable save(String entityName, Object object) {
return session.save( entityName, object ); return session.save( entityName, object );
} }
@Override
public void saveOrUpdate(Object object) { public void saveOrUpdate(Object object) {
session.saveOrUpdate( object ); session.saveOrUpdate( object );
} }
@Override
public void saveOrUpdate(String entityName, Object object) { public void saveOrUpdate(String entityName, Object object) {
session.saveOrUpdate( entityName, object ); session.saveOrUpdate( entityName, object );
} }
@Override
public void update(Object object) { public void update(Object object) {
session.update( object ); session.update( object );
} }
@Override
public void update(String entityName, Object object) { public void update(String entityName, Object object) {
session.update( entityName, object ); session.update( entityName, object );
} }
@Override
public Object merge(Object object) { public Object merge(Object object) {
return session.merge( object ); return session.merge( object );
} }
@Override
public Object merge(String entityName, Object object) { public Object merge(String entityName, Object object) {
return session.merge( entityName, object ); return session.merge( entityName, object );
} }
@Override
public void persist(Object object) { public void persist(Object object) {
session.persist( object ); session.persist( object );
} }
@Override
public void persist(String entityName, Object object) { public void persist(String entityName, Object object) {
session.persist( entityName, object ); session.persist( entityName, object );
} }
@Override
public void delete(Object object) { public void delete(Object object) {
session.delete( object ); session.delete( object );
} }
@Override
public void delete(String entityName, Object object) { public void delete(String entityName, Object object) {
session.delete( entityName, object ); session.delete( entityName, object );
} }
@Override
public void lock(Object object, LockMode lockMode) { public void lock(Object object, LockMode lockMode) {
session.lock( object, lockMode ); session.lock( object, lockMode );
} }
@Override
public void lock(String entityName, Object object, LockMode lockMode) { public void lock(String entityName, Object object, LockMode lockMode) {
session.lock( entityName, object, lockMode ); session.lock( entityName, object, lockMode );
} }
@Override
public LockRequest buildLockRequest(LockOptions lockOptions) { public LockRequest buildLockRequest(LockOptions lockOptions) {
return session.buildLockRequest( lockOptions ); return session.buildLockRequest( lockOptions );
} }
@Override
public void refresh(Object object) { public void refresh(Object object) {
session.refresh( object ); session.refresh( object );
} }
@Override
public void refresh(String entityName, Object object) { public void refresh(String entityName, Object object) {
session.refresh( entityName, object ); session.refresh( entityName, object );
} }
@Override
public void refresh(Object object, LockMode lockMode) { public void refresh(Object object, LockMode lockMode) {
session.refresh( object, lockMode ); session.refresh( object, lockMode );
} }
@Override
public void refresh(Object object, LockOptions lockOptions) { public void refresh(Object object, LockOptions lockOptions) {
session.refresh( object, lockOptions ); session.refresh( object, lockOptions );
} }
@Override
public void refresh(String entityName, Object object, LockOptions lockOptions) { public void refresh(String entityName, Object object, LockOptions lockOptions) {
session.refresh( entityName, object, lockOptions ); session.refresh( entityName, object, lockOptions );
} }
@Override
public LockMode getCurrentLockMode(Object object) { public LockMode getCurrentLockMode(Object object) {
return session.getCurrentLockMode( object ); return session.getCurrentLockMode( object );
} }
@Override
public Query createFilter(Object collection, String queryString) { public Query createFilter(Object collection, String queryString) {
return session.createFilter( collection, queryString ); return session.createFilter( collection, queryString );
} }
@Override
public void clear() { public void clear() {
session.clear(); session.clear();
} }
@Override
public Object get(Class clazz, Serializable id) { public Object get(Class clazz, Serializable id) {
return session.get( clazz, id ); return session.get( clazz, id );
} }
@Override
public Object get(Class clazz, Serializable id, LockMode lockMode) { public Object get(Class clazz, Serializable id, LockMode lockMode) {
return session.get( clazz, id, lockMode ); return session.get( clazz, id, lockMode );
} }
@Override
public Object get(Class clazz, Serializable id, LockOptions lockOptions) { public Object get(Class clazz, Serializable id, LockOptions lockOptions) {
return session.get( clazz, id, lockOptions ); return session.get( clazz, id, lockOptions );
} }
@Override
public Object get(String entityName, Serializable id) { public Object get(String entityName, Serializable id) {
return session.get( entityName, id ); return session.get( entityName, id );
} }
@Override
public Object get(String entityName, Serializable id, LockMode lockMode) { public Object get(String entityName, Serializable id, LockMode lockMode) {
return session.get( entityName, id, lockMode ); return session.get( entityName, id, lockMode );
} }
@Override
public Object get(String entityName, Serializable id, LockOptions lockOptions) { public Object get(String entityName, Serializable id, LockOptions lockOptions) {
return session.get( entityName, id, lockOptions ); return session.get( entityName, id, lockOptions );
} }
@Override
public String getEntityName(Object object) { public String getEntityName(Object object) {
return session.getEntityName( object ); return session.getEntityName( object );
} }
@Override
public IdentifierLoadAccess byId(String entityName) { public IdentifierLoadAccess byId(String entityName) {
return session.byId( entityName ); return session.byId( entityName );
} }
@Override
public IdentifierLoadAccess byId(Class entityClass) { public IdentifierLoadAccess byId(Class entityClass) {
return session.byId( entityClass ); return session.byId( entityClass );
} }
@Override
public NaturalIdLoadAccess byNaturalId(String entityName) { public NaturalIdLoadAccess byNaturalId(String entityName) {
return session.byNaturalId( entityName ); return session.byNaturalId( entityName );
} }
@Override
public NaturalIdLoadAccess byNaturalId(Class entityClass) { public NaturalIdLoadAccess byNaturalId(Class entityClass) {
return session.byNaturalId( entityClass ); return session.byNaturalId( entityClass );
} }
@Override
public SimpleNaturalIdLoadAccess bySimpleNaturalId(String entityName) { public SimpleNaturalIdLoadAccess bySimpleNaturalId(String entityName) {
return session.bySimpleNaturalId( entityName ); return session.bySimpleNaturalId( entityName );
} }
@Override
public SimpleNaturalIdLoadAccess bySimpleNaturalId(Class entityClass) { public SimpleNaturalIdLoadAccess bySimpleNaturalId(Class entityClass) {
return session.bySimpleNaturalId( entityClass ); return session.bySimpleNaturalId( entityClass );
} }
@Override
public Filter enableFilter(String filterName) { public Filter enableFilter(String filterName) {
return session.enableFilter( filterName ); return session.enableFilter( filterName );
} }
@Override
public Filter getEnabledFilter(String filterName) { public Filter getEnabledFilter(String filterName) {
return session.getEnabledFilter( filterName ); return session.getEnabledFilter( filterName );
} }
@Override
public void disableFilter(String filterName) { public void disableFilter(String filterName) {
session.disableFilter( filterName ); session.disableFilter( filterName );
} }
@Override
public SessionStatistics getStatistics() { public SessionStatistics getStatistics() {
return session.getStatistics(); return session.getStatistics();
} }
@Override
public boolean isReadOnly(Object entityOrProxy) { public boolean isReadOnly(Object entityOrProxy) {
return session.isReadOnly( entityOrProxy ); return session.isReadOnly( entityOrProxy );
} }
@Override
public void setReadOnly(Object entityOrProxy, boolean readOnly) { public void setReadOnly(Object entityOrProxy, boolean readOnly) {
session.setReadOnly( entityOrProxy, readOnly ); session.setReadOnly( entityOrProxy, readOnly );
} }
@Override
public void doWork(Work work) throws HibernateException { public void doWork(Work work) throws HibernateException {
session.doWork( work ); session.doWork( work );
} }
@Override
public <T> T doReturningWork(ReturningWork<T> work) throws HibernateException { public <T> T doReturningWork(ReturningWork<T> work) throws HibernateException {
return session.doReturningWork( work ); return session.doReturningWork( work );
} }
@Override
public Connection disconnect() { public Connection disconnect() {
return session.disconnect(); return session.disconnect();
} }
@Override
public void reconnect(Connection connection) { public void reconnect(Connection connection) {
session.reconnect( connection ); session.reconnect( connection );
} }
@Override
public boolean isFetchProfileEnabled(String name) throws UnknownProfileException { public boolean isFetchProfileEnabled(String name) throws UnknownProfileException {
return session.isFetchProfileEnabled( name ); return session.isFetchProfileEnabled( name );
} }
@Override
public void enableFetchProfile(String name) throws UnknownProfileException { public void enableFetchProfile(String name) throws UnknownProfileException {
session.enableFetchProfile( name ); session.enableFetchProfile( name );
} }
@Override
public void disableFetchProfile(String name) throws UnknownProfileException { public void disableFetchProfile(String name) throws UnknownProfileException {
session.disableFetchProfile( name ); session.disableFetchProfile( name );
} }
@Override
public TypeHelper getTypeHelper() { public TypeHelper getTypeHelper() {
return session.getTypeHelper(); return session.getTypeHelper();
} }
@Override
public LobHelper getLobHelper() { public LobHelper getLobHelper() {
return session.getLobHelper(); return session.getLobHelper();
} }

View File

@ -53,6 +53,7 @@ import org.hibernate.id.IdentifierGenerator;
import org.hibernate.internal.NamedQueryRepository; import org.hibernate.internal.NamedQueryRepository;
import org.hibernate.persister.collection.CollectionPersister; import org.hibernate.persister.collection.CollectionPersister;
import org.hibernate.persister.entity.EntityPersister; import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.procedure.ProcedureCallMemento;
import org.hibernate.proxy.EntityNotFoundDelegate; import org.hibernate.proxy.EntityNotFoundDelegate;
import org.hibernate.service.spi.ServiceRegistryImplementor; import org.hibernate.service.spi.ServiceRegistryImplementor;
import org.hibernate.stat.spi.StatisticsImplementor; import org.hibernate.stat.spi.StatisticsImplementor;

View File

@ -24,6 +24,7 @@
package org.hibernate.hql.internal.ast; package org.hibernate.hql.internal.ast;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
@ -133,6 +134,7 @@ public class QueryTranslatorImpl implements FilterTranslator {
* @throws QueryException There was a problem parsing the query string. * @throws QueryException There was a problem parsing the query string.
* @throws MappingException There was a problem querying defined mappings. * @throws MappingException There was a problem querying defined mappings.
*/ */
@Override
public void compile( public void compile(
Map replacements, Map replacements,
boolean shallow) throws QueryException, MappingException { boolean shallow) throws QueryException, MappingException {
@ -149,6 +151,7 @@ public class QueryTranslatorImpl implements FilterTranslator {
* @throws QueryException There was a problem parsing the query string. * @throws QueryException There was a problem parsing the query string.
* @throws MappingException There was a problem querying defined mappings. * @throws MappingException There was a problem querying defined mappings.
*/ */
@Override
public void compile( public void compile(
String collectionRole, String collectionRole,
Map replacements, Map replacements,
@ -304,7 +307,7 @@ public class QueryTranslatorImpl implements FilterTranslator {
throw new QueryExecutionRequestException( "Not supported for select queries", hql ); throw new QueryExecutionRequestException( "Not supported for select queries", hql );
} }
} }
@Override
public String getQueryIdentifier() { public String getQueryIdentifier() {
return queryIdentifier; return queryIdentifier;
} }
@ -322,25 +325,27 @@ public class QueryTranslatorImpl implements FilterTranslator {
* *
* @return an array of <tt>Type</tt>s. * @return an array of <tt>Type</tt>s.
*/ */
@Override
public Type[] getReturnTypes() { public Type[] getReturnTypes() {
errorIfDML(); errorIfDML();
return getWalker().getReturnTypes(); return getWalker().getReturnTypes();
} }
@Override
public String[] getReturnAliases() { public String[] getReturnAliases() {
errorIfDML(); errorIfDML();
return getWalker().getReturnAliases(); return getWalker().getReturnAliases();
} }
@Override
public String[][] getColumnNames() { public String[][] getColumnNames() {
errorIfDML(); errorIfDML();
return getWalker().getSelectClause().getColumnNames(); return getWalker().getSelectClause().getColumnNames();
} }
@Override
public Set getQuerySpaces() { public Set getQuerySpaces() {
return getWalker().getQuerySpaces(); return getWalker().getQuerySpaces();
} }
@Override
public List list(SessionImplementor session, QueryParameters queryParameters) public List list(SessionImplementor session, QueryParameters queryParameters)
throws HibernateException { throws HibernateException {
// Delegate to the QueryLoader... // Delegate to the QueryLoader...
@ -397,6 +402,7 @@ public class QueryTranslatorImpl implements FilterTranslator {
/** /**
* Return the query results as an iterator * Return the query results as an iterator
*/ */
@Override
public Iterator iterate(QueryParameters queryParameters, EventSource session) public Iterator iterate(QueryParameters queryParameters, EventSource session)
throws HibernateException { throws HibernateException {
// Delegate to the QueryLoader... // Delegate to the QueryLoader...
@ -407,13 +413,14 @@ public class QueryTranslatorImpl implements FilterTranslator {
/** /**
* Return the query results, as an instance of <tt>ScrollableResults</tt> * Return the query results, as an instance of <tt>ScrollableResults</tt>
*/ */
@Override
public ScrollableResults scroll(QueryParameters queryParameters, SessionImplementor session) public ScrollableResults scroll(QueryParameters queryParameters, SessionImplementor session)
throws HibernateException { throws HibernateException {
// Delegate to the QueryLoader... // Delegate to the QueryLoader...
errorIfDML(); errorIfDML();
return queryLoader.scroll( queryParameters, session ); return queryLoader.scroll( queryParameters, session );
} }
@Override
public int executeUpdate(QueryParameters queryParameters, SessionImplementor session) public int executeUpdate(QueryParameters queryParameters, SessionImplementor session)
throws HibernateException { throws HibernateException {
errorIfSelect(); errorIfSelect();
@ -423,17 +430,16 @@ public class QueryTranslatorImpl implements FilterTranslator {
/** /**
* The SQL query string to be called; implemented by all subclasses * The SQL query string to be called; implemented by all subclasses
*/ */
@Override
public String getSQLString() { public String getSQLString() {
return sql; return sql;
} }
@Override
public List<String> collectSqlStrings() { public List<String> collectSqlStrings() {
ArrayList<String> list = new ArrayList<String>(); ArrayList<String> list = new ArrayList<String>();
if ( isManipulationStatement() ) { if ( isManipulationStatement() ) {
String[] sqlStatements = statementExecutor.getSqlStatements(); String[] sqlStatements = statementExecutor.getSqlStatements();
for ( int i = 0; i < sqlStatements.length; i++ ) { Collections.addAll( list, sqlStatements );
list.add( sqlStatements[i] );
}
} }
else { else {
list.add( sql ); list.add( sql );
@ -446,11 +452,12 @@ public class QueryTranslatorImpl implements FilterTranslator {
public boolean isShallowQuery() { public boolean isShallowQuery() {
return shallowQuery; return shallowQuery;
} }
@Override
public String getQueryString() { public String getQueryString() {
return hql; return hql;
} }
@Override
public Map<String, Filter> getEnabledFilters() { public Map<String, Filter> getEnabledFilters() {
return enabledFilters; return enabledFilters;
} }
@ -458,17 +465,17 @@ public class QueryTranslatorImpl implements FilterTranslator {
public int[] getNamedParameterLocs(String name) { public int[] getNamedParameterLocs(String name) {
return getWalker().getNamedParameterLocations( name ); return getWalker().getNamedParameterLocations( name );
} }
@Override
public boolean containsCollectionFetches() { public boolean containsCollectionFetches() {
errorIfDML(); errorIfDML();
List collectionFetches = ( ( QueryNode ) sqlAst ).getFromClause().getCollectionFetches(); List collectionFetches = ( ( QueryNode ) sqlAst ).getFromClause().getCollectionFetches();
return collectionFetches != null && collectionFetches.size() > 0; return collectionFetches != null && collectionFetches.size() > 0;
} }
@Override
public boolean isManipulationStatement() { public boolean isManipulationStatement() {
return sqlAst.needsExecutor(); return sqlAst.needsExecutor();
} }
@Override
public void validateScrollability() throws HibernateException { public void validateScrollability() throws HibernateException {
// Impl Note: allows multiple collection fetches as long as the // Impl Note: allows multiple collection fetches as long as the
// entire fecthed graph still "points back" to a single // entire fecthed graph still "points back" to a single
@ -496,10 +503,9 @@ public class QueryTranslatorImpl implements FilterTranslator {
} }
FromElement owner = null; FromElement owner = null;
Iterator itr = query.getSelectClause().getFromElementsForLoad().iterator(); for ( Object o : query.getSelectClause().getFromElementsForLoad() ) {
while ( itr.hasNext() ) {
// should be the first, but just to be safe... // should be the first, but just to be safe...
final FromElement fromElement = ( FromElement ) itr.next(); final FromElement fromElement = (FromElement) o;
if ( fromElement.getOrigin() == null ) { if ( fromElement.getOrigin() == null ) {
owner = fromElement; owner = fromElement;
break; break;
@ -560,7 +566,7 @@ public class QueryTranslatorImpl implements FilterTranslator {
throw new QueryException( "Unexpected statement type" ); throw new QueryException( "Unexpected statement type" );
} }
} }
@Override
public ParameterTranslations getParameterTranslations() { public ParameterTranslations getParameterTranslations() {
if ( paramTranslations == null ) { if ( paramTranslations == null ) {
paramTranslations = new ParameterTranslationsImpl( getWalker().getParameters() ); paramTranslations = new ParameterTranslationsImpl( getWalker().getParameters() );
@ -581,6 +587,7 @@ public class QueryTranslatorImpl implements FilterTranslator {
public static class JavaConstantConverter implements NodeTraverser.VisitationStrategy { public static class JavaConstantConverter implements NodeTraverser.VisitationStrategy {
private AST dotRoot; private AST dotRoot;
@Override
public void visit(AST node) { public void visit(AST node) {
if ( dotRoot != null ) { if ( dotRoot != null ) {
// we are already processing a dot-structure // we are already processing a dot-structure
@ -589,7 +596,7 @@ public class QueryTranslatorImpl implements FilterTranslator {
dotRoot = null; dotRoot = null;
} }
if ( dotRoot == null && node.getType() == HqlTokenTypes.DOT ) { if ( node.getType() == HqlTokenTypes.DOT ) {
dotRoot = node; dotRoot = node;
handleDotStructure( dotRoot ); handleDotStructure( dotRoot );
} }

View File

@ -1,10 +1,10 @@
/* /*
* Hibernate, Relational Persistence for Idiomatic Java * Hibernate, Relational Persistence for Idiomatic Java
* *
* Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as * Copyright (c) 2008, 2013, Red Hat Inc. or third-party contributors as
* indicated by the @author tags or express copyright attribution * indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are * 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, * 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 * copy, or redistribute it subject to the terms and conditions of the GNU
@ -20,7 +20,6 @@
* Free Software Foundation, Inc. * Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor * 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA * Boston, MA 02110-1301 USA
*
*/ */
package org.hibernate.hql.internal.ast.tree; package org.hibernate.hql.internal.ast.tree;
import java.util.ArrayList; import java.util.ArrayList;
@ -326,7 +325,7 @@ public class SelectClause extends SelectExpressionList {
private void addCollectionFromElement(FromElement fromElement) { private void addCollectionFromElement(FromElement fromElement) {
if ( fromElement.isFetch() ) { if ( fromElement.isFetch() ) {
if ( fromElement.isCollectionJoin() || fromElement.getQueryableCollection() != null ) { if ( fromElement.getQueryableCollection() != null ) {
String suffix; String suffix;
if (collectionFromElements==null) { if (collectionFromElements==null) {
collectionFromElements = new ArrayList(); collectionFromElements = new ArrayList();

View File

@ -23,6 +23,7 @@
* *
*/ */
package org.hibernate.hql.internal.ast.util; package org.hibernate.hql.internal.ast.util;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
@ -58,8 +59,8 @@ import org.hibernate.type.Type;
*/ */
public class SessionFactoryHelper { public class SessionFactoryHelper {
private SessionFactoryImplementor sfi; private final SessionFactoryImplementor sfi;
private Map collectionPropertyMappingByRole; private final Map<String, PropertyMapping> collectionPropertyMappingByRole;
/** /**
* Construct a new SessionFactoryHelper instance. * Construct a new SessionFactoryHelper instance.
@ -68,7 +69,7 @@ public class SessionFactoryHelper {
*/ */
public SessionFactoryHelper(SessionFactoryImplementor sfi) { public SessionFactoryHelper(SessionFactoryImplementor sfi) {
this.sfi = sfi; this.sfi = sfi;
collectionPropertyMappingByRole = new HashMap(); this.collectionPropertyMappingByRole = new HashMap<String, PropertyMapping>();
} }
/** /**
@ -85,6 +86,7 @@ public class SessionFactoryHelper {
* for the purpose of inheritance discrimination? * for the purpose of inheritance discrimination?
* *
* @param persister The persister to be checked. * @param persister The persister to be checked.
*
* @return True if the persister does define an actual discriminator column. * @return True if the persister does define an actual discriminator column.
*/ */
public boolean hasPhysicalDiscriminatorColumn(Queryable persister) { public boolean hasPhysicalDiscriminatorColumn(Queryable persister) {
@ -103,6 +105,7 @@ public class SessionFactoryHelper {
* Given a (potentially unqualified) class name, locate its imported qualified name. * Given a (potentially unqualified) class name, locate its imported qualified name.
* *
* @param className The potentially unqualified class name * @param className The potentially unqualified class name
*
* @return The qualified class name. * @return The qualified class name.
*/ */
public String getImportedClassName(String className) { public String getImportedClassName(String className) {
@ -113,6 +116,7 @@ public class SessionFactoryHelper {
* Given a (potentially unqualified) class name, locate its persister. * Given a (potentially unqualified) class name, locate its persister.
* *
* @param className The (potentially unqualified) class name. * @param className The (potentially unqualified) class name.
*
* @return The defined persister for this class, or null if none found. * @return The defined persister for this class, or null if none found.
*/ */
public Queryable findQueryableUsingImports(String className) { public Queryable findQueryableUsingImports(String className) {
@ -125,6 +129,7 @@ public class SessionFactoryHelper {
* *
* @param sfi The session factory implementor. * @param sfi The session factory implementor.
* @param className The (potentially unqualified) class name. * @param className The (potentially unqualified) class name.
*
* @return The defined persister for this class, or null if none found. * @return The defined persister for this class, or null if none found.
*/ */
public static Queryable findQueryableUsingImports(SessionFactoryImplementor sfi, String className) { public static Queryable findQueryableUsingImports(SessionFactoryImplementor sfi, String className) {
@ -144,7 +149,9 @@ public class SessionFactoryHelper {
* Locate the persister by class or entity name. * Locate the persister by class or entity name.
* *
* @param name The class or entity name * @param name The class or entity name
*
* @return The defined persister for this entity, or null if none found. * @return The defined persister for this entity, or null if none found.
*
* @throws MappingException * @throws MappingException
*/ */
private EntityPersister findEntityPersisterByName(String name) throws MappingException { private EntityPersister findEntityPersisterByName(String name) throws MappingException {
@ -169,7 +176,9 @@ public class SessionFactoryHelper {
* exist. * exist.
* *
* @param name The class or entity name * @param name The class or entity name
*
* @return The defined persister for this entity * @return The defined persister for this entity
*
* @throws SemanticException Indicates the persister could not be found * @throws SemanticException Indicates the persister could not be found
*/ */
public EntityPersister requireClassPersister(String name) throws SemanticException { public EntityPersister requireClassPersister(String name) throws SemanticException {
@ -190,6 +199,7 @@ public class SessionFactoryHelper {
* Locate the collection persister by the collection role. * Locate the collection persister by the collection role.
* *
* @param role The collection role name. * @param role The collection role name.
*
* @return The defined CollectionPersister for this collection role, or null. * @return The defined CollectionPersister for this collection role, or null.
*/ */
public QueryableCollection getCollectionPersister(String role) { public QueryableCollection getCollectionPersister(String role) {
@ -209,7 +219,9 @@ public class SessionFactoryHelper {
* such a persister exist. * such a persister exist.
* *
* @param role The collection role name. * @param role The collection role name.
*
* @return The defined CollectionPersister for this collection role. * @return The defined CollectionPersister for this collection role.
*
* @throws QueryException Indicates that the collection persister could not be found. * @throws QueryException Indicates that the collection persister could not be found.
*/ */
public QueryableCollection requireQueryableCollection(String role) throws QueryException { public QueryableCollection requireQueryableCollection(String role) throws QueryException {
@ -232,10 +244,11 @@ public class SessionFactoryHelper {
* Retrieve a PropertyMapping describing the given collection role. * Retrieve a PropertyMapping describing the given collection role.
* *
* @param role The collection role for which to retrieve the property mapping. * @param role The collection role for which to retrieve the property mapping.
*
* @return The property mapping. * @return The property mapping.
*/ */
public PropertyMapping getCollectionPropertyMapping(String role) { public PropertyMapping getCollectionPropertyMapping(String role) {
return ( PropertyMapping ) collectionPropertyMappingByRole.get( role ); return collectionPropertyMappingByRole.get( role );
} }
/** /**
@ -244,6 +257,7 @@ public class SessionFactoryHelper {
* *
* @param role The collection role * @param role The collection role
* @param roleAlias The sql column-qualification alias (i.e., the table alias) * @param roleAlias The sql column-qualification alias (i.e., the table alias)
*
* @return the collection element columns * @return the collection element columns
*/ */
public String[] getCollectionElementColumns(String role, String roleAlias) { public String[] getCollectionElementColumns(String role, String roleAlias) {
@ -267,6 +281,7 @@ public class SessionFactoryHelper {
* @param tableAlias The table alias to use in qualifying the join conditions * @param tableAlias The table alias to use in qualifying the join conditions
* @param joinType The type of join to render (inner, outer, etc); see {@link org.hibernate.sql.JoinFragment} * @param joinType The type of join to render (inner, outer, etc); see {@link org.hibernate.sql.JoinFragment}
* @param columns The columns making up the condition of the join. * @param columns The columns making up the condition of the join.
*
* @return The generated join sequence. * @return The generated join sequence.
*/ */
public JoinSequence createJoinSequence(boolean implicit, AssociationType associationType, String tableAlias, JoinType joinType, String[] columns) { public JoinSequence createJoinSequence(boolean implicit, AssociationType associationType, String tableAlias, JoinType joinType, String[] columns) {
@ -281,6 +296,7 @@ public class SessionFactoryHelper {
* *
* @param collPersister The persister for the collection at which the join should be rooted. * @param collPersister The persister for the collection at which the join should be rooted.
* @param collectionName The alias to use for qualifying column references. * @param collectionName The alias to use for qualifying column references.
*
* @return The generated join sequence. * @return The generated join sequence.
*/ */
public JoinSequence createCollectionJoinSequence(QueryableCollection collPersister, String collectionName) { public JoinSequence createCollectionJoinSequence(QueryableCollection collPersister, String collectionName) {
@ -299,7 +315,9 @@ public class SessionFactoryHelper {
* given type which represents the id or unique-key. * given type which represents the id or unique-key.
* *
* @param entityType The type representing the entity. * @param entityType The type representing the entity.
*
* @return The corresponding property name * @return The corresponding property name
*
* @throws QueryException Indicates such a property could not be found. * @throws QueryException Indicates such a property could not be found.
*/ */
public String getIdentifierOrUniqueKeyPropertyName(EntityType entityType) { public String getIdentifierOrUniqueKeyPropertyName(EntityType entityType) {
@ -315,6 +333,7 @@ public class SessionFactoryHelper {
* Retrieve the number of columns represented by this type. * Retrieve the number of columns represented by this type.
* *
* @param type The type. * @param type The type.
*
* @return The number of columns. * @return The number of columns.
*/ */
public int getColumnSpan(Type type) { public int getColumnSpan(Type type) {
@ -326,6 +345,7 @@ public class SessionFactoryHelper {
* contained within instance of that collection. * contained within instance of that collection.
* *
* @param collectionType The collection type to check. * @param collectionType The collection type to check.
*
* @return The entity name of the elements of this collection. * @return The entity name of the elements of this collection.
*/ */
public String getAssociatedEntityName(CollectionType collectionType) { public String getAssociatedEntityName(CollectionType collectionType) {
@ -337,6 +357,7 @@ public class SessionFactoryHelper {
* within instances of that collection. * within instances of that collection.
* *
* @param collectionType The collection type to be checked. * @param collectionType The collection type to be checked.
*
* @return The Type of the elements of the collection. * @return The Type of the elements of the collection.
*/ */
private Type getElementType(CollectionType collectionType) { private Type getElementType(CollectionType collectionType) {
@ -348,6 +369,7 @@ public class SessionFactoryHelper {
* element type be an association type. * element type be an association type.
* *
* @param collectionType The collection type to be checked. * @param collectionType The collection type to be checked.
*
* @return The AssociationType of the elements of the collection. * @return The AssociationType of the elements of the collection.
*/ */
public AssociationType getElementAssociationType(CollectionType collectionType) { public AssociationType getElementAssociationType(CollectionType collectionType) {
@ -358,6 +380,7 @@ public class SessionFactoryHelper {
* Locate a registered sql function by name. * Locate a registered sql function by name.
* *
* @param functionName The name of the function to locate * @param functionName The name of the function to locate
*
* @return The sql function, or null if not found. * @return The sql function, or null if not found.
*/ */
public SQLFunction findSQLFunction(String functionName) { public SQLFunction findSQLFunction(String functionName) {
@ -368,7 +391,9 @@ public class SessionFactoryHelper {
* Locate a registered sql function by name, requiring that such a registered function exist. * Locate a registered sql function by name, requiring that such a registered function exist.
* *
* @param functionName The name of the function to locate * @param functionName The name of the function to locate
*
* @return The sql function. * @return The sql function.
*
* @throws QueryException Indicates no matching sql functions could be found. * @throws QueryException Indicates no matching sql functions could be found.
*/ */
private SQLFunction requireSQLFunction(String functionName) { private SQLFunction requireSQLFunction(String functionName) {
@ -384,6 +409,7 @@ public class SessionFactoryHelper {
* *
* @param functionName The function name. * @param functionName The function name.
* @param first The first argument expression. * @param first The first argument expression.
*
* @return the function return type given the function name and the first argument expression node. * @return the function return type given the function name and the first argument expression node.
*/ */
public Type findFunctionReturnType(String functionName, AST first) { public Type findFunctionReturnType(String functionName, AST first) {

View File

@ -59,6 +59,7 @@ import org.hibernate.jdbc.WorkExecutor;
import org.hibernate.jdbc.WorkExecutorVisitable; import org.hibernate.jdbc.WorkExecutorVisitable;
import org.hibernate.persister.entity.EntityPersister; import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.procedure.ProcedureCall; import org.hibernate.procedure.ProcedureCall;
import org.hibernate.procedure.ProcedureCallMemento;
import org.hibernate.procedure.internal.ProcedureCallImpl; import org.hibernate.procedure.internal.ProcedureCallImpl;
import org.hibernate.type.Type; import org.hibernate.type.Type;
@ -67,11 +68,11 @@ import org.hibernate.type.Type;
* *
* @author Gavin King * @author Gavin King
*/ */
public abstract class AbstractSessionImpl implements Serializable, SharedSessionContract, public abstract class AbstractSessionImpl
SessionImplementor, TransactionContext { implements Serializable, SharedSessionContract, SessionImplementor, TransactionContext {
protected transient SessionFactoryImpl factory; protected transient SessionFactoryImpl factory;
private final String tenantIdentifier; private final String tenantIdentifier;
private boolean closed = false; private boolean closed;
protected AbstractSessionImpl(SessionFactoryImpl factory, String tenantIdentifier) { protected AbstractSessionImpl(SessionFactoryImpl factory, String tenantIdentifier) {
this.factory = factory; this.factory = factory;
@ -218,7 +219,7 @@ public abstract class AbstractSessionImpl implements Serializable, SharedSession
@Override @Override
public Query createQuery(String queryString) { public Query createQuery(String queryString) {
errorIfClosed(); errorIfClosed();
QueryImpl query = new QueryImpl( final QueryImpl query = new QueryImpl(
queryString, queryString,
this, this,
getHQLQueryPlan( queryString, false ).getParameterMetadata() getHQLQueryPlan( queryString, false ).getParameterMetadata()
@ -230,7 +231,7 @@ public abstract class AbstractSessionImpl implements Serializable, SharedSession
@Override @Override
public SQLQuery createSQLQuery(String sql) { public SQLQuery createSQLQuery(String sql) {
errorIfClosed(); errorIfClosed();
SQLQueryImpl query = new SQLQueryImpl( final SQLQueryImpl query = new SQLQueryImpl(
sql, sql,
this, this,
factory.getQueryPlanCache().getSQLParameterMetadata( sql ) factory.getQueryPlanCache().getSQLParameterMetadata( sql )
@ -239,6 +240,22 @@ public abstract class AbstractSessionImpl implements Serializable, SharedSession
return query; return query;
} }
@Override
@SuppressWarnings("UnnecessaryLocalVariable")
public ProcedureCall getNamedProcedureCall(String name) {
errorIfClosed();
final ProcedureCallMemento memento = factory.getNamedQueryRepository().getNamedProcedureCallMemento( name );
if ( memento == null ) {
throw new IllegalArgumentException(
"Could not find named stored procedure call with that registration name : " + name
);
}
final ProcedureCall procedureCall = memento.makeProcedureCall( this );
// procedureCall.setComment( "Named stored procedure call [" + name + "]" );
return procedureCall;
}
@Override @Override
@SuppressWarnings("UnnecessaryLocalVariable") @SuppressWarnings("UnnecessaryLocalVariable")
public ProcedureCall createStoredProcedureCall(String procedureName) { public ProcedureCall createStoredProcedureCall(String procedureName) {

View File

@ -57,15 +57,15 @@ public class CriteriaImpl implements Criteria, Serializable {
private transient SessionImplementor session; private transient SessionImplementor session;
private final String rootAlias; private final String rootAlias;
private List criterionEntries = new ArrayList(); private List<CriterionEntry> criterionEntries = new ArrayList<CriterionEntry>();
private List orderEntries = new ArrayList(); private List<OrderEntry> orderEntries = new ArrayList<OrderEntry>();
private Projection projection; private Projection projection;
private Criteria projectionCriteria; private Criteria projectionCriteria;
private List subcriteriaList = new ArrayList(); private List<Subcriteria> subcriteriaList = new ArrayList<Subcriteria>();
private Map fetchModes = new HashMap(); private Map<String, FetchMode> fetchModes = new HashMap<String, FetchMode>();
private Map lockModes = new HashMap(); private Map<String, LockMode> lockModes = new HashMap<String, LockMode>();
private Integer maxResults; private Integer maxResults;
private Integer firstResult; private Integer firstResult;
@ -98,7 +98,7 @@ public class CriteriaImpl implements Criteria, Serializable {
this.cacheable = false; this.cacheable = false;
this.rootAlias = alias; this.rootAlias = alias;
} }
@Override
public String toString() { public String toString() {
return "CriteriaImpl(" + return "CriteriaImpl(" +
entityOrClassName + ":" + entityOrClassName + ":" +
@ -124,7 +124,7 @@ public class CriteriaImpl implements Criteria, Serializable {
return entityOrClassName; return entityOrClassName;
} }
public Map getLockModes() { public Map<String, LockMode> getLockModes() {
return lockModes; return lockModes;
} }
@ -132,15 +132,15 @@ public class CriteriaImpl implements Criteria, Serializable {
return projectionCriteria; return projectionCriteria;
} }
public Iterator iterateSubcriteria() { public Iterator<Subcriteria> iterateSubcriteria() {
return subcriteriaList.iterator(); return subcriteriaList.iterator();
} }
public Iterator iterateExpressionEntries() { public Iterator<CriterionEntry> iterateExpressionEntries() {
return criterionEntries.iterator(); return criterionEntries.iterator();
} }
public Iterator iterateOrderings() { public Iterator<OrderEntry> iterateOrderings() {
return orderEntries.iterator(); return orderEntries.iterator();
} }
@ -151,7 +151,7 @@ public class CriteriaImpl implements Criteria, Serializable {
// Criteria impl ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Criteria impl ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@Override
public String getAlias() { public String getAlias() {
return rootAlias; return rootAlias;
} }
@ -159,46 +159,45 @@ public class CriteriaImpl implements Criteria, Serializable {
public Projection getProjection() { public Projection getProjection() {
return projection; return projection;
} }
@Override
public Criteria setProjection(Projection projection) { public Criteria setProjection(Projection projection) {
this.projection = projection; this.projection = projection;
this.projectionCriteria = this; this.projectionCriteria = this;
setResultTransformer( PROJECTION ); setResultTransformer( PROJECTION );
return this; return this;
} }
@Override
public Criteria add(Criterion expression) { public Criteria add(Criterion expression) {
add( this, expression ); add( this, expression );
return this; return this;
} }
@Override
public Criteria addOrder(Order ordering) { public Criteria addOrder(Order ordering) {
orderEntries.add( new OrderEntry( ordering, this ) ); orderEntries.add( new OrderEntry( ordering, this ) );
return this; return this;
} }
public FetchMode getFetchMode(String path) { public FetchMode getFetchMode(String path) {
return (FetchMode) fetchModes.get(path); return fetchModes.get(path);
} }
@Override
public Criteria setFetchMode(String associationPath, FetchMode mode) { public Criteria setFetchMode(String associationPath, FetchMode mode) {
fetchModes.put( associationPath, mode ); fetchModes.put( associationPath, mode );
return this; return this;
} }
@Override
public Criteria setLockMode(LockMode lockMode) { public Criteria setLockMode(LockMode lockMode) {
return setLockMode( getAlias(), lockMode ); return setLockMode( getAlias(), lockMode );
} }
@Override
public Criteria setLockMode(String alias, LockMode lockMode) { public Criteria setLockMode(String alias, LockMode lockMode) {
lockModes.put( alias, lockMode ); lockModes.put( alias, lockMode );
return this; return this;
} }
@Override
public Criteria createAlias(String associationPath, String alias) { public Criteria createAlias(String associationPath, String alias) {
return createAlias( associationPath, alias, JoinType.INNER_JOIN ); return createAlias( associationPath, alias, JoinType.INNER_JOIN );
} }
@Override
public Criteria createAlias(String associationPath, String alias, JoinType joinType) { public Criteria createAlias(String associationPath, String alias, JoinType joinType) {
new Subcriteria( this, associationPath, alias, joinType ); new Subcriteria( this, associationPath, alias, joinType );
return this; return this;
@ -208,7 +207,7 @@ public class CriteriaImpl implements Criteria, Serializable {
public Criteria createAlias(String associationPath, String alias, int joinType) throws HibernateException { public Criteria createAlias(String associationPath, String alias, int joinType) throws HibernateException {
return createAlias( associationPath, alias, JoinType.parse( joinType ) ); return createAlias( associationPath, alias, JoinType.parse( joinType ) );
} }
@Override
public Criteria createAlias(String associationPath, String alias, JoinType joinType, Criterion withClause) { public Criteria createAlias(String associationPath, String alias, JoinType joinType, Criterion withClause) {
new Subcriteria( this, associationPath, alias, joinType, withClause ); new Subcriteria( this, associationPath, alias, joinType, withClause );
return this; return this;
@ -219,11 +218,11 @@ public class CriteriaImpl implements Criteria, Serializable {
throws HibernateException { throws HibernateException {
return createAlias( associationPath, alias, JoinType.parse( joinType ), withClause ); return createAlias( associationPath, alias, JoinType.parse( joinType ), withClause );
} }
@Override
public Criteria createCriteria(String associationPath) { public Criteria createCriteria(String associationPath) {
return createCriteria( associationPath, JoinType.INNER_JOIN ); return createCriteria( associationPath, JoinType.INNER_JOIN );
} }
@Override
public Criteria createCriteria(String associationPath, JoinType joinType) { public Criteria createCriteria(String associationPath, JoinType joinType) {
return new Subcriteria( this, associationPath, joinType ); return new Subcriteria( this, associationPath, joinType );
} }
@ -232,11 +231,11 @@ public class CriteriaImpl implements Criteria, Serializable {
public Criteria createCriteria(String associationPath, int joinType) throws HibernateException { public Criteria createCriteria(String associationPath, int joinType) throws HibernateException {
return createCriteria(associationPath, JoinType.parse( joinType )); return createCriteria(associationPath, JoinType.parse( joinType ));
} }
@Override
public Criteria createCriteria(String associationPath, String alias) { public Criteria createCriteria(String associationPath, String alias) {
return createCriteria( associationPath, alias, JoinType.INNER_JOIN ); return createCriteria( associationPath, alias, JoinType.INNER_JOIN );
} }
@Override
public Criteria createCriteria(String associationPath, String alias, JoinType joinType) { public Criteria createCriteria(String associationPath, String alias, JoinType joinType) {
return new Subcriteria( this, associationPath, alias, joinType ); return new Subcriteria( this, associationPath, alias, joinType );
} }
@ -245,7 +244,7 @@ public class CriteriaImpl implements Criteria, Serializable {
public Criteria createCriteria(String associationPath, String alias, int joinType) throws HibernateException { public Criteria createCriteria(String associationPath, String alias, int joinType) throws HibernateException {
return createCriteria( associationPath, alias, JoinType.parse( joinType ) ); return createCriteria( associationPath, alias, JoinType.parse( joinType ) );
} }
@Override
public Criteria createCriteria(String associationPath, String alias, JoinType joinType, Criterion withClause) { public Criteria createCriteria(String associationPath, String alias, JoinType joinType, Criterion withClause) {
return new Subcriteria( this, associationPath, alias, joinType, withClause ); return new Subcriteria( this, associationPath, alias, joinType, withClause );
} }
@ -259,7 +258,7 @@ public class CriteriaImpl implements Criteria, Serializable {
public ResultTransformer getResultTransformer() { public ResultTransformer getResultTransformer() {
return resultTransformer; return resultTransformer;
} }
@Override
public Criteria setResultTransformer(ResultTransformer tupleMapper) { public Criteria setResultTransformer(ResultTransformer tupleMapper) {
this.resultTransformer = tupleMapper; this.resultTransformer = tupleMapper;
return this; return this;
@ -268,7 +267,7 @@ public class CriteriaImpl implements Criteria, Serializable {
public Integer getMaxResults() { public Integer getMaxResults() {
return maxResults; return maxResults;
} }
@Override
public Criteria setMaxResults(int maxResults) { public Criteria setMaxResults(int maxResults) {
this.maxResults = maxResults; this.maxResults = maxResults;
return this; return this;
@ -277,7 +276,7 @@ public class CriteriaImpl implements Criteria, Serializable {
public Integer getFirstResult() { public Integer getFirstResult() {
return firstResult; return firstResult;
} }
@Override
public Criteria setFirstResult(int firstResult) { public Criteria setFirstResult(int firstResult) {
this.firstResult = firstResult; this.firstResult = firstResult;
return this; return this;
@ -286,7 +285,7 @@ public class CriteriaImpl implements Criteria, Serializable {
public Integer getFetchSize() { public Integer getFetchSize() {
return fetchSize; return fetchSize;
} }
@Override
public Criteria setFetchSize(int fetchSize) { public Criteria setFetchSize(int fetchSize) {
this.fetchSize = fetchSize; this.fetchSize = fetchSize;
return this; return this;
@ -295,22 +294,18 @@ public class CriteriaImpl implements Criteria, Serializable {
public Integer getTimeout() { public Integer getTimeout() {
return timeout; return timeout;
} }
@Override
public Criteria setTimeout(int timeout) { public Criteria setTimeout(int timeout) {
this.timeout = timeout; this.timeout = timeout;
return this; return this;
} }
/** @Override
* {@inheritDoc}
*/
public boolean isReadOnlyInitialized() { public boolean isReadOnlyInitialized() {
return readOnly != null; return readOnly != null;
} }
/** @Override
* {@inheritDoc}
*/
public boolean isReadOnly() { public boolean isReadOnly() {
if ( ! isReadOnlyInitialized() && getSession() == null ) { if ( ! isReadOnlyInitialized() && getSession() == null ) {
throw new IllegalStateException( throw new IllegalStateException(
@ -318,23 +313,21 @@ public class CriteriaImpl implements Criteria, Serializable {
); );
} }
return ( isReadOnlyInitialized() ? return ( isReadOnlyInitialized() ?
readOnly.booleanValue() : readOnly :
getSession().getPersistenceContext().isDefaultReadOnly() getSession().getPersistenceContext().isDefaultReadOnly()
); );
} }
/** @Override
* {@inheritDoc}
*/
public Criteria setReadOnly(boolean readOnly) { public Criteria setReadOnly(boolean readOnly) {
this.readOnly = Boolean.valueOf( readOnly ); this.readOnly = readOnly;
return this; return this;
} }
public boolean getCacheable() { public boolean getCacheable() {
return this.cacheable; return this.cacheable;
} }
@Override
public Criteria setCacheable(boolean cacheable) { public Criteria setCacheable(boolean cacheable) {
this.cacheable = cacheable; this.cacheable = cacheable;
return this; return this;
@ -343,7 +336,7 @@ public class CriteriaImpl implements Criteria, Serializable {
public String getCacheRegion() { public String getCacheRegion() {
return this.cacheRegion; return this.cacheRegion;
} }
@Override
public Criteria setCacheRegion(String cacheRegion) { public Criteria setCacheRegion(String cacheRegion) {
this.cacheRegion = cacheRegion.trim(); this.cacheRegion = cacheRegion.trim();
return this; return this;
@ -352,22 +345,22 @@ public class CriteriaImpl implements Criteria, Serializable {
public String getComment() { public String getComment() {
return comment; return comment;
} }
@Override
public Criteria setComment(String comment) { public Criteria setComment(String comment) {
this.comment = comment; this.comment = comment;
return this; return this;
} }
@Override
public Criteria setFlushMode(FlushMode flushMode) { public Criteria setFlushMode(FlushMode flushMode) {
this.flushMode = flushMode; this.flushMode = flushMode;
return this; return this;
} }
@Override
public Criteria setCacheMode(CacheMode cacheMode) { public Criteria setCacheMode(CacheMode cacheMode) {
this.cacheMode = cacheMode; this.cacheMode = cacheMode;
return this; return this;
} }
@Override
public List list() throws HibernateException { public List list() throws HibernateException {
before(); before();
try { try {
@ -377,11 +370,11 @@ public class CriteriaImpl implements Criteria, Serializable {
after(); after();
} }
} }
@Override
public ScrollableResults scroll() { public ScrollableResults scroll() {
return scroll( ScrollMode.SCROLL_INSENSITIVE ); return scroll( ScrollMode.SCROLL_INSENSITIVE );
} }
@Override
public ScrollableResults scroll(ScrollMode scrollMode) { public ScrollableResults scroll(ScrollMode scrollMode) {
before(); before();
try { try {
@ -391,7 +384,7 @@ public class CriteriaImpl implements Criteria, Serializable {
after(); after();
} }
} }
@Override
public Object uniqueResult() throws HibernateException { public Object uniqueResult() throws HibernateException {
return AbstractQueryImpl.uniqueElement( list() ); return AbstractQueryImpl.uniqueElement( list() );
} }
@ -428,7 +421,7 @@ public class CriteriaImpl implements Criteria, Serializable {
if ( criterionEntries.size() != 1 ) { if ( criterionEntries.size() != 1 ) {
return false; return false;
} }
CriterionEntry ce = (CriterionEntry) criterionEntries.get(0); CriterionEntry ce = criterionEntries.get(0);
return ce.getCriterion() instanceof NaturalIdentifier; return ce.getCriterion() instanceof NaturalIdentifier;
} }
@ -464,7 +457,7 @@ public class CriteriaImpl implements Criteria, Serializable {
private Subcriteria(Criteria parent, String path, JoinType joinType) { private Subcriteria(Criteria parent, String path, JoinType joinType) {
this( parent, path, null, joinType ); this( parent, path, null, joinType );
} }
@Override
public String toString() { public String toString() {
return "Subcriteria(" return "Subcriteria("
+ path + ":" + path + ":"
@ -474,7 +467,7 @@ public class CriteriaImpl implements Criteria, Serializable {
// State ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // State ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@Override
public String getAlias() { public String getAlias() {
return alias; return alias;
} }
@ -494,7 +487,7 @@ public class CriteriaImpl implements Criteria, Serializable {
public LockMode getLockMode() { public LockMode getLockMode() {
return lockMode; return lockMode;
} }
@Override
public Criteria setLockMode(LockMode lockMode) { public Criteria setLockMode(LockMode lockMode) {
this.lockMode = lockMode; this.lockMode = lockMode;
return this; return this;
@ -513,22 +506,22 @@ public class CriteriaImpl implements Criteria, Serializable {
} }
// Criteria impl ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Criteria impl ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@Override
public Criteria add(Criterion expression) { public Criteria add(Criterion expression) {
hasRestriction = true; hasRestriction = true;
CriteriaImpl.this.add(this, expression); CriteriaImpl.this.add(this, expression);
return this; return this;
} }
@Override
public Criteria addOrder(Order order) { public Criteria addOrder(Order order) {
CriteriaImpl.this.orderEntries.add( new OrderEntry(order, this) ); CriteriaImpl.this.orderEntries.add( new OrderEntry(order, this) );
return this; return this;
} }
@Override
public Criteria createAlias(String associationPath, String alias) { public Criteria createAlias(String associationPath, String alias) {
return createAlias( associationPath, alias, JoinType.INNER_JOIN ); return createAlias( associationPath, alias, JoinType.INNER_JOIN );
} }
@Override
public Criteria createAlias(String associationPath, String alias, JoinType joinType) throws HibernateException { public Criteria createAlias(String associationPath, String alias, JoinType joinType) throws HibernateException {
new Subcriteria( this, associationPath, alias, joinType ); new Subcriteria( this, associationPath, alias, joinType );
return this; return this;
@ -538,7 +531,7 @@ public class CriteriaImpl implements Criteria, Serializable {
public Criteria createAlias(String associationPath, String alias, int joinType) throws HibernateException { public Criteria createAlias(String associationPath, String alias, int joinType) throws HibernateException {
return createAlias( associationPath, alias, JoinType.parse( joinType ) ); return createAlias( associationPath, alias, JoinType.parse( joinType ) );
} }
@Override
public Criteria createAlias(String associationPath, String alias, JoinType joinType, Criterion withClause) throws HibernateException { public Criteria createAlias(String associationPath, String alias, JoinType joinType, Criterion withClause) throws HibernateException {
new Subcriteria( this, associationPath, alias, joinType, withClause ); new Subcriteria( this, associationPath, alias, joinType, withClause );
return this; return this;
@ -549,11 +542,11 @@ public class CriteriaImpl implements Criteria, Serializable {
throws HibernateException { throws HibernateException {
return createAlias( associationPath, alias, JoinType.parse( joinType ), withClause ); return createAlias( associationPath, alias, JoinType.parse( joinType ), withClause );
} }
@Override
public Criteria createCriteria(String associationPath) { public Criteria createCriteria(String associationPath) {
return createCriteria( associationPath, JoinType.INNER_JOIN ); return createCriteria( associationPath, JoinType.INNER_JOIN );
} }
@Override
public Criteria createCriteria(String associationPath, JoinType joinType) throws HibernateException { public Criteria createCriteria(String associationPath, JoinType joinType) throws HibernateException {
return new Subcriteria( Subcriteria.this, associationPath, joinType ); return new Subcriteria( Subcriteria.this, associationPath, joinType );
} }
@ -562,11 +555,11 @@ public class CriteriaImpl implements Criteria, Serializable {
public Criteria createCriteria(String associationPath, int joinType) throws HibernateException { public Criteria createCriteria(String associationPath, int joinType) throws HibernateException {
return createCriteria( associationPath, JoinType.parse( joinType ) ); return createCriteria( associationPath, JoinType.parse( joinType ) );
} }
@Override
public Criteria createCriteria(String associationPath, String alias) { public Criteria createCriteria(String associationPath, String alias) {
return createCriteria( associationPath, alias, JoinType.INNER_JOIN ); return createCriteria( associationPath, alias, JoinType.INNER_JOIN );
} }
@Override
public Criteria createCriteria(String associationPath, String alias, JoinType joinType) throws HibernateException { public Criteria createCriteria(String associationPath, String alias, JoinType joinType) throws HibernateException {
return new Subcriteria( Subcriteria.this, associationPath, alias, joinType ); return new Subcriteria( Subcriteria.this, associationPath, alias, joinType );
} }
@ -575,7 +568,7 @@ public class CriteriaImpl implements Criteria, Serializable {
public Criteria createCriteria(String associationPath, String alias, int joinType) throws HibernateException { public Criteria createCriteria(String associationPath, String alias, int joinType) throws HibernateException {
return createCriteria( associationPath, alias, JoinType.parse( joinType ) ); return createCriteria( associationPath, alias, JoinType.parse( joinType ) );
} }
@Override
public Criteria createCriteria(String associationPath, String alias, JoinType joinType, Criterion withClause) throws HibernateException { public Criteria createCriteria(String associationPath, String alias, JoinType joinType, Criterion withClause) throws HibernateException {
return new Subcriteria( this, associationPath, alias, joinType, withClause ); return new Subcriteria( this, associationPath, alias, joinType, withClause );
} }
@ -585,96 +578,96 @@ public class CriteriaImpl implements Criteria, Serializable {
throws HibernateException { throws HibernateException {
return createCriteria( associationPath, alias, JoinType.parse( joinType ), withClause ); return createCriteria( associationPath, alias, JoinType.parse( joinType ), withClause );
} }
@Override
public boolean isReadOnly() { public boolean isReadOnly() {
return CriteriaImpl.this.isReadOnly(); return CriteriaImpl.this.isReadOnly();
} }
@Override
public boolean isReadOnlyInitialized() { public boolean isReadOnlyInitialized() {
return CriteriaImpl.this.isReadOnlyInitialized(); return CriteriaImpl.this.isReadOnlyInitialized();
} }
@Override
public Criteria setReadOnly(boolean readOnly) { public Criteria setReadOnly(boolean readOnly) {
CriteriaImpl.this.setReadOnly( readOnly ); CriteriaImpl.this.setReadOnly( readOnly );
return this; return this;
} }
@Override
public Criteria setCacheable(boolean cacheable) { public Criteria setCacheable(boolean cacheable) {
CriteriaImpl.this.setCacheable(cacheable); CriteriaImpl.this.setCacheable(cacheable);
return this; return this;
} }
@Override
public Criteria setCacheRegion(String cacheRegion) { public Criteria setCacheRegion(String cacheRegion) {
CriteriaImpl.this.setCacheRegion(cacheRegion); CriteriaImpl.this.setCacheRegion(cacheRegion);
return this; return this;
} }
@Override
public List list() throws HibernateException { public List list() throws HibernateException {
return CriteriaImpl.this.list(); return CriteriaImpl.this.list();
} }
@Override
public ScrollableResults scroll() throws HibernateException { public ScrollableResults scroll() throws HibernateException {
return CriteriaImpl.this.scroll(); return CriteriaImpl.this.scroll();
} }
@Override
public ScrollableResults scroll(ScrollMode scrollMode) throws HibernateException { public ScrollableResults scroll(ScrollMode scrollMode) throws HibernateException {
return CriteriaImpl.this.scroll(scrollMode); return CriteriaImpl.this.scroll(scrollMode);
} }
@Override
public Object uniqueResult() throws HibernateException { public Object uniqueResult() throws HibernateException {
return CriteriaImpl.this.uniqueResult(); return CriteriaImpl.this.uniqueResult();
} }
@Override
public Criteria setFetchMode(String associationPath, FetchMode mode) { public Criteria setFetchMode(String associationPath, FetchMode mode) {
CriteriaImpl.this.setFetchMode( StringHelper.qualify(path, associationPath), mode); CriteriaImpl.this.setFetchMode( StringHelper.qualify(path, associationPath), mode);
return this; return this;
} }
@Override
public Criteria setFlushMode(FlushMode flushMode) { public Criteria setFlushMode(FlushMode flushMode) {
CriteriaImpl.this.setFlushMode(flushMode); CriteriaImpl.this.setFlushMode(flushMode);
return this; return this;
} }
@Override
public Criteria setCacheMode(CacheMode cacheMode) { public Criteria setCacheMode(CacheMode cacheMode) {
CriteriaImpl.this.setCacheMode(cacheMode); CriteriaImpl.this.setCacheMode(cacheMode);
return this; return this;
} }
@Override
public Criteria setFirstResult(int firstResult) { public Criteria setFirstResult(int firstResult) {
CriteriaImpl.this.setFirstResult(firstResult); CriteriaImpl.this.setFirstResult(firstResult);
return this; return this;
} }
@Override
public Criteria setMaxResults(int maxResults) { public Criteria setMaxResults(int maxResults) {
CriteriaImpl.this.setMaxResults(maxResults); CriteriaImpl.this.setMaxResults(maxResults);
return this; return this;
} }
@Override
public Criteria setTimeout(int timeout) { public Criteria setTimeout(int timeout) {
CriteriaImpl.this.setTimeout(timeout); CriteriaImpl.this.setTimeout(timeout);
return this; return this;
} }
@Override
public Criteria setFetchSize(int fetchSize) { public Criteria setFetchSize(int fetchSize) {
CriteriaImpl.this.setFetchSize(fetchSize); CriteriaImpl.this.setFetchSize(fetchSize);
return this; return this;
} }
@Override
public Criteria setLockMode(String alias, LockMode lockMode) { public Criteria setLockMode(String alias, LockMode lockMode) {
CriteriaImpl.this.setLockMode(alias, lockMode); CriteriaImpl.this.setLockMode(alias, lockMode);
return this; return this;
} }
@Override
public Criteria setResultTransformer(ResultTransformer resultProcessor) { public Criteria setResultTransformer(ResultTransformer resultProcessor) {
CriteriaImpl.this.setResultTransformer(resultProcessor); CriteriaImpl.this.setResultTransformer(resultProcessor);
return this; return this;
} }
@Override
public Criteria setComment(String comment) { public Criteria setComment(String comment) {
CriteriaImpl.this.setComment(comment); CriteriaImpl.this.setComment(comment);
return this; return this;
} }
@Override
public Criteria setProjection(Projection projection) { public Criteria setProjection(Projection projection) {
CriteriaImpl.this.projection = projection; CriteriaImpl.this.projection = projection;
CriteriaImpl.this.projectionCriteria = this; CriteriaImpl.this.projectionCriteria = this;
@ -699,7 +692,7 @@ public class CriteriaImpl implements Criteria, Serializable {
public Criteria getCriteria() { public Criteria getCriteria() {
return criteria; return criteria;
} }
@Override
public String toString() { public String toString() {
return criterion.toString(); return criterion.toString();
} }
@ -721,7 +714,7 @@ public class CriteriaImpl implements Criteria, Serializable {
public Criteria getCriteria() { public Criteria getCriteria() {
return criteria; return criteria;
} }
@Override
public String toString() { public String toString() {
return order.toString(); return order.toString();
} }

View File

@ -25,20 +25,20 @@ package org.hibernate.internal;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator; import java.util.List;
import java.util.Map; import java.util.Map;
import org.jboss.logging.Logger; import org.jboss.logging.Logger;
import org.hibernate.HibernateException; import org.hibernate.HibernateException;
import org.hibernate.MappingException; import org.hibernate.MappingException;
import org.hibernate.QueryException;
import org.hibernate.engine.ResultSetMappingDefinition; import org.hibernate.engine.ResultSetMappingDefinition;
import org.hibernate.engine.query.spi.QueryPlanCache; import org.hibernate.engine.query.spi.QueryPlanCache;
import org.hibernate.engine.query.spi.sql.NativeSQLQuerySpecification; import org.hibernate.engine.query.spi.sql.NativeSQLQuerySpecification;
import org.hibernate.engine.spi.NamedQueryDefinition; import org.hibernate.engine.spi.NamedQueryDefinition;
import org.hibernate.engine.spi.NamedSQLQueryDefinition; import org.hibernate.engine.spi.NamedSQLQueryDefinition;
import org.hibernate.internal.util.collections.CollectionHelper; import org.hibernate.internal.util.collections.CollectionHelper;
import org.hibernate.procedure.ProcedureCallMemento;
/** /**
* @author Steve Ebersole * @author Steve Ebersole
@ -46,14 +46,17 @@ import org.hibernate.internal.util.collections.CollectionHelper;
public class NamedQueryRepository { public class NamedQueryRepository {
private static final Logger log = Logger.getLogger( NamedQueryRepository.class ); private static final Logger log = Logger.getLogger( NamedQueryRepository.class );
private final Map<String, ResultSetMappingDefinition> namedSqlResultSetMappingMap;
private volatile Map<String, NamedQueryDefinition> namedQueryDefinitionMap; private volatile Map<String, NamedQueryDefinition> namedQueryDefinitionMap;
private volatile Map<String, NamedSQLQueryDefinition> namedSqlQueryDefinitionMap; private volatile Map<String, NamedSQLQueryDefinition> namedSqlQueryDefinitionMap;
private final Map<String, ResultSetMappingDefinition> namedSqlResultSetMappingMap; private volatile Map<String, ProcedureCallMemento> procedureCallMementoMap;
public NamedQueryRepository( public NamedQueryRepository(
Iterable<NamedQueryDefinition> namedQueryDefinitions, Iterable<NamedQueryDefinition> namedQueryDefinitions,
Iterable<NamedSQLQueryDefinition> namedSqlQueryDefinitions, Iterable<NamedSQLQueryDefinition> namedSqlQueryDefinitions,
Iterable<ResultSetMappingDefinition> namedSqlResultSetMappings) { Iterable<ResultSetMappingDefinition> namedSqlResultSetMappings,
List<ProcedureCallMemento> namedProcedureCalls) {
final HashMap<String, NamedQueryDefinition> namedQueryDefinitionMap = new HashMap<String, NamedQueryDefinition>(); final HashMap<String, NamedQueryDefinition> namedQueryDefinitionMap = new HashMap<String, NamedQueryDefinition>();
for ( NamedQueryDefinition namedQueryDefinition : namedQueryDefinitions ) { for ( NamedQueryDefinition namedQueryDefinition : namedQueryDefinitions ) {
namedQueryDefinitionMap.put( namedQueryDefinition.getName(), namedQueryDefinition ); namedQueryDefinitionMap.put( namedQueryDefinition.getName(), namedQueryDefinition );
@ -83,6 +86,10 @@ public class NamedQueryRepository {
return namedSqlQueryDefinitionMap.get( queryName ); return namedSqlQueryDefinitionMap.get( queryName );
} }
public ProcedureCallMemento getNamedProcedureCallMemento(String name) {
return procedureCallMementoMap.get( name );
}
public ResultSetMappingDefinition getResultSetMappingDefinition(String mappingName) { public ResultSetMappingDefinition getResultSetMappingDefinition(String mappingName) {
return namedSqlResultSetMappingMap.get( mappingName ); return namedSqlResultSetMappingMap.get( mappingName );
} }
@ -127,6 +134,20 @@ public class NamedQueryRepository {
this.namedSqlQueryDefinitionMap = Collections.unmodifiableMap( copy ); this.namedSqlQueryDefinitionMap = Collections.unmodifiableMap( copy );
} }
public synchronized void registerNamedProcedureCallMemento(String name, ProcedureCallMemento memento) {
final Map<String, ProcedureCallMemento> copy = CollectionHelper.makeCopy( procedureCallMementoMap );
final ProcedureCallMemento previous = copy.put( name, memento );
if ( previous != null ) {
log.debugf(
"registering named procedure call definition [%s] overriding previously registered definition [%s]",
name,
previous
);
}
this.procedureCallMementoMap = Collections.unmodifiableMap( copy );
}
public Map<String,HibernateException> checkNamedQueries(QueryPlanCache queryPlanCache) { public Map<String,HibernateException> checkNamedQueries(QueryPlanCache queryPlanCache) {
Map<String,HibernateException> errors = new HashMap<String,HibernateException>(); Map<String,HibernateException> errors = new HashMap<String,HibernateException>();

View File

@ -35,6 +35,7 @@ import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Properties; import java.util.Properties;
import java.util.Set; import java.util.Set;
@ -85,6 +86,7 @@ import org.hibernate.cfg.Configuration;
import org.hibernate.cfg.Environment; import org.hibernate.cfg.Environment;
import org.hibernate.cfg.Settings; import org.hibernate.cfg.Settings;
import org.hibernate.cfg.SettingsFactory; import org.hibernate.cfg.SettingsFactory;
import org.hibernate.cfg.annotations.NamedProcedureCallDefinition;
import org.hibernate.context.internal.JTASessionContext; import org.hibernate.context.internal.JTASessionContext;
import org.hibernate.context.internal.ManagedSessionContext; import org.hibernate.context.internal.ManagedSessionContext;
import org.hibernate.context.internal.ThreadLocalSessionContext; import org.hibernate.context.internal.ThreadLocalSessionContext;
@ -138,6 +140,7 @@ import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.persister.entity.Loadable; import org.hibernate.persister.entity.Loadable;
import org.hibernate.persister.entity.Queryable; import org.hibernate.persister.entity.Queryable;
import org.hibernate.persister.spi.PersisterFactory; import org.hibernate.persister.spi.PersisterFactory;
import org.hibernate.procedure.ProcedureCallMemento;
import org.hibernate.proxy.EntityNotFoundDelegate; import org.hibernate.proxy.EntityNotFoundDelegate;
import org.hibernate.service.ServiceRegistry; import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.spi.ServiceRegistryImplementor; import org.hibernate.service.spi.ServiceRegistryImplementor;
@ -499,7 +502,8 @@ public final class SessionFactoryImpl
this.namedQueryRepository = new NamedQueryRepository( this.namedQueryRepository = new NamedQueryRepository(
cfg.getNamedQueries().values(), cfg.getNamedQueries().values(),
cfg.getNamedSQLQueries().values(), cfg.getNamedSQLQueries().values(),
cfg.getSqlResultSetMappings().values() cfg.getSqlResultSetMappings().values(),
toProcedureCallMementos( cfg.getNamedProcedureCallMap(), cfg.getSqlResultSetMappings() )
); );
imports = new HashMap<String,String>( cfg.getImports() ); imports = new HashMap<String,String>( cfg.getImports() );
@ -630,6 +634,18 @@ public final class SessionFactoryImpl
} }
} }
private List<ProcedureCallMemento> toProcedureCallMementos(
Map<String, NamedProcedureCallDefinition> definitions,
Map<String, ResultSetMappingDefinition> resultSetMappingMap) {
final List<ProcedureCallMemento> rtn = new ArrayList<ProcedureCallMemento>();
if ( definitions != null ) {
for ( NamedProcedureCallDefinition definition : definitions.values() ) {
rtn.add( definition.toMemento( this, resultSetMappingMap ) );
}
}
return rtn;
}
private JdbcConnectionAccess buildLocalConnectionAccess() { private JdbcConnectionAccess buildLocalConnectionAccess() {
return new JdbcConnectionAccess() { return new JdbcConnectionAccess() {
@Override @Override
@ -920,7 +936,8 @@ public final class SessionFactoryImpl
namedQueryRepository = new NamedQueryRepository( namedQueryRepository = new NamedQueryRepository(
metadata.getNamedQueryDefinitions(), metadata.getNamedQueryDefinitions(),
metadata.getNamedNativeQueryDefinitions(), metadata.getNamedNativeQueryDefinitions(),
metadata.getResultSetMappingDefinitions().values() metadata.getResultSetMappingDefinitions().values(),
null
); );
imports = new HashMap<String,String>(); imports = new HashMap<String,String>();

View File

@ -30,7 +30,6 @@ import java.util.Arrays;
import java.util.BitSet; import java.util.BitSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.StringTokenizer; import java.util.StringTokenizer;
import java.util.UUID;
import org.hibernate.dialect.Dialect; import org.hibernate.dialect.Dialect;
import org.hibernate.internal.util.collections.ArrayHelper; import org.hibernate.internal.util.collections.ArrayHelper;
@ -763,18 +762,4 @@ public final class StringHelper {
public static String[] toArrayElement(String s) { public static String[] toArrayElement(String s) {
return ( s == null || s.length() == 0 ) ? new String[0] : new String[] { s }; return ( s == null || s.length() == 0 ) ? new String[0] : new String[] { s };
} }
// Oracle restricts identifier lengths to 30. Rather than tie this to
// Dialect, simply restrict randomly-generated constrain names across
// the board.
private static final int MAX_NAME_LENGTH = 30;
public static String randomFixedLengthHex(String prefix) {
int length = MAX_NAME_LENGTH - prefix.length();
String s = UUID.randomUUID().toString();
s = s.replace( "-", "" );
if (s.length() > length) {
s = s.substring( 0, length );
}
return prefix + s;
}
} }

View File

@ -28,6 +28,7 @@ import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
@ -132,6 +133,17 @@ public final class CollectionHelper {
return new ArrayList<T>( anticipatedSize ); return new ArrayList<T>( anticipatedSize );
} }
public static <T> Set<T> makeCopy(Set<T> source) {
if ( source == null ) {
return null;
}
final int size = source.size();
final Set<T> copy = new HashSet<T>( size + 1 );
copy.addAll( source );
return copy;
}
public static boolean isEmpty(Collection collection) { public static boolean isEmpty(Collection collection) {
return collection == null || collection.isEmpty(); return collection == null || collection.isEmpty();
} }

View File

@ -76,7 +76,7 @@ public class JoinedIterator<T> implements Iterator<T> {
protected void updateCurrentIterator() { protected void updateCurrentIterator() {
if ( currentIterator == null ) { if ( currentIterator == null ) {
if( wrappedIterators.length == 0 ) { if( wrappedIterators.length == 0 ) {
currentIterator = Collections.emptyIterator(); currentIterator = Collections.<T>emptyList().iterator();
} }
else { else {
currentIterator = wrappedIterators[0]; currentIterator = wrappedIterators[0];

View File

@ -38,8 +38,8 @@ import org.hibernate.type.Type;
*/ */
class ComponentCollectionCriteriaInfoProvider implements CriteriaInfoProvider { class ComponentCollectionCriteriaInfoProvider implements CriteriaInfoProvider {
QueryableCollection persister; private final QueryableCollection persister;
Map /* <String,Type> */ subTypes = new HashMap /* <String,Type> */(); private final Map<String, Type> subTypes = new HashMap<String, Type>();
ComponentCollectionCriteriaInfoProvider(QueryableCollection persister) { ComponentCollectionCriteriaInfoProvider(QueryableCollection persister) {
this.persister = persister; this.persister = persister;
@ -57,28 +57,31 @@ class ComponentCollectionCriteriaInfoProvider implements CriteriaInfoProvider {
} }
@Override
public String getName() { public String getName() {
return persister.getRole(); return persister.getRole();
} }
@Override
public Serializable[] getSpaces() { public Serializable[] getSpaces() {
return persister.getCollectionSpaces(); return persister.getCollectionSpaces();
} }
@Override
public PropertyMapping getPropertyMapping() { public PropertyMapping getPropertyMapping() {
return persister; return persister;
} }
@Override
public Type getType(String relativePath) { public Type getType(String relativePath) {
// TODO: can a component have a nested component? then we may need to do something more here... // TODO: can a component have a nested component? then we may need to do something more here...
if (relativePath.indexOf('.') >= 0) if ( relativePath.indexOf( '.' ) >= 0 ) {
throw new IllegalArgumentException( "dotted paths not handled (yet?!) for collection-of-component" ); throw new IllegalArgumentException( "dotted paths not handled (yet?!) for collection-of-component" );
}
Type type = (Type)subTypes.get(relativePath); Type type = subTypes.get( relativePath );
if ( type == null ) {
if (type == null)
throw new IllegalArgumentException( "property " + relativePath + " not found in component of collection " + getName() ); throw new IllegalArgumentException( "property " + relativePath + " not found in component of collection " + getName() );
}
return type; return type;
} }
} }

View File

@ -66,9 +66,9 @@ public class CriteriaJoinWalker extends AbstractEntityJoinWalker {
//the user visible aliases, which are unknown to the superclass, //the user visible aliases, which are unknown to the superclass,
//these are not the actual "physical" SQL aliases //these are not the actual "physical" SQL aliases
private final String[] userAliases; private final String[] userAliases;
private final List userAliasList = new ArrayList(); private final List<String> userAliasList = new ArrayList<String>();
private final List resultTypeList = new ArrayList(); private final List<Type> resultTypeList = new ArrayList<Type>();
private final List includeInResultRowList = new ArrayList(); private final List<Boolean> includeInResultRowList = new ArrayList<Boolean>();
public Type[] getResultTypes() { public Type[] getResultTypes() {
return resultTypes; return resultTypes;
@ -130,7 +130,7 @@ public class CriteriaJoinWalker extends AbstractEntityJoinWalker {
includeInResultRow = ArrayHelper.toBooleanArray( includeInResultRowList ); includeInResultRow = ArrayHelper.toBooleanArray( includeInResultRowList );
} }
} }
@Override
protected JoinType getJoinType( protected JoinType getJoinType(
OuterJoinLoadable persister, OuterJoinLoadable persister,
final PropertyPath path, final PropertyPath path,
@ -207,7 +207,7 @@ public class CriteriaJoinWalker extends AbstractEntityJoinWalker {
} }
return resolvedJoinType; return resolvedJoinType;
} }
@Override
protected JoinType getJoinType( protected JoinType getJoinType(
AssociationType associationType, AssociationType associationType,
FetchMode config, FetchMode config,
@ -239,11 +239,12 @@ public class CriteriaJoinWalker extends AbstractEntityJoinWalker {
* Use the discriminator, to narrow the select to instances * Use the discriminator, to narrow the select to instances
* of the queried subclass, also applying any filters. * of the queried subclass, also applying any filters.
*/ */
@Override
protected String getWhereFragment() throws MappingException { protected String getWhereFragment() throws MappingException {
return super.getWhereFragment() + return super.getWhereFragment() +
( (Queryable) getPersister() ).filterFragment( getAlias(), getLoadQueryInfluencers().getEnabledFilters() ); ( (Queryable) getPersister() ).filterFragment( getAlias(), getLoadQueryInfluencers().getEnabledFilters() );
} }
@Override
protected String generateTableAlias(int n, PropertyPath path, Joinable joinable) { protected String generateTableAlias(int n, PropertyPath path, Joinable joinable) {
// TODO: deal with side-effects (changes to includeInResultRowList, userAliasList, resultTypeList)!!! // TODO: deal with side-effects (changes to includeInResultRowList, userAliasList, resultTypeList)!!!
@ -288,7 +289,7 @@ public class CriteriaJoinWalker extends AbstractEntityJoinWalker {
return sqlAlias; return sqlAlias;
} }
@Override
protected String generateRootAlias(String tableName) { protected String generateRootAlias(String tableName) {
return CriteriaQueryTranslator.ROOT_SQL_ALIAS; return CriteriaQueryTranslator.ROOT_SQL_ALIAS;
} }
@ -296,15 +297,15 @@ public class CriteriaJoinWalker extends AbstractEntityJoinWalker {
public Set getQuerySpaces() { public Set getQuerySpaces() {
return querySpaces; return querySpaces;
} }
@Override
public String getComment() { public String getComment() {
return "criteria query"; return "criteria query";
} }
@Override
protected String getWithClause(PropertyPath path) { protected String getWithClause(PropertyPath path) {
return translator.getWithClause( path.getFullPath() ); return translator.getWithClause( path.getFullPath() );
} }
@Override
protected boolean hasRestriction(PropertyPath path) { protected boolean hasRestriction(PropertyPath path) {
return translator.hasRestriction( path.getFullPath() ); return translator.hasRestriction( path.getFullPath() );
} }

View File

@ -125,23 +125,23 @@ public class CriteriaLoader extends OuterJoinLoader {
return list( session, translator.getQueryParameters(), querySpaces, resultTypes ); return list( session, translator.getQueryParameters(), querySpaces, resultTypes );
} }
@Override
protected String[] getResultRowAliases() { protected String[] getResultRowAliases() {
return userAliases; return userAliases;
} }
@Override
protected ResultTransformer resolveResultTransformer(ResultTransformer resultTransformer) { protected ResultTransformer resolveResultTransformer(ResultTransformer resultTransformer) {
return translator.getRootCriteria().getResultTransformer(); return translator.getRootCriteria().getResultTransformer();
} }
@Override
protected boolean areResultSetRowsTransformedImmediately() { protected boolean areResultSetRowsTransformedImmediately() {
return true; return true;
} }
@Override
protected boolean[] includeInResultRow() { protected boolean[] includeInResultRow() {
return includeInResultRow; return includeInResultRow;
} }
@Override
protected Object getResultColumnOrRow(Object[] row, ResultTransformer transformer, ResultSet rs, SessionImplementor session) protected Object getResultColumnOrRow(Object[] row, ResultTransformer transformer, ResultSet rs, SessionImplementor session)
throws SQLException, HibernateException { throws SQLException, HibernateException {
return resolveResultTransformer( transformer ).transformTuple( return resolveResultTransformer( transformer ).transformTuple(
@ -149,7 +149,7 @@ public class CriteriaLoader extends OuterJoinLoader {
getResultRowAliases() getResultRowAliases()
); );
} }
@Override
protected Object[] getResultRow(Object[] row, ResultSet rs, SessionImplementor session) protected Object[] getResultRow(Object[] row, ResultSet rs, SessionImplementor session)
throws SQLException, HibernateException { throws SQLException, HibernateException {
final Object[] result; final Object[] result;
@ -249,7 +249,7 @@ public class CriteriaLoader extends OuterJoinLoader {
} }
@Override
protected LockMode determineFollowOnLockMode(LockOptions lockOptions) { protected LockMode determineFollowOnLockMode(LockOptions lockOptions) {
final LockMode lockModeToUse = lockOptions.findGreatestLockMode(); final LockMode lockModeToUse = lockOptions.findGreatestLockMode();
@ -260,7 +260,7 @@ public class CriteriaLoader extends OuterJoinLoader {
return lockModeToUse; return lockModeToUse;
} }
@Override
protected LockMode[] getLockModes(LockOptions lockOptions) { protected LockMode[] getLockModes(LockOptions lockOptions) {
final String[] entityAliases = getAliases(); final String[] entityAliases = getAliases();
if ( entityAliases == null ) { if ( entityAliases == null ) {
@ -274,15 +274,15 @@ public class CriteriaLoader extends OuterJoinLoader {
} }
return lockModesArray; return lockModesArray;
} }
@Override
protected boolean isSubselectLoadingEnabled() { protected boolean isSubselectLoadingEnabled() {
return hasSubselectLoadableCollections(); return hasSubselectLoadableCollections();
} }
@Override
protected List getResultList(List results, ResultTransformer resultTransformer) { protected List getResultList(List results, ResultTransformer resultTransformer) {
return resolveResultTransformer( resultTransformer ).transformList( results ); return resolveResultTransformer( resultTransformer ).transformList( results );
} }
@Override
protected String getQueryIdentifier() { protected String getQueryIdentifier() {
return "[CRITERIA] " + getSQLString(); return "[CRITERIA] " + getSQLString();
} }

View File

@ -23,6 +23,7 @@
* *
*/ */
package org.hibernate.loader.criteria; package org.hibernate.loader.criteria;
import java.io.Serializable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
@ -74,15 +75,14 @@ public class CriteriaQueryTranslator implements CriteriaQuery {
private final CriteriaImpl rootCriteria; private final CriteriaImpl rootCriteria;
private final String rootEntityName; private final String rootEntityName;
private final String rootSQLAlias; private final String rootSQLAlias;
private int aliasCount = 0;
private final Map /* <Criteria, CriteriaInfoProvider> */ criteriaInfoMap = new LinkedHashMap(); private final Map<Criteria, CriteriaInfoProvider> criteriaInfoMap = new LinkedHashMap<Criteria, CriteriaInfoProvider>();
private final Map /* <String, CriteriaInfoProvider> */ nameCriteriaInfoMap = new LinkedHashMap(); private final Map<String, CriteriaInfoProvider> nameCriteriaInfoMap = new LinkedHashMap<String, CriteriaInfoProvider>();
private final Map criteriaSQLAliasMap = new HashMap(); private final Map<Criteria, String> criteriaSQLAliasMap = new HashMap<Criteria, String>();
private final Map aliasCriteriaMap = new HashMap(); private final Map<String, Criteria> aliasCriteriaMap = new HashMap<String, Criteria>();
private final Map associationPathCriteriaMap = new LinkedHashMap(); private final Map<String, Criteria> associationPathCriteriaMap = new LinkedHashMap<String, Criteria>();
private final Map<String, JoinType> associationPathJoinTypesMap = new LinkedHashMap<String,JoinType>(); private final Map<String, JoinType> associationPathJoinTypesMap = new LinkedHashMap<String,JoinType>();
private final Map withClauseMap = new HashMap(); private final Map<String, Criterion> withClauseMap = new HashMap<String, Criterion>();
private final SessionFactoryImplementor sessionFactory; private final SessionFactoryImplementor sessionFactory;
private final SessionFactoryHelper helper; private final SessionFactoryHelper helper;
@ -112,8 +112,9 @@ public class CriteriaQueryTranslator implements CriteriaQuery {
createCriteriaEntityNameMap(); createCriteriaEntityNameMap();
createCriteriaSQLAliasMap(); createCriteriaSQLAliasMap();
} }
@Override
public String generateSQLAlias() { public String generateSQLAlias() {
int aliasCount = 0;
return StringHelper.generateAlias( Criteria.ROOT_ALIAS, aliasCount ) + '_'; return StringHelper.generateAlias( Criteria.ROOT_ALIAS, aliasCount ) + '_';
} }
@ -122,7 +123,7 @@ public class CriteriaQueryTranslator implements CriteriaQuery {
} }
private Criteria getAliasedCriteria(String alias) { private Criteria getAliasedCriteria(String alias) {
return ( Criteria ) aliasCriteriaMap.get( alias ); return aliasCriteriaMap.get( alias );
} }
public boolean isJoin(String path) { public boolean isJoin(String path) {
@ -135,14 +136,12 @@ public class CriteriaQueryTranslator implements CriteriaQuery {
} }
public Criteria getCriteria(String path) { public Criteria getCriteria(String path) {
return ( Criteria ) associationPathCriteriaMap.get( path ); return associationPathCriteriaMap.get( path );
} }
public Set getQuerySpaces() { public Set<Serializable> getQuerySpaces() {
Set result = new HashSet(); Set<Serializable> result = new HashSet<Serializable>();
Iterator iter = criteriaInfoMap.values().iterator(); for ( CriteriaInfoProvider info : criteriaInfoMap.values() ) {
while ( iter.hasNext() ) {
CriteriaInfoProvider info = ( CriteriaInfoProvider )iter.next();
result.addAll( Arrays.asList( info.getSpaces() ) ); result.addAll( Arrays.asList( info.getSpaces() ) );
} }
return result; return result;
@ -150,9 +149,9 @@ public class CriteriaQueryTranslator implements CriteriaQuery {
private void createAliasCriteriaMap() { private void createAliasCriteriaMap() {
aliasCriteriaMap.put( rootCriteria.getAlias(), rootCriteria ); aliasCriteriaMap.put( rootCriteria.getAlias(), rootCriteria );
Iterator iter = rootCriteria.iterateSubcriteria(); Iterator<CriteriaImpl.Subcriteria> iter = rootCriteria.iterateSubcriteria();
while ( iter.hasNext() ) { while ( iter.hasNext() ) {
Criteria subcriteria = ( Criteria ) iter.next(); Criteria subcriteria = iter.next();
if ( subcriteria.getAlias() != null ) { if ( subcriteria.getAlias() != null ) {
Object old = aliasCriteriaMap.put( subcriteria.getAlias(), subcriteria ); Object old = aliasCriteriaMap.put( subcriteria.getAlias(), subcriteria );
if ( old != null ) { if ( old != null ) {
@ -163,9 +162,9 @@ public class CriteriaQueryTranslator implements CriteriaQuery {
} }
private void createAssociationPathCriteriaMap() { private void createAssociationPathCriteriaMap() {
Iterator iter = rootCriteria.iterateSubcriteria(); final Iterator<CriteriaImpl.Subcriteria> iter = rootCriteria.iterateSubcriteria();
while ( iter.hasNext() ) { while ( iter.hasNext() ) {
CriteriaImpl.Subcriteria crit = ( CriteriaImpl.Subcriteria ) iter.next(); CriteriaImpl.Subcriteria crit = iter.next();
String wholeAssociationPath = getWholeAssociationPath( crit ); String wholeAssociationPath = getWholeAssociationPath( crit );
Object old = associationPathCriteriaMap.put( wholeAssociationPath, crit ); Object old = associationPathCriteriaMap.put( wholeAssociationPath, crit );
if ( old != null ) { if ( old != null ) {
@ -197,7 +196,7 @@ public class CriteriaQueryTranslator implements CriteriaQuery {
// and the qualifier is not the alias of this criteria // and the qualifier is not the alias of this criteria
// -> check to see if we belong to some criteria other // -> check to see if we belong to some criteria other
// than the one that created us // than the one that created us
parent = ( Criteria ) aliasCriteriaMap.get( testAlias ); parent = aliasCriteriaMap.get( testAlias );
} }
} }
if ( parent == null ) { if ( parent == null ) {
@ -224,16 +223,10 @@ public class CriteriaQueryTranslator implements CriteriaQuery {
criteriaInfoMap.put( rootCriteria, rootProvider); criteriaInfoMap.put( rootCriteria, rootProvider);
nameCriteriaInfoMap.put ( rootProvider.getName(), rootProvider ); nameCriteriaInfoMap.put ( rootProvider.getName(), rootProvider );
Iterator iter = associationPathCriteriaMap.entrySet().iterator(); for(final String key : associationPathCriteriaMap.keySet() ){
while ( iter.hasNext() ) { Criteria value = associationPathCriteriaMap.get( key );
Map.Entry me = ( Map.Entry ) iter.next(); CriteriaInfoProvider info = getPathInfo( key );
CriteriaInfoProvider info = getPathInfo((String)me.getKey()); criteriaInfoMap.put( value, info );
criteriaInfoMap.put(
me.getValue(), //the criteria instance
info
);
nameCriteriaInfoMap.put( info.getName(), info ); nameCriteriaInfoMap.put( info.getName(), info );
} }
} }
@ -244,7 +237,7 @@ public class CriteriaQueryTranslator implements CriteriaQuery {
String componentPath = ""; String componentPath = "";
// start with the 'rootProvider' // start with the 'rootProvider'
CriteriaInfoProvider provider = ( CriteriaInfoProvider )nameCriteriaInfoMap.get( rootEntityName ); CriteriaInfoProvider provider = nameCriteriaInfoMap.get( rootEntityName );
while ( tokens.hasMoreTokens() ) { while ( tokens.hasMoreTokens() ) {
componentPath += tokens.nextToken(); componentPath += tokens.nextToken();
@ -290,16 +283,15 @@ public class CriteriaQueryTranslator implements CriteriaQuery {
private void createCriteriaSQLAliasMap() { private void createCriteriaSQLAliasMap() {
int i = 0; int i = 0;
Iterator criteriaIterator = criteriaInfoMap.entrySet().iterator(); for(final Criteria crit : criteriaInfoMap.keySet()){
while ( criteriaIterator.hasNext() ) { CriteriaInfoProvider value = criteriaInfoMap.get( crit );
Map.Entry me = ( Map.Entry ) criteriaIterator.next();
Criteria crit = ( Criteria ) me.getKey();
String alias = crit.getAlias(); String alias = crit.getAlias();
if ( alias == null ) { if ( alias == null ) {
alias = (( CriteriaInfoProvider ) me.getValue()).getName(); // the entity name alias = value.getName(); // the entity name
} }
criteriaSQLAliasMap.put( crit, StringHelper.generateAlias( alias, i++ ) ); criteriaSQLAliasMap.put( crit, StringHelper.generateAlias( alias, i++ ) );
} }
criteriaSQLAliasMap.put( rootCriteria, rootSQLAlias ); criteriaSQLAliasMap.put( rootCriteria, rootSQLAlias );
} }
@ -314,18 +306,16 @@ public class CriteriaQueryTranslator implements CriteriaQuery {
selection.setMaxRows( rootCriteria.getMaxResults() ); selection.setMaxRows( rootCriteria.getMaxResults() );
selection.setTimeout( rootCriteria.getTimeout() ); selection.setTimeout( rootCriteria.getTimeout() );
selection.setFetchSize( rootCriteria.getFetchSize() ); selection.setFetchSize( rootCriteria.getFetchSize() );
final Map<String, LockMode> lockModeMap = rootCriteria.getLockModes();
Iterator iter = rootCriteria.getLockModes().entrySet().iterator(); for ( final String key : lockModeMap.keySet() ) {
while ( iter.hasNext() ) { final Criteria subcriteria = getAliasedCriteria( key );
Map.Entry me = ( Map.Entry ) iter.next(); lockOptions.setAliasSpecificLockMode( getSQLAlias( subcriteria ), lockModeMap.get( key ) );
final Criteria subcriteria = getAliasedCriteria( ( String ) me.getKey() );
lockOptions.setAliasSpecificLockMode( getSQLAlias( subcriteria ), (LockMode)me.getValue() );
} }
List values = new ArrayList(); final List<Object> values = new ArrayList<Object>();
List types = new ArrayList(); final List<Type> types = new ArrayList<Type>();
iter = rootCriteria.iterateSubcriteria(); final Iterator<CriteriaImpl.Subcriteria> subcriteriaIterator = rootCriteria.iterateSubcriteria();
while ( iter.hasNext() ) { while ( subcriteriaIterator.hasNext() ) {
CriteriaImpl.Subcriteria subcriteria = ( CriteriaImpl.Subcriteria ) iter.next(); CriteriaImpl.Subcriteria subcriteria = subcriteriaIterator.next();
LockMode lm = subcriteria.getLockMode(); LockMode lm = subcriteria.getLockMode();
if ( lm != null ) { if ( lm != null ) {
lockOptions.setAliasSpecificLockMode( getSQLAlias( subcriteria ), lm ); lockOptions.setAliasSpecificLockMode( getSQLAlias( subcriteria ), lm );
@ -333,9 +323,9 @@ public class CriteriaQueryTranslator implements CriteriaQuery {
if ( subcriteria.getWithClause() != null ) if ( subcriteria.getWithClause() != null )
{ {
TypedValue[] tv = subcriteria.getWithClause().getTypedValues( subcriteria, this ); TypedValue[] tv = subcriteria.getWithClause().getTypedValues( subcriteria, this );
for ( int i = 0; i < tv.length; i++ ) { for ( TypedValue aTv : tv ) {
values.add( tv[i].getValue() ); values.add( aTv.getValue() );
types.add( tv[i].getType() ); types.add( aTv.getType() );
} }
} }
} }
@ -343,13 +333,13 @@ public class CriteriaQueryTranslator implements CriteriaQuery {
// Type and value gathering for the WHERE clause needs to come AFTER lock mode gathering, // Type and value gathering for the WHERE clause needs to come AFTER lock mode gathering,
// because the lock mode gathering loop now contains join clauses which can contain // because the lock mode gathering loop now contains join clauses which can contain
// parameter bindings (as in the HQL WITH clause). // parameter bindings (as in the HQL WITH clause).
iter = rootCriteria.iterateExpressionEntries(); Iterator<CriteriaImpl.CriterionEntry> iter = rootCriteria.iterateExpressionEntries();
while ( iter.hasNext() ) { while ( iter.hasNext() ) {
CriteriaImpl.CriterionEntry ce = ( CriteriaImpl.CriterionEntry ) iter.next(); CriteriaImpl.CriterionEntry ce = iter.next();
TypedValue[] tv = ce.getCriterion().getTypedValues( ce.getCriteria(), this ); TypedValue[] tv = ce.getCriterion().getTypedValues( ce.getCriteria(), this );
for ( int i = 0; i < tv.length; i++ ) { for ( TypedValue aTv : tv ) {
values.add( tv[i].getValue() ); values.add( aTv.getValue() );
types.add( tv[i].getType() ); types.add( aTv.getType() );
} }
} }
@ -361,7 +351,7 @@ public class CriteriaQueryTranslator implements CriteriaQuery {
lockOptions, lockOptions,
selection, selection,
rootCriteria.isReadOnlyInitialized(), rootCriteria.isReadOnlyInitialized(),
( rootCriteria.isReadOnlyInitialized() ? rootCriteria.isReadOnly() : false ), ( rootCriteria.isReadOnlyInitialized() && rootCriteria.isReadOnly() ),
rootCriteria.getCacheable(), rootCriteria.getCacheable(),
rootCriteria.getCacheRegion(), rootCriteria.getCacheRegion(),
rootCriteria.getComment(), rootCriteria.getComment(),
@ -413,9 +403,9 @@ public class CriteriaQueryTranslator implements CriteriaQuery {
public String getWhereCondition() { public String getWhereCondition() {
StringBuilder condition = new StringBuilder( 30 ); StringBuilder condition = new StringBuilder( 30 );
Iterator criterionIterator = rootCriteria.iterateExpressionEntries(); Iterator<CriteriaImpl.CriterionEntry> criterionIterator = rootCriteria.iterateExpressionEntries();
while ( criterionIterator.hasNext() ) { while ( criterionIterator.hasNext() ) {
CriteriaImpl.CriterionEntry entry = ( CriteriaImpl.CriterionEntry ) criterionIterator.next(); CriteriaImpl.CriterionEntry entry = criterionIterator.next();
String sqlString = entry.getCriterion().toSqlString( entry.getCriteria(), this ); String sqlString = entry.getCriterion().toSqlString( entry.getCriteria(), this );
condition.append( sqlString ); condition.append( sqlString );
if ( criterionIterator.hasNext() ) { if ( criterionIterator.hasNext() ) {
@ -427,9 +417,9 @@ public class CriteriaQueryTranslator implements CriteriaQuery {
public String getOrderBy() { public String getOrderBy() {
StringBuilder orderBy = new StringBuilder( 30 ); StringBuilder orderBy = new StringBuilder( 30 );
Iterator criterionIterator = rootCriteria.iterateOrderings(); Iterator<CriteriaImpl.OrderEntry> criterionIterator = rootCriteria.iterateOrderings();
while ( criterionIterator.hasNext() ) { while ( criterionIterator.hasNext() ) {
CriteriaImpl.OrderEntry oe = ( CriteriaImpl.OrderEntry ) criterionIterator.next(); CriteriaImpl.OrderEntry oe = criterionIterator.next();
orderBy.append( oe.getOrder().toSqlString( oe.getCriteria(), this ) ); orderBy.append( oe.getOrder().toSqlString( oe.getCriteria(), this ) );
if ( criterionIterator.hasNext() ) { if ( criterionIterator.hasNext() ) {
orderBy.append( ", " ); orderBy.append( ", " );
@ -437,20 +427,20 @@ public class CriteriaQueryTranslator implements CriteriaQuery {
} }
return orderBy.toString(); return orderBy.toString();
} }
@Override
public SessionFactoryImplementor getFactory() { public SessionFactoryImplementor getFactory() {
return sessionFactory; return sessionFactory;
} }
@Override
public String getSQLAlias(Criteria criteria) { public String getSQLAlias(Criteria criteria) {
return ( String ) criteriaSQLAliasMap.get( criteria ); return criteriaSQLAliasMap.get( criteria );
} }
@Override
public String getEntityName(Criteria criteria) { public String getEntityName(Criteria criteria) {
final CriteriaInfoProvider infoProvider = ( CriteriaInfoProvider ) criteriaInfoMap.get( criteria ); final CriteriaInfoProvider infoProvider = criteriaInfoMap.get( criteria );
return infoProvider != null ? infoProvider.getName() : null; return infoProvider != null ? infoProvider.getName() : null;
} }
@Override
public String getColumn(Criteria criteria, String propertyName) { public String getColumn(Criteria criteria, String propertyName) {
String[] cols = getColumns( propertyName, criteria ); String[] cols = getColumns( propertyName, criteria );
if ( cols.length != 1 ) { if ( cols.length != 1 ) {
@ -463,6 +453,7 @@ public class CriteriaQueryTranslator implements CriteriaQuery {
* Get the names of the columns constrained * Get the names of the columns constrained
* by this criterion. * by this criterion.
*/ */
@Override
public String[] getColumnsUsingProjection( public String[] getColumnsUsingProjection(
Criteria subcriteria, Criteria subcriteria,
String propertyName) throws HibernateException { String propertyName) throws HibernateException {
@ -497,25 +488,22 @@ public class CriteriaQueryTranslator implements CriteriaQuery {
return projectionColumns; return projectionColumns;
} }
} }
@Override
public String[] getIdentifierColumns(Criteria criteria) { public String[] getIdentifierColumns(Criteria criteria) {
String[] idcols = String[] idcols =
( ( Loadable ) getPropertyMapping( getEntityName( criteria ) ) ).getIdentifierColumnNames(); ( ( Loadable ) getPropertyMapping( getEntityName( criteria ) ) ).getIdentifierColumnNames();
return StringHelper.qualify( getSQLAlias( criteria ), idcols ); return StringHelper.qualify( getSQLAlias( criteria ), idcols );
} }
@Override
public Type getIdentifierType(Criteria criteria) { public Type getIdentifierType(Criteria criteria) {
return ( ( Loadable ) getPropertyMapping( getEntityName( criteria ) ) ).getIdentifierType(); return ( ( Loadable ) getPropertyMapping( getEntityName( criteria ) ) ).getIdentifierType();
} }
@Override
public TypedValue getTypedIdentifierValue(Criteria criteria, Object value) { public TypedValue getTypedIdentifierValue(Criteria criteria, Object value) {
final Loadable loadable = ( Loadable ) getPropertyMapping( getEntityName( criteria ) ); final Loadable loadable = ( Loadable ) getPropertyMapping( getEntityName( criteria ) );
return new TypedValue( return new TypedValue( loadable.getIdentifierType(), value );
loadable.getIdentifierType(),
value
);
} }
@Override
public String[] getColumns( public String[] getColumns(
String propertyName, String propertyName,
Criteria subcriteria) throws HibernateException { Criteria subcriteria) throws HibernateException {
@ -531,6 +519,7 @@ public class CriteriaQueryTranslator implements CriteriaQuery {
* property path is not found in subcriteria, try the "outer" query. * property path is not found in subcriteria, try the "outer" query.
* Projection aliases are ignored. * Projection aliases are ignored.
*/ */
@Override
public String[] findColumns(String propertyName, Criteria subcriteria ) public String[] findColumns(String propertyName, Criteria subcriteria )
throws HibernateException { throws HibernateException {
try { try {
@ -546,7 +535,7 @@ public class CriteriaQueryTranslator implements CriteriaQuery {
} }
} }
} }
@Override
public Type getTypeUsingProjection(Criteria subcriteria, String propertyName) public Type getTypeUsingProjection(Criteria subcriteria, String propertyName)
throws HibernateException { throws HibernateException {
@ -580,7 +569,7 @@ public class CriteriaQueryTranslator implements CriteriaQuery {
return projectionTypes[0]; return projectionTypes[0];
} }
} }
@Override
public Type getType(Criteria subcriteria, String propertyName) public Type getType(Criteria subcriteria, String propertyName)
throws HibernateException { throws HibernateException {
return getPropertyMapping( getEntityName( subcriteria, propertyName ) ) return getPropertyMapping( getEntityName( subcriteria, propertyName ) )
@ -590,6 +579,7 @@ public class CriteriaQueryTranslator implements CriteriaQuery {
/** /**
* Get the a typed value for the given property value. * Get the a typed value for the given property value.
*/ */
@Override
public TypedValue getTypedValue(Criteria subcriteria, String propertyName, Object value) public TypedValue getTypedValue(Criteria subcriteria, String propertyName, Object value)
throws HibernateException { throws HibernateException {
// Detect discriminator values... // Detect discriminator values...
@ -624,7 +614,7 @@ public class CriteriaQueryTranslator implements CriteriaQuery {
private PropertyMapping getPropertyMapping(String entityName) private PropertyMapping getPropertyMapping(String entityName)
throws MappingException { throws MappingException {
CriteriaInfoProvider info = ( CriteriaInfoProvider )nameCriteriaInfoMap.get(entityName); CriteriaInfoProvider info = nameCriteriaInfoMap.get(entityName);
if (info==null) { if (info==null) {
throw new HibernateException( "Unknown entity: " + entityName ); throw new HibernateException( "Unknown entity: " + entityName );
} }
@ -632,7 +622,7 @@ public class CriteriaQueryTranslator implements CriteriaQuery {
} }
//TODO: use these in methods above //TODO: use these in methods above
@Override
public String getEntityName(Criteria subcriteria, String propertyName) { public String getEntityName(Criteria subcriteria, String propertyName) {
if ( propertyName.indexOf( '.' ) > 0 ) { if ( propertyName.indexOf( '.' ) > 0 ) {
String root = StringHelper.root( propertyName ); String root = StringHelper.root( propertyName );
@ -643,7 +633,7 @@ public class CriteriaQueryTranslator implements CriteriaQuery {
} }
return getEntityName( subcriteria ); return getEntityName( subcriteria );
} }
@Override
public String getSQLAlias(Criteria criteria, String propertyName) { public String getSQLAlias(Criteria criteria, String propertyName) {
if ( propertyName.indexOf( '.' ) > 0 ) { if ( propertyName.indexOf( '.' ) > 0 ) {
String root = StringHelper.root( propertyName ); String root = StringHelper.root( propertyName );
@ -654,7 +644,7 @@ public class CriteriaQueryTranslator implements CriteriaQuery {
} }
return getSQLAlias( criteria ); return getSQLAlias( criteria );
} }
@Override
public String getPropertyName(String propertyName) { public String getPropertyName(String propertyName) {
if ( propertyName.indexOf( '.' ) > 0 ) { if ( propertyName.indexOf( '.' ) > 0 ) {
String root = StringHelper.root( propertyName ); String root = StringHelper.root( propertyName );
@ -668,14 +658,14 @@ public class CriteriaQueryTranslator implements CriteriaQuery {
public String getWithClause(String path) public String getWithClause(String path)
{ {
final Criterion crit = (Criterion)this.withClauseMap.get(path); final Criterion crit = withClauseMap.get(path);
return crit == null ? null : crit.toSqlString(getCriteria(path), this); return crit == null ? null : crit.toSqlString(getCriteria(path), this);
} }
public boolean hasRestriction(String path) public boolean hasRestriction(String path)
{ {
final CriteriaImpl.Subcriteria crit = ( CriteriaImpl.Subcriteria ) getCriteria( path ); final CriteriaImpl.Subcriteria crit = ( CriteriaImpl.Subcriteria ) getCriteria( path );
return crit == null ? false : crit.hasRestriction(); return crit != null && crit.hasRestriction();
} }

View File

@ -35,24 +35,24 @@ import org.hibernate.type.Type;
*/ */
class EntityCriteriaInfoProvider implements CriteriaInfoProvider { class EntityCriteriaInfoProvider implements CriteriaInfoProvider {
Queryable persister; private final Queryable persister;
EntityCriteriaInfoProvider(Queryable persister) { EntityCriteriaInfoProvider(Queryable persister) {
this.persister = persister; this.persister = persister;
} }
@Override
public String getName() { public String getName() {
return persister.getEntityName(); return persister.getEntityName();
} }
@Override
public Serializable[] getSpaces() { public Serializable[] getSpaces() {
return persister.getQuerySpaces(); return persister.getQuerySpaces();
} }
@Override
public PropertyMapping getPropertyMapping() { public PropertyMapping getPropertyMapping() {
return persister; return persister;
} }
@Override
public Type getType(String relativePath) { public Type getType(String relativePath) {
return persister.toType( relativePath ); return persister.toType( relativePath );
} }

View File

@ -36,9 +36,9 @@ import org.hibernate.type.Type;
*/ */
class ScalarCollectionCriteriaInfoProvider implements CriteriaInfoProvider { class ScalarCollectionCriteriaInfoProvider implements CriteriaInfoProvider {
String role; private final String role;
QueryableCollection persister; private final QueryableCollection persister;
SessionFactoryHelper helper; private final SessionFactoryHelper helper;
ScalarCollectionCriteriaInfoProvider(SessionFactoryHelper helper, String role) { ScalarCollectionCriteriaInfoProvider(SessionFactoryHelper helper, String role) {
this.role = role; this.role = role;
@ -46,18 +46,22 @@ class ScalarCollectionCriteriaInfoProvider implements CriteriaInfoProvider {
this.persister = helper.requireQueryableCollection( role ); this.persister = helper.requireQueryableCollection( role );
} }
@Override
public String getName() { public String getName() {
return role; return role;
} }
@Override
public Serializable[] getSpaces() { public Serializable[] getSpaces() {
return persister.getCollectionSpaces(); return persister.getCollectionSpaces();
} }
@Override
public PropertyMapping getPropertyMapping() { public PropertyMapping getPropertyMapping() {
return helper.getCollectionPropertyMapping( role ); return helper.getCollectionPropertyMapping( role );
} }
@Override
public Type getType(String relativePath) { public Type getType(String relativePath) {
//not sure what things are going to be passed here, how about 'id', maybe 'index' or 'key' or 'elements' ??? //not sure what things are going to be passed here, how about 'id', maybe 'index' or 'key' or 'elements' ???
// todo: wtf! // todo: wtf!

View File

@ -24,7 +24,10 @@
*/ */
package org.hibernate.loader.custom.sql; package org.hibernate.loader.custom.sql;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -56,8 +59,10 @@ import org.hibernate.loader.custom.NonScalarReturn;
import org.hibernate.loader.custom.Return; import org.hibernate.loader.custom.Return;
import org.hibernate.loader.custom.RootReturn; import org.hibernate.loader.custom.RootReturn;
import org.hibernate.loader.custom.ScalarReturn; import org.hibernate.loader.custom.ScalarReturn;
import org.hibernate.persister.collection.CollectionPersister;
import org.hibernate.persister.collection.SQLLoadableCollection; import org.hibernate.persister.collection.SQLLoadableCollection;
import org.hibernate.persister.entity.EntityPersister; import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.persister.entity.Joinable;
import org.hibernate.persister.entity.SQLLoadable; import org.hibernate.persister.entity.SQLLoadable;
import org.hibernate.type.EntityType; import org.hibernate.type.EntityType;
import org.hibernate.type.Type; import org.hibernate.type.Type;
@ -99,7 +104,7 @@ public class SQLQueryReturnProcessor {
this.factory = factory; this.factory = factory;
} }
/*package*/ class ResultAliasContext { public class ResultAliasContext {
public SQLLoadable getEntityPersister(String alias) { public SQLLoadable getEntityPersister(String alias) {
return alias2Persister.get( alias ); return alias2Persister.get( alias );
} }
@ -123,6 +128,25 @@ public class SQLQueryReturnProcessor {
public Map<String, String[]> getPropertyResultsMap(String alias) { public Map<String, String[]> getPropertyResultsMap(String alias) {
return internalGetPropertyResultsMap( alias ); return internalGetPropertyResultsMap( alias );
} }
public String[] collectQuerySpaces() {
final HashSet<String> spaces = new HashSet<String>();
collectQuerySpaces( spaces );
return spaces.toArray( new String[ spaces.size() ] );
}
public void collectQuerySpaces(Collection<String> spaces) {
for ( EntityPersister persister : alias2Persister.values() ) {
Collections.addAll( spaces, (String[]) persister.getQuerySpaces() );
}
for ( CollectionPersister persister : alias2CollectionPersister.values() ) {
final Type elementType = persister.getElementType();
if ( elementType.isEntityType() && ! elementType.isAnyType() ) {
final Joinable joinable = ( (EntityType) elementType ).getAssociatedJoinable( factory );
Collections.addAll( spaces, (String[]) ( (EntityPersister) joinable ).getQuerySpaces() );
}
}
}
} }
private Map<String, String[]> internalGetPropertyResultsMap(String alias) { private Map<String, String[]> internalGetPropertyResultsMap(String alias) {

View File

@ -366,7 +366,7 @@ public abstract class Collection implements Fetchable, Value, Filterable {
} }
public Iterator<Selectable> getColumnIterator() { public Iterator<Selectable> getColumnIterator() {
return Collections.emptyIterator(); return Collections.<Selectable>emptyList().iterator();
} }
public int getColumnSpan() { public int getColumnSpan() {

View File

@ -23,10 +23,16 @@
*/ */
package org.hibernate.mapping; package org.hibernate.mapping;
import java.io.Serializable; import java.io.Serializable;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import org.hibernate.HibernateException;
import org.hibernate.dialect.Dialect; import org.hibernate.dialect.Dialect;
import org.hibernate.engine.spi.Mapping; import org.hibernate.engine.spi.Mapping;
@ -34,11 +40,12 @@ import org.hibernate.engine.spi.Mapping;
* A relational constraint. * A relational constraint.
* *
* @author Gavin King * @author Gavin King
* @author Brett Meyer
*/ */
public abstract class Constraint implements RelationalModel, Serializable { public abstract class Constraint implements RelationalModel, Serializable {
private String name; private String name;
private final List<Column> columns = new ArrayList<Column>(); private final ArrayList<Column> columns = new ArrayList<Column>();
private Table table; private Table table;
public String getName() { public String getName() {
@ -49,6 +56,85 @@ public abstract class Constraint implements RelationalModel, Serializable {
this.name = name; this.name = name;
} }
/**
* If a constraint is not explicitly named, this is called to generate
* a unique hash using the table and column names.
* Static so the name can be generated prior to creating the Constraint.
* They're cached, keyed by name, in multiple locations.
*
* @param prefix
* Appended to the beginning of the generated name
* @param table
* @param columns
* @return String The generated name
*/
public static String generateName(String prefix, Table table, Column... columns) {
// Use a concatenation that guarantees uniqueness, even if identical names
// exist between all table and column identifiers.
StringBuilder sb = new StringBuilder( "table`" + table.getName() + "`" );
// Ensure a consistent ordering of columns, regardless of the order
// they were bound.
// Clone the list, as sometimes a set of order-dependent Column
// bindings are given.
Column[] alphabeticalColumns = columns.clone();
Arrays.sort( alphabeticalColumns, ColumnComparator.INSTANCE );
for ( Column column : alphabeticalColumns ) {
String columnName = column == null ? "" : column.getName();
sb.append( "column`" + columnName + "`" );
}
return prefix + hashedName( sb.toString() );
}
/**
* Helper method for {@link #generateName(String, Table, Column...)}.
*
* @param prefix
* Appended to the beginning of the generated name
* @param table
* @param columns
* @return String The generated name
*/
public static String generateName(String prefix, Table table, List<Column> columns) {
return generateName( prefix, table, columns.toArray( new Column[columns.size()] ) );
}
/**
* Hash a constraint name using MD5. Convert the MD5 digest to base 35
* (full alphanumeric), guaranteeing
* that the length of the name will always be smaller than the 30
* character identifier restriction enforced by a few dialects.
*
* @param s
* The name to be hashed.
* @return String The hased name.
*/
public static String hashedName(String s) {
try {
MessageDigest md = MessageDigest.getInstance( "MD5" );
md.reset();
md.update( s.getBytes() );
byte[] digest = md.digest();
BigInteger bigInt = new BigInteger( 1, digest );
// By converting to base 35 (full alphanumeric), we guarantee
// that the length of the name will always be smaller than the 30
// character identifier restriction enforced by a few dialects.
return bigInt.toString( 35 );
}
catch ( NoSuchAlgorithmException e ) {
throw new HibernateException( "Unable to generate a hashed Constraint name!", e );
}
}
private static class ColumnComparator implements Comparator<Column> {
public static ColumnComparator INSTANCE = new ColumnComparator();
public int compare(Column col1, Column col2) {
return col1.getName().compareTo( col2.getName() );
}
}
public void addColumn(Column column) { public void addColumn(Column column) {
if ( !columns.contains( column ) ) columns.add( column ); if ( !columns.contains( column ) ) columns.add( column );
} }
@ -133,4 +219,10 @@ public abstract class Constraint implements RelationalModel, Serializable {
public String toString() { public String toString() {
return getClass().getName() + '(' + getTable().getName() + getColumns() + ") as " + name; return getClass().getName() + '(' + getTable().getName() + getColumns() + ") as " + name;
} }
/**
* @return String The prefix to use in generated constraint names. Examples:
* "UK_", "FK_", and "PK_".
*/
public abstract String generatedConstraintNamePrefix();
} }

View File

@ -180,4 +180,8 @@ public class ForeignKey extends Constraint {
} }
} }
public String generatedConstraintNamePrefix() {
return "FK_";
}
} }

View File

@ -53,4 +53,8 @@ public class PrimaryKey extends Constraint {
} }
return buf.append(')').toString(); return buf.append(')').toString();
} }
public String generatedConstraintNamePrefix() {
return "PK_";
}
} }

View File

@ -36,7 +36,6 @@ import org.hibernate.HibernateException;
import org.hibernate.MappingException; import org.hibernate.MappingException;
import org.hibernate.dialect.Dialect; import org.hibernate.dialect.Dialect;
import org.hibernate.engine.spi.Mapping; import org.hibernate.engine.spi.Mapping;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.tool.hbm2ddl.ColumnMetadata; import org.hibernate.tool.hbm2ddl.ColumnMetadata;
import org.hibernate.tool.hbm2ddl.TableMetadata; import org.hibernate.tool.hbm2ddl.TableMetadata;
@ -70,15 +69,6 @@ public class Table implements RelationalModel, Serializable {
private boolean hasDenormalizedTables = false; private boolean hasDenormalizedTables = false;
private String comment; private String comment;
/**
* Natural ID columns must reside in one single UniqueKey within the Table.
* To prevent separate UniqueKeys from being created, this keeps track of
* a sole name used for all of them. It's necessary since
* AnnotationBinder#processElementAnnotations (static) creates the
* UniqueKeys on a second pass using randomly-generated names.
*/
private final String naturalIdUniqueKeyName = StringHelper.randomFixedLengthHex( "UK_" );
static class ForeignKeyKey implements Serializable { static class ForeignKeyKey implements Serializable {
String referencedClassName; String referencedClassName;
List columns; List columns;
@ -431,8 +421,8 @@ public class Table implements RelationalModel, Serializable {
} }
if ( column.isUnique() ) { if ( column.isUnique() ) {
UniqueKey uk = getOrCreateUniqueKey( String keyName = Constraint.generateName( "UK_", this, column );
StringHelper.randomFixedLengthHex("UK_")); UniqueKey uk = getOrCreateUniqueKey( keyName );
uk.addColumn( column ); uk.addColumn( column );
alter.append( dialect.getUniqueDelegate() alter.append( dialect.getUniqueDelegate()
.getColumnDefinitionUniquenessFragment( column ) ); .getColumnDefinitionUniquenessFragment( column ) );
@ -534,8 +524,8 @@ public class Table implements RelationalModel, Serializable {
} }
if ( col.isUnique() ) { if ( col.isUnique() ) {
UniqueKey uk = getOrCreateUniqueKey( String keyName = Constraint.generateName( "UK_", this, col );
StringHelper.randomFixedLengthHex("UK_")); UniqueKey uk = getOrCreateUniqueKey( keyName );
uk.addColumn( col ); uk.addColumn( col );
buf.append( dialect.getUniqueDelegate() buf.append( dialect.getUniqueDelegate()
.getColumnDefinitionUniquenessFragment( col ) ); .getColumnDefinitionUniquenessFragment( col ) );
@ -658,7 +648,7 @@ public class Table implements RelationalModel, Serializable {
} }
public UniqueKey createUniqueKey(List keyColumns) { public UniqueKey createUniqueKey(List keyColumns) {
String keyName = StringHelper.randomFixedLengthHex("UK_"); String keyName = Constraint.generateName( "UK_", this, keyColumns );
UniqueKey uk = getOrCreateUniqueKey( keyName ); UniqueKey uk = getOrCreateUniqueKey( keyName );
uk.addColumns( keyColumns.iterator() ); uk.addColumns( keyColumns.iterator() );
return uk; return uk;
@ -694,19 +684,22 @@ public class Table implements RelationalModel, Serializable {
ForeignKey fk = (ForeignKey) foreignKeys.get( key ); ForeignKey fk = (ForeignKey) foreignKeys.get( key );
if ( fk == null ) { if ( fk == null ) {
fk = new ForeignKey(); fk = new ForeignKey();
if ( keyName != null ) {
fk.setName( keyName );
}
else {
fk.setName( StringHelper.randomFixedLengthHex("FK_") );
}
fk.setTable( this ); fk.setTable( this );
foreignKeys.put( key, fk );
fk.setReferencedEntityName( referencedEntityName ); fk.setReferencedEntityName( referencedEntityName );
fk.addColumns( keyColumns.iterator() ); fk.addColumns( keyColumns.iterator() );
if ( referencedColumns != null ) { if ( referencedColumns != null ) {
fk.addReferencedColumns( referencedColumns.iterator() ); fk.addReferencedColumns( referencedColumns.iterator() );
} }
if ( keyName != null ) {
fk.setName( keyName );
}
else {
fk.setName( Constraint.generateName( fk.generatedConstraintNamePrefix(),
this, keyColumns ) );
}
foreignKeys.put( key, fk );
} }
if ( keyName != null ) { if ( keyName != null ) {
@ -856,10 +849,6 @@ public class Table implements RelationalModel, Serializable {
return checkConstraints.iterator(); return checkConstraints.iterator();
} }
public String getNaturalIdUniqueKeyName() {
return naturalIdUniqueKeyName;
}
public Iterator sqlCommentStrings(Dialect dialect, String defaultCatalog, String defaultSchema) { public Iterator sqlCommentStrings(Dialect dialect, String defaultCatalog, String defaultSchema) {
List comments = new ArrayList(); List comments = new ArrayList();
if ( dialect.supportsCommentOn() ) { if ( dialect.supportsCommentOn() ) {

View File

@ -75,4 +75,8 @@ public class UniqueKey extends Constraint {
public Map<Column, String> getColumnOrderMap() { public Map<Column, String> getColumnOrderMap() {
return columnOrderMap; return columnOrderMap;
} }
public String generatedConstraintNamePrefix() {
return "UK_";
}
} }

View File

@ -414,7 +414,7 @@ public class SingleTableEntityPersister extends AbstractEntityPersister {
subclassClosure = new String[subclassSpan]; subclassClosure = new String[subclassSpan];
subclassClosure[0] = getEntityName(); subclassClosure[0] = getEntityName();
if ( persistentClass.isPolymorphic() ) { if ( persistentClass.isPolymorphic() ) {
subclassesByDiscriminatorValue.put( discriminatorValue, getEntityName() ); addSubclassByDiscriminatorValue( discriminatorValue, getEntityName() );
} }
// SUBCLASSES // SUBCLASSES
@ -425,15 +425,15 @@ public class SingleTableEntityPersister extends AbstractEntityPersister {
Subclass sc = (Subclass) iter.next(); Subclass sc = (Subclass) iter.next();
subclassClosure[k++] = sc.getEntityName(); subclassClosure[k++] = sc.getEntityName();
if ( sc.isDiscriminatorValueNull() ) { if ( sc.isDiscriminatorValueNull() ) {
subclassesByDiscriminatorValue.put( NULL_DISCRIMINATOR, sc.getEntityName() ); addSubclassByDiscriminatorValue( NULL_DISCRIMINATOR, sc.getEntityName() );
} }
else if ( sc.isDiscriminatorValueNotNull() ) { else if ( sc.isDiscriminatorValueNotNull() ) {
subclassesByDiscriminatorValue.put( NOT_NULL_DISCRIMINATOR, sc.getEntityName() ); addSubclassByDiscriminatorValue( NOT_NULL_DISCRIMINATOR, sc.getEntityName() );
} }
else { else {
try { try {
DiscriminatorType dtype = (DiscriminatorType) discriminatorType; DiscriminatorType dtype = (DiscriminatorType) discriminatorType;
subclassesByDiscriminatorValue.put( addSubclassByDiscriminatorValue(
dtype.stringToObject( sc.getDiscriminatorValue() ), dtype.stringToObject( sc.getDiscriminatorValue() ),
sc.getEntityName() sc.getEntityName()
); );
@ -455,7 +455,17 @@ public class SingleTableEntityPersister extends AbstractEntityPersister {
postConstruct(mapping); postConstruct(mapping);
} }
@SuppressWarnings( {"UnusedDeclaration"})
private void addSubclassByDiscriminatorValue(Object discriminatorValue, String entityName) {
String mappedEntityName = (String) subclassesByDiscriminatorValue.put( discriminatorValue, entityName );
if ( mappedEntityName != null ) {
throw new MappingException(
"Entities [" + entityName + "] and [" + mappedEntityName
+ "] are mapped with the same discriminator value '" + discriminatorValue + "'."
);
}
}
public SingleTableEntityPersister( public SingleTableEntityPersister(
final EntityBinding entityBinding, final EntityBinding entityBinding,
final EntityRegionAccessStrategy cacheAccessStrategy, final EntityRegionAccessStrategy cacheAccessStrategy,
@ -711,7 +721,7 @@ public class SingleTableEntityPersister extends AbstractEntityPersister {
subclassClosure = new String[subclassSpan]; subclassClosure = new String[subclassSpan];
subclassClosure[0] = getEntityName(); subclassClosure[0] = getEntityName();
if ( entityBinding.isPolymorphic() ) { if ( entityBinding.isPolymorphic() ) {
subclassesByDiscriminatorValue.put( discriminatorValue, getEntityName() ); addSubclassByDiscriminatorValue( discriminatorValue, getEntityName() );
} }
// SUBCLASSES // SUBCLASSES
@ -720,15 +730,15 @@ public class SingleTableEntityPersister extends AbstractEntityPersister {
for ( EntityBinding subEntityBinding : entityBinding.getPostOrderSubEntityBindingClosure() ) { for ( EntityBinding subEntityBinding : entityBinding.getPostOrderSubEntityBindingClosure() ) {
subclassClosure[k++] = subEntityBinding.getEntity().getName(); subclassClosure[k++] = subEntityBinding.getEntity().getName();
if ( subEntityBinding.isDiscriminatorMatchValueNull() ) { if ( subEntityBinding.isDiscriminatorMatchValueNull() ) {
subclassesByDiscriminatorValue.put( NULL_DISCRIMINATOR, subEntityBinding.getEntity().getName() ); addSubclassByDiscriminatorValue( NULL_DISCRIMINATOR, subEntityBinding.getEntity().getName() );
} }
else if ( subEntityBinding.isDiscriminatorMatchValueNotNull() ) { else if ( subEntityBinding.isDiscriminatorMatchValueNotNull() ) {
subclassesByDiscriminatorValue.put( NOT_NULL_DISCRIMINATOR, subEntityBinding.getEntity().getName() ); addSubclassByDiscriminatorValue( NOT_NULL_DISCRIMINATOR, subEntityBinding.getEntity().getName() );
} }
else { else {
try { try {
DiscriminatorType dtype = (DiscriminatorType) discriminatorType; DiscriminatorType dtype = (DiscriminatorType) discriminatorType;
subclassesByDiscriminatorValue.put( addSubclassByDiscriminatorValue(
dtype.stringToObject( subEntityBinding.getDiscriminatorMatchValue() ), dtype.stringToObject( subEntityBinding.getDiscriminatorMatchValue() ),
subEntityBinding.getEntity().getName() subEntityBinding.getEntity().getName()
); );

View File

@ -25,6 +25,7 @@ package org.hibernate.procedure;
import java.util.List; import java.util.List;
import javax.persistence.ParameterMode; import javax.persistence.ParameterMode;
import java.util.Map;
import org.hibernate.BasicQueryContract; import org.hibernate.BasicQueryContract;
import org.hibernate.MappingException; import org.hibernate.MappingException;
@ -58,6 +59,7 @@ public interface ProcedureCall extends BasicQueryContract, SynchronizeableQuery
* @param position The position * @param position The position
* @param type The Java type of the parameter * @param type The Java type of the parameter
* @param mode The parameter mode (in, out, inout) * @param mode The parameter mode (in, out, inout)
* @param <T> The parameterized Java type of the parameter.
* *
* @return The parameter registration memento * @return The parameter registration memento
*/ */
@ -89,8 +91,12 @@ public interface ProcedureCall extends BasicQueryContract, SynchronizeableQuery
* @param parameterName The parameter name * @param parameterName The parameter name
* @param type The Java type of the parameter * @param type The Java type of the parameter
* @param mode The parameter mode (in, out, inout) * @param mode The parameter mode (in, out, inout)
* @param <T> The parameterized Java type of the parameter.
* *
* @return The parameter registration memento * @return The parameter registration memento
*
* @throws NamedParametersNotSupportedException When the underlying database is known to not support
* named procedure parameters.
*/ */
public <T> ParameterRegistration<T> registerParameter(String parameterName, Class<T> type, ParameterMode mode) public <T> ParameterRegistration<T> registerParameter(String parameterName, Class<T> type, ParameterMode mode)
throws NamedParametersNotSupportedException; throws NamedParametersNotSupportedException;
@ -103,6 +109,9 @@ public interface ProcedureCall extends BasicQueryContract, SynchronizeableQuery
* @param mode The parameter mode (in, out, inout) * @param mode The parameter mode (in, out, inout)
* *
* @return The parameter registration memento * @return The parameter registration memento
*
* @throws NamedParametersNotSupportedException When the underlying database is known to not support
* named procedure parameters.
*/ */
public ProcedureCall registerParameter0(String parameterName, Class type, ParameterMode mode) public ProcedureCall registerParameter0(String parameterName, Class type, ParameterMode mode)
throws NamedParametersNotSupportedException; throws NamedParametersNotSupportedException;
@ -133,4 +142,12 @@ public interface ProcedureCall extends BasicQueryContract, SynchronizeableQuery
*/ */
public ProcedureResult getResult(); public ProcedureResult getResult();
/**
* Extract the disconnected representation of this call. Used in HEM to allow redefining a named query
*
* @param hints The hints to incorporate into the memento
*
* @return The memento
*/
public ProcedureCallMemento extractMemento(Map<String, Object> hints);
} }

View File

@ -1,7 +1,7 @@
/* /*
* Hibernate, Relational Persistence for Idiomatic Java * Hibernate, Relational Persistence for Idiomatic Java
* *
* Copyright (c) 2012, Red Hat Inc. or third-party contributors as * Copyright (c) 2013, Red Hat Inc. or third-party contributors as
* indicated by the @author tags or express copyright attribution * indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are * statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Inc. * distributed under license by Red Hat Inc.
@ -21,25 +21,43 @@
* 51 Franklin Street, Fifth Floor * 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA * Boston, MA 02110-1301 USA
*/ */
package org.hibernate.build.gradle.testing.database; package org.hibernate.procedure;
import java.io.File;
import java.util.Map; import java.util.Map;
import org.gradle.api.artifacts.Configuration; import org.hibernate.Session;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.build.qalab.DatabaseAllocation;
/** /**
* Contract for database "profiles". * Represents a "memento" of a ProcedureCall
* *
* @author Steve Ebersole * @author Steve Ebersole
* @author Strong Liu
*/ */
public interface DatabaseProfile { public interface ProcedureCallMemento {
public String getName(); /**
public File getDirectory(); * Convert the memento back into an executable (connected) form.
public Map<String,String> getHibernateProperties(); *
public Configuration getTestingRuntimeConfiguration(); * @param session The session to connect the procedure call to
public DatabaseAllocation getDatabaseAllocation(); *
* @return The executable call
*/
public ProcedureCall makeProcedureCall(Session session);
/**
* Convert the memento back into an executable (connected) form.
*
* @param session The session to connect the procedure call to
*
* @return The executable call
*/
public ProcedureCall makeProcedureCall(SessionImplementor session);
/**
* Access to any hints associated with the memento.
* <p/>
* IMPL NOTE : exposed separately because only HEM needs access to this.
*
* @return The hints.
*/
public Map<String, Object> getHintsMap();
} }

View File

@ -42,6 +42,8 @@ import org.hibernate.type.ProcedureParameterExtractionAware;
import org.hibernate.type.Type; import org.hibernate.type.Type;
/** /**
* Abstract implementation of ParameterRegistration/ParameterRegistrationImplementor
*
* @author Steve Ebersole * @author Steve Ebersole
*/ */
public abstract class AbstractParameterRegistrationImpl<T> implements ParameterRegistrationImplementor<T> { public abstract class AbstractParameterRegistrationImpl<T> implements ParameterRegistrationImplementor<T> {
@ -61,28 +63,53 @@ public abstract class AbstractParameterRegistrationImpl<T> implements ParameterR
private Type hibernateType; private Type hibernateType;
private int[] sqlTypes; private int[] sqlTypes;
// positional constructors ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
protected AbstractParameterRegistrationImpl( protected AbstractParameterRegistrationImpl(
ProcedureCallImpl procedureCall, ProcedureCallImpl procedureCall,
Integer position, Integer position,
ParameterMode mode,
Class<T> type) {
this( procedureCall, position, null, mode, type );
}
protected AbstractParameterRegistrationImpl(
ProcedureCallImpl procedureCall,
Integer position,
ParameterMode mode,
Class<T> type, Class<T> type,
ParameterMode mode) { Type hibernateType) {
this( procedureCall, position, null, type, mode ); this( procedureCall, position, null, mode, type, hibernateType );
}
// named constructors ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
protected AbstractParameterRegistrationImpl(
ProcedureCallImpl procedureCall,
String name,
ParameterMode mode,
Class<T> type) {
this( procedureCall, null, name, mode, type );
} }
protected AbstractParameterRegistrationImpl( protected AbstractParameterRegistrationImpl(
ProcedureCallImpl procedureCall, ProcedureCallImpl procedureCall,
String name, String name,
ParameterMode mode,
Class<T> type, Class<T> type,
ParameterMode mode) { Type hibernateType) {
this( procedureCall, null, name, type, mode ); this( procedureCall, null, name, mode, type, hibernateType );
} }
private AbstractParameterRegistrationImpl( private AbstractParameterRegistrationImpl(
ProcedureCallImpl procedureCall, ProcedureCallImpl procedureCall,
Integer position, Integer position,
String name, String name,
ParameterMode mode,
Class<T> type, Class<T> type,
ParameterMode mode) { Type hibernateType) {
this.procedureCall = procedureCall; this.procedureCall = procedureCall;
this.position = position; this.position = position;
@ -91,7 +118,23 @@ public abstract class AbstractParameterRegistrationImpl<T> implements ParameterR
this.mode = mode; this.mode = mode;
this.type = type; this.type = type;
setHibernateType( session().getFactory().getTypeResolver().heuristicType( type.getName() ) ); setHibernateType( hibernateType );
}
private AbstractParameterRegistrationImpl(
ProcedureCallImpl procedureCall,
Integer position,
String name,
ParameterMode mode,
Class<T> type) {
this(
procedureCall,
position,
name,
mode,
type,
procedureCall.getSession().getFactory().getTypeResolver().heuristicType( type.getName() )
);
} }
protected SessionImplementor session() { protected SessionImplementor session() {
@ -118,6 +161,11 @@ public abstract class AbstractParameterRegistrationImpl<T> implements ParameterR
return mode; return mode;
} }
@Override
public Type getHibernateType() {
return hibernateType;
}
@Override @Override
public void setHibernateType(Type type) { public void setHibernateType(Type type) {
if ( type == null ) { if ( type == null ) {
@ -128,6 +176,7 @@ public abstract class AbstractParameterRegistrationImpl<T> implements ParameterR
} }
@Override @Override
@SuppressWarnings("unchecked")
public ParameterBind<T> getBind() { public ParameterBind<T> getBind() {
return bind; return bind;
} }
@ -174,11 +223,12 @@ public abstract class AbstractParameterRegistrationImpl<T> implements ParameterR
if ( mode == ParameterMode.IN || mode == ParameterMode.INOUT || mode == ParameterMode.OUT ) { if ( mode == ParameterMode.IN || mode == ParameterMode.INOUT || mode == ParameterMode.OUT ) {
if ( mode == ParameterMode.INOUT || mode == ParameterMode.OUT ) { if ( mode == ParameterMode.INOUT || mode == ParameterMode.OUT ) {
if ( sqlTypes.length > 1 ) { if ( sqlTypes.length > 1 ) {
if ( ProcedureParameterExtractionAware.class.isInstance( hibernateType ) // there is more than one column involved; see if the Hibernate Type can handle
&& ( (ProcedureParameterExtractionAware) hibernateType ).canDoExtraction() ) { // multi-param extraction...
// the type can handle multi-param extraction... final boolean canHandleMultiParamExtraction =
} ProcedureParameterExtractionAware.class.isInstance( hibernateType )
else { && ( (ProcedureParameterExtractionAware) hibernateType ).canDoExtraction();
if ( ! canHandleMultiParamExtraction ) {
// it cannot... // it cannot...
throw new UnsupportedOperationException( throw new UnsupportedOperationException(
"Type [" + hibernateType + "] does support multi-parameter value extraction" "Type [" + hibernateType + "] does support multi-parameter value extraction"

View File

@ -25,15 +25,28 @@ package org.hibernate.procedure.internal;
import javax.persistence.ParameterMode; import javax.persistence.ParameterMode;
import org.hibernate.type.Type;
/** /**
* Represents a registered named parameter
*
* @author Steve Ebersole * @author Steve Ebersole
*/ */
public class NamedParameterRegistration<T> extends AbstractParameterRegistrationImpl<T> { public class NamedParameterRegistration<T> extends AbstractParameterRegistrationImpl<T> {
public NamedParameterRegistration( NamedParameterRegistration(
ProcedureCallImpl procedureCall, ProcedureCallImpl procedureCall,
String name, String name,
ParameterMode mode,
Class<T> type) {
super( procedureCall, name, mode, type );
}
NamedParameterRegistration(
ProcedureCallImpl procedureCall,
String name,
ParameterMode mode,
Class<T> type, Class<T> type,
ParameterMode mode) { Type hibernateType) {
super( procedureCall, name, type, mode ); super( procedureCall, name, mode, type, hibernateType );
} }
} }

View File

@ -36,11 +36,11 @@ public class ParameterBindImpl<T> implements ParameterBind<T> {
private final T value; private final T value;
private final TemporalType explicitTemporalType; private final TemporalType explicitTemporalType;
public ParameterBindImpl(T value) { ParameterBindImpl(T value) {
this( value, null ); this( value, null );
} }
public ParameterBindImpl(T value, TemporalType explicitTemporalType) { ParameterBindImpl(T value, TemporalType explicitTemporalType) {
this.value = value; this.value = value;
this.explicitTemporalType = explicitTemporalType; this.explicitTemporalType = explicitTemporalType;
} }

View File

@ -27,15 +27,45 @@ import java.sql.CallableStatement;
import java.sql.SQLException; import java.sql.SQLException;
import org.hibernate.procedure.ParameterRegistration; import org.hibernate.procedure.ParameterRegistration;
import org.hibernate.type.Type;
/** /**
* Additional internal contract for ParameterRegistration
*
* @author Steve Ebersole * @author Steve Ebersole
*/ */
public interface ParameterRegistrationImplementor<T> extends ParameterRegistration<T> { public interface ParameterRegistrationImplementor<T> extends ParameterRegistration<T> {
/**
* Prepare for execution.
*
* @param statement The statement about to be executed
* @param i The parameter index for this registration (used for positional)
*
* @throws SQLException Indicates a problem accessing the statement object
*/
public void prepare(CallableStatement statement, int i) throws SQLException; public void prepare(CallableStatement statement, int i) throws SQLException;
/**
* Access to the Hibernate type for this parameter registration
*
* @return The Hibernate Type
*/
public Type getHibernateType();
/**
* Access to the SQL type(s) for this parameter
*
* @return The SQL types (JDBC type codes)
*/
public int[] getSqlTypes(); public int[] getSqlTypes();
/**
* Extract value from the statement after execution (used for OUT/INOUT parameters).
*
* @param statement The callable statement
*
* @return The extracted value
*/
public T extract(CallableStatement statement); public T extract(CallableStatement statement);
} }

View File

@ -27,7 +27,16 @@ package org.hibernate.procedure.internal;
* The style/strategy of parameter registration used in a particular procedure call definition. * The style/strategy of parameter registration used in a particular procedure call definition.
*/ */
public enum ParameterStrategy { public enum ParameterStrategy {
/**
* The parameters are named
*/
NAMED, NAMED,
/**
* The parameters are positional
*/
POSITIONAL, POSITIONAL,
/**
* We do not (yet) know
*/
UNKNOWN UNKNOWN
} }

View File

@ -25,15 +25,28 @@ package org.hibernate.procedure.internal;
import javax.persistence.ParameterMode; import javax.persistence.ParameterMode;
import org.hibernate.type.Type;
/** /**
* Represents a registered positional parameter
*
* @author Steve Ebersole * @author Steve Ebersole
*/ */
public class PositionalParameterRegistration<T> extends AbstractParameterRegistrationImpl<T> { public class PositionalParameterRegistration<T> extends AbstractParameterRegistrationImpl<T> {
public PositionalParameterRegistration( PositionalParameterRegistration(
ProcedureCallImpl procedureCall, ProcedureCallImpl procedureCall,
Integer position, Integer position,
ParameterMode mode,
Class<T> type) {
super( procedureCall, position, mode, type );
}
PositionalParameterRegistration(
ProcedureCallImpl procedureCall,
Integer position,
ParameterMode mode,
Class<T> type, Class<T> type,
ParameterMode mode) { Type hibernateType) {
super( procedureCall, position, type, mode ); super( procedureCall, position, mode, type, hibernateType );
} }
} }

View File

@ -30,26 +30,29 @@ import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Set; import java.util.Set;
import javax.persistence.ParameterMode; import javax.persistence.ParameterMode;
import org.jboss.logging.Logger;
import org.hibernate.HibernateException; import org.hibernate.HibernateException;
import org.hibernate.LockMode;
import org.hibernate.MappingException;
import org.hibernate.QueryException; import org.hibernate.QueryException;
import org.hibernate.cfg.NotYetImplementedException; import org.hibernate.cfg.NotYetImplementedException;
import org.hibernate.engine.ResultSetMappingDefinition; import org.hibernate.engine.ResultSetMappingDefinition;
import org.hibernate.engine.jdbc.env.spi.ExtractedDatabaseMetaData; import org.hibernate.engine.jdbc.env.spi.ExtractedDatabaseMetaData;
import org.hibernate.engine.query.spi.sql.NativeSQLQueryReturn; import org.hibernate.engine.query.spi.sql.NativeSQLQueryReturn;
import org.hibernate.engine.query.spi.sql.NativeSQLQueryRootReturn;
import org.hibernate.engine.spi.QueryParameters; import org.hibernate.engine.spi.QueryParameters;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.internal.AbstractBasicQueryContractImpl; import org.hibernate.internal.AbstractBasicQueryContractImpl;
import org.hibernate.internal.util.StringHelper; import org.hibernate.internal.util.StringHelper;
import org.hibernate.internal.util.collections.CollectionHelper;
import org.hibernate.persister.entity.EntityPersister; import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.procedure.NamedParametersNotSupportedException; import org.hibernate.procedure.NamedParametersNotSupportedException;
import org.hibernate.procedure.ParameterRegistration; import org.hibernate.procedure.ParameterRegistration;
import org.hibernate.procedure.ProcedureCall; import org.hibernate.procedure.ProcedureCall;
import org.hibernate.procedure.ProcedureCallMemento;
import org.hibernate.procedure.ProcedureResult; import org.hibernate.procedure.ProcedureResult;
import org.hibernate.result.spi.ResultContext; import org.hibernate.result.spi.ResultContext;
import org.hibernate.type.Type; import org.hibernate.type.Type;
@ -60,6 +63,10 @@ import org.hibernate.type.Type;
* @author Steve Ebersole * @author Steve Ebersole
*/ */
public class ProcedureCallImpl extends AbstractBasicQueryContractImpl implements ProcedureCall, ResultContext { public class ProcedureCallImpl extends AbstractBasicQueryContractImpl implements ProcedureCall, ResultContext {
private static final Logger log = Logger.getLogger( ProcedureCallImpl.class );
private static final NativeSQLQueryReturn[] NO_RETURNS = new NativeSQLQueryReturn[0];
private final String procedureName; private final String procedureName;
private final NativeSQLQueryReturn[] queryReturns; private final NativeSQLQueryReturn[] queryReturns;
@ -70,74 +77,167 @@ public class ProcedureCallImpl extends AbstractBasicQueryContractImpl implements
private ProcedureResultImpl outputs; private ProcedureResultImpl outputs;
/**
@SuppressWarnings("unchecked") * The no-returns form.
*
* @param session The session
* @param procedureName The name of the procedure to call
*/
public ProcedureCallImpl(SessionImplementor session, String procedureName) { public ProcedureCallImpl(SessionImplementor session, String procedureName) {
this( session, procedureName, (List) null ); super( session );
this.procedureName = procedureName;
this.queryReturns = NO_RETURNS;
} }
public ProcedureCallImpl(SessionImplementor session, String procedureName, List<NativeSQLQueryReturn> queryReturns) { /**
* The result Class(es) return form
*
* @param session The session
* @param procedureName The name of the procedure to call
* @param resultClasses The classes making up the result
*/
public ProcedureCallImpl(final SessionImplementor session, String procedureName, Class... resultClasses) {
super( session ); super( session );
this.procedureName = procedureName; this.procedureName = procedureName;
if ( queryReturns == null || queryReturns.isEmpty() ) { final List<NativeSQLQueryReturn> collectedQueryReturns = new ArrayList<NativeSQLQueryReturn>();
this.queryReturns = new NativeSQLQueryReturn[0]; final Set<String> collectedQuerySpaces = new HashSet<String>();
Util.resolveResultClasses(
new Util.ResultClassesResolutionContext() {
@Override
public SessionFactoryImplementor getSessionFactory() {
return session.getFactory();
}
@Override
public void addQueryReturns(NativeSQLQueryReturn... queryReturns) {
Collections.addAll( collectedQueryReturns, queryReturns );
}
@Override
public void addQuerySpaces(String... spaces) {
Collections.addAll( collectedQuerySpaces, spaces );
}
},
resultClasses
);
this.queryReturns = collectedQueryReturns.toArray( new NativeSQLQueryReturn[ collectedQueryReturns.size() ] );
this.synchronizedQuerySpaces = collectedQuerySpaces;
}
/**
* The result-set-mapping(s) return form
*
* @param session The session
* @param procedureName The name of the procedure to call
* @param resultSetMappings The names of the result set mappings making up the result
*/
public ProcedureCallImpl(final SessionImplementor session, String procedureName, String... resultSetMappings) {
super( session );
this.procedureName = procedureName;
final List<NativeSQLQueryReturn> collectedQueryReturns = new ArrayList<NativeSQLQueryReturn>();
final Set<String> collectedQuerySpaces = new HashSet<String>();
Util.resolveResultSetMappings(
new Util.ResultSetMappingResolutionContext() {
@Override
public SessionFactoryImplementor getSessionFactory() {
return session.getFactory();
}
@Override
public ResultSetMappingDefinition findResultSetMapping(String name) {
return session.getFactory().getResultSetMapping( name );
}
@Override
public void addQueryReturns(NativeSQLQueryReturn... queryReturns) {
Collections.addAll( collectedQueryReturns, queryReturns );
}
@Override
public void addQuerySpaces(String... spaces) {
Collections.addAll( collectedQuerySpaces, spaces );
}
},
resultSetMappings
);
this.queryReturns = collectedQueryReturns.toArray( new NativeSQLQueryReturn[ collectedQueryReturns.size() ] );
this.synchronizedQuerySpaces = collectedQuerySpaces;
}
/**
* The named/stored copy constructor
*
* @param session The session
* @param memento The named/stored memento
*/
@SuppressWarnings("unchecked")
ProcedureCallImpl(SessionImplementor session, ProcedureCallMementoImpl memento) {
super( session );
this.procedureName = memento.getProcedureName();
this.queryReturns = memento.getQueryReturns();
this.synchronizedQuerySpaces = Util.copy( memento.getSynchronizedQuerySpaces() );
this.parameterStrategy = memento.getParameterStrategy();
if ( parameterStrategy == ParameterStrategy.UNKNOWN ) {
// nothing else to do in this case
return;
}
final List<ProcedureCallMementoImpl.ParameterMemento> storedRegistrations = memento.getParameterDeclarations();
if ( storedRegistrations == null ) {
// most likely a problem if ParameterStrategy is not UNKNOWN...
log.debugf(
"ParameterStrategy was [%s] on named copy [%s], but no parameters stored",
parameterStrategy,
procedureName
);
return;
}
final List<ParameterRegistrationImplementor<?>> parameterRegistrations =
CollectionHelper.arrayList( storedRegistrations.size() );
for ( ProcedureCallMementoImpl.ParameterMemento storedRegistration : storedRegistrations ) {
final ParameterRegistrationImplementor<?> registration;
if ( StringHelper.isNotEmpty( storedRegistration.getName() ) ) {
if ( parameterStrategy != ParameterStrategy.NAMED ) {
throw new IllegalStateException(
"Found named stored procedure parameter associated with positional parameters"
);
}
registration = new NamedParameterRegistration(
this,
storedRegistration.getName(),
storedRegistration.getMode(),
storedRegistration.getType(),
storedRegistration.getHibernateType()
);
} }
else { else {
this.queryReturns = queryReturns.toArray( new NativeSQLQueryReturn[ queryReturns.size() ] ); if ( parameterStrategy != ParameterStrategy.POSITIONAL ) {
throw new IllegalStateException(
"Found named stored procedure parameter associated with positional parameters"
);
} }
registration = new PositionalParameterRegistration(
this,
storedRegistration.getPosition(),
storedRegistration.getMode(),
storedRegistration.getType(),
storedRegistration.getHibernateType()
);
} }
parameterRegistrations.add( registration );
public ProcedureCallImpl(SessionImplementor session, String procedureName, Class... resultClasses) {
this( session, procedureName, collectQueryReturns( resultClasses ) );
} }
this.registeredParameters = parameterRegistrations;
private static List<NativeSQLQueryReturn> collectQueryReturns(Class[] resultClasses) {
if ( resultClasses == null || resultClasses.length == 0 ) {
return null;
} }
List<NativeSQLQueryReturn> queryReturns = new ArrayList<NativeSQLQueryReturn>( resultClasses.length );
int i = 1;
for ( Class resultClass : resultClasses ) {
queryReturns.add( new NativeSQLQueryRootReturn( "alias" + i, resultClass.getName(), LockMode.READ ) );
i++;
}
return queryReturns;
}
public ProcedureCallImpl(SessionImplementor session, String procedureName, String... resultSetMappings) {
this( session, procedureName, collectQueryReturns( session, resultSetMappings ) );
}
private static List<NativeSQLQueryReturn> collectQueryReturns(SessionImplementor session, String[] resultSetMappings) {
if ( resultSetMappings == null || resultSetMappings.length == 0 ) {
return null;
}
List<NativeSQLQueryReturn> queryReturns = new ArrayList<NativeSQLQueryReturn>( resultSetMappings.length );
for ( String resultSetMapping : resultSetMappings ) {
ResultSetMappingDefinition mapping = session.getFactory().getResultSetMapping( resultSetMapping );
if ( mapping == null ) {
throw new MappingException( "Unknown SqlResultSetMapping [" + resultSetMapping + "]" );
}
queryReturns.addAll( Arrays.asList( mapping.getQueryReturns() ) );
}
return queryReturns;
}
// public ProcedureCallImpl(
// SessionImplementor session,
// String procedureName,
// List<StoredProcedureParameter> parameters) {
// // this form is intended for named stored procedure calls.
// // todo : introduce a NamedProcedureCallDefinition object to hold all needed info and pass that in here; will help with EM.addNamedQuery as well..
// this( session, procedureName );
// for ( StoredProcedureParameter parameter : parameters ) {
// registerParameter( (StoredProcedureParameterImplementor) parameter );
// }
// }
@Override @Override
public SessionImplementor getSession() { public SessionImplementor getSession() {
return super.session(); return super.session();
@ -165,7 +265,8 @@ public class ProcedureCallImpl extends AbstractBasicQueryContractImpl implements
@Override @Override
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public <T> ParameterRegistration<T> registerParameter(int position, Class<T> type, ParameterMode mode) { public <T> ParameterRegistration<T> registerParameter(int position, Class<T> type, ParameterMode mode) {
final PositionalParameterRegistration parameterRegistration = new PositionalParameterRegistration( this, position, type, mode ); final PositionalParameterRegistration parameterRegistration =
new PositionalParameterRegistration( this, position, mode, type );
registerParameter( parameterRegistration ); registerParameter( parameterRegistration );
return parameterRegistration; return parameterRegistration;
} }
@ -233,7 +334,8 @@ public class ProcedureCallImpl extends AbstractBasicQueryContractImpl implements
@Override @Override
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public <T> ParameterRegistration<T> registerParameter(String name, Class<T> type, ParameterMode mode) { public <T> ParameterRegistration<T> registerParameter(String name, Class<T> type, ParameterMode mode) {
final NamedParameterRegistration parameterRegistration = new NamedParameterRegistration( this, name, type, mode ); final NamedParameterRegistration parameterRegistration
= new NamedParameterRegistration( this, name, mode, type );
registerParameter( parameterRegistration ); registerParameter( parameterRegistration );
return parameterRegistration; return parameterRegistration;
} }
@ -329,6 +431,12 @@ public class ProcedureCallImpl extends AbstractBasicQueryContractImpl implements
throw new NotYetImplementedException(); throw new NotYetImplementedException();
} }
/**
* Use this form instead of {@link #getSynchronizedQuerySpaces()} when you want to make sure the
* underlying Set is instantiated (aka, on add)
*
* @return The spaces
*/
protected Set<String> synchronizedQuerySpaces() { protected Set<String> synchronizedQuerySpaces() {
if ( synchronizedQuerySpaces == null ) { if ( synchronizedQuerySpaces == null ) {
synchronizedQuerySpaces = new HashSet<String>(); synchronizedQuerySpaces = new HashSet<String>();
@ -374,16 +482,22 @@ public class ProcedureCallImpl extends AbstractBasicQueryContractImpl implements
return buildQueryParametersObject(); return buildQueryParametersObject();
} }
@Override
public QueryParameters buildQueryParametersObject() { public QueryParameters buildQueryParametersObject() {
QueryParameters qp = super.buildQueryParametersObject(); final QueryParameters qp = super.buildQueryParametersObject();
// both of these are for documentation purposes, they are actually handled directly... // both of these are for documentation purposes, they are actually handled directly...
qp.setAutoDiscoverScalarTypes( true ); qp.setAutoDiscoverScalarTypes( true );
qp.setCallable( true ); qp.setCallable( true );
return qp; return qp;
} }
/**
* Collects any parameter registrations which indicate a REF_CURSOR parameter type/mode.
*
* @return The collected REF_CURSOR type parameters.
*/
public ParameterRegistrationImplementor[] collectRefCursorParameters() { public ParameterRegistrationImplementor[] collectRefCursorParameters() {
List<ParameterRegistrationImplementor> refCursorParams = new ArrayList<ParameterRegistrationImplementor>(); final List<ParameterRegistrationImplementor> refCursorParams = new ArrayList<ParameterRegistrationImplementor>();
for ( ParameterRegistrationImplementor param : registeredParameters ) { for ( ParameterRegistrationImplementor param : registeredParameters ) {
if ( param.getMode() == ParameterMode.REF_CURSOR ) { if ( param.getMode() == ParameterMode.REF_CURSOR ) {
refCursorParams.add( param ); refCursorParams.add( param );
@ -391,4 +505,29 @@ public class ProcedureCallImpl extends AbstractBasicQueryContractImpl implements
} }
return refCursorParams.toArray( new ParameterRegistrationImplementor[refCursorParams.size()] ); return refCursorParams.toArray( new ParameterRegistrationImplementor[refCursorParams.size()] );
} }
@Override
public ProcedureCallMemento extractMemento(Map<String, Object> hints) {
return new ProcedureCallMementoImpl(
procedureName,
Util.copy( queryReturns ),
parameterStrategy,
toParameterMementos( registeredParameters ),
Util.copy( synchronizedQuerySpaces ),
Util.copy( hints )
);
}
private static List<ProcedureCallMementoImpl.ParameterMemento> toParameterMementos(List<ParameterRegistrationImplementor<?>> registeredParameters) {
if ( registeredParameters == null ) {
return null;
}
final List<ProcedureCallMementoImpl.ParameterMemento> copy = CollectionHelper.arrayList( registeredParameters.size() );
for ( ParameterRegistrationImplementor registration : registeredParameters ) {
copy.add( ProcedureCallMementoImpl.ParameterMemento.fromRegistration( registration ) );
}
return copy;
}
} }

View File

@ -0,0 +1,179 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2013, 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.procedure.internal;
import javax.persistence.ParameterMode;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.hibernate.Session;
import org.hibernate.engine.query.spi.sql.NativeSQLQueryReturn;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.procedure.ProcedureCall;
import org.hibernate.procedure.ProcedureCallMemento;
import org.hibernate.type.Type;
/**
* Implementation of ProcedureCallMemento
*
* @author Steve Ebersole
*/
public class ProcedureCallMementoImpl implements ProcedureCallMemento {
private final String procedureName;
private final NativeSQLQueryReturn[] queryReturns;
private final ParameterStrategy parameterStrategy;
private final List<ParameterMemento> parameterDeclarations;
private final Set<String> synchronizedQuerySpaces;
private final Map<String,Object> hintsMap;
/**
* Constructs a ProcedureCallImpl
*
* @param procedureName The name of the procedure to be called
* @param queryReturns The result mappings
* @param parameterStrategy Are parameters named or positional?
* @param parameterDeclarations The parameters registrations
* @param synchronizedQuerySpaces Any query spaces to synchronize on execution
* @param hintsMap Map of JPA query hints
*/
public ProcedureCallMementoImpl(
String procedureName,
NativeSQLQueryReturn[] queryReturns,
ParameterStrategy parameterStrategy,
List<ParameterMemento> parameterDeclarations,
Set<String> synchronizedQuerySpaces,
Map<String,Object> hintsMap) {
this.procedureName = procedureName;
this.queryReturns = queryReturns;
this.parameterStrategy = parameterStrategy;
this.parameterDeclarations = parameterDeclarations;
this.synchronizedQuerySpaces = synchronizedQuerySpaces;
this.hintsMap = hintsMap;
}
@Override
public ProcedureCall makeProcedureCall(Session session) {
return new ProcedureCallImpl( (SessionImplementor) session, this );
}
@Override
public ProcedureCall makeProcedureCall(SessionImplementor session) {
return new ProcedureCallImpl( session, this );
}
public String getProcedureName() {
return procedureName;
}
public NativeSQLQueryReturn[] getQueryReturns() {
return queryReturns;
}
public ParameterStrategy getParameterStrategy() {
return parameterStrategy;
}
public List<ParameterMemento> getParameterDeclarations() {
return parameterDeclarations;
}
public Set<String> getSynchronizedQuerySpaces() {
return synchronizedQuerySpaces;
}
@Override
public Map<String, Object> getHintsMap() {
return hintsMap;
}
/**
* A "disconnected" copy of the metadata for a parameter, that can be used in ProcedureCallMementoImpl.
*/
public static class ParameterMemento {
private final Integer position;
private final String name;
private final ParameterMode mode;
private final Class type;
private final Type hibernateType;
/**
* Create the memento
*
* @param position The parameter position
* @param name The parameter name
* @param mode The parameter mode
* @param type The Java type of the parameter
* @param hibernateType The Hibernate Type.
*/
public ParameterMemento(int position, String name, ParameterMode mode, Class type, Type hibernateType) {
this.position = position;
this.name = name;
this.mode = mode;
this.type = type;
this.hibernateType = hibernateType;
}
public Integer getPosition() {
return position;
}
public String getName() {
return name;
}
public ParameterMode getMode() {
return mode;
}
public Class getType() {
return type;
}
public Type getHibernateType() {
return hibernateType;
}
/**
* Build a ParameterMemento from the given parameter registration
*
* @param registration The parameter registration from a ProcedureCall
*
* @return The memento
*/
public static ParameterMemento fromRegistration(ParameterRegistrationImplementor registration) {
return new ParameterMemento(
registration.getPosition(),
registration.getName(),
registration.getMode(),
registration.getType(),
registration.getHibernateType()
);
}
}
}

View File

@ -35,6 +35,8 @@ import org.hibernate.result.Return;
import org.hibernate.result.internal.ResultImpl; import org.hibernate.result.internal.ResultImpl;
/** /**
* Implementation of ProcedureResult. Defines centralized access to all of the results of a procedure call.
*
* @author Steve Ebersole * @author Steve Ebersole
*/ */
public class ProcedureResultImpl extends ResultImpl implements ProcedureResult { public class ProcedureResultImpl extends ResultImpl implements ProcedureResult {
@ -42,7 +44,7 @@ public class ProcedureResultImpl extends ResultImpl implements ProcedureResult {
private final CallableStatement callableStatement; private final CallableStatement callableStatement;
private final ParameterRegistrationImplementor[] refCursorParameters; private final ParameterRegistrationImplementor[] refCursorParameters;
private int refCursorParamIndex = 0; private int refCursorParamIndex;
ProcedureResultImpl(ProcedureCallImpl procedureCall, CallableStatement callableStatement) { ProcedureResultImpl(ProcedureCallImpl procedureCall, CallableStatement callableStatement) {
super( procedureCall, callableStatement ); super( procedureCall, callableStatement );
@ -80,9 +82,9 @@ public class ProcedureResultImpl extends ResultImpl implements ProcedureResult {
@Override @Override
protected Return buildExtendedReturn(CurrentReturnDescriptor returnDescriptor) { protected Return buildExtendedReturn(CurrentReturnDescriptor returnDescriptor) {
this.refCursorParamIndex++; this.refCursorParamIndex++;
final int refCursorParamIndex = ( (ProcedureCurrentReturnDescriptor) returnDescriptor ).refCursorParamIndex;
final ParameterRegistrationImplementor refCursorParam = refCursorParameters[refCursorParamIndex];
ResultSet resultSet; ResultSet resultSet;
int refCursorParamIndex = ( (ProcedureCurrentReturnDescriptor) returnDescriptor ).refCursorParamIndex;
ParameterRegistrationImplementor refCursorParam = refCursorParameters[refCursorParamIndex];
if ( refCursorParam.getName() != null ) { if ( refCursorParam.getName() != null ) {
resultSet = procedureCall.getSession().getFactory().getServiceRegistry() resultSet = procedureCall.getSession().getFactory().getServiceRegistry()
.getService( RefCursorSupport.class ) .getService( RefCursorSupport.class )

View File

@ -0,0 +1,189 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2013, 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.procedure.internal;
import java.util.Map;
import java.util.Set;
import org.hibernate.LockMode;
import org.hibernate.MappingException;
import org.hibernate.engine.ResultSetMappingDefinition;
import org.hibernate.engine.query.spi.sql.NativeSQLQueryReturn;
import org.hibernate.engine.query.spi.sql.NativeSQLQueryRootReturn;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.internal.util.collections.CollectionHelper;
import org.hibernate.loader.custom.sql.SQLQueryReturnProcessor;
import org.hibernate.persister.entity.EntityPersister;
/**
* Utilities used to implement procedure call support.
*
* @author Steve Ebersole
*/
public class Util {
private Util() {
}
/**
* Makes a copy of the given query return array.
*
* @param queryReturns The returns to copy
*
* @return The copy
*/
public static NativeSQLQueryReturn[] copy(NativeSQLQueryReturn[] queryReturns) {
if ( queryReturns == null ) {
return new NativeSQLQueryReturn[0];
}
final NativeSQLQueryReturn[] copy = new NativeSQLQueryReturn[ queryReturns.length ];
System.arraycopy( queryReturns, 0, copy, 0, queryReturns.length );
return copy;
}
/**
* Make a (shallow) copy of query spaces to be synchronized
*
* @param synchronizedQuerySpaces The query spaces
*
* @return The copy
*/
public static Set<String> copy(Set<String> synchronizedQuerySpaces) {
return CollectionHelper.makeCopy( synchronizedQuerySpaces );
}
/**
* Make a (shallow) copy of the JPA query hints map
*
* @param hints The JPA query hints to copy
*
* @return The copy
*/
public static Map<String,Object> copy(Map<String, Object> hints) {
return CollectionHelper.makeCopy( hints );
}
/**
* Context for resolving result-set-mapping definitions
*/
public static interface ResultSetMappingResolutionContext {
/**
* Access to the SessionFactory
*
* @return SessionFactory
*/
public SessionFactoryImplementor getSessionFactory();
/**
* Locate a ResultSetMappingDefinition by name
*
* @param name The name of the ResultSetMappingDefinition to locate
*
* @return The ResultSetMappingDefinition
*/
public ResultSetMappingDefinition findResultSetMapping(String name);
/**
* Callback to add query returns indicated by the result set mapping(s)
*
* @param queryReturns The query returns
*/
public void addQueryReturns(NativeSQLQueryReturn... queryReturns);
/**
* Callback to add query spaces indicated by the result set mapping(s)
*
* @param querySpaces The query spaces
*/
public void addQuerySpaces(String... querySpaces);
}
/**
* Resolve the given result set mapping names
*
* @param context The context for the resolution. See {@link ResultSetMappingResolutionContext}
* @param resultSetMappingNames The names of the result-set-mappings to resolve
*/
public static void resolveResultSetMappings(ResultSetMappingResolutionContext context, String... resultSetMappingNames) {
for ( String resultSetMappingName : resultSetMappingNames ) {
final ResultSetMappingDefinition mapping = context.findResultSetMapping( resultSetMappingName );
if ( mapping == null ) {
throw new MappingException( "Unknown SqlResultSetMapping [" + resultSetMappingName + "]" );
}
context.addQueryReturns( mapping.getQueryReturns() );
final SQLQueryReturnProcessor processor =
new SQLQueryReturnProcessor( mapping.getQueryReturns(), context.getSessionFactory() );
final SQLQueryReturnProcessor.ResultAliasContext processResult = processor.process();
context.addQuerySpaces( processResult.collectQuerySpaces() );
}
}
/**
* Context for resolving result-class definitions
*/
public static interface ResultClassesResolutionContext {
/**
* Access to the SessionFactory
*
* @return SessionFactory
*/
public SessionFactoryImplementor getSessionFactory();
/**
* Callback to add query returns indicated by the result set mapping(s)
*
* @param queryReturns The query returns
*/
public void addQueryReturns(NativeSQLQueryReturn... queryReturns);
/**
* Callback to add query spaces indicated by the result set mapping(s)
*
* @param querySpaces The query spaces
*/
public void addQuerySpaces(String... querySpaces);
}
/**
* Resolve the given result classes
*
* @param context The context for the resolution. See {@link ResultSetMappingResolutionContext}
* @param resultClasses The Classes to which the results should be mapped
*/
public static void resolveResultClasses(ResultClassesResolutionContext context, Class... resultClasses) {
int i = 0;
for ( Class resultClass : resultClasses ) {
context.addQueryReturns(
new NativeSQLQueryRootReturn( "alias" + (++i), resultClass.getName(), LockMode.READ )
);
try {
final EntityPersister persister = context.getSessionFactory().getEntityPersister( resultClass.getName() );
context.addQuerySpaces( (String[]) persister.getQuerySpaces() );
}
catch (Exception ignore) {
}
}
}
}

View File

@ -0,0 +1,4 @@
/**
* Defines the internal support for implementing stored procedure calling.
*/
package org.hibernate.procedure.internal;

View File

@ -26,10 +26,18 @@ package org.hibernate.test.annotations.collectionelement.ordered;
import org.junit.Test; import org.junit.Test;
import org.hibernate.Session; import org.hibernate.Session;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.junit.Assert;
import org.hibernate.persister.collection.BasicCollectionPersister;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
/** /**
* @author Steve Ebersole * @author Steve Ebersole
* @author Lukasz Antoniak (lukasz dot antoniak at gmail dot com)
*/ */
public class ElementCollectionSortingTest extends BaseCoreFunctionalTestCase { public class ElementCollectionSortingTest extends BaseCoreFunctionalTestCase {
@Override @Override
@ -53,4 +61,71 @@ public class ElementCollectionSortingTest extends BaseCoreFunctionalTestCase {
session.getTransaction().commit(); session.getTransaction().commit();
session.close(); session.close();
} }
@Test
@TestForIssue( jiraKey = "HHH-6875" )
public void testSortingEmbeddableCollectionOfPrimitives() {
final Session session = openSession();
session.beginTransaction();
final Person steve = new Person();
steve.setName( "Steve" );
steve.getNickNamesAscendingNaturalSort().add( "sebersole" );
steve.getNickNamesAscendingNaturalSort().add( "ebersole" );
steve.getNickNamesDescendingNaturalSort().add( "ebersole" );
steve.getNickNamesDescendingNaturalSort().add( "sebersole" );
final Person lukasz = new Person();
lukasz.setName( "Lukasz" );
lukasz.getNickNamesAscendingNaturalSort().add( "antoniak" );
lukasz.getNickNamesAscendingNaturalSort().add( "lantoniak" );
lukasz.getNickNamesDescendingNaturalSort().add( "lantoniak" );
lukasz.getNickNamesDescendingNaturalSort().add( "antoniak" );
session.save( steve );
session.save( lukasz );
session.flush();
session.clear();
final List<String> lukaszNamesAsc = Arrays.asList( "antoniak", "lantoniak" );
final List<String> lukaszNamesDesc = Arrays.asList( "lantoniak", "antoniak" );
final List<String> steveNamesAsc = Arrays.asList( "ebersole", "sebersole" );
final List<String> steveNamesDesc = Arrays.asList( "sebersole", "ebersole" );
// Testing object graph navigation. Lazy loading collections.
checkPersonNickNames( lukaszNamesAsc, lukaszNamesDesc, (Person) session.get( Person.class, lukasz.getId() ) );
checkPersonNickNames( steveNamesAsc, steveNamesDesc, (Person) session.get( Person.class, steve.getId() ) );
session.clear();
// Testing HQL query. Eagerly fetching nicknames.
final List<Person> result = session.createQuery(
"select distinct p from Person p join fetch p.nickNamesAscendingNaturalSort join fetch p.nickNamesDescendingNaturalSort order by p.name"
).list();
Assert.assertEquals( 2, result.size() );
checkPersonNickNames( lukaszNamesAsc, lukaszNamesDesc, result.get( 0 ) );
checkPersonNickNames( steveNamesAsc, steveNamesDesc, result.get( 1 ) );
// Metadata verification.
checkSQLOrderBy( session, Person.class.getName(), "nickNamesAscendingNaturalSort", "asc" );
checkSQLOrderBy( session, Person.class.getName(), "nickNamesDescendingNaturalSort", "desc" );
session.getTransaction().rollback();
session.close();
}
private void checkSQLOrderBy(Session session, String entityName, String propertyName, String order) {
String roleName = entityName + "." + propertyName;
String alias = "alias1";
BasicCollectionPersister collectionPersister = (BasicCollectionPersister) session.getSessionFactory().getCollectionMetadata( roleName );
Assert.assertTrue( collectionPersister.hasOrdering() );
Assert.assertEquals( alias + "." + propertyName + " " + order, collectionPersister.getSQLOrderByString( alias ) );
}
private void checkPersonNickNames(List<String> expectedAscending, List<String> expectedDescending, Person person) {
// Comparing lists to verify ordering.
Assert.assertEquals( expectedAscending, new ArrayList<String>( person.getNickNamesAscendingNaturalSort() ) );
Assert.assertEquals( expectedDescending, new ArrayList<String>( person.getNickNamesDescendingNaturalSort() ) );
}
} }

View File

@ -23,14 +23,14 @@
*/ */
package org.hibernate.test.annotations.derivedidentities.bidirectional; package org.hibernate.test.annotations.derivedidentities.bidirectional;
import org.junit.Test; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import org.hibernate.Session; import org.hibernate.Session;
import org.hibernate.testing.FailureExpected; import org.hibernate.testing.FailureExpected;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
@FailureExpected(jiraKey = "HHH-5695") @FailureExpected(jiraKey = "HHH-5695")
public class OneToOneWithDerivedIdentityTest extends BaseCoreFunctionalTestCase { public class OneToOneWithDerivedIdentityTest extends BaseCoreFunctionalTestCase {
@ -58,6 +58,29 @@ public class OneToOneWithDerivedIdentityTest extends BaseCoreFunctionalTestCase
s.close(); s.close();
} }
@Test
@TestForIssue(jiraKey = "HHH-6813")
public void testSelectWithDerivedId() {
Session s = openSession();
s.beginTransaction();
Bar bar = new Bar();
bar.setDetails( "Some details" );
Foo foo = new Foo();
foo.setBar( bar );
bar.setFoo( foo );
s.persist( foo );
s.flush();
assertNotNull( foo.getId() );
assertEquals( foo.getId(), bar.getFoo().getId() );
s.clear();
Foo newFoo = (Foo) s.createQuery( "SELECT f FROM Foo f" ).uniqueResult();
assertNotNull( newFoo );
assertEquals( "Some details", newFoo.getBar().getDetails() );
s.getTransaction().rollback();
s.close();
}
@Override @Override
protected Class<?>[] getAnnotatedClasses() { protected Class<?>[] getAnnotatedClasses() {
return new Class<?>[] { return new Class<?>[] {

View File

@ -0,0 +1,91 @@
package org.hibernate.test.annotations.inheritance.singletable;
import javax.persistence.DiscriminatorColumn;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import org.junit.Assert;
import org.junit.Test;
import org.hibernate.MappingException;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.testing.ServiceRegistryBuilder;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.junit4.BaseUnitTestCase;
/**
* @author Lukasz Antoniak (lukasz dot antoniak at gmail dot com)
*/
@TestForIssue( jiraKey = "HHH-7214" )
public class DuplicatedDiscriminatorValueTest extends BaseUnitTestCase {
private static final String DISCRIMINATOR_VALUE = "D";
@Test
public void testDuplicatedDiscriminatorValueSameHierarchy() {
try {
tryBuildingSessionFactory( Building.class, Building1.class, Building2.class );
Assert.fail( MappingException.class.getName() + " expected when two subclasses are mapped with the same discriminator value." );
}
catch ( MappingException e ) {
final String errorMsg = e.getCause().getMessage();
// Check if error message contains descriptive information.
Assert.assertTrue( errorMsg.contains( Building1.class.getName() ) );
Assert.assertTrue( errorMsg.contains( Building2.class.getName() ) );
Assert.assertTrue( errorMsg.contains( "discriminator value '" + DISCRIMINATOR_VALUE + "'." ) );
}
}
@Test
public void testDuplicatedDiscriminatorValueDifferentHierarchy() {
tryBuildingSessionFactory( Building.class, Building1.class, Furniture.class, Chair.class );
}
private void tryBuildingSessionFactory(Class... annotatedClasses) {
Configuration cfg = new Configuration();
for ( Class annotatedClass : annotatedClasses ) {
cfg.addAnnotatedClass( annotatedClass );
}
ServiceRegistry serviceRegistry = null;
SessionFactory sessionFactory = null;
try {
serviceRegistry = ServiceRegistryBuilder.buildServiceRegistry( cfg.getProperties() );
sessionFactory = cfg.buildSessionFactory( serviceRegistry );
}
finally {
if ( sessionFactory != null ) {
sessionFactory.close();
}
if ( serviceRegistry != null ) {
ServiceRegistryBuilder.destroy( serviceRegistry );
}
}
}
@Entity
@DiscriminatorValue(DISCRIMINATOR_VALUE) // Duplicated discriminator value in single hierarchy.
private static class Building1 extends Building {
}
@Entity
@DiscriminatorValue(DISCRIMINATOR_VALUE) // Duplicated discriminator value in single hierarchy.
private static class Building2 extends Building {
}
@Entity
@DiscriminatorColumn(name = "entity_type")
@DiscriminatorValue("F")
private static class Furniture {
@Id
@GeneratedValue
private Integer id;
}
@Entity
@DiscriminatorValue(DISCRIMINATOR_VALUE) // Duplicated discriminator value in different hierarchy.
private static class Chair extends Furniture {
}
}

View File

@ -0,0 +1,94 @@
package org.hibernate.test.collection.basic;
import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.Basic;
import javax.persistence.CollectionTable;
import javax.persistence.ElementCollection;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.Table;
@Entity
@Table(name="contact")
public class Contact implements Serializable {
private static final long serialVersionUID = 1L;
private Long id;
private String name;
private Set<EmailAddress> emailAddresses = new HashSet<EmailAddress>();
private Set<EmailAddress> emailAddresses2 = new HashSet<EmailAddress>();
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
@Basic
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@ElementCollection
@CollectionTable(name = "user_email_addresses2", joinColumns = @JoinColumn(name = "user_id", referencedColumnName = "id"))
public Set<EmailAddress> getEmailAddresses2() {
return emailAddresses2;
}
public void setEmailAddresses2(Set<EmailAddress> emailAddresses2) {
this.emailAddresses2 = emailAddresses2;
}
@ElementCollection
@CollectionTable(name = "user_email_addresses", joinColumns = @JoinColumn(name = "user_id", referencedColumnName = "id"))
public Set<EmailAddress> getEmailAddresses() {
return emailAddresses;
}
public void setEmailAddresses(Set<EmailAddress> emailAddresses) {
this.emailAddresses = emailAddresses;
}
@Override
public int hashCode() {
int hash = 0;
hash += (id != null ? id.hashCode() : 0);
return hash;
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (!(obj instanceof Contact)) {
return false;
}
final Contact other = (Contact) obj;
if (this.id == null || other.id == null) {
return this == obj;
}
if(!this.id.equals(other.id)) {
return this == obj;
}
return true;
}
@Override
public String toString() {
return "com.clevercure.web.hibernateissuecache.User[ id=" + id + " ]";
}
}

View File

@ -0,0 +1,56 @@
package org.hibernate.test.collection.basic;
import java.io.Serializable;
import javax.persistence.*;
@Embeddable
public class EmailAddress implements Serializable {
private static final long serialVersionUID = 1L;
private String email;
public EmailAddress() {
}
public EmailAddress(String email) {
this.email = email;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
@Override
public int hashCode() {
int hash = 0;
hash += (email != null ? email.hashCode() : 0);
return hash;
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (!(obj instanceof EmailAddress)) {
return false;
}
final EmailAddress other = (EmailAddress) obj;
if (this.email == null || other.email == null) {
return this == obj;
}
if(!this.email.equals(other.email)) {
return this == obj;
}
return true;
}
@Override
public String toString() {
return "com.clevercure.web.hibernateissuecache.EmailAddress[ email=" + email + " ]";
}
}

View File

@ -0,0 +1,133 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2013, 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.collection.basic;
import java.util.HashSet;
import java.util.Set;
import org.hibernate.Session;
import org.junit.Assert;
import org.junit.Test;
import org.hibernate.testing.FailureExpected;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
public class JoinFetchElementCollectionTest extends BaseCoreFunctionalTestCase {
@Override
protected Class<?>[] getAnnotatedClasses() {
return new Class[] {Contact.class, EmailAddress.class, User.class};
}
@Test
@TestForIssue(jiraKey = "HHH-8206")
@FailureExpected(jiraKey = "HHH-8206", message = "This is not explicitly supported, however should arguably throw an exception")
public void testJoinFetchesByPath() {
Set<EmailAddress> emailAddresses = new HashSet<EmailAddress>();
emailAddresses.add( new EmailAddress( "test1@test.com" ) );
emailAddresses.add( new EmailAddress( "test2@test.com" ) );
emailAddresses.add( new EmailAddress( "test3@test.com" ) );
{
// Session 1: Insert a user with email addresses but no emailAddresses2
Session session = openSession();
session.beginTransaction();
User user = new User();
user.setName( "john" );
Contact contact = new Contact();
contact.setName( "John Doe" );
contact.setEmailAddresses( emailAddresses );
contact = (Contact) session.merge( contact );
user.setContact( contact );
user = (User) session.merge( user );
session.getTransaction().commit();
session.close();
}
{
// Session 2: Retrieve the user object and check if the sets have the expected values
Session session = openSession();
session.beginTransaction();
final String qry = "SELECT user "
+ "FROM User user "
+ "LEFT OUTER JOIN FETCH user.contact "
+ "LEFT OUTER JOIN FETCH user.contact.emailAddresses2 "
+ "LEFT OUTER JOIN FETCH user.contact.emailAddresses";
User user = (User) session.createQuery( qry ).uniqueResult();
session.getTransaction().commit();
session.close();
Assert.assertEquals( emailAddresses, user.getContact().getEmailAddresses() );
Assert.assertTrue( user.getContact().getEmailAddresses2().isEmpty() );
}
}
@Test
@TestForIssue(jiraKey = "HHH-5465")
public void testJoinFetchElementCollection() {
Set<EmailAddress> emailAddresses = new HashSet<EmailAddress>();
emailAddresses.add( new EmailAddress( "test1@test.com" ) );
emailAddresses.add( new EmailAddress( "test2@test.com" ) );
emailAddresses.add( new EmailAddress( "test3@test.com" ) );
{
// Session 1: Insert a user with email addresses but no emailAddresses2
Session session = openSession();
session.beginTransaction();
User user = new User();
user.setName( "john" );
Contact contact = new Contact();
contact.setName( "John Doe" );
contact.setEmailAddresses( emailAddresses );
contact = (Contact) session.merge( contact );
user.setContact( contact );
user = (User) session.merge( user );
session.getTransaction().commit();
session.close();
}
{
// Session 2: Retrieve the user object and check if the sets have the expected values
Session session = openSession();
session.beginTransaction();
final String qry = "SELECT user "
+ "FROM User user "
+ "LEFT OUTER JOIN FETCH user.contact c "
+ "LEFT OUTER JOIN FETCH c.emailAddresses2 "
+ "LEFT OUTER JOIN FETCH c.emailAddresses";
User user = (User) session.createQuery( qry ).uniqueResult();
session.getTransaction().commit();
session.close();
Assert.assertEquals( emailAddresses, user.getContact().getEmailAddresses() );
Assert.assertTrue( user.getContact().getEmailAddresses2().isEmpty() );
}
}
}

View File

@ -0,0 +1,80 @@
package org.hibernate.test.collection.basic;
import java.io.Serializable;
import javax.persistence.Basic;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
@Entity
@Table(name="users")
public class User implements Serializable {
private static final long serialVersionUID = 1L;
private Long id;
private String name;
private Contact contact;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
@Basic
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@ManyToOne(optional = true)
@JoinColumn(name = "contact_id", nullable = true, unique = true)
public Contact getContact() {
return contact;
}
public void setContact(Contact contact) {
this.contact = contact;
}
@Override
public int hashCode() {
int hash = 0;
hash += (id != null ? id.hashCode() : 0);
return hash;
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (!(obj instanceof User)) {
return false;
}
final User other = (User) obj;
if (this.id == null || other.id == null) {
return this == obj;
}
if(!this.id.equals(other.id)) {
return this == obj;
}
return true;
}
@Override
public String toString() {
return "com.clevercure.web.hibernateissuecache.User[ id=" + id + " ]";
}
}

View File

@ -0,0 +1,187 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* JBoss, Home of Professional Open Source
* Copyright 2013 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.test.schemavalidation;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.cfg.Configuration;
import org.hibernate.dialect.Oracle9iDialect;
import org.hibernate.testing.RequiresDialect;
import org.hibernate.testing.junit4.BaseUnitTestCase;
import org.hibernate.tool.hbm2ddl.SchemaValidator;
import org.junit.Test;
/**
* @author Brett Meyer
*/
@RequiresDialect( Oracle9iDialect.class )
public class SynonymValidationTest extends BaseUnitTestCase {
@Test
public void testSynonymValidation() {
// Session s = openSession();
// s.getTransaction().begin();
// s.createSQLQuery( "CREATE SYNONYM test_synonym FOR test_entity" ).executeUpdate();
// s.getTransaction().commit();
// s.close();
Configuration cfg = new Configuration();
// cfg.addAnnotatedClass( TestEntityWithSynonym.class );
cfg.addAnnotatedClass( TestEntity.class );
cfg.setProperty( AvailableSettings.ENABLE_SYNONYMS, "true" );
cfg.setProperty( "hibernate.connection.includeSynonyms", "true" );
cfg.getProperties().put( "includeSynonyms", true );
// SchemaValidator schemaValidator = new SchemaValidator( serviceRegistry(), cfg );
SchemaValidator schemaValidator = new SchemaValidator( cfg );
schemaValidator.validate();
// s = openSession();
// s.getTransaction().begin();
// s.createSQLQuery( "DROP SYNONYM test_synonym FORCE" ).executeUpdate();
// s.getTransaction().commit();
// s.close();
}
// protected Class<?>[] getAnnotatedClasses() {
// return new Class<?>[] { TestEntity.class };
// }
@Entity
@Table(name = "TEST_SYN")
private static class TestEntity implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue
private Long id;
@Column(nullable = false)
private String key;
private String value;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
// @Entity
// @Table(name = "test_entity")
// private static class TestEntity {
// @Id
// @GeneratedValue
// private Long id;
//
// @Column(nullable = false)
// private String key;
//
// private String value;
//
// public Long getId() {
// return id;
// }
//
// public void setId(Long id) {
// this.id = id;
// }
//
// public String getKey() {
// return key;
// }
//
// public void setKey(String key) {
// this.key = key;
// }
//
// public String getValue() {
// return value;
// }
//
// public void setValue(String value) {
// this.value = value;
// }
// }
//
// @Entity
// @Table(name = "test_synonym")
// private static class TestEntityWithSynonym {
// @Id
// @GeneratedValue
// private Long id;
//
// @Column(nullable = false)
// private String key;
//
// private String value;
//
// public Long getId() {
// return id;
// }
//
// public void setId(Long id) {
// this.id = id;
// }
//
// public String getKey() {
// return key;
// }
//
// public void setKey(String key) {
// this.key = key;
// }
//
// public String getValue() {
// return value;
// }
//
// public void setValue(String value) {
// this.value = value;
// }
// }
}

View File

@ -212,7 +212,7 @@ public class EhcacheTransactionalDataRegion extends EhcacheDataRegion implements
* *
* @throws CacheException Indicates a problem accessing the cache * @throws CacheException Indicates a problem accessing the cache
*/ */
public final void writeLock(Object key) { public final void writeLock(Object key) throws CacheException {
try { try {
lockProvider.getSyncForKey( key ).lock( LockType.WRITE ); lockProvider.getSyncForKey( key ).lock( LockType.WRITE );
} }
@ -234,7 +234,7 @@ public class EhcacheTransactionalDataRegion extends EhcacheDataRegion implements
* *
* @throws CacheException Indicates a problem accessing the cache * @throws CacheException Indicates a problem accessing the cache
*/ */
public final void writeUnlock(Object key) { public final void writeUnlock(Object key) throws CacheException {
try { try {
lockProvider.getSyncForKey( key ).unlock( LockType.WRITE ); lockProvider.getSyncForKey( key ).unlock( LockType.WRITE );
} }
@ -256,7 +256,7 @@ public class EhcacheTransactionalDataRegion extends EhcacheDataRegion implements
* *
* @throws CacheException Indicates a problem accessing the cache * @throws CacheException Indicates a problem accessing the cache
*/ */
public final void readLock(Object key) { public final void readLock(Object key) throws CacheException {
try { try {
lockProvider.getSyncForKey( key ).lock( LockType.WRITE ); lockProvider.getSyncForKey( key ).lock( LockType.WRITE );
} }
@ -278,7 +278,7 @@ public class EhcacheTransactionalDataRegion extends EhcacheDataRegion implements
* *
* @throws CacheException Indicates a problem accessing the cache * @throws CacheException Indicates a problem accessing the cache
*/ */
public final void readUnlock(Object key) { public final void readUnlock(Object key) throws CacheException {
try { try {
lockProvider.getSyncForKey( key ).unlock( LockType.WRITE ); lockProvider.getSyncForKey( key ).unlock( LockType.WRITE );
} }

View File

@ -103,6 +103,7 @@ public abstract class AbstractEmitterBean extends StandardMBean implements Notif
/** /**
* Dispose of this SampledCacheManager and clean up held resources * Dispose of this SampledCacheManager and clean up held resources
*/ */
@SuppressWarnings("UnusedDeclaration")
public final void dispose() { public final void dispose() {
doDispose(); doDispose();
removeAllNotificationListeners(); removeAllNotificationListeners();
@ -138,6 +139,9 @@ public abstract class AbstractEmitterBean extends StandardMBean implements Notif
notificationListeners.clear(); notificationListeners.clear();
} }
/**
* {@inheritDoc}
*/
@Override @Override
public abstract MBeanNotificationInfo[] getNotificationInfo(); public abstract MBeanNotificationInfo[] getNotificationInfo();

View File

@ -95,7 +95,7 @@ public abstract class CacheRegionUtils {
} }
boolean truncate = true; boolean truncate = true;
for ( int i = 0; i < comps.length; i++ ) { for ( int i = 0; i < comps.length; i++ ) {
String comp = comps[i]; final String comp = comps[i];
final char c = comp.charAt( 0 ); final char c = comp.charAt( 0 );
if ( truncate && Character.isUpperCase( c ) ) { if ( truncate && Character.isUpperCase( c ) ) {
truncate = false; truncate = false;

View File

@ -63,7 +63,7 @@ public class EhcacheHibernate extends AbstractEmitterBean implements EhcacheHibe
* *
* @param manager the backing {@link CacheManager} * @param manager the backing {@link CacheManager}
* *
* @throws NotCompliantMBeanException * @throws NotCompliantMBeanException if bean doesn't comply
*/ */
public EhcacheHibernate(CacheManager manager) throws NotCompliantMBeanException { public EhcacheHibernate(CacheManager manager) throws NotCompliantMBeanException {
super( EhcacheHibernateMBean.class ); super( EhcacheHibernateMBean.class );
@ -72,6 +72,7 @@ public class EhcacheHibernate extends AbstractEmitterBean implements EhcacheHibe
/** /**
* Enable hibernate statistics with the input session factory * Enable hibernate statistics with the input session factory
* @param sessionFactory the session factory to enable stats for
*/ */
public void enableHibernateStatistics(SessionFactory sessionFactory) { public void enableHibernateStatistics(SessionFactory sessionFactory) {
try { try {
@ -85,6 +86,7 @@ public class EhcacheHibernate extends AbstractEmitterBean implements EhcacheHibe
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override
public boolean isHibernateStatisticsSupported() { public boolean isHibernateStatisticsSupported() {
return hibernateStats instanceof HibernateStatsImpl; return hibernateStats instanceof HibernateStatsImpl;
} }
@ -92,6 +94,7 @@ public class EhcacheHibernate extends AbstractEmitterBean implements EhcacheHibe
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override
public void setStatisticsEnabled(boolean flag) { public void setStatisticsEnabled(boolean flag) {
if ( flag ) { if ( flag ) {
ehcacheStats.enableStats(); ehcacheStats.enableStats();
@ -108,6 +111,7 @@ public class EhcacheHibernate extends AbstractEmitterBean implements EhcacheHibe
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override
public boolean isStatisticsEnabled() { public boolean isStatisticsEnabled() {
return statsEnabled.get(); return statsEnabled.get();
} }
@ -115,6 +119,7 @@ public class EhcacheHibernate extends AbstractEmitterBean implements EhcacheHibe
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override
public void clearStats() { public void clearStats() {
ehcacheStats.clearStats(); ehcacheStats.clearStats();
hibernateStats.clearStats(); hibernateStats.clearStats();
@ -123,6 +128,7 @@ public class EhcacheHibernate extends AbstractEmitterBean implements EhcacheHibe
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override
public void disableStats() { public void disableStats() {
setStatisticsEnabled( false ); setStatisticsEnabled( false );
} }
@ -130,6 +136,7 @@ public class EhcacheHibernate extends AbstractEmitterBean implements EhcacheHibe
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override
public void enableStats() { public void enableStats() {
setStatisticsEnabled( true ); setStatisticsEnabled( true );
} }
@ -137,6 +144,7 @@ public class EhcacheHibernate extends AbstractEmitterBean implements EhcacheHibe
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override
public void flushRegionCache(String region) { public void flushRegionCache(String region) {
ehcacheStats.flushRegionCache( region ); ehcacheStats.flushRegionCache( region );
sendNotification( HibernateStats.CACHE_REGION_FLUSHED, region ); sendNotification( HibernateStats.CACHE_REGION_FLUSHED, region );
@ -145,6 +153,7 @@ public class EhcacheHibernate extends AbstractEmitterBean implements EhcacheHibe
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override
public void flushRegionCaches() { public void flushRegionCaches() {
ehcacheStats.flushRegionCaches(); ehcacheStats.flushRegionCaches();
sendNotification( HibernateStats.CACHE_FLUSHED ); sendNotification( HibernateStats.CACHE_FLUSHED );
@ -153,6 +162,7 @@ public class EhcacheHibernate extends AbstractEmitterBean implements EhcacheHibe
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override
public String generateActiveConfigDeclaration() { public String generateActiveConfigDeclaration() {
return ehcacheStats.generateActiveConfigDeclaration(); return ehcacheStats.generateActiveConfigDeclaration();
} }
@ -160,6 +170,7 @@ public class EhcacheHibernate extends AbstractEmitterBean implements EhcacheHibe
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override
public String generateActiveConfigDeclaration(String region) { public String generateActiveConfigDeclaration(String region) {
return ehcacheStats.generateActiveConfigDeclaration( region ); return ehcacheStats.generateActiveConfigDeclaration( region );
} }
@ -167,6 +178,7 @@ public class EhcacheHibernate extends AbstractEmitterBean implements EhcacheHibe
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override
public long getCacheHitCount() { public long getCacheHitCount() {
return ehcacheStats.getCacheHitCount(); return ehcacheStats.getCacheHitCount();
} }
@ -174,6 +186,7 @@ public class EhcacheHibernate extends AbstractEmitterBean implements EhcacheHibe
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override
public double getCacheHitRate() { public double getCacheHitRate() {
return ehcacheStats.getCacheHitRate(); return ehcacheStats.getCacheHitRate();
} }
@ -181,6 +194,7 @@ public class EhcacheHibernate extends AbstractEmitterBean implements EhcacheHibe
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override
public long getCacheHitSample() { public long getCacheHitSample() {
return ehcacheStats.getCacheHitSample(); return ehcacheStats.getCacheHitSample();
} }
@ -188,6 +202,7 @@ public class EhcacheHibernate extends AbstractEmitterBean implements EhcacheHibe
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override
public long getCacheMissCount() { public long getCacheMissCount() {
return ehcacheStats.getCacheMissCount(); return ehcacheStats.getCacheMissCount();
} }
@ -195,6 +210,7 @@ public class EhcacheHibernate extends AbstractEmitterBean implements EhcacheHibe
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override
public double getCacheMissRate() { public double getCacheMissRate() {
return ehcacheStats.getCacheMissRate(); return ehcacheStats.getCacheMissRate();
} }
@ -202,6 +218,7 @@ public class EhcacheHibernate extends AbstractEmitterBean implements EhcacheHibe
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override
public long getCacheMissSample() { public long getCacheMissSample() {
return ehcacheStats.getCacheMissSample(); return ehcacheStats.getCacheMissSample();
} }
@ -209,6 +226,7 @@ public class EhcacheHibernate extends AbstractEmitterBean implements EhcacheHibe
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override
public long getCachePutCount() { public long getCachePutCount() {
return ehcacheStats.getCachePutCount(); return ehcacheStats.getCachePutCount();
} }
@ -216,6 +234,7 @@ public class EhcacheHibernate extends AbstractEmitterBean implements EhcacheHibe
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override
public double getCachePutRate() { public double getCachePutRate() {
return ehcacheStats.getCachePutRate(); return ehcacheStats.getCachePutRate();
} }
@ -223,6 +242,7 @@ public class EhcacheHibernate extends AbstractEmitterBean implements EhcacheHibe
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override
public long getCachePutSample() { public long getCachePutSample() {
return ehcacheStats.getCachePutSample(); return ehcacheStats.getCachePutSample();
} }
@ -230,6 +250,7 @@ public class EhcacheHibernate extends AbstractEmitterBean implements EhcacheHibe
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override
public TabularData getCacheRegionStats() { public TabularData getCacheRegionStats() {
return hibernateStats.getCacheRegionStats(); return hibernateStats.getCacheRegionStats();
} }
@ -237,6 +258,7 @@ public class EhcacheHibernate extends AbstractEmitterBean implements EhcacheHibe
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override
public long getCloseStatementCount() { public long getCloseStatementCount() {
return hibernateStats.getCloseStatementCount(); return hibernateStats.getCloseStatementCount();
} }
@ -244,6 +266,7 @@ public class EhcacheHibernate extends AbstractEmitterBean implements EhcacheHibe
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override
public TabularData getCollectionStats() { public TabularData getCollectionStats() {
return hibernateStats.getCollectionStats(); return hibernateStats.getCollectionStats();
} }
@ -251,6 +274,7 @@ public class EhcacheHibernate extends AbstractEmitterBean implements EhcacheHibe
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override
public long getConnectCount() { public long getConnectCount() {
return hibernateStats.getConnectCount(); return hibernateStats.getConnectCount();
} }
@ -258,6 +282,7 @@ public class EhcacheHibernate extends AbstractEmitterBean implements EhcacheHibe
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override
public TabularData getEntityStats() { public TabularData getEntityStats() {
return hibernateStats.getEntityStats(); return hibernateStats.getEntityStats();
} }
@ -265,6 +290,7 @@ public class EhcacheHibernate extends AbstractEmitterBean implements EhcacheHibe
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override
public long getFlushCount() { public long getFlushCount() {
return hibernateStats.getFlushCount(); return hibernateStats.getFlushCount();
} }
@ -272,6 +298,7 @@ public class EhcacheHibernate extends AbstractEmitterBean implements EhcacheHibe
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override
public long getOptimisticFailureCount() { public long getOptimisticFailureCount() {
return hibernateStats.getOptimisticFailureCount(); return hibernateStats.getOptimisticFailureCount();
} }
@ -279,6 +306,7 @@ public class EhcacheHibernate extends AbstractEmitterBean implements EhcacheHibe
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override
public String getOriginalConfigDeclaration() { public String getOriginalConfigDeclaration() {
return ehcacheStats.getOriginalConfigDeclaration(); return ehcacheStats.getOriginalConfigDeclaration();
} }
@ -286,6 +314,7 @@ public class EhcacheHibernate extends AbstractEmitterBean implements EhcacheHibe
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override
public String getOriginalConfigDeclaration(String region) { public String getOriginalConfigDeclaration(String region) {
return ehcacheStats.getOriginalConfigDeclaration( region ); return ehcacheStats.getOriginalConfigDeclaration( region );
} }
@ -293,6 +322,7 @@ public class EhcacheHibernate extends AbstractEmitterBean implements EhcacheHibe
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override
public long getPrepareStatementCount() { public long getPrepareStatementCount() {
return hibernateStats.getPrepareStatementCount(); return hibernateStats.getPrepareStatementCount();
} }
@ -300,6 +330,7 @@ public class EhcacheHibernate extends AbstractEmitterBean implements EhcacheHibe
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override
public long getQueryExecutionCount() { public long getQueryExecutionCount() {
return hibernateStats.getQueryExecutionCount(); return hibernateStats.getQueryExecutionCount();
} }
@ -307,6 +338,7 @@ public class EhcacheHibernate extends AbstractEmitterBean implements EhcacheHibe
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override
public double getQueryExecutionRate() { public double getQueryExecutionRate() {
return hibernateStats.getQueryExecutionRate(); return hibernateStats.getQueryExecutionRate();
} }
@ -314,6 +346,7 @@ public class EhcacheHibernate extends AbstractEmitterBean implements EhcacheHibe
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override
public long getQueryExecutionSample() { public long getQueryExecutionSample() {
return hibernateStats.getQueryExecutionSample(); return hibernateStats.getQueryExecutionSample();
} }
@ -321,6 +354,7 @@ public class EhcacheHibernate extends AbstractEmitterBean implements EhcacheHibe
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override
public TabularData getQueryStats() { public TabularData getQueryStats() {
return hibernateStats.getQueryStats(); return hibernateStats.getQueryStats();
} }
@ -328,6 +362,7 @@ public class EhcacheHibernate extends AbstractEmitterBean implements EhcacheHibe
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override
public Map<String, Map<String, Object>> getRegionCacheAttributes() { public Map<String, Map<String, Object>> getRegionCacheAttributes() {
return ehcacheStats.getRegionCacheAttributes(); return ehcacheStats.getRegionCacheAttributes();
} }
@ -335,6 +370,7 @@ public class EhcacheHibernate extends AbstractEmitterBean implements EhcacheHibe
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override
public Map<String, Object> getRegionCacheAttributes(String regionName) { public Map<String, Object> getRegionCacheAttributes(String regionName) {
return ehcacheStats.getRegionCacheAttributes( regionName ); return ehcacheStats.getRegionCacheAttributes( regionName );
} }
@ -342,6 +378,7 @@ public class EhcacheHibernate extends AbstractEmitterBean implements EhcacheHibe
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override
public int getRegionCacheMaxTTISeconds(String region) { public int getRegionCacheMaxTTISeconds(String region) {
return ehcacheStats.getRegionCacheMaxTTISeconds( region ); return ehcacheStats.getRegionCacheMaxTTISeconds( region );
} }
@ -349,6 +386,7 @@ public class EhcacheHibernate extends AbstractEmitterBean implements EhcacheHibe
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override
public int getRegionCacheMaxTTLSeconds(String region) { public int getRegionCacheMaxTTLSeconds(String region) {
return ehcacheStats.getRegionCacheMaxTTLSeconds( region ); return ehcacheStats.getRegionCacheMaxTTLSeconds( region );
} }
@ -356,6 +394,7 @@ public class EhcacheHibernate extends AbstractEmitterBean implements EhcacheHibe
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override
public int getRegionCacheOrphanEvictionPeriod(String region) { public int getRegionCacheOrphanEvictionPeriod(String region) {
return ehcacheStats.getRegionCacheOrphanEvictionPeriod( region ); return ehcacheStats.getRegionCacheOrphanEvictionPeriod( region );
} }
@ -363,6 +402,7 @@ public class EhcacheHibernate extends AbstractEmitterBean implements EhcacheHibe
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override
public Map<String, int[]> getRegionCacheSamples() { public Map<String, int[]> getRegionCacheSamples() {
return ehcacheStats.getRegionCacheSamples(); return ehcacheStats.getRegionCacheSamples();
} }
@ -370,6 +410,7 @@ public class EhcacheHibernate extends AbstractEmitterBean implements EhcacheHibe
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override
public int getRegionCacheTargetMaxInMemoryCount(String region) { public int getRegionCacheTargetMaxInMemoryCount(String region) {
return ehcacheStats.getRegionCacheTargetMaxInMemoryCount( region ); return ehcacheStats.getRegionCacheTargetMaxInMemoryCount( region );
} }
@ -377,6 +418,7 @@ public class EhcacheHibernate extends AbstractEmitterBean implements EhcacheHibe
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override
public int getRegionCacheTargetMaxTotalCount(String region) { public int getRegionCacheTargetMaxTotalCount(String region) {
return ehcacheStats.getRegionCacheTargetMaxTotalCount( region ); return ehcacheStats.getRegionCacheTargetMaxTotalCount( region );
} }
@ -384,6 +426,7 @@ public class EhcacheHibernate extends AbstractEmitterBean implements EhcacheHibe
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override
public long getSessionCloseCount() { public long getSessionCloseCount() {
return hibernateStats.getSessionCloseCount(); return hibernateStats.getSessionCloseCount();
} }
@ -391,6 +434,7 @@ public class EhcacheHibernate extends AbstractEmitterBean implements EhcacheHibe
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override
public long getSessionOpenCount() { public long getSessionOpenCount() {
return hibernateStats.getSessionOpenCount(); return hibernateStats.getSessionOpenCount();
} }
@ -398,6 +442,7 @@ public class EhcacheHibernate extends AbstractEmitterBean implements EhcacheHibe
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override
public long getSuccessfulTransactionCount() { public long getSuccessfulTransactionCount() {
return hibernateStats.getSuccessfulTransactionCount(); return hibernateStats.getSuccessfulTransactionCount();
} }
@ -405,6 +450,7 @@ public class EhcacheHibernate extends AbstractEmitterBean implements EhcacheHibe
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override
public String[] getTerracottaHibernateCacheRegionNames() { public String[] getTerracottaHibernateCacheRegionNames() {
return ehcacheStats.getTerracottaHibernateCacheRegionNames(); return ehcacheStats.getTerracottaHibernateCacheRegionNames();
} }
@ -412,6 +458,7 @@ public class EhcacheHibernate extends AbstractEmitterBean implements EhcacheHibe
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override
public long getTransactionCount() { public long getTransactionCount() {
return hibernateStats.getTransactionCount(); return hibernateStats.getTransactionCount();
} }
@ -419,6 +466,7 @@ public class EhcacheHibernate extends AbstractEmitterBean implements EhcacheHibe
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override
public boolean isRegionCacheEnabled(String region) { public boolean isRegionCacheEnabled(String region) {
return ehcacheStats.isRegionCacheEnabled( region ); return ehcacheStats.isRegionCacheEnabled( region );
} }
@ -426,6 +474,7 @@ public class EhcacheHibernate extends AbstractEmitterBean implements EhcacheHibe
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override
public void setRegionCachesEnabled(boolean enabled) { public void setRegionCachesEnabled(boolean enabled) {
ehcacheStats.setRegionCachesEnabled( enabled ); ehcacheStats.setRegionCachesEnabled( enabled );
sendNotification( HibernateStats.CACHE_ENABLED, enabled ); sendNotification( HibernateStats.CACHE_ENABLED, enabled );
@ -434,6 +483,7 @@ public class EhcacheHibernate extends AbstractEmitterBean implements EhcacheHibe
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override
public void setRegionCacheEnabled(String region, boolean enabled) { public void setRegionCacheEnabled(String region, boolean enabled) {
ehcacheStats.setRegionCacheEnabled( region, enabled ); ehcacheStats.setRegionCacheEnabled( region, enabled );
sendNotification( HibernateStats.CACHE_REGION_CHANGED, getRegionCacheAttributes( region ), region ); sendNotification( HibernateStats.CACHE_REGION_CHANGED, getRegionCacheAttributes( region ), region );
@ -442,6 +492,7 @@ public class EhcacheHibernate extends AbstractEmitterBean implements EhcacheHibe
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override
public boolean isRegionCacheLoggingEnabled(String region) { public boolean isRegionCacheLoggingEnabled(String region) {
return ehcacheStats.isRegionCacheLoggingEnabled( region ); return ehcacheStats.isRegionCacheLoggingEnabled( region );
} }
@ -449,6 +500,7 @@ public class EhcacheHibernate extends AbstractEmitterBean implements EhcacheHibe
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override
public boolean isRegionCacheOrphanEvictionEnabled(String region) { public boolean isRegionCacheOrphanEvictionEnabled(String region) {
return ehcacheStats.isRegionCacheOrphanEvictionEnabled( region ); return ehcacheStats.isRegionCacheOrphanEvictionEnabled( region );
} }
@ -456,6 +508,7 @@ public class EhcacheHibernate extends AbstractEmitterBean implements EhcacheHibe
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override
public boolean isRegionCachesEnabled() { public boolean isRegionCachesEnabled() {
return ehcacheStats.isRegionCachesEnabled(); return ehcacheStats.isRegionCachesEnabled();
} }
@ -463,6 +516,7 @@ public class EhcacheHibernate extends AbstractEmitterBean implements EhcacheHibe
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override
public boolean isTerracottaHibernateCache(String region) { public boolean isTerracottaHibernateCache(String region) {
return ehcacheStats.isTerracottaHibernateCache( region ); return ehcacheStats.isTerracottaHibernateCache( region );
} }
@ -470,6 +524,7 @@ public class EhcacheHibernate extends AbstractEmitterBean implements EhcacheHibe
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override
public void setRegionCacheLoggingEnabled(String region, boolean loggingEnabled) { public void setRegionCacheLoggingEnabled(String region, boolean loggingEnabled) {
ehcacheStats.setRegionCacheLoggingEnabled( region, loggingEnabled ); ehcacheStats.setRegionCacheLoggingEnabled( region, loggingEnabled );
sendNotification( HibernateStats.CACHE_REGION_CHANGED, getRegionCacheAttributes( region ), region ); sendNotification( HibernateStats.CACHE_REGION_CHANGED, getRegionCacheAttributes( region ), region );
@ -478,6 +533,7 @@ public class EhcacheHibernate extends AbstractEmitterBean implements EhcacheHibe
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override
public void setRegionCacheMaxTTISeconds(String region, int maxTTISeconds) { public void setRegionCacheMaxTTISeconds(String region, int maxTTISeconds) {
ehcacheStats.setRegionCacheMaxTTISeconds( region, maxTTISeconds ); ehcacheStats.setRegionCacheMaxTTISeconds( region, maxTTISeconds );
sendNotification( HibernateStats.CACHE_REGION_CHANGED, getRegionCacheAttributes( region ), region ); sendNotification( HibernateStats.CACHE_REGION_CHANGED, getRegionCacheAttributes( region ), region );
@ -486,6 +542,7 @@ public class EhcacheHibernate extends AbstractEmitterBean implements EhcacheHibe
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override
public void setRegionCacheMaxTTLSeconds(String region, int maxTTLSeconds) { public void setRegionCacheMaxTTLSeconds(String region, int maxTTLSeconds) {
ehcacheStats.setRegionCacheMaxTTLSeconds( region, maxTTLSeconds ); ehcacheStats.setRegionCacheMaxTTLSeconds( region, maxTTLSeconds );
sendNotification( HibernateStats.CACHE_REGION_CHANGED, getRegionCacheAttributes( region ), region ); sendNotification( HibernateStats.CACHE_REGION_CHANGED, getRegionCacheAttributes( region ), region );
@ -494,6 +551,7 @@ public class EhcacheHibernate extends AbstractEmitterBean implements EhcacheHibe
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override
public void setRegionCacheTargetMaxInMemoryCount(String region, int targetMaxInMemoryCount) { public void setRegionCacheTargetMaxInMemoryCount(String region, int targetMaxInMemoryCount) {
ehcacheStats.setRegionCacheTargetMaxInMemoryCount( region, targetMaxInMemoryCount ); ehcacheStats.setRegionCacheTargetMaxInMemoryCount( region, targetMaxInMemoryCount );
sendNotification( HibernateStats.CACHE_REGION_CHANGED, getRegionCacheAttributes( region ), region ); sendNotification( HibernateStats.CACHE_REGION_CHANGED, getRegionCacheAttributes( region ), region );
@ -502,6 +560,7 @@ public class EhcacheHibernate extends AbstractEmitterBean implements EhcacheHibe
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override
public void setRegionCacheTargetMaxTotalCount(String region, int targetMaxTotalCount) { public void setRegionCacheTargetMaxTotalCount(String region, int targetMaxTotalCount) {
ehcacheStats.setRegionCacheTargetMaxTotalCount( region, targetMaxTotalCount ); ehcacheStats.setRegionCacheTargetMaxTotalCount( region, targetMaxTotalCount );
sendNotification( HibernateStats.CACHE_REGION_CHANGED, getRegionCacheAttributes( region ), region ); sendNotification( HibernateStats.CACHE_REGION_CHANGED, getRegionCacheAttributes( region ), region );
@ -512,6 +571,7 @@ public class EhcacheHibernate extends AbstractEmitterBean implements EhcacheHibe
* *
* @see EhcacheStats#getNumberOfElementsInMemory(java.lang.String) * @see EhcacheStats#getNumberOfElementsInMemory(java.lang.String)
*/ */
@Override
public int getNumberOfElementsInMemory(String region) { public int getNumberOfElementsInMemory(String region) {
return ehcacheStats.getNumberOfElementsInMemory( region ); return ehcacheStats.getNumberOfElementsInMemory( region );
} }
@ -521,6 +581,7 @@ public class EhcacheHibernate extends AbstractEmitterBean implements EhcacheHibe
* *
* @see EhcacheStats#getNumberOfElementsInMemory(java.lang.String) * @see EhcacheStats#getNumberOfElementsInMemory(java.lang.String)
*/ */
@Override
public int getNumberOfElementsOffHeap(String region) { public int getNumberOfElementsOffHeap(String region) {
return ehcacheStats.getNumberOfElementsOffHeap( region ); return ehcacheStats.getNumberOfElementsOffHeap( region );
} }
@ -530,6 +591,7 @@ public class EhcacheHibernate extends AbstractEmitterBean implements EhcacheHibe
* *
* @see EhcacheStats#getNumberOfElementsOnDisk(java.lang.String) * @see EhcacheStats#getNumberOfElementsOnDisk(java.lang.String)
*/ */
@Override
public int getNumberOfElementsOnDisk(String region) { public int getNumberOfElementsOnDisk(String region) {
return ehcacheStats.getNumberOfElementsOnDisk( region ); return ehcacheStats.getNumberOfElementsOnDisk( region );
} }
@ -539,6 +601,7 @@ public class EhcacheHibernate extends AbstractEmitterBean implements EhcacheHibe
* *
* @see EhcacheStats#getMaxGetTimeMillis() * @see EhcacheStats#getMaxGetTimeMillis()
*/ */
@Override
public long getMaxGetTimeMillis() { public long getMaxGetTimeMillis() {
return ehcacheStats.getMaxGetTimeMillis(); return ehcacheStats.getMaxGetTimeMillis();
} }
@ -548,6 +611,7 @@ public class EhcacheHibernate extends AbstractEmitterBean implements EhcacheHibe
* *
* @see EhcacheStats#getMaxGetTimeMillis(java.lang.String) * @see EhcacheStats#getMaxGetTimeMillis(java.lang.String)
*/ */
@Override
public long getMaxGetTimeMillis(String cacheName) { public long getMaxGetTimeMillis(String cacheName) {
return ehcacheStats.getMaxGetTimeMillis( cacheName ); return ehcacheStats.getMaxGetTimeMillis( cacheName );
} }
@ -557,6 +621,7 @@ public class EhcacheHibernate extends AbstractEmitterBean implements EhcacheHibe
* *
* @see EhcacheStats#getMinGetTimeMillis() * @see EhcacheStats#getMinGetTimeMillis()
*/ */
@Override
public long getMinGetTimeMillis() { public long getMinGetTimeMillis() {
return ehcacheStats.getMinGetTimeMillis(); return ehcacheStats.getMinGetTimeMillis();
} }
@ -566,6 +631,7 @@ public class EhcacheHibernate extends AbstractEmitterBean implements EhcacheHibe
* *
* @see EhcacheStats#getMinGetTimeMillis(java.lang.String) * @see EhcacheStats#getMinGetTimeMillis(java.lang.String)
*/ */
@Override
public long getMinGetTimeMillis(String cacheName) { public long getMinGetTimeMillis(String cacheName) {
return ehcacheStats.getMinGetTimeMillis( cacheName ); return ehcacheStats.getMinGetTimeMillis( cacheName );
} }
@ -575,6 +641,7 @@ public class EhcacheHibernate extends AbstractEmitterBean implements EhcacheHibe
* *
* @see EhcacheStats#getAverageGetTimeMillis(java.lang.String) * @see EhcacheStats#getAverageGetTimeMillis(java.lang.String)
*/ */
@Override
public float getAverageGetTimeMillis(String region) { public float getAverageGetTimeMillis(String region) {
return ehcacheStats.getAverageGetTimeMillis( region ); return ehcacheStats.getAverageGetTimeMillis( region );
} }
@ -588,6 +655,8 @@ public class EhcacheHibernate extends AbstractEmitterBean implements EhcacheHibe
} }
/** /**
* {@inheritDoc}
*
* @see AbstractEmitterBean#getNotificationInfo() * @see AbstractEmitterBean#getNotificationInfo()
*/ */
@Override @Override

View File

@ -44,17 +44,17 @@ public interface EhcacheHibernateMBeanRegistration {
* MBeans will be registered based on the input session factory name. If the input name is null or blank, the name of the cache-manager * MBeans will be registered based on the input session factory name. If the input name is null or blank, the name of the cache-manager
* is used * is used
* *
* @param manager * @param manager the {@link CacheManager} to register the MBean for
* @param properties * @param properties properties to used to create the associated {@link SessionFactory}
* *
* @throws Exception * @throws Exception reflecting the source of the problem registering the MBean
*/ */
public void registerMBeanForCacheManager(CacheManager manager, Properties properties) throws Exception; public void registerMBeanForCacheManager(CacheManager manager, Properties properties) throws Exception;
/** /**
* Enable hibernate statistics in the mbean. * Enable hibernate statistics in the mbean.
* *
* @param sessionFactory * @param sessionFactory the {@link SessionFactory} to enable stats for
*/ */
public void enableHibernateStatisticsSupport(SessionFactory sessionFactory); public void enableHibernateStatisticsSupport(SessionFactory sessionFactory);

View File

@ -56,19 +56,15 @@ public class EhcacheHibernateMBeanRegistrationImpl
EhcacheHibernateMBeanRegistrationImpl.class.getName() EhcacheHibernateMBeanRegistrationImpl.class.getName()
); );
private static final int MAX_MBEAN_REGISTRATION_RETRIES = 50; private static final int MAX_MBEAN_REGISTRATION_RETRIES = 50;
private String cacheManagerClusterUUID;
private String registeredCacheManagerName;
private Status status = Status.STATUS_UNINITIALISED; private Status status = Status.STATUS_UNINITIALISED;
private volatile EhcacheHibernate ehcacheHibernate; private volatile EhcacheHibernate ehcacheHibernate;
private volatile ObjectName cacheManagerObjectName; private volatile ObjectName cacheManagerObjectName;
/** @Override
* {@inheritDoc}
*/
public synchronized void registerMBeanForCacheManager(final CacheManager manager, final Properties properties) public synchronized void registerMBeanForCacheManager(final CacheManager manager, final Properties properties)
throws Exception { throws Exception {
String sessionFactoryName = properties.getProperty( Environment.SESSION_FACTORY_NAME ); final String sessionFactoryName = properties.getProperty( Environment.SESSION_FACTORY_NAME );
String name = null; final String name;
if ( sessionFactoryName == null ) { if ( sessionFactoryName == null ) {
name = manager.getName(); name = manager.getName();
} }
@ -81,17 +77,18 @@ public class EhcacheHibernateMBeanRegistrationImpl
private void registerBean(String name, CacheManager manager) throws Exception { private void registerBean(String name, CacheManager manager) throws Exception {
ehcacheHibernate = new EhcacheHibernate( manager ); ehcacheHibernate = new EhcacheHibernate( manager );
int tries = 0; int tries = 0;
boolean success = false; boolean success;
Exception exception = null; Exception exception = null;
cacheManagerClusterUUID = manager.getClusterUUID(); final String cacheManagerClusterUUID = manager.getClusterUUID();
String registeredCacheManagerName;
do { do {
this.registeredCacheManagerName = name; registeredCacheManagerName = name;
if ( tries != 0 ) { if ( tries != 0 ) {
registeredCacheManagerName += "_" + tries; registeredCacheManagerName += "_" + tries;
} }
try { try {
// register the CacheManager MBean // register the CacheManager MBean
MBeanServer mBeanServer = getMBeanServer(); final MBeanServer mBeanServer = getMBeanServer();
cacheManagerObjectName = EhcacheHibernateMbeanNames.getCacheManagerObjectName( cacheManagerObjectName = EhcacheHibernateMbeanNames.getCacheManagerObjectName(
cacheManagerClusterUUID, cacheManagerClusterUUID,
registeredCacheManagerName registeredCacheManagerName
@ -120,16 +117,12 @@ public class EhcacheHibernateMBeanRegistrationImpl
return ManagementFactory.getPlatformMBeanServer(); return ManagementFactory.getPlatformMBeanServer();
} }
/** @Override
* {@inheritDoc}
*/
public void enableHibernateStatisticsSupport(SessionFactory sessionFactory) { public void enableHibernateStatisticsSupport(SessionFactory sessionFactory) {
ehcacheHibernate.enableHibernateStatistics( sessionFactory ); ehcacheHibernate.enableHibernateStatistics( sessionFactory );
} }
/** @Override
* {@inheritDoc}
*/
public synchronized void dispose() throws CacheException { public synchronized void dispose() throws CacheException {
if ( status == Status.STATUS_SHUTDOWN ) { if ( status == Status.STATUS_SHUTDOWN ) {
return; return;
@ -149,30 +142,37 @@ public class EhcacheHibernateMBeanRegistrationImpl
status = Status.STATUS_SHUTDOWN; status = Status.STATUS_SHUTDOWN;
} }
/** @Override
* {@inheritDoc}
*/
public synchronized Status getStatus() { public synchronized Status getStatus() {
return status; return status;
} }
/** /**
* No-op in this case * {@inheritDoc}
* <p/>
* NOTE : No-op in this case
*/ */
@Override
public void init() throws CacheException { public void init() throws CacheException {
// no-op // no-op
} }
/** /**
* No-op in this case * {@inheritDoc}
* <p/>
* NOTE : No-op in this case
*/ */
@Override
public void notifyCacheAdded(String cacheName) { public void notifyCacheAdded(String cacheName) {
// no-op // no-op
} }
/** /**
* No-op in this case * {@inheritDoc}
* <p/>
* NOTE : No-op in this case
*/ */
@Override
public void notifyCacheRemoved(String cacheName) { public void notifyCacheRemoved(String cacheName) {
// no-op // no-op
} }

View File

@ -49,7 +49,7 @@ public abstract class EhcacheHibernateMbeanNames {
/** /**
* Filter out invalid ObjectName characters from s. * Filter out invalid ObjectName characters from s.
* *
* @param s * @param s the name to be filtered out
* *
* @return A valid JMX ObjectName attribute value. * @return A valid JMX ObjectName attribute value.
*/ */
@ -60,19 +60,19 @@ public abstract class EhcacheHibernateMbeanNames {
/** /**
* Returns an ObjectName for the passed name * Returns an ObjectName for the passed name
* *
* @param name * @param cacheManagerClusterUUID the UUID of the cacheManager within the cluster
* @param name the name to use, which should be made "mbean safe"
* *
* @return An {@link javax.management.ObjectName} using the input name of cache manager * @return An {@link javax.management.ObjectName} using the input name of cache manager
* *
* @throws javax.management.MalformedObjectNameException * @throws javax.management.MalformedObjectNameException The name derived from the params does not correspond to a valid ObjectName
*/ */
public static ObjectName getCacheManagerObjectName(String cacheManagerClusterUUID, String name) public static ObjectName getCacheManagerObjectName(String cacheManagerClusterUUID, String name)
throws MalformedObjectNameException { throws MalformedObjectNameException {
ObjectName objectName = new ObjectName( return new ObjectName(
GROUP_ID + ":type=" + EHCACHE_HIBERNATE_TYPE + ",name=" + mbeanSafe( name ) GROUP_ID + ":type=" + EHCACHE_HIBERNATE_TYPE
+ getBeanNameSuffix( cacheManagerClusterUUID ) + ",name=" + mbeanSafe( name ) + getBeanNameSuffix( cacheManagerClusterUUID )
); );
return objectName;
} }
private static String getBeanNameSuffix(String cacheManagerClusterUUID) { private static String getBeanNameSuffix(String cacheManagerClusterUUID) {

View File

@ -63,7 +63,8 @@ public class EhcacheStatsImpl extends AbstractEmitterBean implements EhcacheStat
/** /**
* Constructor accepting the backing {@link CacheManager} * Constructor accepting the backing {@link CacheManager}
* *
* @throws javax.management.NotCompliantMBeanException * @param manager The {@link CacheManager} to expose stats for
* @throws javax.management.NotCompliantMBeanException should registering the MBean fail
*/ */
public EhcacheStatsImpl(CacheManager manager) throws NotCompliantMBeanException { public EhcacheStatsImpl(CacheManager manager) throws NotCompliantMBeanException {
super( EhcacheStats.class ); super( EhcacheStats.class );
@ -71,79 +72,60 @@ public class EhcacheStatsImpl extends AbstractEmitterBean implements EhcacheStat
this.cacheManager = manager; this.cacheManager = manager;
} }
/** @Override
* {@inheritDoc}
*/
public boolean isStatisticsEnabled() { public boolean isStatisticsEnabled() {
return false; return false;
} }
/** @Override
* {@inheritDoc}
*/
public void clearStats() { public void clearStats() {
sampledCacheManager.clearStatistics(); sampledCacheManager.clearStatistics();
statsSince = System.currentTimeMillis(); statsSince = System.currentTimeMillis();
} }
/** @Override
* {@inheritDoc}
*/
public void disableStats() { public void disableStats() {
setStatisticsEnabled( false ); setStatisticsEnabled( false );
} }
/** @Override
* {@inheritDoc}
*/
public void enableStats() { public void enableStats() {
setStatisticsEnabled( true ); setStatisticsEnabled( true );
} }
/** @Override
* {@inheritDoc}
*/
public void flushRegionCache(String region) { public void flushRegionCache(String region) {
Cache cache = this.cacheManager.getCache( region ); final Cache cache = this.cacheManager.getCache( region );
if ( cache != null ) { if ( cache != null ) {
cache.flush(); cache.flush();
} }
} }
/** @Override
* {@inheritDoc}
*/
public void flushRegionCaches() { public void flushRegionCaches() {
for ( String name : cacheManager.getCacheNames() ) { for ( String name : cacheManager.getCacheNames() ) {
Cache cache = this.cacheManager.getCache( name ); final Cache cache = this.cacheManager.getCache( name );
if ( cache != null ) { if ( cache != null ) {
cache.flush(); cache.flush();
} }
} }
} }
/** @Override
* {@inheritDoc}
*/
public String generateActiveConfigDeclaration() { public String generateActiveConfigDeclaration() {
return this.cacheManager.getActiveConfigurationText(); return this.cacheManager.getActiveConfigurationText();
} }
/** @Override
* {@inheritDoc}
*/
public String generateActiveConfigDeclaration(String region) { public String generateActiveConfigDeclaration(String region) {
return this.cacheManager.getActiveConfigurationText( region ); return this.cacheManager.getActiveConfigurationText( region );
} }
/** @Override
* {@inheritDoc}
*/
public long getCacheHitCount() { public long getCacheHitCount() {
long count = 0; long count = 0;
for ( String name : cacheManager.getCacheNames() ) { for ( String name : cacheManager.getCacheNames() ) {
Cache cache = cacheManager.getCache( name ); final Cache cache = cacheManager.getCache( name );
if ( cache != null ) { if ( cache != null ) {
count += cache.getLiveCacheStatistics().getCacheHitCount(); count += cache.getLiveCacheStatistics().getCacheHitCount();
} }
@ -151,22 +133,18 @@ public class EhcacheStatsImpl extends AbstractEmitterBean implements EhcacheStat
return count; return count;
} }
/** @Override
* {@inheritDoc}
*/
public double getCacheHitRate() { public double getCacheHitRate() {
long now = System.currentTimeMillis(); final long now = System.currentTimeMillis();
double deltaSecs = (double) (now - statsSince) / MILLIS_PER_SECOND; final double deltaSecs = (double) (now - statsSince) / MILLIS_PER_SECOND;
return getCacheHitCount() / deltaSecs; return getCacheHitCount() / deltaSecs;
} }
/** @Override
* {@inheritDoc}
*/
public long getCacheHitSample() { public long getCacheHitSample() {
long count = 0; long count = 0;
for ( String name : cacheManager.getCacheNames() ) { for ( String name : cacheManager.getCacheNames() ) {
Cache cache = cacheManager.getCache( name ); final Cache cache = cacheManager.getCache( name );
if ( cache != null ) { if ( cache != null ) {
count += cache.getSampledCacheStatistics().getCacheHitMostRecentSample(); count += cache.getSampledCacheStatistics().getCacheHitMostRecentSample();
} }
@ -174,13 +152,11 @@ public class EhcacheStatsImpl extends AbstractEmitterBean implements EhcacheStat
return count; return count;
} }
/** @Override
* {@inheritDoc}
*/
public long getCacheMissCount() { public long getCacheMissCount() {
long count = 0; long count = 0;
for ( String name : cacheManager.getCacheNames() ) { for ( String name : cacheManager.getCacheNames() ) {
Cache cache = cacheManager.getCache( name ); final Cache cache = cacheManager.getCache( name );
if ( cache != null ) { if ( cache != null ) {
count += cache.getLiveCacheStatistics().getCacheMissCount(); count += cache.getLiveCacheStatistics().getCacheMissCount();
} }
@ -188,22 +164,18 @@ public class EhcacheStatsImpl extends AbstractEmitterBean implements EhcacheStat
return count; return count;
} }
/** @Override
* {@inheritDoc}
*/
public double getCacheMissRate() { public double getCacheMissRate() {
long now = System.currentTimeMillis(); final long now = System.currentTimeMillis();
double deltaSecs = (double) (now - statsSince) / MILLIS_PER_SECOND; final double deltaSecs = (double) (now - statsSince) / MILLIS_PER_SECOND;
return getCacheMissCount() / deltaSecs; return getCacheMissCount() / deltaSecs;
} }
/** @Override
* {@inheritDoc}
*/
public long getCacheMissSample() { public long getCacheMissSample() {
long count = 0; long count = 0;
for ( String name : cacheManager.getCacheNames() ) { for ( String name : cacheManager.getCacheNames() ) {
Cache cache = cacheManager.getCache( name ); final Cache cache = cacheManager.getCache( name );
if ( cache != null ) { if ( cache != null ) {
count += cache.getSampledCacheStatistics().getCacheMissMostRecentSample(); count += cache.getSampledCacheStatistics().getCacheMissMostRecentSample();
} }
@ -211,13 +183,11 @@ public class EhcacheStatsImpl extends AbstractEmitterBean implements EhcacheStat
return count; return count;
} }
/** @Override
* {@inheritDoc}
*/
public long getCachePutCount() { public long getCachePutCount() {
long count = 0; long count = 0;
for ( String name : cacheManager.getCacheNames() ) { for ( String name : cacheManager.getCacheNames() ) {
Cache cache = cacheManager.getCache( name ); final Cache cache = cacheManager.getCache( name );
if ( cache != null ) { if ( cache != null ) {
count += cache.getLiveCacheStatistics().getPutCount(); count += cache.getLiveCacheStatistics().getPutCount();
} }
@ -225,22 +195,18 @@ public class EhcacheStatsImpl extends AbstractEmitterBean implements EhcacheStat
return count; return count;
} }
/** @Override
* {@inheritDoc}
*/
public double getCachePutRate() { public double getCachePutRate() {
long now = System.currentTimeMillis(); final long now = System.currentTimeMillis();
double deltaSecs = (double) (now - statsSince) / MILLIS_PER_SECOND; final double deltaSecs = (double) (now - statsSince) / MILLIS_PER_SECOND;
return getCachePutCount() / deltaSecs; return getCachePutCount() / deltaSecs;
} }
/** @Override
* {@inheritDoc}
*/
public long getCachePutSample() { public long getCachePutSample() {
long count = 0; long count = 0;
for ( String name : cacheManager.getCacheNames() ) { for ( String name : cacheManager.getCacheNames() ) {
Cache cache = cacheManager.getCache( name ); final Cache cache = cacheManager.getCache( name );
if ( cache != null ) { if ( cache != null ) {
count += cache.getSampledCacheStatistics().getCacheElementPutMostRecentSample(); count += cache.getSampledCacheStatistics().getCacheElementPutMostRecentSample();
} }
@ -248,36 +214,28 @@ public class EhcacheStatsImpl extends AbstractEmitterBean implements EhcacheStat
return count; return count;
} }
/** @Override
* {@inheritDoc}
*/
public String getOriginalConfigDeclaration() { public String getOriginalConfigDeclaration() {
return this.cacheManager.getOriginalConfigurationText(); return this.cacheManager.getOriginalConfigurationText();
} }
/** @Override
* {@inheritDoc}
*/
public String getOriginalConfigDeclaration(String region) { public String getOriginalConfigDeclaration(String region) {
return this.cacheManager.getOriginalConfigurationText( region ); return this.cacheManager.getOriginalConfigurationText( region );
} }
/** @Override
* {@inheritDoc}
*/
public Map<String, Map<String, Object>> getRegionCacheAttributes() { public Map<String, Map<String, Object>> getRegionCacheAttributes() {
Map<String, Map<String, Object>> result = new HashMap<String, Map<String, Object>>(); final Map<String, Map<String, Object>> result = new HashMap<String, Map<String, Object>>();
for ( String regionName : this.cacheManager.getCacheNames() ) { for ( String regionName : this.cacheManager.getCacheNames() ) {
result.put( regionName, getRegionCacheAttributes( regionName ) ); result.put( regionName, getRegionCacheAttributes( regionName ) );
} }
return result; return result;
} }
/** @Override
* {@inheritDoc}
*/
public Map<String, Object> getRegionCacheAttributes(String regionName) { public Map<String, Object> getRegionCacheAttributes(String regionName) {
Map<String, Object> result = new HashMap<String, Object>(); final Map<String, Object> result = new HashMap<String, Object>();
result.put( "Enabled", isRegionCacheEnabled( regionName ) ); result.put( "Enabled", isRegionCacheEnabled( regionName ) );
result.put( "LoggingEnabled", isRegionCacheLoggingEnabled( regionName ) ); result.put( "LoggingEnabled", isRegionCacheLoggingEnabled( regionName ) );
result.put( "MaxTTISeconds", getRegionCacheMaxTTISeconds( regionName ) ); result.put( "MaxTTISeconds", getRegionCacheMaxTTISeconds( regionName ) );
@ -289,11 +247,9 @@ public class EhcacheStatsImpl extends AbstractEmitterBean implements EhcacheStat
return result; return result;
} }
/** @Override
* {@inheritDoc}
*/
public int getRegionCacheMaxTTISeconds(String region) { public int getRegionCacheMaxTTISeconds(String region) {
Cache cache = cacheManager.getCache( region ); final Cache cache = cacheManager.getCache( region );
if ( cache != null ) { if ( cache != null ) {
return (int) cache.getCacheConfiguration().getTimeToIdleSeconds(); return (int) cache.getCacheConfiguration().getTimeToIdleSeconds();
} }
@ -302,11 +258,9 @@ public class EhcacheStatsImpl extends AbstractEmitterBean implements EhcacheStat
} }
} }
/** @Override
* {@inheritDoc}
*/
public int getRegionCacheMaxTTLSeconds(String region) { public int getRegionCacheMaxTTLSeconds(String region) {
Cache cache = cacheManager.getCache( region ); final Cache cache = cacheManager.getCache( region );
if ( cache != null ) { if ( cache != null ) {
return (int) cache.getCacheConfiguration().getTimeToLiveSeconds(); return (int) cache.getCacheConfiguration().getTimeToLiveSeconds();
} }
@ -315,11 +269,9 @@ public class EhcacheStatsImpl extends AbstractEmitterBean implements EhcacheStat
} }
} }
/** @Override
* {@inheritDoc}
*/
public int getRegionCacheOrphanEvictionPeriod(String region) { public int getRegionCacheOrphanEvictionPeriod(String region) {
Cache cache = this.cacheManager.getCache( region ); final Cache cache = this.cacheManager.getCache( region );
if ( cache != null && cache.isTerracottaClustered() ) { if ( cache != null && cache.isTerracottaClustered() ) {
return cache.getCacheConfiguration().getTerracottaConfiguration().getOrphanEvictionPeriod(); return cache.getCacheConfiguration().getTerracottaConfiguration().getOrphanEvictionPeriod();
} }
@ -328,13 +280,11 @@ public class EhcacheStatsImpl extends AbstractEmitterBean implements EhcacheStat
} }
} }
/** @Override
* {@inheritDoc}
*/
public Map<String, int[]> getRegionCacheSamples() { public Map<String, int[]> getRegionCacheSamples() {
Map<String, int[]> rv = new HashMap<String, int[]>(); final Map<String, int[]> rv = new HashMap<String, int[]>();
for ( String name : cacheManager.getCacheNames() ) { for ( String name : cacheManager.getCacheNames() ) {
Cache cache = cacheManager.getCache( name ); final Cache cache = cacheManager.getCache( name );
if ( cache != null ) { if ( cache != null ) {
rv.put( rv.put(
name, new int[] { name, new int[] {
@ -349,11 +299,9 @@ public class EhcacheStatsImpl extends AbstractEmitterBean implements EhcacheStat
return rv; return rv;
} }
/** @Override
* {@inheritDoc}
*/
public int getRegionCacheTargetMaxInMemoryCount(String region) { public int getRegionCacheTargetMaxInMemoryCount(String region) {
Cache cache = cacheManager.getCache( region ); final Cache cache = cacheManager.getCache( region );
if ( cache != null ) { if ( cache != null ) {
return cache.getCacheConfiguration().getMaxElementsInMemory(); return cache.getCacheConfiguration().getMaxElementsInMemory();
} }
@ -362,11 +310,9 @@ public class EhcacheStatsImpl extends AbstractEmitterBean implements EhcacheStat
} }
} }
/** @Override
* {@inheritDoc}
*/
public int getRegionCacheTargetMaxTotalCount(String region) { public int getRegionCacheTargetMaxTotalCount(String region) {
Cache cache = cacheManager.getCache( region ); final Cache cache = cacheManager.getCache( region );
if ( cache != null ) { if ( cache != null ) {
return cache.getCacheConfiguration().getMaxElementsOnDisk(); return cache.getCacheConfiguration().getMaxElementsOnDisk();
} }
@ -375,52 +321,39 @@ public class EhcacheStatsImpl extends AbstractEmitterBean implements EhcacheStat
} }
} }
/** @Override
* {@inheritDoc}
*/
public String[] getTerracottaHibernateCacheRegionNames() { public String[] getTerracottaHibernateCacheRegionNames() {
ArrayList<String> rv = new ArrayList<String>(); final ArrayList<String> rv = new ArrayList<String>();
for ( String name : cacheManager.getCacheNames() ) { for ( String name : cacheManager.getCacheNames() ) {
Cache cache = cacheManager.getCache( name ); final Cache cache = cacheManager.getCache( name );
if ( cache != null ) { if ( cache != null ) {
if ( cache.getCacheConfiguration().isTerracottaClustered() ) { if ( cache.getCacheConfiguration().isTerracottaClustered() ) {
rv.add( name ); rv.add( name );
} }
} }
} }
return rv.toArray( new String[] {} ); return rv.toArray( new String[ rv.size() ] );
} }
/** @Override
* {@inheritDoc}
*/
public boolean isRegionCacheEnabled(String region) { public boolean isRegionCacheEnabled(String region) {
Cache cache = this.cacheManager.getCache( region ); final Cache cache = this.cacheManager.getCache( region );
if ( cache != null ) { return cache != null && !cache.isDisabled();
return !cache.isDisabled();
}
else {
return false;
}
} }
/** @Override
* {@inheritDoc}
*/
public void setRegionCacheEnabled(String region, boolean enabled) { public void setRegionCacheEnabled(String region, boolean enabled) {
Cache cache = this.cacheManager.getCache( region ); final Cache cache = this.cacheManager.getCache( region );
if ( cache != null ) { if ( cache != null ) {
cache.setDisabled( !enabled ); cache.setDisabled( !enabled );
} }
sendNotification( CACHE_REGION_CHANGED, getRegionCacheAttributes( region ), region ); sendNotification( CACHE_REGION_CHANGED, getRegionCacheAttributes( region ), region );
} }
/** @Override
* {@inheritDoc}
*/
public boolean isRegionCachesEnabled() { public boolean isRegionCachesEnabled() {
for ( String name : this.cacheManager.getCacheNames() ) { for ( String name : this.cacheManager.getCacheNames() ) {
Cache cache = this.cacheManager.getCache( name ); final Cache cache = this.cacheManager.getCache( name );
if ( cache != null ) { if ( cache != null ) {
if ( cache.isDisabled() ) { if ( cache.isDisabled() ) {
return false; return false;
@ -430,12 +363,10 @@ public class EhcacheStatsImpl extends AbstractEmitterBean implements EhcacheStat
return true; return true;
} }
/** @Override
* @see EhcacheStats#setRegionCachesEnabled(boolean)
*/
public void setRegionCachesEnabled(final boolean flag) { public void setRegionCachesEnabled(final boolean flag) {
for ( String name : this.cacheManager.getCacheNames() ) { for ( String name : this.cacheManager.getCacheNames() ) {
Cache cache = this.cacheManager.getCache( name ); final Cache cache = this.cacheManager.getCache( name );
if ( cache != null ) { if ( cache != null ) {
cache.setDisabled( !flag ); cache.setDisabled( !flag );
} }
@ -443,107 +374,74 @@ public class EhcacheStatsImpl extends AbstractEmitterBean implements EhcacheStat
sendNotification( CACHE_ENABLED, flag ); sendNotification( CACHE_ENABLED, flag );
} }
/** @Override
* {@inheritDoc}
*/
public boolean isRegionCacheLoggingEnabled(String region) { public boolean isRegionCacheLoggingEnabled(String region) {
Cache cache = this.cacheManager.getCache( region ); final Cache cache = this.cacheManager.getCache( region );
if ( cache != null ) { return cache != null && cache.getCacheConfiguration().getLogging();
return cache.getCacheConfiguration().getLogging();
}
else {
return false;
}
} }
/** @Override
* {@inheritDoc}
*/
public boolean isRegionCacheOrphanEvictionEnabled(String region) { public boolean isRegionCacheOrphanEvictionEnabled(String region) {
Cache cache = this.cacheManager.getCache( region ); final Cache cache = this.cacheManager.getCache( region );
if ( cache != null && cache.isTerracottaClustered() ) { return cache != null && cache.isTerracottaClustered() && cache.getCacheConfiguration()
return cache.getCacheConfiguration().getTerracottaConfiguration().getOrphanEviction(); .getTerracottaConfiguration()
} .getOrphanEviction();
else {
return false;
}
} }
/** @Override
* {@inheritDoc}
*/
public boolean isTerracottaHibernateCache(String region) { public boolean isTerracottaHibernateCache(String region) {
Cache cache = cacheManager.getCache( region ); final Cache cache = cacheManager.getCache( region );
if ( cache != null ) { return cache != null && cache.getCacheConfiguration().isTerracottaClustered();
return cache.getCacheConfiguration().isTerracottaClustered();
}
else {
return false;
}
} }
/** @Override
* {@inheritDoc}
*/
public void setRegionCacheLoggingEnabled(String region, boolean loggingEnabled) { public void setRegionCacheLoggingEnabled(String region, boolean loggingEnabled) {
Cache cache = this.cacheManager.getCache( region ); final Cache cache = this.cacheManager.getCache( region );
if ( cache != null ) { if ( cache != null ) {
cache.getCacheConfiguration().setLogging( loggingEnabled ); cache.getCacheConfiguration().setLogging( loggingEnabled );
sendNotification( CACHE_REGION_CHANGED, getRegionCacheAttributes( region ), region ); sendNotification( CACHE_REGION_CHANGED, getRegionCacheAttributes( region ), region );
} }
} }
/** @Override
* {@inheritDoc}
*/
public void setRegionCacheMaxTTISeconds(String region, int maxTTISeconds) { public void setRegionCacheMaxTTISeconds(String region, int maxTTISeconds) {
Cache cache = this.cacheManager.getCache( region ); final Cache cache = this.cacheManager.getCache( region );
if ( cache != null ) { if ( cache != null ) {
cache.getCacheConfiguration().setTimeToIdleSeconds( maxTTISeconds ); cache.getCacheConfiguration().setTimeToIdleSeconds( maxTTISeconds );
sendNotification( CACHE_REGION_CHANGED, getRegionCacheAttributes( region ), region ); sendNotification( CACHE_REGION_CHANGED, getRegionCacheAttributes( region ), region );
} }
} }
/** @Override
* {@inheritDoc}
*/
public void setRegionCacheMaxTTLSeconds(String region, int maxTTLSeconds) { public void setRegionCacheMaxTTLSeconds(String region, int maxTTLSeconds) {
Cache cache = this.cacheManager.getCache( region ); final Cache cache = this.cacheManager.getCache( region );
if ( cache != null ) { if ( cache != null ) {
cache.getCacheConfiguration().setTimeToLiveSeconds( maxTTLSeconds ); cache.getCacheConfiguration().setTimeToLiveSeconds( maxTTLSeconds );
sendNotification( CACHE_REGION_CHANGED, getRegionCacheAttributes( region ), region ); sendNotification( CACHE_REGION_CHANGED, getRegionCacheAttributes( region ), region );
} }
} }
/** @Override
* {@inheritDoc}
*/
public void setRegionCacheTargetMaxInMemoryCount(String region, int targetMaxInMemoryCount) { public void setRegionCacheTargetMaxInMemoryCount(String region, int targetMaxInMemoryCount) {
Cache cache = this.cacheManager.getCache( region ); final Cache cache = this.cacheManager.getCache( region );
if ( cache != null ) { if ( cache != null ) {
cache.getCacheConfiguration().setMaxElementsInMemory( targetMaxInMemoryCount ); cache.getCacheConfiguration().setMaxElementsInMemory( targetMaxInMemoryCount );
sendNotification( CACHE_REGION_CHANGED, getRegionCacheAttributes( region ), region ); sendNotification( CACHE_REGION_CHANGED, getRegionCacheAttributes( region ), region );
} }
} }
/** @Override
* {@inheritDoc}
*/
public void setRegionCacheTargetMaxTotalCount(String region, int targetMaxTotalCount) { public void setRegionCacheTargetMaxTotalCount(String region, int targetMaxTotalCount) {
Cache cache = this.cacheManager.getCache( region ); final Cache cache = this.cacheManager.getCache( region );
if ( cache != null ) { if ( cache != null ) {
cache.getCacheConfiguration().setMaxElementsOnDisk( targetMaxTotalCount ); cache.getCacheConfiguration().setMaxElementsOnDisk( targetMaxTotalCount );
sendNotification( CACHE_REGION_CHANGED, getRegionCacheAttributes( region ), region ); sendNotification( CACHE_REGION_CHANGED, getRegionCacheAttributes( region ), region );
} }
} }
/** @Override
* {@inheritDoc}
*
* @see EhcacheStats#getNumberOfElementsInMemory(java.lang.String)
*/
public int getNumberOfElementsInMemory(String region) { public int getNumberOfElementsInMemory(String region) {
Cache cache = this.cacheManager.getCache( region ); final Cache cache = this.cacheManager.getCache( region );
if ( cache != null ) { if ( cache != null ) {
return (int) cache.getMemoryStoreSize(); return (int) cache.getMemoryStoreSize();
} }
@ -552,13 +450,9 @@ public class EhcacheStatsImpl extends AbstractEmitterBean implements EhcacheStat
} }
} }
/** @Override
* {@inheritDoc}
*
* @see EhcacheStats#getNumberOfElementsOffHeap(java.lang.String)
*/
public int getNumberOfElementsOffHeap(String region) { public int getNumberOfElementsOffHeap(String region) {
Cache cache = this.cacheManager.getCache( region ); final Cache cache = this.cacheManager.getCache( region );
if ( cache != null ) { if ( cache != null ) {
return (int) cache.getOffHeapStoreSize(); return (int) cache.getOffHeapStoreSize();
} }
@ -567,13 +461,9 @@ public class EhcacheStatsImpl extends AbstractEmitterBean implements EhcacheStat
} }
} }
/** @Override
* {@inheritDoc}
*
* @see EhcacheStats#getNumberOfElementsOnDisk(java.lang.String)
*/
public int getNumberOfElementsOnDisk(String region) { public int getNumberOfElementsOnDisk(String region) {
Cache cache = this.cacheManager.getCache( region ); final Cache cache = this.cacheManager.getCache( region );
if ( cache != null ) { if ( cache != null ) {
return cache.getDiskStoreSize(); return cache.getDiskStoreSize();
} }
@ -582,12 +472,10 @@ public class EhcacheStatsImpl extends AbstractEmitterBean implements EhcacheStat
} }
} }
/** @Override
* {@inheritDoc}
*/
public void setStatisticsEnabled(boolean flag) { public void setStatisticsEnabled(boolean flag) {
for ( String cacheName : cacheManager.getCacheNames() ) { for ( String cacheName : cacheManager.getCacheNames() ) {
Cache cache = cacheManager.getCache( cacheName ); final Cache cache = cacheManager.getCache( cacheName );
if ( cache != null ) { if ( cache != null ) {
cache.setStatisticsEnabled( flag ); cache.setStatisticsEnabled( flag );
} }
@ -598,13 +486,11 @@ public class EhcacheStatsImpl extends AbstractEmitterBean implements EhcacheStat
sendNotification( CACHE_STATISTICS_ENABLED, flag ); sendNotification( CACHE_STATISTICS_ENABLED, flag );
} }
/** @Override
* {@inheritDoc}
*/
public long getMaxGetTimeMillis() { public long getMaxGetTimeMillis() {
long rv = 0; long rv = 0;
for ( String cacheName : cacheManager.getCacheNames() ) { for ( String cacheName : cacheManager.getCacheNames() ) {
Cache cache = cacheManager.getCache( cacheName ); final Cache cache = cacheManager.getCache( cacheName );
if ( cache != null ) { if ( cache != null ) {
rv = Math.max( rv, cache.getLiveCacheStatistics().getMaxGetTimeMillis() ); rv = Math.max( rv, cache.getLiveCacheStatistics().getMaxGetTimeMillis() );
} }
@ -612,13 +498,11 @@ public class EhcacheStatsImpl extends AbstractEmitterBean implements EhcacheStat
return rv; return rv;
} }
/** @Override
* {@inheritDoc}
*/
public long getMinGetTimeMillis() { public long getMinGetTimeMillis() {
long rv = 0; long rv = 0;
for ( String cacheName : cacheManager.getCacheNames() ) { for ( String cacheName : cacheManager.getCacheNames() ) {
Cache cache = cacheManager.getCache( cacheName ); final Cache cache = cacheManager.getCache( cacheName );
if ( cache != null ) { if ( cache != null ) {
rv = Math.max( rv, cache.getLiveCacheStatistics().getMinGetTimeMillis() ); rv = Math.max( rv, cache.getLiveCacheStatistics().getMinGetTimeMillis() );
} }
@ -626,13 +510,9 @@ public class EhcacheStatsImpl extends AbstractEmitterBean implements EhcacheStat
return rv; return rv;
} }
/** @Override
* {@inheritDoc}
*
* @see EhcacheStats#getMaxGetTimeMillis(java.lang.String)
*/
public long getMaxGetTimeMillis(String cacheName) { public long getMaxGetTimeMillis(String cacheName) {
Cache cache = cacheManager.getCache( cacheName ); final Cache cache = cacheManager.getCache( cacheName );
if ( cache != null ) { if ( cache != null ) {
return cache.getLiveCacheStatistics().getMaxGetTimeMillis(); return cache.getLiveCacheStatistics().getMaxGetTimeMillis();
} }
@ -641,13 +521,9 @@ public class EhcacheStatsImpl extends AbstractEmitterBean implements EhcacheStat
} }
} }
/** @Override
* {@inheritDoc}
*
* @see EhcacheStats#getMinGetTimeMillis(java.lang.String)
*/
public long getMinGetTimeMillis(String cacheName) { public long getMinGetTimeMillis(String cacheName) {
Cache cache = cacheManager.getCache( cacheName ); final Cache cache = cacheManager.getCache( cacheName );
if ( cache != null ) { if ( cache != null ) {
return cache.getLiveCacheStatistics().getMinGetTimeMillis(); return cache.getLiveCacheStatistics().getMinGetTimeMillis();
} }
@ -656,13 +532,9 @@ public class EhcacheStatsImpl extends AbstractEmitterBean implements EhcacheStat
} }
} }
/** @Override
* {@inheritDoc}
*
* @see EhcacheStats#getAverageGetTimeMillis(java.lang.String)
*/
public float getAverageGetTimeMillis(String region) { public float getAverageGetTimeMillis(String region) {
Cache cache = this.cacheManager.getCache( region ); final Cache cache = this.cacheManager.getCache( region );
if ( cache != null ) { if ( cache != null ) {
return cache.getLiveCacheStatistics().getAverageGetTimeMillis(); return cache.getLiveCacheStatistics().getAverageGetTimeMillis();
} }
@ -671,17 +543,11 @@ public class EhcacheStatsImpl extends AbstractEmitterBean implements EhcacheStat
} }
} }
/**
* {@inheritDoc}
*/
@Override @Override
protected void doDispose() { protected void doDispose() {
// no-op // no-op
} }
/**
* @see AbstractEmitterBean#getNotificationInfo()
*/
@Override @Override
public MBeanNotificationInfo[] getNotificationInfo() { public MBeanNotificationInfo[] getNotificationInfo() {
return new MBeanNotificationInfo[] {NOTIFICATION_INFO}; return new MBeanNotificationInfo[] {NOTIFICATION_INFO};

View File

@ -34,7 +34,6 @@ import javax.management.openmbean.TabularDataSupport;
import javax.management.openmbean.TabularType; import javax.management.openmbean.TabularType;
import java.io.Serializable; import java.io.Serializable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Iterator;
import java.util.List; import java.util.List;
import org.hibernate.stat.EntityStatistics; import org.hibernate.stat.EntityStatistics;
@ -120,7 +119,8 @@ public class EntityStats implements Serializable {
protected long optimisticFailureCount; protected long optimisticFailureCount;
/** /**
* @param name * Constructor only naming the stat
* @param name the name of the entity
*/ */
public EntityStats(String name) { public EntityStats(String name) {
this.name = name; this.name = name;
@ -128,8 +128,9 @@ public class EntityStats implements Serializable {
} }
/** /**
* @param name * Constructor naming the stat and sourcing stats
* @param src * @param name the name of the entity
* @param src its source for the stats to expose
*/ */
public EntityStats(String name, EntityStatistics src) { public EntityStats(String name, EntityStatistics src) {
this( name ); this( name );
@ -149,8 +150,10 @@ public class EntityStats implements Serializable {
} }
/** /**
* @param cData * Constructor from compositeDate
* @param cData CompositeData of the stats
*/ */
@SuppressWarnings("UnusedAssignment")
public EntityStats(final CompositeData cData) { public EntityStats(final CompositeData cData) {
int i = 0; int i = 0;
name = (String) cData.get( ITEM_NAMES[i++] ); name = (String) cData.get( ITEM_NAMES[i++] );
@ -163,17 +166,9 @@ public class EntityStats implements Serializable {
optimisticFailureCount = (Long) cData.get( ITEM_NAMES[i++] ); optimisticFailureCount = (Long) cData.get( ITEM_NAMES[i++] );
} }
private static int safeParseInt(String s) {
try {
return Integer.parseInt( s );
}
catch (Exception e) {
return -1;
}
}
/** /**
* @param stats * Adds the counters of this instance up with the ones passed in
* @param stats the stats to add to this one
*/ */
public void add(EntityStats stats) { public void add(EntityStats stats) {
loadCount += stats.getLoadCount(); loadCount += stats.getLoadCount();
@ -185,7 +180,7 @@ public class EntityStats implements Serializable {
} }
/** /**
* toString * {@inheritDoc}
*/ */
@Override @Override
public String toString() { public String toString() {
@ -195,63 +190,73 @@ public class EntityStats implements Serializable {
} }
/** /**
* getName * The name of the entity those stats are about
* @return the entity name
*/ */
public String getName() { public String getName() {
return name; return name;
} }
/** /**
* getShortName * The short name of the entity those stats are about
* @return the shortName of the entity
*/ */
@SuppressWarnings("UnusedDeclaration")
public String getShortName() { public String getShortName() {
return shortName; return shortName;
} }
/** /**
* getLoadCount * Amount of load ops on the entity
* @return the load count
*/ */
public long getLoadCount() { public long getLoadCount() {
return loadCount; return loadCount;
} }
/** /**
* getUpdateCount * Amount of update ops on the entity
* @return the update count
*/ */
public long getUpdateCount() { public long getUpdateCount() {
return updateCount; return updateCount;
} }
/** /**
* getInsertCount * Amount of insert ops on the entity
* @return the insert count
*/ */
public long getInsertCount() { public long getInsertCount() {
return insertCount; return insertCount;
} }
/** /**
* getDeleteCount * Amount of delete ops on the entity
* @return the delete count
*/ */
public long getDeleteCount() { public long getDeleteCount() {
return deleteCount; return deleteCount;
} }
/** /**
* getFetchCount * Amount of fetch ops on the entity
* @return the fetch count
*/ */
public long getFetchCount() { public long getFetchCount() {
return fetchCount; return fetchCount;
} }
/** /**
* getOptimisticFailureCount * Amount of optimistic failures on the entity
* @return the optimistic failure count
*/ */
public long getOptimisticFailureCount() { public long getOptimisticFailureCount() {
return optimisticFailureCount; return optimisticFailureCount;
} }
/** /**
* toCompositeData * Creates a CompositeData instance of this instance
* @return the compositeData representation of this instance
*/ */
public CompositeData toCompositeData() { public CompositeData toCompositeData() {
try { try {
@ -268,19 +273,23 @@ public class EntityStats implements Serializable {
} }
/** /**
* newTabularDataInstance * Creates a new TabularData
* @return a new TabularData instance
*/ */
public static TabularData newTabularDataInstance() { public static TabularData newTabularDataInstance() {
return new TabularDataSupport( TABULAR_TYPE ); return new TabularDataSupport( TABULAR_TYPE );
} }
/** /**
* fromTabularData * Reads an array of entityStats from TabularData
* @param tabularData the tabularData with the {@link CompositeData} of stats to extract
* @return all entityStats as an array
*/ */
@SuppressWarnings({"unchecked", "UnusedDeclaration"})
public static EntityStats[] fromTabularData(final TabularData tabularData) { public static EntityStats[] fromTabularData(final TabularData tabularData) {
final List<EntityStats> countList = new ArrayList( tabularData.size() ); final List<EntityStats> countList = new ArrayList( tabularData.size() );
for ( final Iterator pos = tabularData.values().iterator(); pos.hasNext(); ) { for ( Object o : tabularData.values() ) {
countList.add( new EntityStats( (CompositeData) pos.next() ) ); countList.add( new EntityStats( (CompositeData) o ) );
} }
return countList.toArray( new EntityStats[countList.size()] ); return countList.toArray( new EntityStats[countList.size()] );
} }

View File

@ -59,9 +59,9 @@ public class HibernateStatsImpl extends AbstractEmitterBean implements Hibernate
/** /**
* Constructor accepting the backing {@link SessionFactory} * Constructor accepting the backing {@link SessionFactory}
* *
* @param sessionFactory * @param sessionFactory the {@link SessionFactory} to source stats from
* *
* @throws javax.management.NotCompliantMBeanException * @throws javax.management.NotCompliantMBeanException thrown from JMX super ctor
*/ */
public HibernateStatsImpl(SessionFactory sessionFactory) throws NotCompliantMBeanException { public HibernateStatsImpl(SessionFactory sessionFactory) throws NotCompliantMBeanException {
super( HibernateStats.class ); super( HibernateStats.class );
@ -75,254 +75,171 @@ public class HibernateStatsImpl extends AbstractEmitterBean implements Hibernate
return sessionFactory.getStatistics(); return sessionFactory.getStatistics();
} }
/** @Override
* {@inheritDoc}
*
* @see HibernateStats#clearStats()
*/
public void clearStats() { public void clearStats() {
getStatistics().clear(); getStatistics().clear();
sendNotification( CACHE_STATISTICS_RESET ); sendNotification( CACHE_STATISTICS_RESET );
} }
/** @Override
* {@inheritDoc}
*
* @see HibernateStats#disableStats()
*/
public void disableStats() { public void disableStats() {
setStatisticsEnabled( false ); setStatisticsEnabled( false );
} }
/** @Override
* {@inheritDoc}
*
* @see HibernateStats#enableStats()
*/
public void enableStats() { public void enableStats() {
setStatisticsEnabled( true ); setStatisticsEnabled( true );
} }
/** @Override
* {@inheritDoc}
*
* @see HibernateStats#getCloseStatementCount()
*/
public long getCloseStatementCount() { public long getCloseStatementCount() {
return getStatistics().getCloseStatementCount(); return getStatistics().getCloseStatementCount();
} }
/** @Override
* {@inheritDoc}
*
* @see HibernateStats#getConnectCount()
*/
public long getConnectCount() { public long getConnectCount() {
return getStatistics().getConnectCount(); return getStatistics().getConnectCount();
} }
/** /**
* Not supported right now * Unsupported operation
* @return nothing ever, this only throws!
* @throws UnsupportedOperationException
* @deprecated DO NOT USE, WILL ONLY THROW AT YOU!
*/ */
@Deprecated
@SuppressWarnings("UnusedDeclaration")
public long getDBSQLExecutionSample() { public long getDBSQLExecutionSample() {
throw new UnsupportedOperationException( "Use getQueryExecutionCount() instead" ); throw new UnsupportedOperationException( "Use getQueryExecutionCount() instead" );
} }
/** @Override
* {@inheritDoc}
*
* @see HibernateStats#getFlushCount()
*/
public long getFlushCount() { public long getFlushCount() {
return getStatistics().getFlushCount(); return getStatistics().getFlushCount();
} }
/** @Override
* {@inheritDoc}
*
* @see HibernateStats#getOptimisticFailureCount()
*/
public long getOptimisticFailureCount() { public long getOptimisticFailureCount() {
return getStatistics().getOptimisticFailureCount(); return getStatistics().getOptimisticFailureCount();
} }
/** @Override
* {@inheritDoc}
*
* @see HibernateStats#getPrepareStatementCount()
*/
public long getPrepareStatementCount() { public long getPrepareStatementCount() {
return getStatistics().getPrepareStatementCount(); return getStatistics().getPrepareStatementCount();
} }
/** @Override
* {@inheritDoc}
*
* @see HibernateStats#getQueryExecutionCount()
*/
public long getQueryExecutionCount() { public long getQueryExecutionCount() {
return getStatistics().getQueryExecutionCount(); return getStatistics().getQueryExecutionCount();
} }
/** @Override
* {@inheritDoc}
*
* @see HibernateStats#getQueryExecutionRate()
*/
public double getQueryExecutionRate() { public double getQueryExecutionRate() {
long startTime = getStatistics().getStartTime(); final long startTime = getStatistics().getStartTime();
long now = System.currentTimeMillis(); final long now = System.currentTimeMillis();
double deltaSecs = (now - startTime) / MILLIS_PER_SECOND; final double deltaSecs = (now - startTime) / MILLIS_PER_SECOND;
return getQueryExecutionCount() / deltaSecs; return getQueryExecutionCount() / deltaSecs;
} }
/** @Override
* {@inheritDoc}
*
* @see HibernateStats#getQueryExecutionSample()
*/
public long getQueryExecutionSample() { public long getQueryExecutionSample() {
throw new UnsupportedOperationException( "TODO: need to impl. rates for query execution" ); throw new UnsupportedOperationException( "TODO: need to impl. rates for query execution" );
} }
/** @Override
* {@inheritDoc}
*
* @see HibernateStats#getSessionCloseCount()
*/
public long getSessionCloseCount() { public long getSessionCloseCount() {
return getStatistics().getSessionCloseCount(); return getStatistics().getSessionCloseCount();
} }
/** @Override
* {@inheritDoc}
*
* @see HibernateStats#getSessionOpenCount()
*/
public long getSessionOpenCount() { public long getSessionOpenCount() {
return getStatistics().getSessionOpenCount(); return getStatistics().getSessionOpenCount();
} }
/** @Override
* {@inheritDoc}
*
* @see HibernateStats#getSuccessfulTransactionCount()
*/
public long getSuccessfulTransactionCount() { public long getSuccessfulTransactionCount() {
return getStatistics().getSuccessfulTransactionCount(); return getStatistics().getSuccessfulTransactionCount();
} }
/** @Override
* {@inheritDoc}
*
* @see HibernateStats#getTransactionCount()
*/
public long getTransactionCount() { public long getTransactionCount() {
return getStatistics().getTransactionCount(); return getStatistics().getTransactionCount();
} }
/** @Override
* {@inheritDoc}
*
* @see HibernateStats#isStatisticsEnabled()
*/
public boolean isStatisticsEnabled() { public boolean isStatisticsEnabled() {
return getStatistics().isStatisticsEnabled(); return getStatistics().isStatisticsEnabled();
} }
/** @Override
* {@inheritDoc}
*
* @see HibernateStats#setStatisticsEnabled(boolean)
*/
public void setStatisticsEnabled(boolean flag) { public void setStatisticsEnabled(boolean flag) {
getStatistics().setStatisticsEnabled( flag ); getStatistics().setStatisticsEnabled( flag );
sendNotification( CACHE_STATISTICS_ENABLED, flag ); sendNotification( CACHE_STATISTICS_ENABLED, flag );
} }
/** @Override
* {@inheritDoc}
*
* @see HibernateStats#getEntityStats()
*/
public TabularData getEntityStats() { public TabularData getEntityStats() {
List<CompositeData> result = new ArrayList<CompositeData>(); final List<CompositeData> result = new ArrayList<CompositeData>();
Statistics statistics = getStatistics(); final Statistics statistics = getStatistics();
for ( String entity : statistics.getEntityNames() ) { for ( String entity : statistics.getEntityNames() ) {
EntityStats entityStats = new EntityStats( entity, statistics.getEntityStatistics( entity ) ); final EntityStats entityStats = new EntityStats( entity, statistics.getEntityStatistics( entity ) );
result.add( entityStats.toCompositeData() ); result.add( entityStats.toCompositeData() );
} }
TabularData td = EntityStats.newTabularDataInstance(); final TabularData td = EntityStats.newTabularDataInstance();
td.putAll( result.toArray( new CompositeData[result.size()] ) ); td.putAll( result.toArray( new CompositeData[result.size()] ) );
return td; return td;
} }
/** @Override
* {@inheritDoc}
*
* @see HibernateStats#getCollectionStats()
*/
public TabularData getCollectionStats() { public TabularData getCollectionStats() {
List<CompositeData> result = new ArrayList<CompositeData>(); final List<CompositeData> result = new ArrayList<CompositeData>();
Statistics statistics = getStatistics(); final Statistics statistics = getStatistics();
for ( String roleName : statistics.getCollectionRoleNames() ) { for ( String roleName : statistics.getCollectionRoleNames() ) {
CollectionStats collectionStats = new CollectionStats( final CollectionStats collectionStats = new CollectionStats(
roleName, roleName,
statistics.getCollectionStatistics( roleName ) statistics.getCollectionStatistics( roleName )
); );
result.add( collectionStats.toCompositeData() ); result.add( collectionStats.toCompositeData() );
} }
TabularData td = CollectionStats.newTabularDataInstance(); final TabularData td = CollectionStats.newTabularDataInstance();
td.putAll( result.toArray( new CompositeData[result.size()] ) ); td.putAll( result.toArray( new CompositeData[result.size()] ) );
return td; return td;
} }
/** @Override
* {@inheritDoc}
*
* @see HibernateStats#getQueryStats()
*/
public TabularData getQueryStats() { public TabularData getQueryStats() {
List<CompositeData> result = new ArrayList<CompositeData>(); final List<CompositeData> result = new ArrayList<CompositeData>();
Statistics statistics = getStatistics(); final Statistics statistics = getStatistics();
for ( String query : statistics.getQueries() ) { for ( String query : statistics.getQueries() ) {
QueryStats queryStats = new QueryStats( query, statistics.getQueryStatistics( query ) ); final QueryStats queryStats = new QueryStats( query, statistics.getQueryStatistics( query ) );
result.add( queryStats.toCompositeData() ); result.add( queryStats.toCompositeData() );
} }
TabularData td = QueryStats.newTabularDataInstance(); final TabularData td = QueryStats.newTabularDataInstance();
td.putAll( result.toArray( new CompositeData[result.size()] ) ); td.putAll( result.toArray( new CompositeData[result.size()] ) );
return td; return td;
} }
/** @Override
* {@inheritDoc}
*/
public TabularData getCacheRegionStats() { public TabularData getCacheRegionStats() {
List<CompositeData> list = new ArrayList<CompositeData>(); final List<CompositeData> list = new ArrayList<CompositeData>();
Statistics statistics = getStatistics(); final Statistics statistics = getStatistics();
for ( String region : statistics.getSecondLevelCacheRegionNames() ) { for ( String region : statistics.getSecondLevelCacheRegionNames() ) {
CacheRegionStats l2CacheStats = new CacheRegionStats( final CacheRegionStats l2CacheStats = new CacheRegionStats(
region, region,
statistics.getSecondLevelCacheStatistics( region ) statistics.getSecondLevelCacheStatistics( region )
); );
list.add( l2CacheStats.toCompositeData() ); list.add( l2CacheStats.toCompositeData() );
} }
TabularData td = CacheRegionStats.newTabularDataInstance(); final TabularData td = CacheRegionStats.newTabularDataInstance();
td.putAll( list.toArray( new CompositeData[list.size()] ) ); td.putAll( list.toArray( new CompositeData[list.size()] ) );
return td; return td;
} }
/**
* {@inheritDoc}
*/
@Override @Override
protected void doDispose() { protected void doDispose() {
// no-op // no-op
} }
/**
* @see AbstractEmitterBean#getNotificationInfo()
*/
@Override @Override
public MBeanNotificationInfo[] getNotificationInfo() { public MBeanNotificationInfo[] getNotificationInfo() {
return new MBeanNotificationInfo[] {NOTIFICATION_INFO}; return new MBeanNotificationInfo[] {NOTIFICATION_INFO};

View File

@ -59,6 +59,7 @@ public final class NullHibernateStats implements HibernateStats {
* *
* @see HibernateStats#clearStats() * @see HibernateStats#clearStats()
*/ */
@Override
public void clearStats() { public void clearStats() {
// no-op // no-op
@ -69,6 +70,7 @@ public final class NullHibernateStats implements HibernateStats {
* *
* @see HibernateStats#disableStats() * @see HibernateStats#disableStats()
*/ */
@Override
public void disableStats() { public void disableStats() {
// no-op // no-op
@ -79,6 +81,7 @@ public final class NullHibernateStats implements HibernateStats {
* *
* @see HibernateStats#enableStats() * @see HibernateStats#enableStats()
*/ */
@Override
public void enableStats() { public void enableStats() {
// no-op // no-op
@ -89,6 +92,7 @@ public final class NullHibernateStats implements HibernateStats {
* *
* @see HibernateStats#getCloseStatementCount() * @see HibernateStats#getCloseStatementCount()
*/ */
@Override
public long getCloseStatementCount() { public long getCloseStatementCount() {
// no-op // no-op
return 0; return 0;
@ -99,6 +103,7 @@ public final class NullHibernateStats implements HibernateStats {
* *
* @see HibernateStats#getCollectionStats() * @see HibernateStats#getCollectionStats()
*/ */
@Override
public TabularData getCollectionStats() { public TabularData getCollectionStats() {
// no-op // no-op
return null; return null;
@ -109,6 +114,7 @@ public final class NullHibernateStats implements HibernateStats {
* *
* @see HibernateStats#getConnectCount() * @see HibernateStats#getConnectCount()
*/ */
@Override
public long getConnectCount() { public long getConnectCount() {
// no-op // no-op
return 0; return 0;
@ -116,7 +122,9 @@ public final class NullHibernateStats implements HibernateStats {
/** /**
* Not supported right now * Not supported right now
* @return 0 always
*/ */
@SuppressWarnings("UnusedDeclaration")
public long getDBSQLExecutionSample() { public long getDBSQLExecutionSample() {
// no-op // no-op
return 0; return 0;
@ -127,6 +135,7 @@ public final class NullHibernateStats implements HibernateStats {
* *
* @see HibernateStats#getEntityStats() * @see HibernateStats#getEntityStats()
*/ */
@Override
public TabularData getEntityStats() { public TabularData getEntityStats() {
// no-op // no-op
return null; return null;
@ -137,6 +146,7 @@ public final class NullHibernateStats implements HibernateStats {
* *
* @see HibernateStats#getFlushCount() * @see HibernateStats#getFlushCount()
*/ */
@Override
public long getFlushCount() { public long getFlushCount() {
// no-op // no-op
return 0; return 0;
@ -147,6 +157,7 @@ public final class NullHibernateStats implements HibernateStats {
* *
* @see HibernateStats#getOptimisticFailureCount() * @see HibernateStats#getOptimisticFailureCount()
*/ */
@Override
public long getOptimisticFailureCount() { public long getOptimisticFailureCount() {
// no-op // no-op
return 0; return 0;
@ -157,6 +168,7 @@ public final class NullHibernateStats implements HibernateStats {
* *
* @see HibernateStats#getPrepareStatementCount() * @see HibernateStats#getPrepareStatementCount()
*/ */
@Override
public long getPrepareStatementCount() { public long getPrepareStatementCount() {
// no-op // no-op
return 0; return 0;
@ -167,6 +179,7 @@ public final class NullHibernateStats implements HibernateStats {
* *
* @see HibernateStats#getQueryExecutionCount() * @see HibernateStats#getQueryExecutionCount()
*/ */
@Override
public long getQueryExecutionCount() { public long getQueryExecutionCount() {
// no-op // no-op
return 0; return 0;
@ -177,6 +190,7 @@ public final class NullHibernateStats implements HibernateStats {
* *
* @see HibernateStats#getQueryExecutionRate() * @see HibernateStats#getQueryExecutionRate()
*/ */
@Override
public double getQueryExecutionRate() { public double getQueryExecutionRate() {
// no-op // no-op
return 0; return 0;
@ -187,6 +201,7 @@ public final class NullHibernateStats implements HibernateStats {
* *
* @see HibernateStats#getQueryExecutionSample() * @see HibernateStats#getQueryExecutionSample()
*/ */
@Override
public long getQueryExecutionSample() { public long getQueryExecutionSample() {
// no-op // no-op
return 0; return 0;
@ -197,6 +212,7 @@ public final class NullHibernateStats implements HibernateStats {
* *
* @see HibernateStats#getQueryStats() * @see HibernateStats#getQueryStats()
*/ */
@Override
public TabularData getQueryStats() { public TabularData getQueryStats() {
// no-op // no-op
return null; return null;
@ -207,6 +223,7 @@ public final class NullHibernateStats implements HibernateStats {
* *
* @see HibernateStats#getSessionCloseCount() * @see HibernateStats#getSessionCloseCount()
*/ */
@Override
public long getSessionCloseCount() { public long getSessionCloseCount() {
// no-op // no-op
return 0; return 0;
@ -217,6 +234,7 @@ public final class NullHibernateStats implements HibernateStats {
* *
* @see HibernateStats#getSessionOpenCount() * @see HibernateStats#getSessionOpenCount()
*/ */
@Override
public long getSessionOpenCount() { public long getSessionOpenCount() {
// no-op // no-op
return 0; return 0;
@ -227,6 +245,7 @@ public final class NullHibernateStats implements HibernateStats {
* *
* @see HibernateStats#getSuccessfulTransactionCount() * @see HibernateStats#getSuccessfulTransactionCount()
*/ */
@Override
public long getSuccessfulTransactionCount() { public long getSuccessfulTransactionCount() {
// no-op // no-op
return 0; return 0;
@ -237,6 +256,7 @@ public final class NullHibernateStats implements HibernateStats {
* *
* @see HibernateStats#getTransactionCount() * @see HibernateStats#getTransactionCount()
*/ */
@Override
public long getTransactionCount() { public long getTransactionCount() {
// no-op // no-op
return 0; return 0;
@ -247,6 +267,7 @@ public final class NullHibernateStats implements HibernateStats {
* *
* @see HibernateStats#isStatisticsEnabled() * @see HibernateStats#isStatisticsEnabled()
*/ */
@Override
public boolean isStatisticsEnabled() { public boolean isStatisticsEnabled() {
// no-op // no-op
return false; return false;
@ -257,43 +278,54 @@ public final class NullHibernateStats implements HibernateStats {
* *
* @see HibernateStats#setStatisticsEnabled(boolean) * @see HibernateStats#setStatisticsEnabled(boolean)
*/ */
@Override
public void setStatisticsEnabled(boolean flag) { public void setStatisticsEnabled(boolean flag) {
// no-op // no-op
} }
/** /**
* {@inheritDoc}
* @see HibernateStats#getCacheRegionStats() * @see HibernateStats#getCacheRegionStats()
*/ */
@Override
public TabularData getCacheRegionStats() { public TabularData getCacheRegionStats() {
return null; return null;
} }
/** /**
* {@inheritDoc}
* @see javax.management.NotificationEmitter#removeNotificationListener(javax.management.NotificationListener, javax.management.NotificationFilter, java.lang.Object) * @see javax.management.NotificationEmitter#removeNotificationListener(javax.management.NotificationListener, javax.management.NotificationFilter, java.lang.Object)
*/ */
@Override
public void removeNotificationListener(NotificationListener listener, NotificationFilter filter, Object handback) public void removeNotificationListener(NotificationListener listener, NotificationFilter filter, Object handback)
throws ListenerNotFoundException { throws ListenerNotFoundException {
/**/ /**/
} }
/** /**
* {@inheritDoc}
* @see javax.management.NotificationBroadcaster#addNotificationListener(javax.management.NotificationListener, javax.management.NotificationFilter, java.lang.Object) * @see javax.management.NotificationBroadcaster#addNotificationListener(javax.management.NotificationListener, javax.management.NotificationFilter, java.lang.Object)
*/ */
@Override
public void addNotificationListener(NotificationListener listener, NotificationFilter filter, Object handback) public void addNotificationListener(NotificationListener listener, NotificationFilter filter, Object handback)
throws IllegalArgumentException { throws IllegalArgumentException {
/**/ /**/
} }
/** /**
* {@inheritDoc}
* @see javax.management.NotificationBroadcaster#getNotificationInfo() * @see javax.management.NotificationBroadcaster#getNotificationInfo()
*/ */
@Override
public MBeanNotificationInfo[] getNotificationInfo() { public MBeanNotificationInfo[] getNotificationInfo() {
return null; return null;
} }
/** /**
* {@inheritDoc}
* @see javax.management.NotificationBroadcaster#removeNotificationListener(javax.management.NotificationListener) * @see javax.management.NotificationBroadcaster#removeNotificationListener(javax.management.NotificationListener)
*/ */
@Override
public void removeNotificationListener(NotificationListener listener) throws ListenerNotFoundException { public void removeNotificationListener(NotificationListener listener) throws ListenerNotFoundException {
/**/ /**/
} }

View File

@ -24,7 +24,6 @@
package org.hibernate.cache.ehcache.management.impl; package org.hibernate.cache.ehcache.management.impl;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.util.Iterator;
import java.util.Map; import java.util.Map;
import java.util.Properties; import java.util.Properties;
import java.util.TimerTask; import java.util.TimerTask;
@ -116,7 +115,7 @@ public class ProviderMBeanRegistrationHelper {
throw new CacheException( e ); throw new CacheException( e );
} }
} }
SessionFactory sessionFactory = locateSessionFactory(); final SessionFactory sessionFactory = locateSessionFactory();
if ( sessionFactory == null ) { if ( sessionFactory == null ) {
LOG.debug( LOG.debug(
"SessionFactory is probably still being initialized..." "SessionFactory is probably still being initialized..."
@ -130,7 +129,6 @@ public class ProviderMBeanRegistrationHelper {
); );
this.cancel(); this.cancel();
} }
return;
} }
else { else {
ehcacheHibernateMBeanRegistration.enableHibernateStatisticsSupport( sessionFactory ); ehcacheHibernateMBeanRegistration.enableHibernateStatisticsSupport( sessionFactory );
@ -140,29 +138,25 @@ public class ProviderMBeanRegistrationHelper {
} }
private SessionFactory locateSessionFactory() { private SessionFactory locateSessionFactory() {
String jndiName = properties.getProperty( Environment.SESSION_FACTORY_NAME ); final String jndiName = properties.getProperty( Environment.SESSION_FACTORY_NAME );
if ( jndiName != null ) { if ( jndiName != null ) {
return SessionFactoryRegistry.INSTANCE.getNamedSessionFactory( jndiName ); return SessionFactoryRegistry.INSTANCE.getNamedSessionFactory( jndiName );
} }
try { try {
Class factoryType = SessionFactoryRegistry.class; final Class factoryType = SessionFactoryRegistry.class;
Field instancesField = getField( factoryType, "sessionFactoryMap" ); final Field instancesField = getField( factoryType, "sessionFactoryMap" );
if ( instancesField == null ) {
throw new RuntimeException( "Expected 'sessionFactoryMap' field on " + SessionFactoryRegistry.class.getName() );
}
instancesField.setAccessible( true ); instancesField.setAccessible( true );
Map map = (Map) instancesField.get( SessionFactoryRegistry.INSTANCE ); final Map map = (Map) instancesField.get( SessionFactoryRegistry.INSTANCE );
if ( map == null ) { if ( map == null ) {
return null; return null;
} }
Iterator values = map.values().iterator(); for ( Object o : map.values() ) {
while ( values.hasNext() ) { final SessionFactory sessionFactory = (SessionFactory) o;
SessionFactory sessionFactory = (SessionFactory) values.next(); final Class sessionFactoryType = sessionFactory.getClass();
Class sessionFactoryType = sessionFactory.getClass(); final Field propertiesField = getField( sessionFactoryType, "properties" );
Field propertiesField = getField( sessionFactoryType, "properties" );
if ( propertiesField != null ) { if ( propertiesField != null ) {
propertiesField.setAccessible( true ); propertiesField.setAccessible( true );
Properties props = (Properties) propertiesField.get( sessionFactory ); final Properties props = (Properties) propertiesField.get( sessionFactory );
if ( props != null && props.equals( properties ) ) { if ( props != null && props.equals( properties ) ) {
return sessionFactory; return sessionFactory;
} }

Some files were not shown because too many files have changed in this diff Show More