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 {
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"
task wrapper(type: Wrapper) {
gradleVersion = '1.5'
gradleVersion = '1.6'
}
idea {
@ -103,6 +104,8 @@ subprojects { subProject ->
configurations {
all*.exclude group: 'xml-apis', module: 'xml-apis'
}
animalSniffer
javaApiSignature
}
// appropriately inject the common dependencies into each sub-project
@ -133,6 +136,8 @@ subprojects { subProject ->
jaxb( libraries.jaxb2_ant )
jaxb( libraries.jaxb2_jaxb )
jaxb( libraries.jaxb2_jaxb_xjc )
animalSniffer ( libraries.animal_sniffer )
javaApiSignature ( libraries.java16_signature )
}
// mac-specific stuff ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -172,7 +177,9 @@ subprojects { subProject ->
"-encoding", "UTF-8",
"-processor", "org.jboss.logging.processor.apt.LoggingToolsProcessor",
"-s", "$sourceSets.main.generatedLoggingSrcDir.absolutePath",
"-AloggingVersion=3.0",
// "-AloggingVersion=3.0",
"-Adebug=true",
"-AskipTranslations=true",
"-source", rootProject.javaLanguageLevel,
"-target", rootProject.javaLanguageLevel,
"-AtranslationFilesPath=${project.rootDir}/src/main/resources"
@ -313,8 +320,25 @@ subprojects { subProject ->
}
}
// eclipseClasspath will not add sources to classpath unless the dirs actually exist.
eclipseClasspath.dependsOn("generateSources")
// eclipseClasspath will not add sources to classpath unless the dirs actually exist.
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 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
task checkstylePublicSources(type: Checkstyle) {
@ -387,30 +411,49 @@ subprojects { subProject ->
}
pom.withXml {
def root = asNode();
root.appendNode( 'name', subProject.pomName() )
root.appendNode( 'description', subProject.pomDescription() )
root.appendNode( 'url', 'http://hibernate.org' )
def org = root.appendNode( 'organization' )
org.appendNode( 'name', 'Hibernate.org' )
org.appendNode( 'url', 'http://hibernate.org' )
def jira = root.appendNode( 'issueManagement' )
jira.appendNode( 'system', 'jira' )
jira.appendNode( 'url', 'https://hibernate.atlassian.net/browse/HHH' )
def scm = root.appendNode( 'scm' )
scm.appendNode( 'url', 'http://github.com/hibernate/hibernate-orm' )
scm.appendNode( 'connection', 'scm:git:http://github.com/hibernate/hibernate-orm.git' )
scm.appendNode( 'developerConnection', 'scm:git:git@github.com:hibernate/hibernate-orm.git' )
def license = root.appendNode( 'licenses' ).appendNode( 'license' );
license.appendNode( 'name', 'GNU Lesser General Public License' )
license.appendNode( 'url', 'http://www.gnu.org/licenses/lgpl-2.1.html' )
license.appendNode( 'comments', 'See discussion at http://hibernate.org/license for more details.' )
license.appendNode( 'distribution', 'repo' )
def dev = root.appendNode( 'developers' ).appendNode( 'developer' );
dev.appendNode( 'id', 'hibernate-team' )
dev.appendNode( 'name', 'The Hibernate Development Team' )
dev.appendNode( 'organization', 'Hibernate.org' )
dev.appendNode( 'organizationUrl', 'http://hibernate.org' )
// append additional metadata
asNode().children().last() + {
resolveStrategy = Closure.DELEGATE_FIRST
name subProject.pomName()
description subProject.pomDescription()
url 'http://hibernate.org'
organization {
name 'Hibernate.org'
url 'http://hibernate.org'
}
issueManagement {
system 'jira'
url 'https://hibernate.atlassian.net/browse/HHH'
}
scm {
url 'http://github.com/hibernate/hibernate-orm'
connection 'scm:git:http://github.com/hibernate/hibernate-orm.git'
developerConnection 'scm:git:git@github.com:hibernate/hibernate-orm.git'
}
licenses {
license {
name 'GNU Lesser General Public License'
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
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
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;
if ( key.startsWith( "hibernate.c3p0." ) ) {
String newKey = key.substring( 15 );
final String newKey = key.substring( 15 );
if ( props.containsKey( newKey ) ) {
warnPropertyConflict( key, newKey );
}
@ -267,6 +267,7 @@ public class C3P0ConnectionProvider
*
* @deprecated Use {@link #stop} instead
*/
@SuppressWarnings("UnusedDeclaration")
@Deprecated
public void close() {
stop();

View File

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

View File

@ -26,6 +26,7 @@ package org.hibernate;
import java.io.Serializable;
import org.hibernate.procedure.ProcedureCall;
import org.hibernate.procedure.ProcedureCallMemento;
/**
* Contract methods shared between {@link Session} and {@link StatelessSession}.
@ -86,6 +87,17 @@ public interface SharedSessionContract extends Serializable {
*/
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.
*
@ -154,5 +166,4 @@ public interface SharedSessionContract extends Serializable {
* @return The criteria instance for manipulation and execution
*/
public Criteria createCriteria(String entityName, String alias);
}

View File

@ -35,6 +35,7 @@ import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import javax.persistence.Basic;
import javax.persistence.Cacheable;
import javax.persistence.CollectionTable;
@ -67,6 +68,8 @@ import javax.persistence.NamedNativeQueries;
import javax.persistence.NamedNativeQuery;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.NamedStoredProcedureQueries;
import javax.persistence.NamedStoredProcedureQuery;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.OrderColumn;
@ -81,8 +84,6 @@ import javax.persistence.TableGenerator;
import javax.persistence.UniqueConstraint;
import javax.persistence.Version;
import org.jboss.logging.Logger;
import org.hibernate.AnnotationException;
import org.hibernate.AssertionFailure;
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.TableBinder;
import org.hibernate.engine.OptimisticLockStyle;
import org.hibernate.engine.internal.Versioning;
import org.hibernate.engine.spi.FilterDefinition;
import org.hibernate.id.MultipleHiLoPerTableGenerator;
import org.hibernate.id.PersistentIdentifierGenerator;
@ -159,9 +159,9 @@ import org.hibernate.id.SequenceHiLoGenerator;
import org.hibernate.id.TableHiLoGenerator;
import org.hibernate.id.enhanced.SequenceStyleGenerator;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.mapping.Any;
import org.hibernate.mapping.Component;
import org.hibernate.mapping.Constraint;
import org.hibernate.mapping.DependantValue;
import org.hibernate.mapping.IdGenerator;
import org.hibernate.mapping.Join;
@ -175,6 +175,7 @@ import org.hibernate.mapping.SingleTableSubclass;
import org.hibernate.mapping.Subclass;
import org.hibernate.mapping.ToOne;
import org.hibernate.mapping.UnionSubclass;
import org.jboss.logging.Logger;
/**
* 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) {
@ -359,6 +382,24 @@ public final class AnnotationBinder {
);
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) {
@ -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 );
if ( naturalIdAnn != null ) {
if ( joinColumns != null ) {
for ( Ejb3Column column : joinColumns ) {
column.addUniqueKey( column.getTable().getNaturalIdUniqueKeyName(), inSecondPass );
String keyName = "UK_" + Constraint.hashedName( column.getTable().getName() + "_NaturalID" );
column.addUniqueKey( keyName, inSecondPass );
}
}
else {
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.classloading.spi.ClassLoaderService;
import org.hibernate.boot.registry.internal.StandardServiceRegistryImpl;
import org.hibernate.cfg.annotations.NamedProcedureCallDefinition;
import org.hibernate.cfg.annotations.reflection.JPAMetadataProvider;
import org.hibernate.context.spi.CurrentTenantIdentifierResolver;
import org.hibernate.dialect.Dialect;
@ -122,6 +123,7 @@ import org.hibernate.jaxb.spi.SourceType;
import org.hibernate.mapping.AuxiliaryDatabaseObject;
import org.hibernate.mapping.Collection;
import org.hibernate.mapping.Column;
import org.hibernate.mapping.Constraint;
import org.hibernate.mapping.DenormalizedTable;
import org.hibernate.mapping.FetchProfile;
import org.hibernate.mapping.ForeignKey;
@ -213,6 +215,7 @@ public class Configuration implements Serializable {
protected Map<String, NamedQueryDefinition> namedQueries;
protected Map<String, NamedSQLQueryDefinition> namedSqlQueries;
protected Map<String, NamedProcedureCallDefinition> namedProcedureCallMap;
protected Map<String, ResultSetMappingDefinition> sqlResultSetMappings;
protected Map<String, TypeDef> typeDefs;
@ -1398,22 +1401,14 @@ public class Configuration implements Serializable {
final Table table = tableListEntry.getKey();
final List<UniqueConstraintHolder> uniqueConstraints = tableListEntry.getValue();
for ( UniqueConstraintHolder holder : uniqueConstraints ) {
final String keyName = StringHelper.isEmpty( holder.getName() )
? StringHelper.randomFixedLengthHex("UK_")
: holder.getName();
buildUniqueKeyFromColumnNames( table, keyName, holder.getColumns() );
buildUniqueKeyFromColumnNames( table, holder.getName(), holder.getColumns() );
}
}
for(Table table : jpaIndexHoldersByTable.keySet()){
final List<JPAIndexHolder> jpaIndexHolders = jpaIndexHoldersByTable.get( table );
int uniqueIndexPerTable = 0;
for ( JPAIndexHolder holder : jpaIndexHolders ) {
uniqueIndexPerTable++;
final String keyName = StringHelper.isEmpty( holder.getName() )
? "idx_"+table.getName()+"_" + uniqueIndexPerTable
: holder.getName();
buildUniqueKeyFromColumnNames( table, keyName, holder.getColumns(), holder.getOrdering(), holder.isUnique() );
buildUniqueKeyFromColumnNames( table, holder.getName(), 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) {
keyName = normalizer.normalizeIdentifierQuoting( keyName );
int size = columnNames.length;
Column[] columns = new Column[size];
Set<Column> unbound = new HashSet<Column>();
@ -1594,6 +1587,12 @@ public class Configuration implements Serializable {
unboundNoLogical.add( new Column( column ) );
}
}
if ( StringHelper.isEmpty( keyName ) ) {
keyName = Constraint.generateName( "UK_", table, columns );
}
keyName = normalizer.normalizeIdentifierQuoting( keyName );
if ( unique ) {
UniqueKey uk = table.getOrCreateUniqueKey( keyName );
for ( int i = 0; i < columns.length; i++ ) {
@ -1775,6 +1774,10 @@ public class Configuration implements Serializable {
return namedQueries;
}
public Map<String, NamedProcedureCallDefinition> getNamedProcedureCallMap() {
return namedProcedureCallMap;
}
/**
* 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
@ -2767,7 +2770,7 @@ public class Configuration implements Serializable {
public Table getTable(String schema, String catalog, String name) {
String key = Table.qualify(catalog, schema, name);
return tables.get(key);
return tables.get( key );
}
public Iterator<Table> iterateTables() {
@ -2873,6 +2876,16 @@ public class Configuration implements Serializable {
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) {
applySQLQuery( name, query );
defaultNamedNativeQueryNames.add( name );

View File

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

View File

@ -36,6 +36,7 @@ import org.hibernate.MappingException;
import org.hibernate.annotations.AnyMetaDef;
import org.hibernate.annotations.common.reflection.ReflectionManager;
import org.hibernate.annotations.common.reflection.XClass;
import org.hibernate.cfg.annotations.NamedProcedureCallDefinition;
import org.hibernate.engine.ResultSetMappingDefinition;
import org.hibernate.engine.spi.FilterDefinition;
import org.hibernate.engine.spi.NamedQueryDefinition;
@ -337,6 +338,15 @@ public interface Mappings {
*/
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.
*

View File

@ -32,6 +32,7 @@ import org.hibernate.annotations.common.reflection.XClass;
import org.hibernate.cfg.annotations.PropertyBinder;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.mapping.Column;
import org.hibernate.mapping.Component;
import org.hibernate.mapping.DependantValue;
import org.hibernate.mapping.Join;
import org.hibernate.mapping.ManyToOne;
@ -211,7 +212,23 @@ public class OneToOneSecondPass implements SecondPass {
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();
if ( propertyRef != null ) {

View File

@ -1416,12 +1416,9 @@ public abstract class CollectionBinder {
private String extractHqlOrderBy(javax.persistence.OrderBy jpaOrderBy) {
if ( jpaOrderBy != null ) {
final String jpaOrderByFragment = jpaOrderBy.value();
return StringHelper.isNotEmpty( jpaOrderByFragment )
? jpaOrderByFragment
: null;
return jpaOrderBy.value(); // Null not possible. In case of empty expression, apply default ordering.
}
return null;
return null; // @OrderBy not found.
}
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.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.NamedStoredProcedureQuery;
import javax.persistence.QueryHint;
import javax.persistence.SqlResultSetMapping;
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) {
if ( ann == null ) return;
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;
}
@ -283,6 +286,16 @@ public class ConnectionProviderInitiator implements StandardServiceInitiator<Con
SPECIAL_PROPERTIES.add( Environment.ISOLATION );
SPECIAL_PROPERTIES.add( Environment.DRIVER );
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
@Override
public Transaction beginTransaction() {
return session.beginTransaction();
}
@Override
public Transaction getTransaction() {
return session.getTransaction();
}
@Override
public Query createQuery(String queryString) {
return session.createQuery( queryString );
}
@Override
public SQLQuery createSQLQuery(String queryString) {
return session.createSQLQuery( queryString );
}
@Override
public ProcedureCall getNamedProcedureCall(String name) {
return session.getNamedProcedureCall( name );
}
@Override
public ProcedureCall createStoredProcedureCall(String procedureName) {
return session.createStoredProcedureCall( procedureName );
@ -411,298 +420,372 @@ public class SessionDelegatorBaseImpl implements SessionImplementor, Session {
return session.createStoredProcedureCall( procedureName, resultSetMappings );
}
@Override
public Criteria createCriteria(Class persistentClass) {
return session.createCriteria( persistentClass );
}
@Override
public Criteria createCriteria(Class persistentClass, String alias) {
return session.createCriteria( persistentClass, alias );
}
@Override
public Criteria createCriteria(String entityName) {
return session.createCriteria( entityName );
}
@Override
public Criteria createCriteria(String entityName, String alias) {
return session.createCriteria( entityName, alias );
}
@Override
public SharedSessionBuilder sessionWithOptions() {
return session.sessionWithOptions();
}
@Override
public SessionFactory getSessionFactory() {
return session.getSessionFactory();
}
@Override
public Connection close() throws HibernateException {
return session.close();
}
@Override
public void cancelQuery() throws HibernateException {
session.cancelQuery();
}
@Override
public boolean isDirty() throws HibernateException {
return session.isDirty();
}
@Override
public boolean isDefaultReadOnly() {
return session.isDefaultReadOnly();
}
@Override
public void setDefaultReadOnly(boolean readOnly) {
session.setDefaultReadOnly( readOnly );
}
@Override
public Serializable getIdentifier(Object object) {
return session.getIdentifier( object );
}
@Override
public boolean contains(Object object) {
return session.contains( object );
}
@Override
public void evict(Object object) {
session.evict( object );
}
@Override
public Object load(Class theClass, Serializable id, LockMode lockMode) {
return session.load( theClass, id, lockMode );
}
@Override
public Object load(Class theClass, Serializable id, LockOptions lockOptions) {
return session.load( theClass, id, lockOptions );
}
@Override
public Object load(String entityName, Serializable id, LockMode lockMode) {
return session.load( entityName, id, lockMode );
}
@Override
public Object load(String entityName, Serializable id, LockOptions lockOptions) {
return session.load( entityName, id, lockOptions );
}
@Override
public Object load(Class theClass, Serializable id) {
return session.load( theClass, id );
}
@Override
public Object load(String entityName, Serializable id) {
return session.load( entityName, id );
}
@Override
public void load(Object object, Serializable id) {
session.load( object, id );
}
@Override
public void replicate(Object object, ReplicationMode replicationMode) {
session.replicate( object, replicationMode );
}
@Override
public void replicate(String entityName, Object object, ReplicationMode replicationMode) {
session.replicate( entityName, object, replicationMode );
}
@Override
public Serializable save(Object object) {
return session.save( object );
}
@Override
public Serializable save(String entityName, Object object) {
return session.save( entityName, object );
}
@Override
public void saveOrUpdate(Object object) {
session.saveOrUpdate( object );
}
@Override
public void saveOrUpdate(String entityName, Object object) {
session.saveOrUpdate( entityName, object );
}
@Override
public void update(Object object) {
session.update( object );
}
@Override
public void update(String entityName, Object object) {
session.update( entityName, object );
}
@Override
public Object merge(Object object) {
return session.merge( object );
}
@Override
public Object merge(String entityName, Object object) {
return session.merge( entityName, object );
}
@Override
public void persist(Object object) {
session.persist( object );
}
@Override
public void persist(String entityName, Object object) {
session.persist( entityName, object );
}
@Override
public void delete(Object object) {
session.delete( object );
}
@Override
public void delete(String entityName, Object object) {
session.delete( entityName, object );
}
@Override
public void lock(Object object, LockMode lockMode) {
session.lock( object, lockMode );
}
@Override
public void lock(String entityName, Object object, LockMode lockMode) {
session.lock( entityName, object, lockMode );
}
@Override
public LockRequest buildLockRequest(LockOptions lockOptions) {
return session.buildLockRequest( lockOptions );
}
@Override
public void refresh(Object object) {
session.refresh( object );
}
@Override
public void refresh(String entityName, Object object) {
session.refresh( entityName, object );
}
@Override
public void refresh(Object object, LockMode lockMode) {
session.refresh( object, lockMode );
}
@Override
public void refresh(Object object, LockOptions lockOptions) {
session.refresh( object, lockOptions );
}
@Override
public void refresh(String entityName, Object object, LockOptions lockOptions) {
session.refresh( entityName, object, lockOptions );
}
@Override
public LockMode getCurrentLockMode(Object object) {
return session.getCurrentLockMode( object );
}
@Override
public Query createFilter(Object collection, String queryString) {
return session.createFilter( collection, queryString );
}
@Override
public void clear() {
session.clear();
}
@Override
public Object get(Class clazz, Serializable id) {
return session.get( clazz, id );
}
@Override
public Object get(Class clazz, Serializable id, LockMode lockMode) {
return session.get( clazz, id, lockMode );
}
@Override
public Object get(Class clazz, Serializable id, LockOptions lockOptions) {
return session.get( clazz, id, lockOptions );
}
@Override
public Object get(String entityName, Serializable id) {
return session.get( entityName, id );
}
@Override
public Object get(String entityName, Serializable id, LockMode lockMode) {
return session.get( entityName, id, lockMode );
}
@Override
public Object get(String entityName, Serializable id, LockOptions lockOptions) {
return session.get( entityName, id, lockOptions );
}
@Override
public String getEntityName(Object object) {
return session.getEntityName( object );
}
@Override
public IdentifierLoadAccess byId(String entityName) {
return session.byId( entityName );
}
@Override
public IdentifierLoadAccess byId(Class entityClass) {
return session.byId( entityClass );
}
@Override
public NaturalIdLoadAccess byNaturalId(String entityName) {
return session.byNaturalId( entityName );
}
@Override
public NaturalIdLoadAccess byNaturalId(Class entityClass) {
return session.byNaturalId( entityClass );
}
@Override
public SimpleNaturalIdLoadAccess bySimpleNaturalId(String entityName) {
return session.bySimpleNaturalId( entityName );
}
@Override
public SimpleNaturalIdLoadAccess bySimpleNaturalId(Class entityClass) {
return session.bySimpleNaturalId( entityClass );
}
@Override
public Filter enableFilter(String filterName) {
return session.enableFilter( filterName );
}
@Override
public Filter getEnabledFilter(String filterName) {
return session.getEnabledFilter( filterName );
}
@Override
public void disableFilter(String filterName) {
session.disableFilter( filterName );
}
@Override
public SessionStatistics getStatistics() {
return session.getStatistics();
}
@Override
public boolean isReadOnly(Object entityOrProxy) {
return session.isReadOnly( entityOrProxy );
}
@Override
public void setReadOnly(Object entityOrProxy, boolean readOnly) {
session.setReadOnly( entityOrProxy, readOnly );
}
@Override
public void doWork(Work work) throws HibernateException {
session.doWork( work );
}
@Override
public <T> T doReturningWork(ReturningWork<T> work) throws HibernateException {
return session.doReturningWork( work );
}
@Override
public Connection disconnect() {
return session.disconnect();
}
@Override
public void reconnect(Connection connection) {
session.reconnect( connection );
}
@Override
public boolean isFetchProfileEnabled(String name) throws UnknownProfileException {
return session.isFetchProfileEnabled( name );
}
@Override
public void enableFetchProfile(String name) throws UnknownProfileException {
session.enableFetchProfile( name );
}
@Override
public void disableFetchProfile(String name) throws UnknownProfileException {
session.disableFetchProfile( name );
}
@Override
public TypeHelper getTypeHelper() {
return session.getTypeHelper();
}
@Override
public LobHelper getLobHelper() {
return session.getLobHelper();
}

View File

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

View File

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

View File

@ -1,10 +1,10 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
* Copyright (c) 2008, 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 Middleware LLC.
* distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
@ -20,7 +20,6 @@
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*
*/
package org.hibernate.hql.internal.ast.tree;
import java.util.ArrayList;
@ -139,7 +138,7 @@ public class SelectClause extends SelectExpressionList {
// NOTE: This must be done *before* invoking setScalarColumnText() because setScalarColumnText()
// changes the AST!!!
SelectExpression[] selectExpressions = collectSelectExpressions();
for ( int i = 0; i < selectExpressions.length; i++ ) {
SelectExpression selectExpression = selectExpressions[i];
@ -176,14 +175,14 @@ public class SelectClause extends SelectExpressionList {
if ( !getWalker().isShallowQuery() ) {
// add the fetched entities
List fromElements = fromClause.getProjectionList();
ASTAppender appender = new ASTAppender( getASTFactory(), this ); // Get ready to start adding nodes.
int size = fromElements.size();
Iterator iterator = fromElements.iterator();
for ( int k = 0; iterator.hasNext(); k++ ) {
FromElement fromElement = ( FromElement ) iterator.next();
if ( fromElement.isFetch() ) {
FromElement origin = null;
if ( fromElement.getRealOrigin() == null ) {
@ -226,7 +225,7 @@ public class SelectClause extends SelectExpressionList {
}
}
}
// generate id select fragment and then property select fragment for
// each expression, just like generateSelectFragments().
renderNonScalarSelects( collectSelectExpressions(), fromClause );
@ -326,7 +325,7 @@ public class SelectClause extends SelectExpressionList {
private void addCollectionFromElement(FromElement fromElement) {
if ( fromElement.isFetch() ) {
if ( fromElement.isCollectionJoin() || fromElement.getQueryableCollection() != null ) {
if ( fromElement.getQueryableCollection() != null ) {
String suffix;
if (collectionFromElements==null) {
collectionFromElements = new ArrayList();

View File

@ -23,6 +23,7 @@
*
*/
package org.hibernate.hql.internal.ast.util;
import java.util.HashMap;
import java.util.Map;
@ -58,8 +59,8 @@ import org.hibernate.type.Type;
*/
public class SessionFactoryHelper {
private SessionFactoryImplementor sfi;
private Map collectionPropertyMappingByRole;
private final SessionFactoryImplementor sfi;
private final Map<String, PropertyMapping> collectionPropertyMappingByRole;
/**
* Construct a new SessionFactoryHelper instance.
@ -68,7 +69,7 @@ public class SessionFactoryHelper {
*/
public SessionFactoryHelper(SessionFactoryImplementor 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?
*
* @param persister The persister to be checked.
*
* @return True if the persister does define an actual discriminator column.
*/
public boolean hasPhysicalDiscriminatorColumn(Queryable persister) {
@ -103,6 +105,7 @@ public class SessionFactoryHelper {
* Given a (potentially unqualified) class name, locate its imported qualified name.
*
* @param className The potentially unqualified class name
*
* @return The qualified class name.
*/
public String getImportedClassName(String className) {
@ -113,6 +116,7 @@ public class SessionFactoryHelper {
* Given a (potentially unqualified) class name, locate its persister.
*
* @param className The (potentially unqualified) class name.
*
* @return The defined persister for this class, or null if none found.
*/
public Queryable findQueryableUsingImports(String className) {
@ -125,6 +129,7 @@ public class SessionFactoryHelper {
*
* @param sfi The session factory implementor.
* @param className The (potentially unqualified) class name.
*
* @return The defined persister for this class, or null if none found.
*/
public static Queryable findQueryableUsingImports(SessionFactoryImplementor sfi, String className) {
@ -133,7 +138,7 @@ public class SessionFactoryHelper {
return null;
}
try {
return ( Queryable ) sfi.getEntityPersister( importedClassName );
return (Queryable) sfi.getEntityPersister( importedClassName );
}
catch ( MappingException me ) {
return null;
@ -144,7 +149,9 @@ public class SessionFactoryHelper {
* Locate the persister by class or entity name.
*
* @param name The class or entity name
*
* @return The defined persister for this entity, or null if none found.
*
* @throws MappingException
*/
private EntityPersister findEntityPersisterByName(String name) throws MappingException {
@ -169,7 +176,9 @@ public class SessionFactoryHelper {
* exist.
*
* @param name The class or entity name
*
* @return The defined persister for this entity
*
* @throws SemanticException Indicates the persister could not be found
*/
public EntityPersister requireClassPersister(String name) throws SemanticException {
@ -190,11 +199,12 @@ public class SessionFactoryHelper {
* Locate the collection persister by the collection role.
*
* @param role The collection role name.
*
* @return The defined CollectionPersister for this collection role, or null.
*/
public QueryableCollection getCollectionPersister(String role) {
try {
return ( QueryableCollection ) sfi.getCollectionPersister( role );
return (QueryableCollection) sfi.getCollectionPersister( role );
}
catch ( ClassCastException cce ) {
throw new QueryException( "collection is not queryable: " + role );
@ -209,12 +219,14 @@ public class SessionFactoryHelper {
* such a persister exist.
*
* @param role The collection role name.
*
* @return The defined CollectionPersister for this collection role.
*
* @throws QueryException Indicates that the collection persister could not be found.
*/
public QueryableCollection requireQueryableCollection(String role) throws QueryException {
try {
QueryableCollection queryableCollection = ( QueryableCollection ) sfi.getCollectionPersister( role );
QueryableCollection queryableCollection = (QueryableCollection) sfi.getCollectionPersister( role );
if ( queryableCollection != null ) {
collectionPropertyMappingByRole.put( role, new CollectionPropertyMapping( queryableCollection ) );
}
@ -232,10 +244,11 @@ public class SessionFactoryHelper {
* Retrieve a PropertyMapping describing the given collection role.
*
* @param role The collection role for which to retrieve the property mapping.
*
* @return The property mapping.
*/
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 roleAlias The sql column-qualification alias (i.e., the table alias)
*
* @return the collection element columns
*/
public String[] getCollectionElementColumns(String role, String roleAlias) {
@ -267,11 +281,12 @@ public class SessionFactoryHelper {
* @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 columns The columns making up the condition of the join.
*
* @return The generated join sequence.
*/
public JoinSequence createJoinSequence(boolean implicit, AssociationType associationType, String tableAlias, JoinType joinType, String[] columns) {
JoinSequence joinSequence = createJoinSequence();
joinSequence.setUseThetaStyle( implicit ); // Implicit joins use theta style (WHERE pk = fk), explicit joins use JOIN (after from)
joinSequence.setUseThetaStyle( implicit ); // Implicit joins use theta style (WHERE pk = fk), explicit joins use JOIN (after from)
joinSequence.addJoin( associationType, tableAlias, joinType, columns );
return joinSequence;
}
@ -281,12 +296,13 @@ public class SessionFactoryHelper {
*
* @param collPersister The persister for the collection at which the join should be rooted.
* @param collectionName The alias to use for qualifying column references.
*
* @return The generated join sequence.
*/
public JoinSequence createCollectionJoinSequence(QueryableCollection collPersister, String collectionName) {
JoinSequence joinSequence = createJoinSequence();
joinSequence.setRoot( collPersister, collectionName );
joinSequence.setUseThetaStyle( true ); // TODO: figure out how this should be set.
joinSequence.setUseThetaStyle( true ); // TODO: figure out how this should be set.
///////////////////////////////////////////////////////////////////////////////
// This was the reason for failures regarding INDEX_OP and subclass joins on
// theta-join dialects; not sure what behavior we were trying to emulate ;)
@ -299,7 +315,9 @@ public class SessionFactoryHelper {
* given type which represents the id or unique-key.
*
* @param entityType The type representing the entity.
*
* @return The corresponding property name
*
* @throws QueryException Indicates such a property could not be found.
*/
public String getIdentifierOrUniqueKeyPropertyName(EntityType entityType) {
@ -315,6 +333,7 @@ public class SessionFactoryHelper {
* Retrieve the number of columns represented by this type.
*
* @param type The type.
*
* @return The number of columns.
*/
public int getColumnSpan(Type type) {
@ -326,6 +345,7 @@ public class SessionFactoryHelper {
* contained within instance of that collection.
*
* @param collectionType The collection type to check.
*
* @return The entity name of the elements of this collection.
*/
public String getAssociatedEntityName(CollectionType collectionType) {
@ -337,6 +357,7 @@ public class SessionFactoryHelper {
* within instances of that collection.
*
* @param collectionType The collection type to be checked.
*
* @return The Type of the elements of the collection.
*/
private Type getElementType(CollectionType collectionType) {
@ -348,16 +369,18 @@ public class SessionFactoryHelper {
* element type be an association type.
*
* @param collectionType The collection type to be checked.
*
* @return The AssociationType of the elements of the collection.
*/
public AssociationType getElementAssociationType(CollectionType collectionType) {
return ( AssociationType ) getElementType( collectionType );
return (AssociationType) getElementType( collectionType );
}
/**
* Locate a registered sql function by name.
*
* @param functionName The name of the function to locate
*
* @return The sql function, or null if not found.
*/
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.
*
* @param functionName The name of the function to locate
*
* @return The sql function.
*
* @throws QueryException Indicates no matching sql functions could be found.
*/
private SQLFunction requireSQLFunction(String functionName) {
@ -383,7 +408,8 @@ public class SessionFactoryHelper {
* Find the function return type given the function name and the first argument expression node.
*
* @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.
*/
public Type findFunctionReturnType(String functionName, AST first) {
@ -395,7 +421,7 @@ public class SessionFactoryHelper {
// determine the type of the first argument...
Type argumentType = null;
if ( firstArgument != null ) {
if ( "cast".equals(functionName) ) {
if ( "cast".equals( functionName ) ) {
argumentType = sfi.getTypeResolver().heuristicType( firstArgument.getNextSibling().getText() );
}
else if ( SqlNode.class.isInstance( firstArgument ) ) {

View File

@ -59,6 +59,7 @@ import org.hibernate.jdbc.WorkExecutor;
import org.hibernate.jdbc.WorkExecutorVisitable;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.procedure.ProcedureCall;
import org.hibernate.procedure.ProcedureCallMemento;
import org.hibernate.procedure.internal.ProcedureCallImpl;
import org.hibernate.type.Type;
@ -67,11 +68,11 @@ import org.hibernate.type.Type;
*
* @author Gavin King
*/
public abstract class AbstractSessionImpl implements Serializable, SharedSessionContract,
SessionImplementor, TransactionContext {
public abstract class AbstractSessionImpl
implements Serializable, SharedSessionContract, SessionImplementor, TransactionContext {
protected transient SessionFactoryImpl factory;
private final String tenantIdentifier;
private boolean closed = false;
private boolean closed;
protected AbstractSessionImpl(SessionFactoryImpl factory, String tenantIdentifier) {
this.factory = factory;
@ -218,10 +219,10 @@ public abstract class AbstractSessionImpl implements Serializable, SharedSession
@Override
public Query createQuery(String queryString) {
errorIfClosed();
QueryImpl query = new QueryImpl(
final QueryImpl query = new QueryImpl(
queryString,
this,
getHQLQueryPlan( queryString, false ).getParameterMetadata()
this,
getHQLQueryPlan( queryString, false ).getParameterMetadata()
);
query.setComment( queryString );
return query;
@ -230,15 +231,31 @@ public abstract class AbstractSessionImpl implements Serializable, SharedSession
@Override
public SQLQuery createSQLQuery(String sql) {
errorIfClosed();
SQLQueryImpl query = new SQLQueryImpl(
final SQLQueryImpl query = new SQLQueryImpl(
sql,
this,
factory.getQueryPlanCache().getSQLParameterMetadata( sql )
this,
factory.getQueryPlanCache().getSQLParameterMetadata( sql )
);
query.setComment( "dynamic native SQL 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
@SuppressWarnings("UnnecessaryLocalVariable")
public ProcedureCall createStoredProcedureCall(String procedureName) {

View File

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

View File

@ -25,20 +25,20 @@ package org.hibernate.internal;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.jboss.logging.Logger;
import org.hibernate.HibernateException;
import org.hibernate.MappingException;
import org.hibernate.QueryException;
import org.hibernate.engine.ResultSetMappingDefinition;
import org.hibernate.engine.query.spi.QueryPlanCache;
import org.hibernate.engine.query.spi.sql.NativeSQLQuerySpecification;
import org.hibernate.engine.spi.NamedQueryDefinition;
import org.hibernate.engine.spi.NamedSQLQueryDefinition;
import org.hibernate.internal.util.collections.CollectionHelper;
import org.hibernate.procedure.ProcedureCallMemento;
/**
* @author Steve Ebersole
@ -46,14 +46,17 @@ import org.hibernate.internal.util.collections.CollectionHelper;
public class NamedQueryRepository {
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, NamedSQLQueryDefinition> namedSqlQueryDefinitionMap;
private final Map<String, ResultSetMappingDefinition> namedSqlResultSetMappingMap;
private volatile Map<String, ProcedureCallMemento> procedureCallMementoMap;
public NamedQueryRepository(
Iterable<NamedQueryDefinition> namedQueryDefinitions,
Iterable<NamedSQLQueryDefinition> namedSqlQueryDefinitions,
Iterable<ResultSetMappingDefinition> namedSqlResultSetMappings) {
Iterable<ResultSetMappingDefinition> namedSqlResultSetMappings,
List<ProcedureCallMemento> namedProcedureCalls) {
final HashMap<String, NamedQueryDefinition> namedQueryDefinitionMap = new HashMap<String, NamedQueryDefinition>();
for ( NamedQueryDefinition namedQueryDefinition : namedQueryDefinitions ) {
namedQueryDefinitionMap.put( namedQueryDefinition.getName(), namedQueryDefinition );
@ -83,6 +86,10 @@ public class NamedQueryRepository {
return namedSqlQueryDefinitionMap.get( queryName );
}
public ProcedureCallMemento getNamedProcedureCallMemento(String name) {
return procedureCallMementoMap.get( name );
}
public ResultSetMappingDefinition getResultSetMappingDefinition(String mappingName) {
return namedSqlResultSetMappingMap.get( mappingName );
}
@ -127,6 +134,20 @@ public class NamedQueryRepository {
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) {
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.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
@ -85,6 +86,7 @@ import org.hibernate.cfg.Configuration;
import org.hibernate.cfg.Environment;
import org.hibernate.cfg.Settings;
import org.hibernate.cfg.SettingsFactory;
import org.hibernate.cfg.annotations.NamedProcedureCallDefinition;
import org.hibernate.context.internal.JTASessionContext;
import org.hibernate.context.internal.ManagedSessionContext;
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.Queryable;
import org.hibernate.persister.spi.PersisterFactory;
import org.hibernate.procedure.ProcedureCallMemento;
import org.hibernate.proxy.EntityNotFoundDelegate;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.spi.ServiceRegistryImplementor;
@ -499,7 +502,8 @@ public final class SessionFactoryImpl
this.namedQueryRepository = new NamedQueryRepository(
cfg.getNamedQueries().values(),
cfg.getNamedSQLQueries().values(),
cfg.getSqlResultSetMappings().values()
cfg.getSqlResultSetMappings().values(),
toProcedureCallMementos( cfg.getNamedProcedureCallMap(), cfg.getSqlResultSetMappings() )
);
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() {
return new JdbcConnectionAccess() {
@Override
@ -920,7 +936,8 @@ public final class SessionFactoryImpl
namedQueryRepository = new NamedQueryRepository(
metadata.getNamedQueryDefinitions(),
metadata.getNamedNativeQueryDefinitions(),
metadata.getResultSetMappingDefinitions().values()
metadata.getResultSetMappingDefinitions().values(),
null
);
imports = new HashMap<String,String>();

View File

@ -30,7 +30,6 @@ import java.util.Arrays;
import java.util.BitSet;
import java.util.Iterator;
import java.util.StringTokenizer;
import java.util.UUID;
import org.hibernate.dialect.Dialect;
import org.hibernate.internal.util.collections.ArrayHelper;
@ -763,18 +762,4 @@ public final class StringHelper {
public static String[] toArrayElement(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.HashMap;
import java.util.Iterator;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
@ -132,6 +133,17 @@ public final class CollectionHelper {
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) {
return collection == null || collection.isEmpty();
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -24,7 +24,10 @@
*/
package org.hibernate.loader.custom.sql;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
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.RootReturn;
import org.hibernate.loader.custom.ScalarReturn;
import org.hibernate.persister.collection.CollectionPersister;
import org.hibernate.persister.collection.SQLLoadableCollection;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.persister.entity.Joinable;
import org.hibernate.persister.entity.SQLLoadable;
import org.hibernate.type.EntityType;
import org.hibernate.type.Type;
@ -99,7 +104,7 @@ public class SQLQueryReturnProcessor {
this.factory = factory;
}
/*package*/ class ResultAliasContext {
public class ResultAliasContext {
public SQLLoadable getEntityPersister(String alias) {
return alias2Persister.get( alias );
}
@ -123,6 +128,25 @@ public class SQLQueryReturnProcessor {
public Map<String, String[]> getPropertyResultsMap(String 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) {

View File

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

View File

@ -23,10 +23,16 @@
*/
package org.hibernate.mapping;
import java.io.Serializable;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import org.hibernate.HibernateException;
import org.hibernate.dialect.Dialect;
import org.hibernate.engine.spi.Mapping;
@ -34,11 +40,12 @@ import org.hibernate.engine.spi.Mapping;
* A relational constraint.
*
* @author Gavin King
* @author Brett Meyer
*/
public abstract class Constraint implements RelationalModel, Serializable {
private String name;
private final List<Column> columns = new ArrayList<Column>();
private final ArrayList<Column> columns = new ArrayList<Column>();
private Table table;
public String getName() {
@ -48,6 +55,85 @@ public abstract class Constraint implements RelationalModel, Serializable {
public void setName(String 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) {
if ( !columns.contains( column ) ) columns.add( column );
@ -133,4 +219,10 @@ public abstract class Constraint implements RelationalModel, Serializable {
public String toString() {
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();
}
public String generatedConstraintNamePrefix() {
return "PK_";
}
}

View File

@ -36,7 +36,6 @@ import org.hibernate.HibernateException;
import org.hibernate.MappingException;
import org.hibernate.dialect.Dialect;
import org.hibernate.engine.spi.Mapping;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.tool.hbm2ddl.ColumnMetadata;
import org.hibernate.tool.hbm2ddl.TableMetadata;
@ -70,15 +69,6 @@ public class Table implements RelationalModel, Serializable {
private boolean hasDenormalizedTables = false;
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 {
String referencedClassName;
List columns;
@ -431,8 +421,8 @@ public class Table implements RelationalModel, Serializable {
}
if ( column.isUnique() ) {
UniqueKey uk = getOrCreateUniqueKey(
StringHelper.randomFixedLengthHex("UK_"));
String keyName = Constraint.generateName( "UK_", this, column );
UniqueKey uk = getOrCreateUniqueKey( keyName );
uk.addColumn( column );
alter.append( dialect.getUniqueDelegate()
.getColumnDefinitionUniquenessFragment( column ) );
@ -534,8 +524,8 @@ public class Table implements RelationalModel, Serializable {
}
if ( col.isUnique() ) {
UniqueKey uk = getOrCreateUniqueKey(
StringHelper.randomFixedLengthHex("UK_"));
String keyName = Constraint.generateName( "UK_", this, col );
UniqueKey uk = getOrCreateUniqueKey( keyName );
uk.addColumn( col );
buf.append( dialect.getUniqueDelegate()
.getColumnDefinitionUniquenessFragment( col ) );
@ -658,7 +648,7 @@ public class Table implements RelationalModel, Serializable {
}
public UniqueKey createUniqueKey(List keyColumns) {
String keyName = StringHelper.randomFixedLengthHex("UK_");
String keyName = Constraint.generateName( "UK_", this, keyColumns );
UniqueKey uk = getOrCreateUniqueKey( keyName );
uk.addColumns( keyColumns.iterator() );
return uk;
@ -694,19 +684,22 @@ public class Table implements RelationalModel, Serializable {
ForeignKey fk = (ForeignKey) foreignKeys.get( key );
if ( fk == null ) {
fk = new ForeignKey();
if ( keyName != null ) {
fk.setName( keyName );
}
else {
fk.setName( StringHelper.randomFixedLengthHex("FK_") );
}
fk.setTable( this );
foreignKeys.put( key, fk );
fk.setReferencedEntityName( referencedEntityName );
fk.addColumns( keyColumns.iterator() );
if ( referencedColumns != null ) {
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 ) {
@ -855,10 +848,6 @@ public class Table implements RelationalModel, Serializable {
public Iterator getCheckConstraintsIterator() {
return checkConstraints.iterator();
}
public String getNaturalIdUniqueKeyName() {
return naturalIdUniqueKeyName;
}
public Iterator sqlCommentStrings(Dialect dialect, String defaultCatalog, String defaultSchema) {
List comments = new ArrayList();

View File

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

View File

@ -414,7 +414,7 @@ public class SingleTableEntityPersister extends AbstractEntityPersister {
subclassClosure = new String[subclassSpan];
subclassClosure[0] = getEntityName();
if ( persistentClass.isPolymorphic() ) {
subclassesByDiscriminatorValue.put( discriminatorValue, getEntityName() );
addSubclassByDiscriminatorValue( discriminatorValue, getEntityName() );
}
// SUBCLASSES
@ -425,15 +425,15 @@ public class SingleTableEntityPersister extends AbstractEntityPersister {
Subclass sc = (Subclass) iter.next();
subclassClosure[k++] = sc.getEntityName();
if ( sc.isDiscriminatorValueNull() ) {
subclassesByDiscriminatorValue.put( NULL_DISCRIMINATOR, sc.getEntityName() );
addSubclassByDiscriminatorValue( NULL_DISCRIMINATOR, sc.getEntityName() );
}
else if ( sc.isDiscriminatorValueNotNull() ) {
subclassesByDiscriminatorValue.put( NOT_NULL_DISCRIMINATOR, sc.getEntityName() );
addSubclassByDiscriminatorValue( NOT_NULL_DISCRIMINATOR, sc.getEntityName() );
}
else {
try {
DiscriminatorType dtype = (DiscriminatorType) discriminatorType;
subclassesByDiscriminatorValue.put(
addSubclassByDiscriminatorValue(
dtype.stringToObject( sc.getDiscriminatorValue() ),
sc.getEntityName()
);
@ -455,7 +455,17 @@ public class SingleTableEntityPersister extends AbstractEntityPersister {
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(
final EntityBinding entityBinding,
final EntityRegionAccessStrategy cacheAccessStrategy,
@ -711,7 +721,7 @@ public class SingleTableEntityPersister extends AbstractEntityPersister {
subclassClosure = new String[subclassSpan];
subclassClosure[0] = getEntityName();
if ( entityBinding.isPolymorphic() ) {
subclassesByDiscriminatorValue.put( discriminatorValue, getEntityName() );
addSubclassByDiscriminatorValue( discriminatorValue, getEntityName() );
}
// SUBCLASSES
@ -720,15 +730,15 @@ public class SingleTableEntityPersister extends AbstractEntityPersister {
for ( EntityBinding subEntityBinding : entityBinding.getPostOrderSubEntityBindingClosure() ) {
subclassClosure[k++] = subEntityBinding.getEntity().getName();
if ( subEntityBinding.isDiscriminatorMatchValueNull() ) {
subclassesByDiscriminatorValue.put( NULL_DISCRIMINATOR, subEntityBinding.getEntity().getName() );
addSubclassByDiscriminatorValue( NULL_DISCRIMINATOR, subEntityBinding.getEntity().getName() );
}
else if ( subEntityBinding.isDiscriminatorMatchValueNotNull() ) {
subclassesByDiscriminatorValue.put( NOT_NULL_DISCRIMINATOR, subEntityBinding.getEntity().getName() );
addSubclassByDiscriminatorValue( NOT_NULL_DISCRIMINATOR, subEntityBinding.getEntity().getName() );
}
else {
try {
DiscriminatorType dtype = (DiscriminatorType) discriminatorType;
subclassesByDiscriminatorValue.put(
addSubclassByDiscriminatorValue(
dtype.stringToObject( subEntityBinding.getDiscriminatorMatchValue() ),
subEntityBinding.getEntity().getName()
);

View File

@ -25,6 +25,7 @@ package org.hibernate.procedure;
import java.util.List;
import javax.persistence.ParameterMode;
import java.util.Map;
import org.hibernate.BasicQueryContract;
import org.hibernate.MappingException;
@ -58,6 +59,7 @@ public interface ProcedureCall extends BasicQueryContract, SynchronizeableQuery
* @param position The position
* @param type The Java type of the parameter
* @param mode The parameter mode (in, out, inout)
* @param <T> The parameterized Java type of the parameter.
*
* @return The parameter registration memento
*/
@ -89,8 +91,12 @@ public interface ProcedureCall extends BasicQueryContract, SynchronizeableQuery
* @param parameterName The parameter name
* @param type The Java type of the parameter
* @param mode The parameter mode (in, out, inout)
* @param <T> The parameterized Java type of the parameter.
*
* @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)
throws NamedParametersNotSupportedException;
@ -103,6 +109,9 @@ public interface ProcedureCall extends BasicQueryContract, SynchronizeableQuery
* @param mode The parameter mode (in, out, inout)
*
* @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)
throws NamedParametersNotSupportedException;
@ -133,4 +142,12 @@ public interface ProcedureCall extends BasicQueryContract, SynchronizeableQuery
*/
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
*
* 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
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Inc.
@ -21,25 +21,43 @@
* 51 Franklin Street, Fifth Floor
* 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 org.gradle.api.artifacts.Configuration;
import org.hibernate.build.qalab.DatabaseAllocation;
import org.hibernate.Session;
import org.hibernate.engine.spi.SessionImplementor;
/**
* Contract for database "profiles".
* Represents a "memento" of a ProcedureCall
*
* @author Steve Ebersole
* @author Strong Liu
*/
public interface DatabaseProfile {
public String getName();
public File getDirectory();
public Map<String,String> getHibernateProperties();
public Configuration getTestingRuntimeConfiguration();
public DatabaseAllocation getDatabaseAllocation();
public interface ProcedureCallMemento {
/**
* 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(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;
/**
* Abstract implementation of ParameterRegistration/ParameterRegistrationImplementor
*
* @author Steve Ebersole
*/
public abstract class AbstractParameterRegistrationImpl<T> implements ParameterRegistrationImplementor<T> {
@ -61,28 +63,53 @@ public abstract class AbstractParameterRegistrationImpl<T> implements ParameterR
private Type hibernateType;
private int[] sqlTypes;
// positional constructors ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
protected AbstractParameterRegistrationImpl(
ProcedureCallImpl procedureCall,
Integer position,
ParameterMode mode,
Class<T> type) {
this( procedureCall, position, null, mode, type );
}
protected AbstractParameterRegistrationImpl(
ProcedureCallImpl procedureCall,
Integer position,
ParameterMode mode,
Class<T> type,
ParameterMode mode) {
this( procedureCall, position, null, type, mode );
Type hibernateType) {
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(
ProcedureCallImpl procedureCall,
String name,
ParameterMode mode,
Class<T> type,
ParameterMode mode) {
this( procedureCall, null, name, type, mode );
Type hibernateType) {
this( procedureCall, null, name, mode, type, hibernateType );
}
private AbstractParameterRegistrationImpl(
ProcedureCallImpl procedureCall,
Integer position,
String name,
ParameterMode mode,
Class<T> type,
ParameterMode mode) {
Type hibernateType) {
this.procedureCall = procedureCall;
this.position = position;
@ -91,7 +118,23 @@ public abstract class AbstractParameterRegistrationImpl<T> implements ParameterR
this.mode = mode;
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() {
@ -118,6 +161,11 @@ public abstract class AbstractParameterRegistrationImpl<T> implements ParameterR
return mode;
}
@Override
public Type getHibernateType() {
return hibernateType;
}
@Override
public void setHibernateType(Type type) {
if ( type == null ) {
@ -128,6 +176,7 @@ public abstract class AbstractParameterRegistrationImpl<T> implements ParameterR
}
@Override
@SuppressWarnings("unchecked")
public ParameterBind<T> getBind() {
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.INOUT || mode == ParameterMode.OUT ) {
if ( sqlTypes.length > 1 ) {
if ( ProcedureParameterExtractionAware.class.isInstance( hibernateType )
&& ( (ProcedureParameterExtractionAware) hibernateType ).canDoExtraction() ) {
// the type can handle multi-param extraction...
}
else {
// there is more than one column involved; see if the Hibernate Type can handle
// multi-param extraction...
final boolean canHandleMultiParamExtraction =
ProcedureParameterExtractionAware.class.isInstance( hibernateType )
&& ( (ProcedureParameterExtractionAware) hibernateType ).canDoExtraction();
if ( ! canHandleMultiParamExtraction ) {
// it cannot...
throw new UnsupportedOperationException(
"Type [" + hibernateType + "] does support multi-parameter value extraction"

View File

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

View File

@ -27,15 +27,45 @@ import java.sql.CallableStatement;
import java.sql.SQLException;
import org.hibernate.procedure.ParameterRegistration;
import org.hibernate.type.Type;
/**
* Additional internal contract for ParameterRegistration
*
* @author Steve Ebersole
*/
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;
/**
* 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();
/**
* 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);
}

View File

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

View File

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

View File

@ -30,26 +30,29 @@ import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.persistence.ParameterMode;
import org.jboss.logging.Logger;
import org.hibernate.HibernateException;
import org.hibernate.LockMode;
import org.hibernate.MappingException;
import org.hibernate.QueryException;
import org.hibernate.cfg.NotYetImplementedException;
import org.hibernate.engine.ResultSetMappingDefinition;
import org.hibernate.engine.jdbc.env.spi.ExtractedDatabaseMetaData;
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.SessionFactoryImplementor;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.internal.AbstractBasicQueryContractImpl;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.internal.util.collections.CollectionHelper;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.procedure.NamedParametersNotSupportedException;
import org.hibernate.procedure.ParameterRegistration;
import org.hibernate.procedure.ProcedureCall;
import org.hibernate.procedure.ProcedureCallMemento;
import org.hibernate.procedure.ProcedureResult;
import org.hibernate.result.spi.ResultContext;
import org.hibernate.type.Type;
@ -60,6 +63,10 @@ import org.hibernate.type.Type;
* @author Steve Ebersole
*/
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 NativeSQLQueryReturn[] queryReturns;
@ -70,74 +77,167 @@ public class ProcedureCallImpl extends AbstractBasicQueryContractImpl implements
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) {
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 );
this.procedureName = procedureName;
if ( queryReturns == null || queryReturns.isEmpty() ) {
this.queryReturns = new NativeSQLQueryReturn[0];
}
else {
this.queryReturns = queryReturns.toArray( new NativeSQLQueryReturn[ queryReturns.size() ] );
}
final List<NativeSQLQueryReturn> collectedQueryReturns = new ArrayList<NativeSQLQueryReturn>();
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;
}
public ProcedureCallImpl(SessionImplementor session, String procedureName, Class... resultClasses) {
this( session, procedureName, collectQueryReturns( resultClasses ) );
/**
* 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;
}
private static List<NativeSQLQueryReturn> collectQueryReturns(Class[] resultClasses) {
if ( resultClasses == null || resultClasses.length == 0 ) {
return null;
/**
* 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;
}
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;
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;
}
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 + "]" );
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()
);
}
queryReturns.addAll( Arrays.asList( mapping.getQueryReturns() ) );
else {
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 );
}
return queryReturns;
this.registeredParameters = parameterRegistrations;
}
// 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
public SessionImplementor getSession() {
return super.session();
@ -165,7 +265,8 @@ public class ProcedureCallImpl extends AbstractBasicQueryContractImpl implements
@Override
@SuppressWarnings("unchecked")
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 );
return parameterRegistration;
}
@ -233,7 +334,8 @@ public class ProcedureCallImpl extends AbstractBasicQueryContractImpl implements
@Override
@SuppressWarnings("unchecked")
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 );
return parameterRegistration;
}
@ -329,6 +431,12 @@ public class ProcedureCallImpl extends AbstractBasicQueryContractImpl implements
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() {
if ( synchronizedQuerySpaces == null ) {
synchronizedQuerySpaces = new HashSet<String>();
@ -374,16 +482,22 @@ public class ProcedureCallImpl extends AbstractBasicQueryContractImpl implements
return buildQueryParametersObject();
}
@Override
public QueryParameters buildQueryParametersObject() {
QueryParameters qp = super.buildQueryParametersObject();
final QueryParameters qp = super.buildQueryParametersObject();
// both of these are for documentation purposes, they are actually handled directly...
qp.setAutoDiscoverScalarTypes( true );
qp.setCallable( true );
return qp;
}
/**
* Collects any parameter registrations which indicate a REF_CURSOR parameter type/mode.
*
* @return The collected REF_CURSOR type parameters.
*/
public ParameterRegistrationImplementor[] collectRefCursorParameters() {
List<ParameterRegistrationImplementor> refCursorParams = new ArrayList<ParameterRegistrationImplementor>();
final List<ParameterRegistrationImplementor> refCursorParams = new ArrayList<ParameterRegistrationImplementor>();
for ( ParameterRegistrationImplementor param : registeredParameters ) {
if ( param.getMode() == ParameterMode.REF_CURSOR ) {
refCursorParams.add( param );
@ -391,4 +505,29 @@ public class ProcedureCallImpl extends AbstractBasicQueryContractImpl implements
}
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;
/**
* Implementation of ProcedureResult. Defines centralized access to all of the results of a procedure call.
*
* @author Steve Ebersole
*/
public class ProcedureResultImpl extends ResultImpl implements ProcedureResult {
@ -42,7 +44,7 @@ public class ProcedureResultImpl extends ResultImpl implements ProcedureResult {
private final CallableStatement callableStatement;
private final ParameterRegistrationImplementor[] refCursorParameters;
private int refCursorParamIndex = 0;
private int refCursorParamIndex;
ProcedureResultImpl(ProcedureCallImpl procedureCall, CallableStatement callableStatement) {
super( procedureCall, callableStatement );
@ -80,9 +82,9 @@ public class ProcedureResultImpl extends ResultImpl implements ProcedureResult {
@Override
protected Return buildExtendedReturn(CurrentReturnDescriptor returnDescriptor) {
this.refCursorParamIndex++;
final int refCursorParamIndex = ( (ProcedureCurrentReturnDescriptor) returnDescriptor ).refCursorParamIndex;
final ParameterRegistrationImplementor refCursorParam = refCursorParameters[refCursorParamIndex];
ResultSet resultSet;
int refCursorParamIndex = ( (ProcedureCurrentReturnDescriptor) returnDescriptor ).refCursorParamIndex;
ParameterRegistrationImplementor refCursorParam = refCursorParameters[refCursorParamIndex];
if ( refCursorParam.getName() != null ) {
resultSet = procedureCall.getSession().getFactory().getServiceRegistry()
.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

@ -22,11 +22,11 @@ public enum JoinType {
return joinTypeValue;
}
public static JoinType parse(int joinType){
if(joinType<0){
public static JoinType parse(int joinType) {
if ( joinType < 0 ) {
return NONE;
}
switch ( joinType ){
switch ( joinType ) {
case 0:
return INNER_JOIN;
case 1:
@ -36,7 +36,7 @@ public enum JoinType {
case 4:
return FULL_JOIN;
default:
throw new HibernateException( "unknown join type: "+joinType );
throw new HibernateException( "unknown join type: " + joinType );
}
}
}

View File

@ -26,10 +26,18 @@ package org.hibernate.test.annotations.collectionelement.ordered;
import org.junit.Test;
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;
/**
* @author Steve Ebersole
* @author Lukasz Antoniak (lukasz dot antoniak at gmail dot com)
*/
public class ElementCollectionSortingTest extends BaseCoreFunctionalTestCase {
@Override
@ -53,4 +61,71 @@ public class ElementCollectionSortingTest extends BaseCoreFunctionalTestCase {
session.getTransaction().commit();
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;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import org.hibernate.Session;
import org.hibernate.testing.FailureExpected;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import org.junit.Test;
@FailureExpected(jiraKey = "HHH-5695")
public class OneToOneWithDerivedIdentityTest extends BaseCoreFunctionalTestCase {
@ -57,6 +57,29 @@ public class OneToOneWithDerivedIdentityTest extends BaseCoreFunctionalTestCase
s.getTransaction().rollback();
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
protected Class<?>[] getAnnotatedClasses() {

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
*/
public final void writeLock(Object key) {
public final void writeLock(Object key) throws CacheException {
try {
lockProvider.getSyncForKey( key ).lock( LockType.WRITE );
}
@ -234,7 +234,7 @@ public class EhcacheTransactionalDataRegion extends EhcacheDataRegion implements
*
* @throws CacheException Indicates a problem accessing the cache
*/
public final void writeUnlock(Object key) {
public final void writeUnlock(Object key) throws CacheException {
try {
lockProvider.getSyncForKey( key ).unlock( LockType.WRITE );
}
@ -256,7 +256,7 @@ public class EhcacheTransactionalDataRegion extends EhcacheDataRegion implements
*
* @throws CacheException Indicates a problem accessing the cache
*/
public final void readLock(Object key) {
public final void readLock(Object key) throws CacheException {
try {
lockProvider.getSyncForKey( key ).lock( LockType.WRITE );
}
@ -278,7 +278,7 @@ public class EhcacheTransactionalDataRegion extends EhcacheDataRegion implements
*
* @throws CacheException Indicates a problem accessing the cache
*/
public final void readUnlock(Object key) {
public final void readUnlock(Object key) throws CacheException {
try {
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
*/
@SuppressWarnings("UnusedDeclaration")
public final void dispose() {
doDispose();
removeAllNotificationListeners();
@ -138,6 +139,9 @@ public abstract class AbstractEmitterBean extends StandardMBean implements Notif
notificationListeners.clear();
}
/**
* {@inheritDoc}
*/
@Override
public abstract MBeanNotificationInfo[] getNotificationInfo();

View File

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

View File

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

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
* is used
*
* @param manager
* @param properties
* @param manager the {@link CacheManager} to register the MBean for
* @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;
/**
* Enable hibernate statistics in the mbean.
*
* @param sessionFactory
* @param sessionFactory the {@link SessionFactory} to enable stats for
*/
public void enableHibernateStatisticsSupport(SessionFactory sessionFactory);

View File

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

View File

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

View File

@ -34,7 +34,6 @@ import javax.management.openmbean.TabularDataSupport;
import javax.management.openmbean.TabularType;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.hibernate.stat.EntityStatistics;
@ -120,7 +119,8 @@ public class EntityStats implements Serializable {
protected long optimisticFailureCount;
/**
* @param name
* Constructor only naming the stat
* @param name the name of the entity
*/
public EntityStats(String name) {
this.name = name;
@ -128,8 +128,9 @@ public class EntityStats implements Serializable {
}
/**
* @param name
* @param src
* Constructor naming the stat and sourcing stats
* @param name the name of the entity
* @param src its source for the stats to expose
*/
public EntityStats(String name, EntityStatistics src) {
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) {
int i = 0;
name = (String) cData.get( ITEM_NAMES[i++] );
@ -163,17 +166,9 @@ public class EntityStats implements Serializable {
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) {
loadCount += stats.getLoadCount();
@ -185,7 +180,7 @@ public class EntityStats implements Serializable {
}
/**
* toString
* {@inheritDoc}
*/
@Override
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() {
return name;
}
/**
* getShortName
* The short name of the entity those stats are about
* @return the shortName of the entity
*/
@SuppressWarnings("UnusedDeclaration")
public String getShortName() {
return shortName;
}
/**
* getLoadCount
* Amount of load ops on the entity
* @return the load count
*/
public long getLoadCount() {
return loadCount;
}
/**
* getUpdateCount
* Amount of update ops on the entity
* @return the update count
*/
public long getUpdateCount() {
return updateCount;
}
/**
* getInsertCount
* Amount of insert ops on the entity
* @return the insert count
*/
public long getInsertCount() {
return insertCount;
}
/**
* getDeleteCount
* Amount of delete ops on the entity
* @return the delete count
*/
public long getDeleteCount() {
return deleteCount;
}
/**
* getFetchCount
* Amount of fetch ops on the entity
* @return the fetch count
*/
public long getFetchCount() {
return fetchCount;
}
/**
* getOptimisticFailureCount
* Amount of optimistic failures on the entity
* @return the optimistic failure count
*/
public long getOptimisticFailureCount() {
return optimisticFailureCount;
}
/**
* toCompositeData
* Creates a CompositeData instance of this instance
* @return the compositeData representation of this instance
*/
public CompositeData toCompositeData() {
try {
@ -268,19 +273,23 @@ public class EntityStats implements Serializable {
}
/**
* newTabularDataInstance
* Creates a new TabularData
* @return a new TabularData instance
*/
public static TabularData newTabularDataInstance() {
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) {
final List<EntityStats> countList = new ArrayList( tabularData.size() );
for ( final Iterator pos = tabularData.values().iterator(); pos.hasNext(); ) {
countList.add( new EntityStats( (CompositeData) pos.next() ) );
for ( Object o : tabularData.values() ) {
countList.add( new EntityStats( (CompositeData) o ) );
}
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}
*
* @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 {
super( HibernateStats.class );
@ -75,254 +75,171 @@ public class HibernateStatsImpl extends AbstractEmitterBean implements Hibernate
return sessionFactory.getStatistics();
}
/**
* {@inheritDoc}
*
* @see HibernateStats#clearStats()
*/
@Override
public void clearStats() {
getStatistics().clear();
sendNotification( CACHE_STATISTICS_RESET );
}
/**
* {@inheritDoc}
*
* @see HibernateStats#disableStats()
*/
@Override
public void disableStats() {
setStatisticsEnabled( false );
}
/**
* {@inheritDoc}
*
* @see HibernateStats#enableStats()
*/
@Override
public void enableStats() {
setStatisticsEnabled( true );
}
/**
* {@inheritDoc}
*
* @see HibernateStats#getCloseStatementCount()
*/
@Override
public long getCloseStatementCount() {
return getStatistics().getCloseStatementCount();
}
/**
* {@inheritDoc}
*
* @see HibernateStats#getConnectCount()
*/
@Override
public long 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() {
throw new UnsupportedOperationException( "Use getQueryExecutionCount() instead" );
}
/**
* {@inheritDoc}
*
* @see HibernateStats#getFlushCount()
*/
@Override
public long getFlushCount() {
return getStatistics().getFlushCount();
}
/**
* {@inheritDoc}
*
* @see HibernateStats#getOptimisticFailureCount()
*/
@Override
public long getOptimisticFailureCount() {
return getStatistics().getOptimisticFailureCount();
}
/**
* {@inheritDoc}
*
* @see HibernateStats#getPrepareStatementCount()
*/
@Override
public long getPrepareStatementCount() {
return getStatistics().getPrepareStatementCount();
}
/**
* {@inheritDoc}
*
* @see HibernateStats#getQueryExecutionCount()
*/
@Override
public long getQueryExecutionCount() {
return getStatistics().getQueryExecutionCount();
}
/**
* {@inheritDoc}
*
* @see HibernateStats#getQueryExecutionRate()
*/
@Override
public double getQueryExecutionRate() {
long startTime = getStatistics().getStartTime();
long now = System.currentTimeMillis();
double deltaSecs = (now - startTime) / MILLIS_PER_SECOND;
final long startTime = getStatistics().getStartTime();
final long now = System.currentTimeMillis();
final double deltaSecs = (now - startTime) / MILLIS_PER_SECOND;
return getQueryExecutionCount() / deltaSecs;
}
/**
* {@inheritDoc}
*
* @see HibernateStats#getQueryExecutionSample()
*/
@Override
public long getQueryExecutionSample() {
throw new UnsupportedOperationException( "TODO: need to impl. rates for query execution" );
}
/**
* {@inheritDoc}
*
* @see HibernateStats#getSessionCloseCount()
*/
@Override
public long getSessionCloseCount() {
return getStatistics().getSessionCloseCount();
}
/**
* {@inheritDoc}
*
* @see HibernateStats#getSessionOpenCount()
*/
@Override
public long getSessionOpenCount() {
return getStatistics().getSessionOpenCount();
}
/**
* {@inheritDoc}
*
* @see HibernateStats#getSuccessfulTransactionCount()
*/
@Override
public long getSuccessfulTransactionCount() {
return getStatistics().getSuccessfulTransactionCount();
}
/**
* {@inheritDoc}
*
* @see HibernateStats#getTransactionCount()
*/
@Override
public long getTransactionCount() {
return getStatistics().getTransactionCount();
}
/**
* {@inheritDoc}
*
* @see HibernateStats#isStatisticsEnabled()
*/
@Override
public boolean isStatisticsEnabled() {
return getStatistics().isStatisticsEnabled();
}
/**
* {@inheritDoc}
*
* @see HibernateStats#setStatisticsEnabled(boolean)
*/
@Override
public void setStatisticsEnabled(boolean flag) {
getStatistics().setStatisticsEnabled( flag );
sendNotification( CACHE_STATISTICS_ENABLED, flag );
}
/**
* {@inheritDoc}
*
* @see HibernateStats#getEntityStats()
*/
@Override
public TabularData getEntityStats() {
List<CompositeData> result = new ArrayList<CompositeData>();
Statistics statistics = getStatistics();
final List<CompositeData> result = new ArrayList<CompositeData>();
final Statistics statistics = getStatistics();
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() );
}
TabularData td = EntityStats.newTabularDataInstance();
final TabularData td = EntityStats.newTabularDataInstance();
td.putAll( result.toArray( new CompositeData[result.size()] ) );
return td;
}
/**
* {@inheritDoc}
*
* @see HibernateStats#getCollectionStats()
*/
@Override
public TabularData getCollectionStats() {
List<CompositeData> result = new ArrayList<CompositeData>();
Statistics statistics = getStatistics();
final List<CompositeData> result = new ArrayList<CompositeData>();
final Statistics statistics = getStatistics();
for ( String roleName : statistics.getCollectionRoleNames() ) {
CollectionStats collectionStats = new CollectionStats(
final CollectionStats collectionStats = new CollectionStats(
roleName,
statistics.getCollectionStatistics( roleName )
);
result.add( collectionStats.toCompositeData() );
}
TabularData td = CollectionStats.newTabularDataInstance();
final TabularData td = CollectionStats.newTabularDataInstance();
td.putAll( result.toArray( new CompositeData[result.size()] ) );
return td;
}
/**
* {@inheritDoc}
*
* @see HibernateStats#getQueryStats()
*/
@Override
public TabularData getQueryStats() {
List<CompositeData> result = new ArrayList<CompositeData>();
Statistics statistics = getStatistics();
final List<CompositeData> result = new ArrayList<CompositeData>();
final Statistics statistics = getStatistics();
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() );
}
TabularData td = QueryStats.newTabularDataInstance();
final TabularData td = QueryStats.newTabularDataInstance();
td.putAll( result.toArray( new CompositeData[result.size()] ) );
return td;
}
/**
* {@inheritDoc}
*/
@Override
public TabularData getCacheRegionStats() {
List<CompositeData> list = new ArrayList<CompositeData>();
Statistics statistics = getStatistics();
final List<CompositeData> list = new ArrayList<CompositeData>();
final Statistics statistics = getStatistics();
for ( String region : statistics.getSecondLevelCacheRegionNames() ) {
CacheRegionStats l2CacheStats = new CacheRegionStats(
final CacheRegionStats l2CacheStats = new CacheRegionStats(
region,
statistics.getSecondLevelCacheStatistics( region )
);
list.add( l2CacheStats.toCompositeData() );
}
TabularData td = CacheRegionStats.newTabularDataInstance();
final TabularData td = CacheRegionStats.newTabularDataInstance();
td.putAll( list.toArray( new CompositeData[list.size()] ) );
return td;
}
/**
* {@inheritDoc}
*/
@Override
protected void doDispose() {
// no-op
}
/**
* @see AbstractEmitterBean#getNotificationInfo()
*/
@Override
public MBeanNotificationInfo[] getNotificationInfo() {
return new MBeanNotificationInfo[] {NOTIFICATION_INFO};

View File

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

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