From 0c72623038cee349c3b6adafeb221e1a0f54c1c7 Mon Sep 17 00:00:00 2001 From: Steve Ebersole Date: Fri, 5 Apr 2013 14:30:56 -0500 Subject: [PATCH 01/54] HHH-8152 - General cleanup --- build.gradle | 39 ++++++++++++++++++--------------------- 1 file changed, 18 insertions(+), 21 deletions(-) diff --git a/build.gradle b/build.gradle index b81c176bb1..e73cc6eea7 100644 --- a/build.gradle +++ b/build.gradle @@ -4,10 +4,9 @@ apply from: "./libraries.gradle" allprojects { repositories { - mavenCentral() - mavenLocal() - - + mavenCentral() + mavenLocal() + mavenRepo name: 'jboss-nexus', url: "http://repository.jboss.org/nexus/content/groups/public/" mavenRepo name: "jboss-snapshots", url: "http://snapshots.jboss.org/maven2/" } @@ -15,10 +14,9 @@ allprojects { buildscript { repositories { - mavenCentral() - mavenLocal() - - + mavenCentral() + mavenLocal() + mavenRepo name: 'jboss-nexus', url: "http://repository.jboss.org/nexus/content/groups/public/" mavenRepo name: "jboss-snapshots", url: "http://snapshots.jboss.org/maven2/" } @@ -29,6 +27,11 @@ buildscript { ext.hibernateTargetVersion = '4.3.0-SNAPSHOT' +task wrapper(type: Wrapper) { + gradleVersion = '1.5' +} + + idea { project { languageLevel = '1.6' @@ -52,7 +55,6 @@ idea { } - subprojects { subProject -> apply plugin: 'idea' apply plugin: 'eclipse' @@ -97,6 +99,7 @@ subprojects { subProject -> // appropriately inject the common dependencies into each sub-project dependencies { compile( libraries.logging ) + testCompile( libraries.junit ) testCompile( libraries.byteman ) testCompile( libraries.byteman_install ) @@ -109,22 +112,28 @@ subprojects { subProject -> testRuntime( libraries.jcl ) testRuntime( libraries.javassist ) testRuntime( libraries.h2 ) + jbossLoggingTool( libraries.logging_processor ) + hibernateJpaModelGenTool( libraries.jpa_modelgen ) + jaxb( libraries.jaxb ){ exclude group: "javax.xml.stream" } jaxb( libraries.jaxb2_basics ) jaxb( libraries.jaxb2_ant ) + deployerJars "org.apache.maven.wagon:wagon-http:1.0" } + // mac-specific stuff ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ext.toolsJar = file("${System.getProperty('java.home')}/../lib/tools.jar") if ( ext.toolsJar.exists() ) { dependencies{ testCompile files( toolsJar ) } } + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ task compile compile.dependsOn compileJava, compileTestJava @@ -233,8 +242,6 @@ subprojects { subProject -> maxHeapSize = "1024m" } - - processTestResources.doLast( { copy { from( sourceSets.test.java.srcDirs ) { @@ -349,13 +356,3 @@ subprojects { subProject -> } } - -// This is a task that generates the gradlew scripts, allowing users to run gradle without having gradle installed -// on their system. -// This task should be run by "build master" and the resulting output committed to source control. Its outputs include: -// 1) /gradlew which is the *NIX shell script for executing builds -// 2) /gradlew.bat which is the windows bat script for for executing builds -// 3) /wrapper which is a directory named by the "jarPath" config which contains other needed files. -task wrapper(type: Wrapper) { - gradleVersion = '1.5' -} From 64cbd2fdd0afcf15bf7db7d57b3678e97f83f07f Mon Sep 17 00:00:00 2001 From: Steve Ebersole Date: Fri, 5 Apr 2013 14:38:23 -0500 Subject: [PATCH 02/54] HHH-8151 - Consolidate defining "java language level" in one place --- build.gradle | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/build.gradle b/build.gradle index e73cc6eea7..4fee2db3c8 100644 --- a/build.gradle +++ b/build.gradle @@ -26,6 +26,7 @@ buildscript { } ext.hibernateTargetVersion = '4.3.0-SNAPSHOT' +ext.javaLanguageLevel = "1.6" task wrapper(type: Wrapper) { gradleVersion = '1.5' @@ -34,7 +35,7 @@ task wrapper(type: Wrapper) { idea { project { - languageLevel = '1.6' + languageLevel = javaLanguageLevel ipr { withXml { provider -> provider.node.component.find { it.@name == 'VcsDirectoryMappings' }.mapping.@vcs = 'Git' @@ -135,6 +136,9 @@ subprojects { subProject -> } // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + targetCompatibility = rootProject.javaLanguageLevel + sourceCompatibility = rootProject.javaLanguageLevel + task compile compile.dependsOn compileJava, compileTestJava @@ -161,8 +165,8 @@ subprojects { subProject -> "-processor", "org.jboss.logging.processor.apt.LoggingToolsProcessor", "-s", "$sourceSets.main.generatedLoggingSrcDir.absolutePath", "-AloggingVersion=3.0", - "-source", "1.6", - "-target", "1.6", + "-source", rootProject.javaLanguageLevel, + "-target", rootProject.javaLanguageLevel, "-AtranslationFilesPath=${project.rootDir}/src/main/resources" ] @@ -255,9 +259,6 @@ subprojects { subProject -> assemble.doLast( { install } ) uploadArchives.dependsOn install - targetCompatibility = "1.6" - sourceCompatibility = "1.6" - idea { module { iml { From e037fcb55f01af0fcb908608b400e639c5c1d09e Mon Sep 17 00:00:00 2001 From: Steve Ebersole Date: Fri, 5 Apr 2013 14:40:43 -0500 Subject: [PATCH 03/54] HHH-8145 - Add MaxPermSize to test configuration --- build.gradle | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index 4fee2db3c8..b5140f7576 100644 --- a/build.gradle +++ b/build.gradle @@ -196,7 +196,7 @@ subprojects { subProject -> Set privatePackages = new HashSet() // TODO: Could more of this be pulled into utilities.gradle? - sourceSets.each { SourceSet sourceSet -> + sourceSets.each { sourceSet -> // skip certain source sets if ( ! ['test','matrix'].contains( sourceSet.name ) ) { sourceSet.java.each { javaFile -> @@ -206,7 +206,7 @@ subprojects { subProject -> final String[] temporaryExports = [ 'org.hibernate.boot.registry.classloading.internal', 'org.hibernate.internal.util' ] - + final String packageName = determinePackageName( sourceSet.java, javaFile ); if ( ! temporaryExports.contains( packageName ) && ( packageName.endsWith( ".internal" ) @@ -244,6 +244,8 @@ subprojects { subProject -> systemProperties['hibernate.test.validatefailureexpected'] = true systemProperties += System.properties.findAll { it.key.startsWith( "hibernate.") } maxHeapSize = "1024m" + // Not strictly needed but useful to attach a profiler: + jvmArgs '-XX:MaxPermSize=256m' } processTestResources.doLast( { From 2b2f333593c1989624d332d47b1358afd1999a91 Mon Sep 17 00:00:00 2001 From: Steve Ebersole Date: Fri, 5 Apr 2013 15:15:11 -0500 Subject: [PATCH 04/54] HHH-8147 - Update to use distribution plugin for createing release bundles --- release/release.gradle | 159 +++++++++++++++++++---------------------- 1 file changed, 73 insertions(+), 86 deletions(-) diff --git a/release/release.gradle b/release/release.gradle index d86a2427d6..5e093039a0 100644 --- a/release/release.gradle +++ b/release/release.gradle @@ -1,5 +1,6 @@ apply plugin: 'base' apply plugin: 'idea' +apply plugin: 'distribution' apply from: "../utilities.gradle" buildDir = "target" @@ -29,7 +30,7 @@ task aggregateJavadocs(type: Javadoc) { parent.subprojects.each{ Project subProject-> // skip certain sub-projects if ( ! ['release','documentation'].contains( subProject.name ) ) { - subProject.sourceSets.each { SourceSet sourceSet -> + subProject.sourceSets.each { sourceSet -> // skip certain source sets if ( ! ['test','matrix'].contains( sourceSet.name ) ) { source sourceSet.java @@ -96,106 +97,92 @@ aggregateJavadocs.doLast { ext.releaseBuildDir = mkdir( buildDir ) task prepareReleaseBundles( dependsOn: [parent.project( 'documentation' ).tasks.buildDocs,aggregateJavadocs] ) +distributions { + main { + baseName = 'hibernate-release' + contents { + from new File( parent.projectDir, 'lgpl.txt' ) + from new File( parent.projectDir, 'changelog.txt' ) + from new File( parent.projectDir, 'hibernate_logo.gif' ) -ext.releaseCopySpec = copySpec { - into( "hibernate-release-$project.version" ) { - from new File( parent.projectDir, 'lgpl.txt' ) - from new File( parent.projectDir, 'changelog.txt' ) - from new File( parent.projectDir, 'hibernate_logo.gif' ) + into('lib/required') { + from parent.project( 'hibernate-core' ).configurations.provided.files { dep -> dep.name == 'jta' } + from parent.project( 'hibernate-core' ).configurations.runtime + from parent.project( 'hibernate-core' ).configurations.archives.allArtifacts.files.filter{ file -> !file.name.endsWith('-sources.jar') } + // for now, + from parent.project( 'hibernate-core' ).configurations.provided.files { dep -> dep.name == 'javassist' } + } - into('lib/required') { - from parent.project( 'hibernate-core' ).configurations.provided.files { dep -> dep.name == 'jta' } - from parent.project( 'hibernate-core' ).configurations.runtime - from parent.project( 'hibernate-core' ).configurations.archives.allArtifacts.files.filter{ file -> !file.name.endsWith('-sources.jar') } - // for now, - from parent.project( 'hibernate-core' ).configurations.provided.files { dep -> dep.name == 'javassist' } - } + into( 'lib/jpa' ) { + from parent.project( 'hibernate-entitymanager' ).configurations.archives.allArtifacts.files.filter{ file -> !file.name.endsWith('-sources.jar') } + } -// into('lib/bytecode/javassist') { -// from parent.project( 'hibernate-core' ).configurations.provided.files { dep -> dep.name == 'javassist' } -// } - - into( 'lib/jpa' ) { - from parent.project( 'hibernate-entitymanager' ).configurations.archives.allArtifacts.files.filter{ file -> !file.name.endsWith('-sources.jar') } - } - - into( 'lib/envers' ) { - from( - ( parent.project( 'hibernate-envers' ).configurations.archives.allArtifacts.files.filter{ file -> !file.name.endsWith('-sources.jar') } - + parent.project( 'hibernate-envers' ).configurations.runtime ) - - parent.project( 'hibernate-core' ).configurations.runtime - - parent.project( 'hibernate-core' ).configurations.archives.allArtifacts.files - - parent.project( 'hibernate-entitymanager' ).configurations.runtime - - parent.project( 'hibernate-entitymanager' ).configurations.archives.allArtifacts.files - ) - } - - // todo : this closure is problematic as it does not write into the hibernate-release-$project.version directory - // due to http://issues.gradle.org/browse/GRADLE-1450 - [ 'hibernate-c3p0', 'hibernate-proxool', 'hibernate-ehcache', 'hibernate-infinispan' ].each { feature -> - final String shortName = feature.substring( 'hibernate-'.length() ); -// WORKAROUND http://issues.gradle.org/browse/GRADLE-1450 -// into('lib/optional/' + shortName) { - owner.into('lib/optional/' + shortName) { - from ( - ( parent.project( feature ).configurations.archives.allArtifacts.files.filter{ file -> !file.name.endsWith('-sources.jar') } - + parent.project( feature ).configurations.runtime ) + into( 'lib/envers' ) { + from( + ( parent.project( 'hibernate-envers' ).configurations.archives.allArtifacts.files.filter{ file -> !file.name.endsWith('-sources.jar') } + + parent.project( 'hibernate-envers' ).configurations.runtime ) - parent.project( 'hibernate-core' ).configurations.runtime - parent.project( 'hibernate-core' ).configurations.archives.allArtifacts.files + - parent.project( 'hibernate-entitymanager' ).configurations.runtime + - parent.project( 'hibernate-entitymanager' ).configurations.archives.allArtifacts.files ) } - } - into('documentation') { - from new File( parent.project( 'documentation' ).buildDir, 'docbook/publish' ) - } + // todo : this closure is problematic as it does not write into the hibernate-release-$project.version directory + // due to http://issues.gradle.org/browse/GRADLE-1450 + [ 'hibernate-c3p0', 'hibernate-proxool', 'hibernate-ehcache', 'hibernate-infinispan' ].each { feature -> + final String shortName = feature.substring( 'hibernate-'.length() ); +// WORKAROUND http://issues.gradle.org/browse/GRADLE-1450 +// into('lib/optional/' + shortName) { + owner.into('lib/optional/' + shortName) { + from ( + ( parent.project( feature ).configurations.archives.allArtifacts.files.filter{ file -> !file.name.endsWith('-sources.jar') } + + parent.project( feature ).configurations.runtime ) + - parent.project( 'hibernate-core' ).configurations.runtime + - parent.project( 'hibernate-core' ).configurations.archives.allArtifacts.files + ) + } + } - into('documentation/javadocs') { - from javadocBuildDir - } + into('documentation') { + from new File( parent.project( 'documentation' ).buildDir, 'docbook/publish' ) + } - into( 'project' ) { - from ( rootProject.projectDir ) { - exclude( '.git' ) - exclude( '.gitignore' ) - exclude( 'changelog.txt' ) - exclude( 'lgpl.txt' ) - exclude( 'hibernate_logo.gif' ) - exclude( 'tagRelease.sh' ) - exclude( 'gradlew' ) - exclude( 'gradlew.bat' ) - exclude( 'wrapper/*' ) - exclude( '**/.gradle/**' ) - exclude( '**/target/**' ) - exclude( '.idea' ) - exclude( '**/*.ipr' ) - exclude( '**/*.iml' ) - exclude( '**/*.iws' ) - exclude( '**/atlassian-ide-plugin.xml' ) - exclude( '**/.classpath' ) - exclude( '**/.project' ) - exclude( '**/.settings' ) - exclude( '**/.nbattrs' ) + into('documentation/javadocs') { + from javadocBuildDir + } + + into( 'project' ) { + from ( rootProject.projectDir ) { + exclude( '.git' ) + exclude( '.gitignore' ) + exclude( 'changelog.txt' ) + exclude( 'lgpl.txt' ) + exclude( 'hibernate_logo.gif' ) + exclude( 'tagRelease.sh' ) + exclude( 'gradlew' ) + exclude( 'gradlew.bat' ) + exclude( 'wrapper/*' ) + exclude( '**/.gradle/**' ) + exclude( '**/target/**' ) + exclude( '.idea' ) + exclude( '**/*.ipr' ) + exclude( '**/*.iml' ) + exclude( '**/*.iws' ) + exclude( '**/atlassian-ide-plugin.xml' ) + exclude( '**/.classpath' ) + exclude( '**/.project' ) + exclude( '**/.settings' ) + exclude( '**/.nbattrs' ) + } } } } } -task buildReleaseZip( type: Zip, dependsOn: [prepareReleaseBundles] ) { - description = "Build release bundle in ZIP format" - baseName = 'hibernate-release' - destinationDir = releaseBuildDir - with project.releaseCopySpec -} +distZip.dependsOn prepareReleaseBundles +distTar.dependsOn prepareReleaseBundles -task buildReleaseTgz( type: Tar, dependsOn: [prepareReleaseBundles] ) { - description = "Build release bundle in GZIP format" - baseName = 'hibernate-release' - destinationDir = releaseBuildDir - compression = Compression.GZIP - with project.releaseCopySpec -} - -task buildReleaseBundles( dependsOn: [buildReleaseZip,buildReleaseTgz] ) { +task buildReleaseBundles( dependsOn: [distZip,distTar] ) { description = "Build release bundle in all formats" } From 5cc051e1dfeb5664d8d1eb9a289097d7f9bfb0e2 Mon Sep 17 00:00:00 2001 From: Lukasz Antoniak Date: Mon, 8 Apr 2013 14:43:29 +0200 Subject: [PATCH 05/54] HHH-7944 - Separation of Envers API, SPI and internal packages --- .../main/docbook/devguide/en-US/Envers.xml | 57 ++-- .../hibernate/envers/AuditReaderFactory.java | 4 +- ...AnnotationConfigurationTaskWithEnvers.java | 38 --- .../ant/ConfigurationTaskWithEnvers.java | 38 --- .../ant/JPAConfigurationTaskWithEnvers.java | 38 --- .../AuditEntitiesConfiguration.java | 185 ------------- .../envers/configuration/EnversSettings.java | 102 +++++++ .../configuration/GlobalConfiguration.java | 198 -------------- .../internal/AuditEntitiesConfiguration.java | 170 ++++++++++++ .../{ => internal}/ClassesAuditingData.java | 8 +- .../{ => internal}/EntitiesConfigurator.java | 24 +- .../internal/GlobalConfiguration.java | 184 +++++++++++++ .../PersistentClassGraphDefiner.java | 6 +- .../RevisionInfoConfiguration.java | 98 ++----- .../RevisionInfoConfigurationResult.java | 77 ++++++ .../metadata/AuditEntityNameRegister.java | 2 +- .../metadata/AuditMetadataGenerator.java | 38 +-- .../metadata/AuditTableData.java | 2 +- .../metadata/BasicMetadataGenerator.java | 6 +- .../metadata/CollectionMetadataGenerator.java | 85 +++--- .../metadata/ComponentMetadataGenerator.java | 14 +- .../metadata/EntityXmlMappingData.java | 2 +- .../metadata/IdMetadataGenerator.java | 30 ++- .../metadata/InheritanceType.java | 2 +- .../metadata/MetadataTools.java | 4 +- .../metadata/QueryGeneratorBuilder.java | 20 +- .../ToOneRelationMetadataGenerator.java | 22 +- .../reader/AnnotationsMetadataReader.java | 4 +- .../reader/AuditedPropertiesHolder.java | 2 +- .../reader/AuditedPropertiesReader.java | 33 ++- .../metadata/reader/ClassAuditingData.java | 4 +- .../ComponentAuditedPropertiesReader.java | 4 +- .../reader/ComponentAuditingData.java | 4 +- .../reader/PersistentPropertiesSource.java | 2 +- .../metadata/reader/PropertyAuditingData.java | 4 +- .../{ => spi}/AuditConfiguration.java | 44 +-- .../enhanced/SequenceIdRevisionEntity.java | 16 +- ...rackingModifiedEntitiesRevisionEntity.java | 13 +- .../BaseEnversCollectionEventListener.java | 22 +- .../{ => spi}/BaseEnversEventListener.java | 20 +- .../event/{ => spi}/EnversIntegrator.java | 6 +- .../event/{ => spi}/EnversListener.java | 4 +- .../EnversListenerDuplicationStrategy.java | 2 +- ...stCollectionRecreateEventListenerImpl.java | 4 +- .../EnversPostDeleteEventListenerImpl.java | 10 +- .../EnversPostInsertEventListenerImpl.java | 10 +- .../EnversPostUpdateEventListenerImpl.java | 10 +- ...sPreCollectionRemoveEventListenerImpl.java | 4 +- ...sPreCollectionUpdateEventListenerImpl.java | 4 +- .../entities/EntitiesConfigurations.java | 2 +- .../entities/EntityConfiguration.java | 8 +- .../entities/EntityInstantiator.java | 33 +-- .../entities/IdMappingData.java | 4 +- .../{ => internal}/entities/PropertyData.java | 2 +- .../entities/RelationDescription.java | 6 +- .../{ => internal}/entities/RelationType.java | 2 +- .../entities/RevisionTypeType.java | 2 +- .../mapper/ComponentPropertyMapper.java | 23 +- .../mapper/CompositeMapperBuilder.java | 6 +- .../mapper/ExtendedPropertyMapper.java | 2 +- .../entities/mapper/MultiPropertyMapper.java | 19 +- .../PersistentCollectionChangeData.java | 2 +- .../entities/mapper/PropertyMapper.java | 6 +- .../entities/mapper/SimpleMapperBuilder.java | 4 +- .../entities/mapper/SinglePropertyMapper.java | 15 +- .../mapper/SubclassPropertyMapper.java | 12 +- .../mapper/id/AbstractCompositeIdMapper.java | 15 +- .../entities/mapper/id/AbstractIdMapper.java | 4 +- .../entities/mapper/id/EmbeddedIdMapper.java | 8 +- .../entities/mapper/id/IdMapper.java | 4 +- .../entities/mapper/id/MultipleIdMapper.java | 10 +- .../mapper/id/QueryParameterData.java | 2 +- .../mapper/id/SimpleIdMapperBuilder.java | 4 +- .../entities/mapper/id/SingleIdMapper.java | 7 +- .../relation/AbstractCollectionMapper.java | 18 +- .../relation/AbstractOneToOneMapper.java | 8 +- .../mapper/relation/AbstractToOneMapper.java | 26 +- .../relation/BasicCollectionMapper.java | 12 +- .../relation/CommonCollectionMapperData.java | 8 +- .../mapper/relation/ListCollectionMapper.java | 17 +- .../mapper/relation/MapCollectionMapper.java | 12 +- .../mapper/relation/MiddleComponentData.java | 4 +- .../mapper/relation/MiddleIdData.java | 8 +- .../relation/OneToOneNotOwningMapper.java | 6 +- .../OneToOnePrimaryKeyJoinColumnMapper.java | 6 +- .../relation/SortedMapCollectionMapper.java | 10 +- .../relation/SortedSetCollectionMapper.java | 10 +- .../mapper/relation/ToOneEntityLoader.java | 8 +- .../mapper/relation/ToOneIdMapper.java | 19 +- .../component/MiddleComponentMapper.java | 8 +- .../component/MiddleDummyComponentMapper.java | 6 +- .../MiddleEmbeddableComponentMapper.java | 29 +- .../MiddleMapKeyIdComponentMapper.java | 10 +- .../MiddleMapKeyPropertyComponentMapper.java | 9 +- .../MiddleRelatedComponentMapper.java | 8 +- .../MiddleSimpleComponentMapper.java | 8 +- .../MiddleStraightComponentMapper.java | 6 +- .../AbstractDelegateSessionImplementor.java | 2 +- .../lazy/ToOneDelegateSessionImplementor.java | 10 +- .../AbstractCollectionInitializor.java | 10 +- .../ArrayCollectionInitializor.java | 10 +- .../BasicCollectionInitializor.java | 10 +- .../lazy/initializor/Initializor.java | 2 +- .../ListCollectionInitializor.java | 10 +- .../initializor/MapCollectionInitializor.java | 10 +- .../SortedMapCollectionInitializor.java | 10 +- .../SortedSetCollectionInitializor.java | 10 +- .../relation/lazy/proxy/CollectionProxy.java | 6 +- .../mapper/relation/lazy/proxy/ListProxy.java | 4 +- .../mapper/relation/lazy/proxy/MapProxy.java | 6 +- .../mapper/relation/lazy/proxy/SetProxy.java | 4 +- .../relation/lazy/proxy/SortedMapProxy.java | 6 +- .../relation/lazy/proxy/SortedSetProxy.java | 4 +- .../query/AbstractRelationQueryGenerator.java | 14 +- .../query/OneAuditEntityQueryGenerator.java | 23 +- .../query/OneEntityQueryGenerator.java | 21 +- .../mapper/relation/query/QueryConstants.java | 2 +- .../query/RelationQueryGenerator.java | 4 +- .../query/ThreeEntityQueryGenerator.java | 31 +-- .../TwoEntityOneAuditedQueryGenerator.java | 23 +- .../query/TwoEntityQueryGenerator.java | 27 +- .../reader/AuditReaderImpl.java | 15 +- .../reader/AuditReaderImplementor.java | 2 +- .../CrossTypeRevisionChangesReaderImpl.java | 14 +- .../reader/FirstLevelCache.java | 8 +- .../DefaultRevisionInfoGenerator.java | 8 +- ...ModifiedEntitiesRevisionInfoGenerator.java | 6 +- .../ModifiedEntityNamesReader.java | 6 +- .../revisioninfo/RevisionInfoGenerator.java | 2 +- .../RevisionInfoNumberReader.java | 6 +- .../RevisionInfoQueryCreator.java | 2 +- .../synchronization/AuditProcess.java | 6 +- .../synchronization/AuditProcessManager.java | 4 +- .../synchronization/EntityChangeNotifier.java | 12 +- .../synchronization/SessionCacheCleaner.java | 2 +- .../work/AbstractAuditWorkUnit.java | 6 +- .../synchronization/work/AddWorkUnit.java | 9 +- .../synchronization/work/AuditWorkUnit.java | 2 +- .../work/CollectionChangeWorkUnit.java | 4 +- .../synchronization/work/DelWorkUnit.java | 9 +- .../FakeBidirectionalRelationWorkUnit.java | 6 +- .../synchronization/work/ModWorkUnit.java | 4 +- .../PersistentCollectionChangeWorkUnit.java | 9 +- .../work/WorkUnitMergeDispatcher.java | 2 +- .../work/WorkUnitMergeVisitor.java | 2 +- .../tools/ArgumentsTools.java} | 23 +- .../envers/internal/tools/ArraysTools.java | 71 +++++ .../envers/internal/tools/EntityTools.java | 86 ++++++ .../envers/internal/tools/MappingTools.java | 43 +++ .../{ => internal}/tools/MutableBoolean.java | 2 +- .../{ => internal}/tools/MutableInteger.java | 2 +- .../internal/tools/ReflectionTools.java | 142 ++++++++++ .../envers/internal/tools/StringTools.java | 77 ++++++ .../envers/internal/tools/Tools.java | 103 +++++++ .../envers/{ => internal}/tools/Triple.java | 3 +- .../tools/graph/GraphDefiner.java | 2 +- .../tools/graph/GraphTopologicalSort.java | 2 +- .../tools/graph/TopologicalSort.java | 2 +- .../{ => internal}/tools/graph/Vertex.java | 2 +- .../tools/query/Parameters.java | 6 +- .../tools/query/QueryBuilder.java | 7 +- .../tools/query/UpdateBuilder.java | 14 +- .../hibernate/envers/query/AuditEntity.java | 12 +- .../envers/query/AuditQueryCreator.java | 16 +- .../criteria/AggregatedAuditExpression.java | 12 +- .../query/criteria/AuditConjunction.java | 9 +- .../envers/query/criteria/AuditCriterion.java | 8 +- .../query/criteria/AuditDisjunction.java | 9 +- .../envers/query/criteria/AuditId.java | 9 +- .../envers/query/criteria/AuditProperty.java | 26 +- .../envers/query/criteria/AuditRelatedId.java | 5 +- .../BetweenAuditExpression.java | 14 +- .../{ => internal}/CriteriaTools.java | 19 +- .../IdentifierEqAuditExpression.java | 12 +- .../{ => internal}/InAuditExpression.java | 14 +- .../LogicalAuditExpression.java | 12 +- .../{ => internal}/NotAuditExpression.java | 11 +- .../NotNullAuditExpression.java | 15 +- .../{ => internal}/NullAuditExpression.java | 15 +- .../PropertyAuditExpression.java | 13 +- .../RelatedAuditExpression.java | 15 +- .../RevisionTypeAuditExpression.java | 11 +- .../{ => internal}/SimpleAuditExpression.java | 15 +- .../impl/AbstractAuditQuery.java | 16 +- .../impl/EntitiesAtRevisionQuery.java | 16 +- .../impl/EntitiesModifiedAtRevisionQuery.java | 8 +- .../impl/RevisionsOfEntityQuery.java | 9 +- .../property/EntityPropertyName.java | 4 +- .../property/ModifiedFlagPropertyName.java | 6 +- .../property/OriginalIdPropertyName.java | 4 +- .../property/PropertyNameGetter.java | 4 +- .../property/RevisionNumberPropertyName.java | 4 +- .../RevisionPropertyPropertyName.java | 4 +- .../property/RevisionTypePropertyName.java | 4 +- .../envers/query/order/AuditOrder.java | 3 +- .../{ => internal}/PropertyAuditOrder.java | 7 +- .../query/projection/AuditProjection.java | 5 +- .../PropertyAuditProjection.java | 9 +- .../envers/strategy/AuditStrategy.java | 12 +- .../envers/strategy/DefaultAuditStrategy.java | 20 +- .../strategy/ValidityAuditStrategy.java | 27 +- .../envers/tools/ArgumentsTools.java | 42 --- .../hibernate/envers/tools/MappingTools.java | 39 --- .../java/org/hibernate/envers/tools/Pair.java | 1 - .../hibernate/envers/tools/StringTools.java | 77 ------ .../org/hibernate/envers/tools/Tools.java | 253 ------------------ .../tools/hbm2ddl}/EnversSchemaGenerator.java | 4 +- .../tools/reflection/ReflectionTools.java | 85 ------ .../tool/ant/EnversHibernateToolTask.java | 61 ----- .../org.hibernate.integrator.spi.Integrator | 2 +- .../envers/test/AbstractOneSessionTest.java | 7 +- .../test/BaseEnversFunctionalTestCase.java | 5 +- .../test/BaseEnversJPAFunctionalTestCase.java | 21 +- .../ExtendedRevisionEntity.java | 2 +- .../envers/test/integration/basic/Delete.java | 2 +- .../basic/OutsideTransactionTest.java | 8 +- .../basic/TransactionRollbackBehaviour.java | 6 +- .../basic/UnversionedProperty.java | 2 +- .../test/integration/collection/EnumSet.java | 2 +- .../embeddable/EmbeddableList2.java | 1 - .../collection/embeddable/EmbeddableMap.java | 7 +- .../AbstractCollectionChangeTest.java | 10 +- .../integration/components/Components.java | 2 +- .../components/PropertiesGroupTest.java | 7 +- .../relations/ManyToOneInComponent.java | 2 +- .../relations/OneToManyInComponent.java | 2 +- .../customtype/ObjectUserTypeTest.java | 3 +- .../integration/data/LobSerializables.java | 2 +- .../envers/test/integration/data/Lobs.java | 2 +- .../flush/ManualFlushAutoCommitDisabled.java | 4 +- .../test/integration/ids/embeddedid/Item.java | 4 +- .../integration/ids/embeddedid/Producer.java | 4 +- .../ids/embeddedid/PurchaseOrder.java | 12 +- .../RelationInsideEmbeddableTest.java | 11 +- .../integration/ids/idclass/ClassType.java | 1 - .../ids/idclass/IdClassWithRelationTest.java | 9 +- .../MixedInheritanceStrategiesEntityTest.java | 2 +- .../AbstractPropertiesAuditedTest.java | 2 +- .../integration/jta/JtaExceptionListener.java | 1 - .../test/integration/jta/JtaTransaction.java | 6 +- .../test/integration/manytomany/BasicSet.java | 2 +- .../ManyToManyInverseToSuperclassTest.java | 6 +- .../manytomany/sametable/BasicSametable.java | 2 +- .../test/integration/merge/AddDelTest.java | 2 +- .../AbstractModifiedFlagsEntityTest.java | 4 +- .../AbstractModifiedFlagsOneSessionTest.java | 5 +- .../HasChangedComponentCollection.java | 2 +- .../HasChangedDetachedMultipleCollection.java | 2 +- .../modifiedflags/ModifiedFlagSuffix.java | 4 +- .../ids/JoinMulIdNamingRefIngEntity.java | 2 +- .../PropertyNotUpdatableTest.java | 19 +- .../test/integration/onetomany/BasicList.java | 2 +- .../detached/DataChangesDetachedSet.java | 2 +- .../onetomany/embeddedid/Constant.java | 6 +- .../onetomany/embeddedid/MapsIdTest.java | 7 +- .../onetomany/embeddedid/Person.java | 9 +- .../onetomany/embeddedid/PersonTuple.java | 12 +- .../OneToManyInverseToSuperclassTest.java | 6 +- .../UnversionedOptimisticLockingField.java | 5 +- .../properties/VersionsProperties.java | 9 +- .../proxy/QueryingWithProxyObjectTest.java | 2 - .../proxy/RemovedObjectQueryTest.java | 17 +- .../query/CustomRevEntityQuery.java | 2 +- .../integration/query/DeletedEntities.java | 2 +- .../query/MaximalizePropertyQuery.java | 7 +- .../query/RevisionConstraintQuery.java | 2 +- .../test/integration/query/SimpleQuery.java | 2 +- .../integration/query/StoreDeletedData.java | 3 +- .../ReadWriteExpressionChange.java | 2 +- .../reventity/DifferentDBSchemaTest.java | 3 +- .../GloballyConfiguredRevListenerTest.java | 3 +- .../reventity/InheritedRevEntity.java | 3 +- .../OverrideCustomRevListenerTest.java | 1 - .../OverrideDefaultRevListenerTest.java | 1 - .../AnnotatedTrackingEntitiesTest.java | 3 +- .../DefaultTrackingEntitiesTest.java | 3 +- .../EntityNamesTest.java | 12 +- .../ExtendedRevisionEntityTest.java | 3 +- .../TrackingEntitiesMultipleChangesTest.java | 3 +- .../ValidityAuditStrategyManyToManyTest.java | 3 +- ...tyAuditStrategyRevEndTestCustomRevEnt.java | 7 +- .../ValidityAuditStrategyRevEndTsTest.java | 7 +- .../integration/tools/SchemaExportTest.java | 11 +- .../AbstractEntityManagerTest.java | 19 +- .../envers/test/tools/TestTools.java | 98 +++---- 285 files changed, 2279 insertions(+), 2325 deletions(-) delete mode 100644 hibernate-envers/src/main/java/org/hibernate/envers/ant/AnnotationConfigurationTaskWithEnvers.java delete mode 100644 hibernate-envers/src/main/java/org/hibernate/envers/ant/ConfigurationTaskWithEnvers.java delete mode 100644 hibernate-envers/src/main/java/org/hibernate/envers/ant/JPAConfigurationTaskWithEnvers.java delete mode 100644 hibernate-envers/src/main/java/org/hibernate/envers/configuration/AuditEntitiesConfiguration.java create mode 100644 hibernate-envers/src/main/java/org/hibernate/envers/configuration/EnversSettings.java delete mode 100644 hibernate-envers/src/main/java/org/hibernate/envers/configuration/GlobalConfiguration.java create mode 100644 hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/AuditEntitiesConfiguration.java rename hibernate-envers/src/main/java/org/hibernate/envers/configuration/{ => internal}/ClassesAuditingData.java (93%) rename hibernate-envers/src/main/java/org/hibernate/envers/configuration/{ => internal}/EntitiesConfigurator.java (88%) create mode 100644 hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/GlobalConfiguration.java rename hibernate-envers/src/main/java/org/hibernate/envers/configuration/{ => internal}/PersistentClassGraphDefiner.java (94%) rename hibernate-envers/src/main/java/org/hibernate/envers/configuration/{ => internal}/RevisionInfoConfiguration.java (83%) create mode 100644 hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/RevisionInfoConfigurationResult.java rename hibernate-envers/src/main/java/org/hibernate/envers/configuration/{ => internal}/metadata/AuditEntityNameRegister.java (96%) rename hibernate-envers/src/main/java/org/hibernate/envers/configuration/{ => internal}/metadata/AuditMetadataGenerator.java (95%) rename hibernate-envers/src/main/java/org/hibernate/envers/configuration/{ => internal}/metadata/AuditTableData.java (96%) rename hibernate-envers/src/main/java/org/hibernate/envers/configuration/{ => internal}/metadata/BasicMetadataGenerator.java (96%) rename hibernate-envers/src/main/java/org/hibernate/envers/configuration/{ => internal}/metadata/CollectionMetadataGenerator.java (90%) rename hibernate-envers/src/main/java/org/hibernate/envers/configuration/{ => internal}/metadata/ComponentMetadataGenerator.java (71%) rename hibernate-envers/src/main/java/org/hibernate/envers/configuration/{ => internal}/metadata/EntityXmlMappingData.java (97%) rename hibernate-envers/src/main/java/org/hibernate/envers/configuration/{ => internal}/metadata/IdMetadataGenerator.java (85%) rename hibernate-envers/src/main/java/org/hibernate/envers/configuration/{ => internal}/metadata/InheritanceType.java (97%) rename hibernate-envers/src/main/java/org/hibernate/envers/configuration/{ => internal}/metadata/MetadataTools.java (99%) rename hibernate-envers/src/main/java/org/hibernate/envers/configuration/{ => internal}/metadata/QueryGeneratorBuilder.java (83%) rename hibernate-envers/src/main/java/org/hibernate/envers/configuration/{ => internal}/metadata/ToOneRelationMetadataGenerator.java (90%) rename hibernate-envers/src/main/java/org/hibernate/envers/configuration/{ => internal}/metadata/reader/AnnotationsMetadataReader.java (97%) rename hibernate-envers/src/main/java/org/hibernate/envers/configuration/{ => internal}/metadata/reader/AuditedPropertiesHolder.java (92%) rename hibernate-envers/src/main/java/org/hibernate/envers/configuration/{ => internal}/metadata/reader/AuditedPropertiesReader.java (95%) rename hibernate-envers/src/main/java/org/hibernate/envers/configuration/{ => internal}/metadata/reader/ClassAuditingData.java (95%) rename hibernate-envers/src/main/java/org/hibernate/envers/configuration/{ => internal}/metadata/reader/ComponentAuditedPropertiesReader.java (90%) rename hibernate-envers/src/main/java/org/hibernate/envers/configuration/{ => internal}/metadata/reader/ComponentAuditingData.java (93%) rename hibernate-envers/src/main/java/org/hibernate/envers/configuration/{ => internal}/metadata/reader/PersistentPropertiesSource.java (85%) rename hibernate-envers/src/main/java/org/hibernate/envers/configuration/{ => internal}/metadata/reader/PropertyAuditingData.java (97%) rename hibernate-envers/src/main/java/org/hibernate/envers/configuration/{ => spi}/AuditConfiguration.java (80%) rename hibernate-envers/src/main/java/org/hibernate/envers/event/{ => spi}/BaseEnversCollectionEventListener.java (93%) rename hibernate-envers/src/main/java/org/hibernate/envers/event/{ => spi}/BaseEnversEventListener.java (88%) rename hibernate-envers/src/main/java/org/hibernate/envers/event/{ => spi}/EnversIntegrator.java (97%) rename hibernate-envers/src/main/java/org/hibernate/envers/event/{ => spi}/EnversListener.java (92%) rename hibernate-envers/src/main/java/org/hibernate/envers/event/{ => spi}/EnversListenerDuplicationStrategy.java (97%) rename hibernate-envers/src/main/java/org/hibernate/envers/event/{ => spi}/EnversPostCollectionRecreateEventListenerImpl.java (94%) rename hibernate-envers/src/main/java/org/hibernate/envers/event/{ => spi}/EnversPostDeleteEventListenerImpl.java (89%) rename hibernate-envers/src/main/java/org/hibernate/envers/event/{ => spi}/EnversPostInsertEventListenerImpl.java (89%) rename hibernate-envers/src/main/java/org/hibernate/envers/event/{ => spi}/EnversPostUpdateEventListenerImpl.java (91%) rename hibernate-envers/src/main/java/org/hibernate/envers/event/{ => spi}/EnversPreCollectionRemoveEventListenerImpl.java (95%) rename hibernate-envers/src/main/java/org/hibernate/envers/event/{ => spi}/EnversPreCollectionUpdateEventListenerImpl.java (94%) rename hibernate-envers/src/main/java/org/hibernate/envers/{ => internal}/entities/EntitiesConfigurations.java (99%) rename hibernate-envers/src/main/java/org/hibernate/envers/{ => internal}/entities/EntityConfiguration.java (95%) rename hibernate-envers/src/main/java/org/hibernate/envers/{ => internal}/entities/EntityInstantiator.java (91%) rename hibernate-envers/src/main/java/org/hibernate/envers/{ => internal}/entities/IdMappingData.java (94%) rename hibernate-envers/src/main/java/org/hibernate/envers/{ => internal}/entities/PropertyData.java (98%) rename hibernate-envers/src/main/java/org/hibernate/envers/{ => internal}/entities/RelationDescription.java (94%) rename hibernate-envers/src/main/java/org/hibernate/envers/{ => internal}/entities/RelationType.java (97%) rename hibernate-envers/src/main/java/org/hibernate/envers/{ => internal}/entities/RevisionTypeType.java (98%) rename hibernate-envers/src/main/java/org/hibernate/envers/{ => internal}/entities/mapper/ComponentPropertyMapper.java (89%) rename hibernate-envers/src/main/java/org/hibernate/envers/{ => internal}/entities/mapper/CompositeMapperBuilder.java (90%) rename hibernate-envers/src/main/java/org/hibernate/envers/{ => internal}/entities/mapper/ExtendedPropertyMapper.java (96%) rename hibernate-envers/src/main/java/org/hibernate/envers/{ => internal}/entities/mapper/MultiPropertyMapper.java (93%) rename hibernate-envers/src/main/java/org/hibernate/envers/{ => internal}/entities/mapper/PersistentCollectionChangeData.java (98%) rename hibernate-envers/src/main/java/org/hibernate/envers/{ => internal}/entities/mapper/PropertyMapper.java (94%) rename hibernate-envers/src/main/java/org/hibernate/envers/{ => internal}/entities/mapper/SimpleMapperBuilder.java (91%) rename hibernate-envers/src/main/java/org/hibernate/envers/{ => internal}/entities/mapper/SinglePropertyMapper.java (92%) rename hibernate-envers/src/main/java/org/hibernate/envers/{ => internal}/entities/mapper/SubclassPropertyMapper.java (93%) rename hibernate-envers/src/main/java/org/hibernate/envers/{ => internal}/entities/mapper/id/AbstractCompositeIdMapper.java (83%) rename hibernate-envers/src/main/java/org/hibernate/envers/{ => internal}/entities/mapper/id/AbstractIdMapper.java (97%) rename hibernate-envers/src/main/java/org/hibernate/envers/{ => internal}/entities/mapper/id/EmbeddedIdMapper.java (93%) rename hibernate-envers/src/main/java/org/hibernate/envers/{ => internal}/entities/mapper/id/IdMapper.java (97%) rename hibernate-envers/src/main/java/org/hibernate/envers/{ => internal}/entities/mapper/id/MultipleIdMapper.java (91%) rename hibernate-envers/src/main/java/org/hibernate/envers/{ => internal}/entities/mapper/id/QueryParameterData.java (97%) rename hibernate-envers/src/main/java/org/hibernate/envers/{ => internal}/entities/mapper/id/SimpleIdMapperBuilder.java (90%) rename hibernate-envers/src/main/java/org/hibernate/envers/{ => internal}/entities/mapper/id/SingleIdMapper.java (96%) rename hibernate-envers/src/main/java/org/hibernate/envers/{ => internal}/entities/mapper/relation/AbstractCollectionMapper.java (93%) rename hibernate-envers/src/main/java/org/hibernate/envers/{ => internal}/entities/mapper/relation/AbstractOneToOneMapper.java (91%) rename hibernate-envers/src/main/java/org/hibernate/envers/{ => internal}/entities/mapper/relation/AbstractToOneMapper.java (81%) rename hibernate-envers/src/main/java/org/hibernate/envers/{ => internal}/entities/mapper/relation/BasicCollectionMapper.java (86%) rename hibernate-envers/src/main/java/org/hibernate/envers/{ => internal}/entities/mapper/relation/CommonCollectionMapperData.java (89%) rename hibernate-envers/src/main/java/org/hibernate/envers/{ => internal}/entities/mapper/relation/ListCollectionMapper.java (85%) rename hibernate-envers/src/main/java/org/hibernate/envers/{ => internal}/entities/mapper/relation/MapCollectionMapper.java (87%) rename hibernate-envers/src/main/java/org/hibernate/envers/{ => internal}/entities/mapper/relation/MiddleComponentData.java (92%) rename hibernate-envers/src/main/java/org/hibernate/envers/{ => internal}/entities/mapper/relation/MiddleIdData.java (91%) rename hibernate-envers/src/main/java/org/hibernate/envers/{ => internal}/entities/mapper/relation/OneToOneNotOwningMapper.java (92%) rename hibernate-envers/src/main/java/org/hibernate/envers/{ => internal}/entities/mapper/relation/OneToOnePrimaryKeyJoinColumnMapper.java (93%) rename hibernate-envers/src/main/java/org/hibernate/envers/{ => internal}/entities/mapper/relation/SortedMapCollectionMapper.java (84%) rename hibernate-envers/src/main/java/org/hibernate/envers/{ => internal}/entities/mapper/relation/SortedSetCollectionMapper.java (84%) rename hibernate-envers/src/main/java/org/hibernate/envers/{ => internal}/entities/mapper/relation/ToOneEntityLoader.java (88%) rename hibernate-envers/src/main/java/org/hibernate/envers/{ => internal}/entities/mapper/relation/ToOneIdMapper.java (87%) rename hibernate-envers/src/main/java/org/hibernate/envers/{ => internal}/entities/mapper/relation/component/MiddleComponentMapper.java (92%) rename hibernate-envers/src/main/java/org/hibernate/envers/{ => internal}/entities/mapper/relation/component/MiddleDummyComponentMapper.java (89%) rename hibernate-envers/src/main/java/org/hibernate/envers/{ => internal}/entities/mapper/relation/component/MiddleEmbeddableComponentMapper.java (83%) rename hibernate-envers/src/main/java/org/hibernate/envers/{ => internal}/entities/mapper/relation/component/MiddleMapKeyIdComponentMapper.java (87%) rename hibernate-envers/src/main/java/org/hibernate/envers/{ => internal}/entities/mapper/relation/component/MiddleMapKeyPropertyComponentMapper.java (90%) rename hibernate-envers/src/main/java/org/hibernate/envers/{ => internal}/entities/mapper/relation/component/MiddleRelatedComponentMapper.java (88%) rename hibernate-envers/src/main/java/org/hibernate/envers/{ => internal}/entities/mapper/relation/component/MiddleSimpleComponentMapper.java (89%) rename hibernate-envers/src/main/java/org/hibernate/envers/{ => internal}/entities/mapper/relation/component/MiddleStraightComponentMapper.java (91%) rename hibernate-envers/src/main/java/org/hibernate/envers/{ => internal}/entities/mapper/relation/lazy/AbstractDelegateSessionImplementor.java (99%) rename hibernate-envers/src/main/java/org/hibernate/envers/{ => internal}/entities/mapper/relation/lazy/ToOneDelegateSessionImplementor.java (87%) rename hibernate-envers/src/main/java/org/hibernate/envers/{ => internal}/entities/mapper/relation/lazy/initializor/AbstractCollectionInitializor.java (87%) rename hibernate-envers/src/main/java/org/hibernate/envers/{ => internal}/entities/mapper/relation/lazy/initializor/ArrayCollectionInitializor.java (88%) rename hibernate-envers/src/main/java/org/hibernate/envers/{ => internal}/entities/mapper/relation/lazy/initializor/BasicCollectionInitializor.java (90%) rename hibernate-envers/src/main/java/org/hibernate/envers/{ => internal}/entities/mapper/relation/lazy/initializor/Initializor.java (93%) rename hibernate-envers/src/main/java/org/hibernate/envers/{ => internal}/entities/mapper/relation/lazy/initializor/ListCollectionInitializor.java (90%) rename hibernate-envers/src/main/java/org/hibernate/envers/{ => internal}/entities/mapper/relation/lazy/initializor/MapCollectionInitializor.java (90%) rename hibernate-envers/src/main/java/org/hibernate/envers/{ => internal}/entities/mapper/relation/lazy/initializor/SortedMapCollectionInitializor.java (86%) rename hibernate-envers/src/main/java/org/hibernate/envers/{ => internal}/entities/mapper/relation/lazy/initializor/SortedSetCollectionInitializor.java (86%) rename hibernate-envers/src/main/java/org/hibernate/envers/{ => internal}/entities/mapper/relation/lazy/proxy/CollectionProxy.java (92%) rename hibernate-envers/src/main/java/org/hibernate/envers/{ => internal}/entities/mapper/relation/lazy/proxy/ListProxy.java (92%) rename hibernate-envers/src/main/java/org/hibernate/envers/{ => internal}/entities/mapper/relation/lazy/proxy/MapProxy.java (91%) rename hibernate-envers/src/main/java/org/hibernate/envers/{ => internal}/entities/mapper/relation/lazy/proxy/SetProxy.java (87%) rename hibernate-envers/src/main/java/org/hibernate/envers/{ => internal}/entities/mapper/relation/lazy/proxy/SortedMapProxy.java (92%) rename hibernate-envers/src/main/java/org/hibernate/envers/{ => internal}/entities/mapper/relation/lazy/proxy/SortedSetProxy.java (90%) rename hibernate-envers/src/main/java/org/hibernate/envers/{ => internal}/entities/mapper/relation/query/AbstractRelationQueryGenerator.java (80%) rename hibernate-envers/src/main/java/org/hibernate/envers/{ => internal}/entities/mapper/relation/query/OneAuditEntityQueryGenerator.java (80%) rename hibernate-envers/src/main/java/org/hibernate/envers/{ => internal}/entities/mapper/relation/query/OneEntityQueryGenerator.java (82%) rename hibernate-envers/src/main/java/org/hibernate/envers/{ => internal}/entities/mapper/relation/query/QueryConstants.java (90%) rename hibernate-envers/src/main/java/org/hibernate/envers/{ => internal}/entities/mapper/relation/query/RelationQueryGenerator.java (92%) rename hibernate-envers/src/main/java/org/hibernate/envers/{ => internal}/entities/mapper/relation/query/ThreeEntityQueryGenerator.java (85%) rename hibernate-envers/src/main/java/org/hibernate/envers/{ => internal}/entities/mapper/relation/query/TwoEntityOneAuditedQueryGenerator.java (82%) rename hibernate-envers/src/main/java/org/hibernate/envers/{ => internal}/entities/mapper/relation/query/TwoEntityQueryGenerator.java (83%) rename hibernate-envers/src/main/java/org/hibernate/envers/{ => internal}/reader/AuditReaderImpl.java (96%) rename hibernate-envers/src/main/java/org/hibernate/envers/{ => internal}/reader/AuditReaderImplementor.java (97%) rename hibernate-envers/src/main/java/org/hibernate/envers/{ => internal}/reader/CrossTypeRevisionChangesReaderImpl.java (90%) rename hibernate-envers/src/main/java/org/hibernate/envers/{ => internal}/reader/FirstLevelCache.java (95%) rename hibernate-envers/src/main/java/org/hibernate/envers/{ => internal}/revisioninfo/DefaultRevisionInfoGenerator.java (94%) rename hibernate-envers/src/main/java/org/hibernate/envers/{ => internal}/revisioninfo/DefaultTrackingModifiedEntitiesRevisionInfoGenerator.java (93%) rename hibernate-envers/src/main/java/org/hibernate/envers/{ => internal}/revisioninfo/ModifiedEntityNamesReader.java (80%) rename hibernate-envers/src/main/java/org/hibernate/envers/{ => internal}/revisioninfo/RevisionInfoGenerator.java (97%) rename hibernate-envers/src/main/java/org/hibernate/envers/{ => internal}/revisioninfo/RevisionInfoNumberReader.java (90%) rename hibernate-envers/src/main/java/org/hibernate/envers/{ => internal}/revisioninfo/RevisionInfoQueryCreator.java (98%) rename hibernate-envers/src/main/java/org/hibernate/envers/{ => internal}/synchronization/AuditProcess.java (96%) rename hibernate-envers/src/main/java/org/hibernate/envers/{ => internal}/synchronization/AuditProcessManager.java (95%) rename hibernate-envers/src/main/java/org/hibernate/envers/{ => internal}/synchronization/EntityChangeNotifier.java (79%) rename hibernate-envers/src/main/java/org/hibernate/envers/{ => internal}/synchronization/SessionCacheCleaner.java (95%) rename hibernate-envers/src/main/java/org/hibernate/envers/{ => internal}/synchronization/work/AbstractAuditWorkUnit.java (94%) rename hibernate-envers/src/main/java/org/hibernate/envers/{ => internal}/synchronization/work/AddWorkUnit.java (93%) rename hibernate-envers/src/main/java/org/hibernate/envers/{ => internal}/synchronization/work/AuditWorkUnit.java (97%) rename hibernate-envers/src/main/java/org/hibernate/envers/{ => internal}/synchronization/work/CollectionChangeWorkUnit.java (96%) rename hibernate-envers/src/main/java/org/hibernate/envers/{ => internal}/synchronization/work/DelWorkUnit.java (93%) rename hibernate-envers/src/main/java/org/hibernate/envers/{ => internal}/synchronization/work/FakeBidirectionalRelationWorkUnit.java (97%) rename hibernate-envers/src/main/java/org/hibernate/envers/{ => internal}/synchronization/work/ModWorkUnit.java (96%) rename hibernate-envers/src/main/java/org/hibernate/envers/{ => internal}/synchronization/work/PersistentCollectionChangeWorkUnit.java (97%) rename hibernate-envers/src/main/java/org/hibernate/envers/{ => internal}/synchronization/work/WorkUnitMergeDispatcher.java (96%) rename hibernate-envers/src/main/java/org/hibernate/envers/{ => internal}/synchronization/work/WorkUnitMergeVisitor.java (96%) rename hibernate-envers/src/main/java/org/hibernate/envers/{tools/ArraysTools.java => internal/tools/ArgumentsTools.java} (72%) create mode 100644 hibernate-envers/src/main/java/org/hibernate/envers/internal/tools/ArraysTools.java create mode 100644 hibernate-envers/src/main/java/org/hibernate/envers/internal/tools/EntityTools.java create mode 100644 hibernate-envers/src/main/java/org/hibernate/envers/internal/tools/MappingTools.java rename hibernate-envers/src/main/java/org/hibernate/envers/{ => internal}/tools/MutableBoolean.java (97%) rename hibernate-envers/src/main/java/org/hibernate/envers/{ => internal}/tools/MutableInteger.java (96%) create mode 100644 hibernate-envers/src/main/java/org/hibernate/envers/internal/tools/ReflectionTools.java create mode 100644 hibernate-envers/src/main/java/org/hibernate/envers/internal/tools/StringTools.java create mode 100644 hibernate-envers/src/main/java/org/hibernate/envers/internal/tools/Tools.java rename hibernate-envers/src/main/java/org/hibernate/envers/{ => internal}/tools/Triple.java (98%) rename hibernate-envers/src/main/java/org/hibernate/envers/{ => internal}/tools/graph/GraphDefiner.java (96%) rename hibernate-envers/src/main/java/org/hibernate/envers/{ => internal}/tools/graph/GraphTopologicalSort.java (97%) rename hibernate-envers/src/main/java/org/hibernate/envers/{ => internal}/tools/graph/TopologicalSort.java (97%) rename hibernate-envers/src/main/java/org/hibernate/envers/{ => internal}/tools/graph/Vertex.java (97%) rename hibernate-envers/src/main/java/org/hibernate/envers/{ => internal}/tools/query/Parameters.java (98%) rename hibernate-envers/src/main/java/org/hibernate/envers/{ => internal}/tools/query/QueryBuilder.java (97%) rename hibernate-envers/src/main/java/org/hibernate/envers/{ => internal}/tools/query/UpdateBuilder.java (91%) rename hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/{ => internal}/BetweenAuditExpression.java (82%) rename hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/{ => internal}/CriteriaTools.java (86%) rename hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/{ => internal}/IdentifierEqAuditExpression.java (83%) rename hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/{ => internal}/InAuditExpression.java (78%) rename hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/{ => internal}/LogicalAuditExpression.java (83%) rename hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/{ => internal}/NotAuditExpression.java (81%) rename hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/{ => internal}/NotNullAuditExpression.java (79%) rename hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/{ => internal}/NullAuditExpression.java (79%) rename hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/{ => internal}/PropertyAuditExpression.java (82%) rename hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/{ => internal}/RelatedAuditExpression.java (81%) rename hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/{ => internal}/RevisionTypeAuditExpression.java (81%) rename hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/{ => internal}/SimpleAuditExpression.java (83%) rename hibernate-envers/src/main/java/org/hibernate/envers/query/{ => internal}/impl/AbstractAuditQuery.java (93%) rename hibernate-envers/src/main/java/org/hibernate/envers/query/{ => internal}/impl/EntitiesAtRevisionQuery.java (87%) rename hibernate-envers/src/main/java/org/hibernate/envers/query/{ => internal}/impl/EntitiesModifiedAtRevisionQuery.java (89%) rename hibernate-envers/src/main/java/org/hibernate/envers/query/{ => internal}/impl/RevisionsOfEntityQuery.java (95%) rename hibernate-envers/src/main/java/org/hibernate/envers/query/{ => internal}/property/EntityPropertyName.java (92%) rename hibernate-envers/src/main/java/org/hibernate/envers/query/{ => internal}/property/ModifiedFlagPropertyName.java (89%) rename hibernate-envers/src/main/java/org/hibernate/envers/query/{ => internal}/property/OriginalIdPropertyName.java (93%) rename hibernate-envers/src/main/java/org/hibernate/envers/query/{ => internal}/property/PropertyNameGetter.java (92%) rename hibernate-envers/src/main/java/org/hibernate/envers/query/{ => internal}/property/RevisionNumberPropertyName.java (92%) rename hibernate-envers/src/main/java/org/hibernate/envers/query/{ => internal}/property/RevisionPropertyPropertyName.java (92%) rename hibernate-envers/src/main/java/org/hibernate/envers/query/{ => internal}/property/RevisionTypePropertyName.java (92%) rename hibernate-envers/src/main/java/org/hibernate/envers/query/order/{ => internal}/PropertyAuditOrder.java (86%) rename hibernate-envers/src/main/java/org/hibernate/envers/query/projection/{ => internal}/PropertyAuditProjection.java (85%) delete mode 100644 hibernate-envers/src/main/java/org/hibernate/envers/tools/ArgumentsTools.java delete mode 100644 hibernate-envers/src/main/java/org/hibernate/envers/tools/MappingTools.java delete mode 100644 hibernate-envers/src/main/java/org/hibernate/envers/tools/StringTools.java delete mode 100644 hibernate-envers/src/main/java/org/hibernate/envers/tools/Tools.java rename hibernate-envers/src/main/java/org/hibernate/{tool => envers/tools/hbm2ddl}/EnversSchemaGenerator.java (93%) delete mode 100644 hibernate-envers/src/main/java/org/hibernate/envers/tools/reflection/ReflectionTools.java delete mode 100644 hibernate-envers/src/main/java/org/hibernate/tool/ant/EnversHibernateToolTask.java diff --git a/documentation/src/main/docbook/devguide/en-US/Envers.xml b/documentation/src/main/docbook/devguide/en-US/Envers.xml index d2e1fd7d0a..1e03a0d1f7 100644 --- a/documentation/src/main/docbook/devguide/en-US/Envers.xml +++ b/documentation/src/main/docbook/devguide/en-US/Envers.xml @@ -1,4 +1,4 @@ - + @@ -40,7 +40,7 @@ which stores the historical data, whenever you commit a transaction. Envers automatically creates audit tables if hibernate.hbm2ddl.auto option is set to create, create-drop or update. Otherwise, to export complete database schema - programatically, use org.hibernate.tool.EnversSchemaGenerator. Appropriate DDL + programatically, use org.hibernate.envers.tools.hbm2ddl.EnversSchemaGenerator. Appropriate DDL statements can be also generated with Ant task described later in this manual. @@ -58,7 +58,7 @@ -
+
Configuration It is possible to configure various aspects of Hibernate Envers behavior, such as table names, etc. @@ -300,7 +300,7 @@ When set to false, such column can be added to selected entities or properties using the @Audited annotation. For more information refer to - and . + and . @@ -480,7 +480,7 @@ class is inaccessible from @RevisionEntity (e.g. exists in a different module), set org.hibernate.envers.revision_listener property to it's fully qualified name. Class name defined by the configuration parameter overrides revision entity's - value attribute. + value attribute. @@ -621,7 +621,7 @@ public class AnnotatedTrackingRevisionEntity { EntityTrackingRevisionListener interface exposes one method that notifies whenever audited entity instance has been added, modified or removed within current revision boundaries. - + Custom implementation of tracking entity classes modified during revisions @@ -735,7 +735,7 @@ Set modifiedEntityTypes = revEntity.getModifiedEntityT To see how "Modified Flags" can be utilized, check out the very - simple query API that uses them: . + simple query API that uses them: .
@@ -771,7 +771,7 @@ Set modifiedEntityTypes = revEntity.getModifiedEntityT In the future, queries will be improved both in terms of speed and possibilities, when using the valid-time audit strategy, that is when storing both start and end revisions for entities. See - . + .
@@ -929,7 +929,7 @@ query.add(AuditEntity.relatedId("address").eq(relatedEntityId));]]> -
+
Querying for revisions of entity that modified given property @@ -948,11 +948,10 @@ query.add(AuditEntity.relatedId("address").eq(relatedEntityId));]]> - + @@ -967,11 +966,10 @@ query.add(AuditEntity.relatedId("address").eq(relatedEntityId));]]> - + @@ -991,11 +989,10 @@ query.add(AuditEntity.relatedId("address").eq(relatedEntityId));]]>forEntitiesModifiedAtRevision query: - +
@@ -1049,7 +1046,7 @@ query.add(AuditEntity.relatedId("address").eq(relatedEntityId));]]>Conditional auditing Envers persists audit data in reaction to various Hibernate events (e.g. post update, post insert, and - so on), using a series of even listeners from the org.hibernate.envers.event + so on), using a series of even listeners from the org.hibernate.envers.event.spi package. By default, if the Envers jar is in the classpath, the event listeners are auto-registered with Hibernate. @@ -1062,13 +1059,13 @@ query.add(AuditEntity.relatedId("address").eq(relatedEntityId));]]>hibernate.listeners.envers.autoRegister Hibernate property to false. - + Create subclasses for appropriate event listeners. For example, if you want to conditionally audit entity insertions, extend the - org.hibernate.envers.eventEnversPostInsertEventListenerImpl + org.hibernate.envers.event.spi.EnversPostInsertEventListenerImpl class. Place the conditional-auditing logic in the subclasses, call the super method if auditing should be performed. @@ -1076,7 +1073,7 @@ query.add(AuditEntity.relatedId("address").eq(relatedEntityId));]]> Create your own implementation of org.hibernate.integrator.spi.Integrator, - similar to org.hibernate.envers.event.EnversIntegrator. Use your event + similar to org.hibernate.envers.event.spi.EnversIntegrator. Use your event listener classes instead of the default ones. @@ -1398,7 +1395,7 @@ query.add(AuditEntity.relatedId("address").eq(relatedEntityId));]]> - Optionally, you can also override the default values following properties: + Optionally, you can also override the default values using following properties: org.hibernate.envers.audit_strategy_validity_end_rev_field_name @@ -1408,7 +1405,7 @@ query.add(AuditEntity.relatedId("address").eq(relatedEntityId));]]> - For more information, see . + For more information, see . diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/AuditReaderFactory.java b/hibernate-envers/src/main/java/org/hibernate/envers/AuditReaderFactory.java index 773555988b..74302e7fb9 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/AuditReaderFactory.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/AuditReaderFactory.java @@ -27,9 +27,9 @@ import org.hibernate.Session; import org.hibernate.engine.spi.SessionImplementor; -import org.hibernate.envers.event.EnversListener; +import org.hibernate.envers.event.spi.EnversListener; import org.hibernate.envers.exception.AuditException; -import org.hibernate.envers.reader.AuditReaderImpl; +import org.hibernate.envers.internal.reader.AuditReaderImpl; import org.hibernate.event.service.spi.EventListenerRegistry; import org.hibernate.event.spi.EventType; import org.hibernate.event.spi.PostInsertEventListener; diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/ant/AnnotationConfigurationTaskWithEnvers.java b/hibernate-envers/src/main/java/org/hibernate/envers/ant/AnnotationConfigurationTaskWithEnvers.java deleted file mode 100644 index 0d66130a91..0000000000 --- a/hibernate-envers/src/main/java/org/hibernate/envers/ant/AnnotationConfigurationTaskWithEnvers.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Hibernate, Relational Persistence for Idiomatic Java - * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as - * indicated by the @author tags or express copyright attribution - * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. - * - * This copyrighted material is made available to anyone wishing to use, modify, - * copy, or redistribute it subject to the terms and conditions of the GNU - * Lesser General Public License, as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this distribution; if not, write to: - * Free Software Foundation, Inc. - * 51 Franklin Street, Fifth Floor - * Boston, MA 02110-1301 USA - */ -package org.hibernate.envers.ant; -import org.hibernate.cfg.Configuration; -import org.hibernate.envers.configuration.AuditConfiguration; -import org.hibernate.tool.ant.AnnotationConfigurationTask; - -/** - * @author Adam Warski (adam at warski dot org) - */ -public class AnnotationConfigurationTaskWithEnvers extends AnnotationConfigurationTask { - protected void doConfiguration(Configuration configuration) { - super.doConfiguration(configuration); - configuration.buildMappings(); - AuditConfiguration.getFor(configuration); - } -} diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/ant/ConfigurationTaskWithEnvers.java b/hibernate-envers/src/main/java/org/hibernate/envers/ant/ConfigurationTaskWithEnvers.java deleted file mode 100644 index a7ead2364f..0000000000 --- a/hibernate-envers/src/main/java/org/hibernate/envers/ant/ConfigurationTaskWithEnvers.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Hibernate, Relational Persistence for Idiomatic Java - * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as - * indicated by the @author tags or express copyright attribution - * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. - * - * This copyrighted material is made available to anyone wishing to use, modify, - * copy, or redistribute it subject to the terms and conditions of the GNU - * Lesser General Public License, as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this distribution; if not, write to: - * Free Software Foundation, Inc. - * 51 Franklin Street, Fifth Floor - * Boston, MA 02110-1301 USA - */ -package org.hibernate.envers.ant; -import org.hibernate.cfg.Configuration; -import org.hibernate.envers.configuration.AuditConfiguration; -import org.hibernate.tool.ant.ConfigurationTask; - -/** - * @author Adam Warski (adam at warski dot org) - */ -public class ConfigurationTaskWithEnvers extends ConfigurationTask { - protected void doConfiguration(Configuration configuration) { - AuditConfiguration.getFor(configuration); - - super.doConfiguration(configuration); - } -} diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/ant/JPAConfigurationTaskWithEnvers.java b/hibernate-envers/src/main/java/org/hibernate/envers/ant/JPAConfigurationTaskWithEnvers.java deleted file mode 100644 index 89eefb2d94..0000000000 --- a/hibernate-envers/src/main/java/org/hibernate/envers/ant/JPAConfigurationTaskWithEnvers.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Hibernate, Relational Persistence for Idiomatic Java - * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as - * indicated by the @author tags or express copyright attribution - * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. - * - * This copyrighted material is made available to anyone wishing to use, modify, - * copy, or redistribute it subject to the terms and conditions of the GNU - * Lesser General Public License, as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this distribution; if not, write to: - * Free Software Foundation, Inc. - * 51 Franklin Street, Fifth Floor - * Boston, MA 02110-1301 USA - */ -package org.hibernate.envers.ant; -import org.hibernate.cfg.Configuration; -import org.hibernate.envers.configuration.AuditConfiguration; -import org.hibernate.tool.ant.JPAConfigurationTask; - -/** - * @author Adam Warski (adam at warski dot org) - */ -public class JPAConfigurationTaskWithEnvers extends JPAConfigurationTask { - protected void doConfiguration(Configuration configuration) { - AuditConfiguration.getFor(configuration); - - super.doConfiguration(configuration); - } -} diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/configuration/AuditEntitiesConfiguration.java b/hibernate-envers/src/main/java/org/hibernate/envers/configuration/AuditEntitiesConfiguration.java deleted file mode 100644 index e4ebd44dff..0000000000 --- a/hibernate-envers/src/main/java/org/hibernate/envers/configuration/AuditEntitiesConfiguration.java +++ /dev/null @@ -1,185 +0,0 @@ -/* - * Hibernate, Relational Persistence for Idiomatic Java - * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as - * indicated by the @author tags or express copyright attribution - * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. - * - * This copyrighted material is made available to anyone wishing to use, modify, - * copy, or redistribute it subject to the terms and conditions of the GNU - * Lesser General Public License, as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this distribution; if not, write to: - * Free Software Foundation, Inc. - * 51 Franklin Street, Fifth Floor - * Boston, MA 02110-1301 USA - */ -package org.hibernate.envers.configuration; -import java.util.HashMap; -import java.util.Map; -import java.util.Properties; - -import org.hibernate.envers.strategy.DefaultAuditStrategy; - -import static org.hibernate.envers.tools.Tools.getProperty; - -/** - * Configuration of versions entities - names of fields, entities and tables created to store versioning information. - * @author Adam Warski (adam at warski dot org) - * @author Stephanie Pau at Markit Group Plc - */ -public class AuditEntitiesConfiguration { - private final String auditTablePrefix; - private final String auditTableSuffix; - - private final String auditStrategyName; - private final String originalIdPropName; - - private final String revisionFieldName; - private final String revisionNumberPath; - private final String revisionPropBasePath; - - private final String revisionTypePropName; - private final String revisionTypePropType; - - private final String revisionInfoEntityName; - - private final Map customAuditTablesNames; - - private final String revisionEndFieldName; - - private final boolean revisionEndTimestampEnabled; - private final String revisionEndTimestampFieldName; - - public AuditEntitiesConfiguration(Properties properties, String revisionInfoEntityName) { - this.revisionInfoEntityName = revisionInfoEntityName; - - auditTablePrefix = getProperty(properties, - "org.hibernate.envers.audit_table_prefix", - "org.hibernate.envers.auditTablePrefix", - ""); - auditTableSuffix = getProperty(properties, - "org.hibernate.envers.audit_table_suffix", - "org.hibernate.envers.auditTableSuffix", - "_AUD"); - - auditStrategyName = getProperty(properties, - "org.hibernate.envers.audit_strategy", - "org.hibernate.envers.audit_strategy", - DefaultAuditStrategy.class.getName()); - - originalIdPropName = "originalId"; - - revisionFieldName = getProperty(properties, - "org.hibernate.envers.revision_field_name", - "org.hibernate.envers.revisionFieldName", - "REV"); - - revisionTypePropName = getProperty(properties, - "org.hibernate.envers.revision_type_field_name", - "org.hibernate.envers.revisionTypeFieldName", - "REVTYPE"); - revisionTypePropType = "byte"; - - revisionEndFieldName = getProperty(properties, - "org.hibernate.envers.audit_strategy_validity_end_rev_field_name", - "org.hibernate.envers.audit_strategy_valid_time_end_name", - "REVEND"); - - String revisionEndTimestampEnabledStr = getProperty(properties, - "org.hibernate.envers.audit_strategy_validity_store_revend_timestamp", - "org.hibernate.envers.audit_strategy_validity_store_revend_timestamp", - "false"); - revisionEndTimestampEnabled = Boolean.parseBoolean(revisionEndTimestampEnabledStr); - - if (revisionEndTimestampEnabled) { - revisionEndTimestampFieldName = getProperty(properties, - "org.hibernate.envers.audit_strategy_validity_revend_timestamp_field_name", - "org.hibernate.envers.audit_strategy_validity_revend_timestamp_field_name", - "REVEND_TSTMP"); - } else { - revisionEndTimestampFieldName = null; - } - - customAuditTablesNames = new HashMap(); - - revisionNumberPath = originalIdPropName + "." + revisionFieldName + ".id"; - revisionPropBasePath = originalIdPropName + "." + revisionFieldName + "."; - } - - public String getOriginalIdPropName() { - return originalIdPropName; - } - - public String getRevisionFieldName() { - return revisionFieldName; - } - - public boolean isRevisionEndTimestampEnabled() { - return revisionEndTimestampEnabled; - } - - public String getRevisionEndTimestampFieldName() { - return revisionEndTimestampFieldName; - } - - public String getRevisionNumberPath() { - return revisionNumberPath; - } - - /** - * @param propertyName Property of the revision entity. - * @return A path to the given property of the revision entity associated with an audit entity. - */ - public String getRevisionPropPath(String propertyName) { - return revisionPropBasePath + propertyName; - } - - public String getRevisionTypePropName() { - return revisionTypePropName; - } - - public String getRevisionTypePropType() { - return revisionTypePropType; - } - - public String getRevisionInfoEntityName() { - return revisionInfoEntityName; - } - - // - - public void addCustomAuditTableName(String entityName, String tableName) { - customAuditTablesNames.put(entityName, tableName); - } - - // - - public String getAuditEntityName(String entityName) { - return auditTablePrefix + entityName + auditTableSuffix; - } - - public String getAuditTableName(String entityName, String tableName) { - String customHistoryTableName = customAuditTablesNames.get(entityName); - if (customHistoryTableName == null) { - return auditTablePrefix + tableName + auditTableSuffix; - } - - return customHistoryTableName; - } - - public String getAuditStrategyName() { - return auditStrategyName; - } - - public String getRevisionEndFieldName() { - return revisionEndFieldName; - } -} diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/configuration/EnversSettings.java b/hibernate-envers/src/main/java/org/hibernate/envers/configuration/EnversSettings.java new file mode 100644 index 0000000000..8b8d889156 --- /dev/null +++ b/hibernate-envers/src/main/java/org/hibernate/envers/configuration/EnversSettings.java @@ -0,0 +1,102 @@ +package org.hibernate.envers.configuration; + +import org.hibernate.envers.strategy.DefaultAuditStrategy; + +/** + * Configuration property names. + * + * @author Lukasz Antoniak (lukasz dot antoniak at gmail dot com) + */ +public interface EnversSettings { + /** + * Triggers revision generation when not-owned relation field changes. Defaults to {@code true}. + */ + public static final String REVISION_ON_COLLECTION_CHANGE = "org.hibernate.envers.revision_on_collection_change"; + + /** + * Treats optimistic locking properties as unversioned. Defaults to {@code true}. + */ + public static final String DO_NOT_AUDIT_OPTIMISTIC_LOCKING_FIELD = "org.hibernate.envers.do_not_audit_optimistic_locking_field"; + + /** + * Indicates whether entity data should be stored during removal. Defaults to {@code false}. + */ + public static final String STORE_DATA_AT_DELETE = "org.hibernate.envers.store_data_at_delete"; + + /** + * Default name of the schema containing audit tables. + */ + public static final String DEFAULT_SCHEMA = "org.hibernate.envers.default_schema"; + + /** + * Default name of the catalog containing audit tables. + */ + public static final String DEFAULT_CATALOG = "org.hibernate.envers.default_catalog"; + + /** + * Track entity names that have been changed during each revision. Defaults to {@code false}. + */ + public static final String TRACK_ENTITIES_CHANGED_IN_REVISION = "org.hibernate.envers.track_entities_changed_in_revision"; + + /** + * Use revision entity with native identifier generator. Defaults to {@code true} for backward compatibility. + */ + public static final String USE_REVISION_ENTITY_WITH_NATIVE_ID = "org.hibernate.envers.use_revision_entity_with_native_id"; + + /** + * Globally activates modified properties flag feature. Defaults to {@code false}. + */ + public static final String GLOBAL_WITH_MODIFIED_FLAG = "org.hibernate.envers.global_with_modified_flag"; + + /** + * Suffix of modified flag columns. Defaults to {@literal _MOD}. + */ + public static final String MODIFIED_FLAG_SUFFIX = "org.hibernate.envers.modified_flag_suffix"; + + /** + * Fully qualified class name of user defined revision listener. + */ + public static final String REVISION_LISTENER = "org.hibernate.envers.revision_listener"; + + /** + * Audit table prefix. Empty by default. + */ + public static final String AUDIT_TABLE_PREFIX = "org.hibernate.envers.audit_table_prefix"; + + /** + * Audit table suffix. Defaults to {@literal _AUD}. + */ + public static final String AUDIT_TABLE_SUFFIX = "org.hibernate.envers.audit_table_suffix"; + + /** + * Audit strategy. Defaults to {@link DefaultAuditStrategy}. + */ + public static final String AUDIT_STRATEGY = "org.hibernate.envers.audit_strategy"; + + /** + * Revision field name. Defaults to {@literal REV}. + */ + public static final String REVISION_FIELD_NAME = "org.hibernate.envers.revision_field_name"; + + /** + * Revision type field name. Defaults to {@literal REVTYPE}. + */ + public static final String REVISION_TYPE_FIELD_NAME = "org.hibernate.envers.revision_type_field_name"; + + /** + * Column name that will hold the end revision number in audit entities. Defaults to {@literal REVEND}. + */ + public static final String AUDIT_STRATEGY_VALIDITY_END_REV_FIELD_NAME = "org.hibernate.envers.audit_strategy_validity_end_rev_field_name"; + + /** + * Store the timestamp of the end revision, until which the data was valid, + * in addition to the end revision itself. Defaults to {@code false}. + */ + public static final String AUDIT_STRATEGY_VALIDITY_STORE_REVEND_TIMESTAMP = "org.hibernate.envers.audit_strategy_validity_store_revend_timestamp"; + + /** + * Column name of the timestamp of the end revision until which the data was valid. + * Defaults to {@literal REVEND_TSTMP}. + */ + public static final String AUDIT_STRATEGY_VALIDITY_REVEND_TIMESTAMP_FIELD_NAME = "org.hibernate.envers.audit_strategy_validity_revend_timestamp_field_name"; +} diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/configuration/GlobalConfiguration.java b/hibernate-envers/src/main/java/org/hibernate/envers/configuration/GlobalConfiguration.java deleted file mode 100644 index 34f3d51f3f..0000000000 --- a/hibernate-envers/src/main/java/org/hibernate/envers/configuration/GlobalConfiguration.java +++ /dev/null @@ -1,198 +0,0 @@ -/* - * Hibernate, Relational Persistence for Idiomatic Java - * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as - * indicated by the @author tags or express copyright attribution - * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. - * - * This copyrighted material is made available to anyone wishing to use, modify, - * copy, or redistribute it subject to the terms and conditions of the GNU - * Lesser General Public License, as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this distribution; if not, write to: - * Free Software Foundation, Inc. - * 51 Franklin Street, Fifth Floor - * Boston, MA 02110-1301 USA - */ -package org.hibernate.envers.configuration; -import static org.hibernate.envers.tools.Tools.getProperty; - -import java.util.Properties; - -import org.hibernate.MappingException; -import org.hibernate.envers.RevisionListener; -import org.hibernate.internal.util.ReflectHelper; - -/** - * @author Adam Warski (adam at warski dot org) - * @author Nicolas Doroskevich - * @author Lukasz Antoniak (lukasz dot antoniak at gmail dot com) - * @author Michal Skowronek (mskowr at o2 dot pl) - */ -public class GlobalConfiguration { - public static final String GLOBAL_WITH_MODIFIED_FLAG_PROPERTY = "org.hibernate.envers.global_with_modified_flag"; - public static final String MODIFIED_FLAG_SUFFIX_PROPERTY = "org.hibernate.envers.modified_flag_suffix"; - public static final String DEFAULT_MODIFIED_FLAG_SUFFIX = "_MOD"; - - // Should a revision be generated when a not-owned relation field changes - private final boolean generateRevisionsForCollections; - - // Should the optimistic locking property of an entity be considered unversioned - private final boolean doNotAuditOptimisticLockingField; - - // Should entity data be stored when it is deleted - private final boolean storeDataAtDelete; - - // The default name of the schema of audit tables. - private final String defaultSchemaName; - - // The default name of the catalog of the audit tables. - private final String defaultCatalogName; - - // Should Envers track (persist) entity names that have been changed during each revision. - private boolean trackEntitiesChangedInRevisionEnabled; - - // Revision listener class name. - private final Class revisionListenerClass; - - // Should Envers use modified property flags by default - private boolean globalWithModifiedFlag; - - // Indicates that user defined global behavior for modified flags feature - private boolean hasGlobalSettingForWithModifiedFlag; - - // Suffix to be used for modified flags columns - private String modifiedFlagSuffix; - - // Use revision entity with native id generator - private final boolean useRevisionEntityWithNativeId; - - /* - Which operator to use in correlated subqueries (when we want a property to be equal to the result of - a correlated subquery, for example: e.p (select max(e2.p) where e2.p2 = e.p2 ...). - Normally, this should be "=". However, HSQLDB has an issue related to that, so as a workaround, - "in" is used. See {@link org.hibernate.envers.test.various.HsqlTest}. - */ - private final String correlatedSubqueryOperator; - - public GlobalConfiguration(Properties properties) { - String generateRevisionsForCollectionsStr = getProperty(properties, - "org.hibernate.envers.revision_on_collection_change", - "org.hibernate.envers.revisionOnCollectionChange", - "true"); - generateRevisionsForCollections = Boolean.parseBoolean(generateRevisionsForCollectionsStr); - - String ignoreOptimisticLockingPropertyStr = getProperty(properties, - "org.hibernate.envers.do_not_audit_optimistic_locking_field", - "org.hibernate.envers.doNotAuditOptimisticLockingField", - "true"); - doNotAuditOptimisticLockingField = Boolean.parseBoolean(ignoreOptimisticLockingPropertyStr); - - String storeDataDeletedEntityStr = getProperty(properties, - "org.hibernate.envers.store_data_at_delete", - "org.hibernate.envers.storeDataAtDelete", - "false"); - storeDataAtDelete = Boolean.parseBoolean(storeDataDeletedEntityStr); - - defaultSchemaName = properties.getProperty("org.hibernate.envers.default_schema", null); - defaultCatalogName = properties.getProperty("org.hibernate.envers.default_catalog", null); - - correlatedSubqueryOperator = "org.hibernate.dialect.HSQLDialect".equals( - properties.getProperty("hibernate.dialect")) ? "in" : "="; - - String trackEntitiesChangedInRevisionEnabledStr = getProperty(properties, - "org.hibernate.envers.track_entities_changed_in_revision", - "org.hibernate.envers.track_entities_changed_in_revision", - "false"); - trackEntitiesChangedInRevisionEnabled = Boolean.parseBoolean(trackEntitiesChangedInRevisionEnabledStr); - - String useRevisionEntityWithNativeIdStr = getProperty(properties, - "org.hibernate.envers.use_revision_entity_with_native_id", - "org.hibernate.envers.use_revision_entity_with_native_id", - "true"); - useRevisionEntityWithNativeId = Boolean.parseBoolean(useRevisionEntityWithNativeIdStr); - - hasGlobalSettingForWithModifiedFlag = - properties.getProperty(GLOBAL_WITH_MODIFIED_FLAG_PROPERTY) != null; - String usingModifiedFlagStr = getProperty(properties, - GLOBAL_WITH_MODIFIED_FLAG_PROPERTY, - GLOBAL_WITH_MODIFIED_FLAG_PROPERTY, - "false"); - globalWithModifiedFlag = Boolean.parseBoolean(usingModifiedFlagStr); - - modifiedFlagSuffix = - getProperty(properties, MODIFIED_FLAG_SUFFIX_PROPERTY, - MODIFIED_FLAG_SUFFIX_PROPERTY, - DEFAULT_MODIFIED_FLAG_SUFFIX); - - String revisionListenerClassName = properties.getProperty("org.hibernate.envers.revision_listener", null); - if (revisionListenerClassName != null) { - try { - revisionListenerClass = (Class) ReflectHelper.classForName(revisionListenerClassName); - } catch (ClassNotFoundException e) { - throw new MappingException("Revision listener class not found: " + revisionListenerClassName + ".", e); - } - } else { - revisionListenerClass = null; - } - } - - public boolean isGenerateRevisionsForCollections() { - return generateRevisionsForCollections; - } - - public boolean isDoNotAuditOptimisticLockingField() { - return doNotAuditOptimisticLockingField; - } - - public String getCorrelatedSubqueryOperator() { - return correlatedSubqueryOperator; - } - - public boolean isStoreDataAtDelete() { - return storeDataAtDelete; - } - - public String getDefaultSchemaName() { - return defaultSchemaName; - } - - public String getDefaultCatalogName() { - return defaultCatalogName; - } - - public boolean isTrackEntitiesChangedInRevisionEnabled() { - return trackEntitiesChangedInRevisionEnabled; - } - - public void setTrackEntitiesChangedInRevisionEnabled(boolean trackEntitiesChangedInRevisionEnabled) { - this.trackEntitiesChangedInRevisionEnabled = trackEntitiesChangedInRevisionEnabled; - } - - public Class getRevisionListenerClass() { - return revisionListenerClass; - } - - public boolean hasSettingForUsingModifiedFlag() { - return hasGlobalSettingForWithModifiedFlag; - } - - public boolean isGlobalWithModifiedFlag() { - return globalWithModifiedFlag; - } - - public String getModifiedFlagSuffix() { - return modifiedFlagSuffix; - } - - public boolean isUseRevisionEntityWithNativeId() { - return useRevisionEntityWithNativeId; - } -} diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/AuditEntitiesConfiguration.java b/hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/AuditEntitiesConfiguration.java new file mode 100644 index 0000000000..ac8ca6d5f6 --- /dev/null +++ b/hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/AuditEntitiesConfiguration.java @@ -0,0 +1,170 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * indicated by the @author tags or express copyright attribution + * statements applied by the authors. All third-party contributions are + * distributed under license by Red Hat Middleware LLC. + * + * This copyrighted material is made available to anyone wishing to use, modify, + * copy, or redistribute it subject to the terms and conditions of the GNU + * Lesser General Public License, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this distribution; if not, write to: + * Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor + * Boston, MA 02110-1301 USA + */ +package org.hibernate.envers.configuration.internal; + +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; + +import org.hibernate.envers.configuration.EnversSettings; +import org.hibernate.envers.strategy.DefaultAuditStrategy; +import org.hibernate.internal.util.config.ConfigurationHelper; + +/** + * Configuration of versions entities - names of fields, entities and tables created to store versioning information. + * + * @author Adam Warski (adam at warski dot org) + * @author Stephanie Pau at Markit Group Plc + */ +public class AuditEntitiesConfiguration { + private final String auditTablePrefix; + private final String auditTableSuffix; + + private final String auditStrategyName; + private final String originalIdPropName; + + private final String revisionFieldName; + private final String revisionNumberPath; + private final String revisionPropBasePath; + + private final String revisionTypePropName; + private final String revisionTypePropType; + + private final String revisionInfoEntityName; + + private final Map customAuditTablesNames; + + private final String revisionEndFieldName; + + private final boolean revisionEndTimestampEnabled; + private final String revisionEndTimestampFieldName; + + public AuditEntitiesConfiguration(Properties properties, String revisionInfoEntityName) { + this.revisionInfoEntityName = revisionInfoEntityName; + + auditTablePrefix = ConfigurationHelper.getString( EnversSettings.AUDIT_TABLE_PREFIX, properties, "" ); + auditTableSuffix = ConfigurationHelper.getString( EnversSettings.AUDIT_TABLE_SUFFIX, properties, "_AUD" ); + + auditStrategyName = ConfigurationHelper.getString( + EnversSettings.AUDIT_STRATEGY, properties, DefaultAuditStrategy.class.getName() + ); + + originalIdPropName = "originalId"; + + revisionFieldName = ConfigurationHelper.getString( EnversSettings.REVISION_FIELD_NAME, properties, "REV" ); + + revisionTypePropName = ConfigurationHelper.getString( + EnversSettings.REVISION_TYPE_FIELD_NAME, properties, "REVTYPE" + ); + revisionTypePropType = "byte"; + + revisionEndFieldName = ConfigurationHelper.getString( + EnversSettings.AUDIT_STRATEGY_VALIDITY_END_REV_FIELD_NAME, properties, "REVEND" + ); + + revisionEndTimestampEnabled = ConfigurationHelper.getBoolean( + EnversSettings.AUDIT_STRATEGY_VALIDITY_STORE_REVEND_TIMESTAMP, properties, false + ); + + if ( revisionEndTimestampEnabled ) { + revisionEndTimestampFieldName = ConfigurationHelper.getString( + EnversSettings.AUDIT_STRATEGY_VALIDITY_REVEND_TIMESTAMP_FIELD_NAME, properties, "REVEND_TSTMP" + ); + } + else { + revisionEndTimestampFieldName = null; + } + + customAuditTablesNames = new HashMap(); + + revisionNumberPath = originalIdPropName + "." + revisionFieldName + ".id"; + revisionPropBasePath = originalIdPropName + "." + revisionFieldName + "."; + } + + public String getOriginalIdPropName() { + return originalIdPropName; + } + + public String getRevisionFieldName() { + return revisionFieldName; + } + + public boolean isRevisionEndTimestampEnabled() { + return revisionEndTimestampEnabled; + } + + public String getRevisionEndTimestampFieldName() { + return revisionEndTimestampFieldName; + } + + public String getRevisionNumberPath() { + return revisionNumberPath; + } + + /** + * @param propertyName Property of the revision entity. + * + * @return A path to the given property of the revision entity associated with an audit entity. + */ + public String getRevisionPropPath(String propertyName) { + return revisionPropBasePath + propertyName; + } + + public String getRevisionTypePropName() { + return revisionTypePropName; + } + + public String getRevisionTypePropType() { + return revisionTypePropType; + } + + public String getRevisionInfoEntityName() { + return revisionInfoEntityName; + } + + public void addCustomAuditTableName(String entityName, String tableName) { + customAuditTablesNames.put( entityName, tableName ); + } + + public String getAuditEntityName(String entityName) { + return auditTablePrefix + entityName + auditTableSuffix; + } + + public String getAuditTableName(String entityName, String tableName) { + final String customHistoryTableName = customAuditTablesNames.get( entityName ); + if ( customHistoryTableName == null ) { + return auditTablePrefix + tableName + auditTableSuffix; + } + + return customHistoryTableName; + } + + public String getAuditStrategyName() { + return auditStrategyName; + } + + public String getRevisionEndFieldName() { + return revisionEndFieldName; + } +} diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/configuration/ClassesAuditingData.java b/hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/ClassesAuditingData.java similarity index 93% rename from hibernate-envers/src/main/java/org/hibernate/envers/configuration/ClassesAuditingData.java rename to hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/ClassesAuditingData.java index 9b24956811..d9a95069f3 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/configuration/ClassesAuditingData.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/ClassesAuditingData.java @@ -1,4 +1,4 @@ -package org.hibernate.envers.configuration; +package org.hibernate.envers.configuration.internal; import java.util.Collection; import java.util.HashMap; import java.util.LinkedHashMap; @@ -7,10 +7,10 @@ import org.jboss.logging.Logger; import org.hibernate.MappingException; -import org.hibernate.envers.configuration.metadata.reader.ClassAuditingData; -import org.hibernate.envers.configuration.metadata.reader.PropertyAuditingData; +import org.hibernate.envers.configuration.internal.metadata.reader.ClassAuditingData; +import org.hibernate.envers.configuration.internal.metadata.reader.PropertyAuditingData; import org.hibernate.envers.internal.EnversMessageLogger; -import org.hibernate.envers.tools.MappingTools; +import org.hibernate.envers.internal.tools.MappingTools; import org.hibernate.mapping.PersistentClass; /** diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/configuration/EntitiesConfigurator.java b/hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/EntitiesConfigurator.java similarity index 88% rename from hibernate-envers/src/main/java/org/hibernate/envers/configuration/EntitiesConfigurator.java rename to hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/EntitiesConfigurator.java index 7ea58c68b1..a12f588edb 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/configuration/EntitiesConfigurator.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/EntitiesConfigurator.java @@ -21,7 +21,8 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.configuration; +package org.hibernate.envers.configuration.internal; + import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.PrintWriter; @@ -39,16 +40,17 @@ import org.hibernate.MappingException; import org.hibernate.annotations.common.reflection.ReflectionManager; +import org.hibernate.boot.registry.classloading.spi.ClassLoaderService; import org.hibernate.cfg.Configuration; -import org.hibernate.envers.configuration.metadata.AuditEntityNameRegister; -import org.hibernate.envers.configuration.metadata.AuditMetadataGenerator; -import org.hibernate.envers.configuration.metadata.EntityXmlMappingData; -import org.hibernate.envers.configuration.metadata.reader.AnnotationsMetadataReader; -import org.hibernate.envers.configuration.metadata.reader.ClassAuditingData; -import org.hibernate.envers.entities.EntitiesConfigurations; +import org.hibernate.envers.configuration.internal.metadata.AuditEntityNameRegister; +import org.hibernate.envers.configuration.internal.metadata.AuditMetadataGenerator; +import org.hibernate.envers.configuration.internal.metadata.EntityXmlMappingData; +import org.hibernate.envers.configuration.internal.metadata.reader.AnnotationsMetadataReader; +import org.hibernate.envers.configuration.internal.metadata.reader.ClassAuditingData; +import org.hibernate.envers.internal.entities.EntitiesConfigurations; +import org.hibernate.envers.internal.tools.StringTools; +import org.hibernate.envers.internal.tools.graph.GraphTopologicalSort; import org.hibernate.envers.strategy.AuditStrategy; -import org.hibernate.envers.tools.StringTools; -import org.hibernate.envers.tools.graph.GraphTopologicalSort; import org.hibernate.mapping.PersistentClass; /** @@ -57,7 +59,7 @@ public class EntitiesConfigurator { public EntitiesConfigurations configure(Configuration cfg, ReflectionManager reflectionManager, GlobalConfiguration globalCfg, AuditEntitiesConfiguration verEntCfg, - AuditStrategy auditStrategy, + AuditStrategy auditStrategy, ClassLoaderService classLoaderService, Document revisionInfoXmlMapping, Element revisionInfoRelationMapping) { // Creating a name register to capture all audit entity names created. AuditEntityNameRegister auditEntityNameRegister = new AuditEntityNameRegister(); @@ -85,7 +87,7 @@ public EntitiesConfigurations configure(Configuration cfg, ReflectionManager ref classesAuditingData.updateCalculatedFields(); AuditMetadataGenerator auditMetaGen = new AuditMetadataGenerator(cfg, globalCfg, verEntCfg, auditStrategy, - revisionInfoRelationMapping, auditEntityNameRegister); + classLoaderService, revisionInfoRelationMapping, auditEntityNameRegister); // First pass for (Map.Entry pcDatasEntry : classesAuditingData.getAllClassAuditedData()) { diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/GlobalConfiguration.java b/hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/GlobalConfiguration.java new file mode 100644 index 0000000000..295f9d4585 --- /dev/null +++ b/hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/GlobalConfiguration.java @@ -0,0 +1,184 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * indicated by the @author tags or express copyright attribution + * statements applied by the authors. All third-party contributions are + * distributed under license by Red Hat Middleware LLC. + * + * This copyrighted material is made available to anyone wishing to use, modify, + * copy, or redistribute it subject to the terms and conditions of the GNU + * Lesser General Public License, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this distribution; if not, write to: + * Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor + * Boston, MA 02110-1301 USA + */ +package org.hibernate.envers.configuration.internal; + +import java.util.Properties; + +import org.hibernate.MappingException; +import org.hibernate.boot.registry.classloading.spi.ClassLoaderService; +import org.hibernate.boot.registry.classloading.spi.ClassLoadingException; +import org.hibernate.cfg.Environment; +import org.hibernate.dialect.HSQLDialect; +import org.hibernate.envers.RevisionListener; +import org.hibernate.envers.configuration.EnversSettings; +import org.hibernate.envers.internal.tools.ReflectionTools; +import org.hibernate.internal.util.config.ConfigurationHelper; + +/** + * @author Adam Warski (adam at warski dot org) + * @author Nicolas Doroskevich + * @author Lukasz Antoniak (lukasz dot antoniak at gmail dot com) + * @author Michal Skowronek (mskowr at o2 dot pl) + */ +public class GlobalConfiguration { + // Should a revision be generated when a not-owned relation field changes + private final boolean generateRevisionsForCollections; + + // Should the optimistic locking property of an entity be considered unversioned + private final boolean doNotAuditOptimisticLockingField; + + // Should entity data be stored when it is deleted + private final boolean storeDataAtDelete; + + // The default name of the schema of audit tables. + private final String defaultSchemaName; + + // The default name of the catalog of the audit tables. + private final String defaultCatalogName; + + // Should Envers track (persist) entity names that have been changed during each revision. + private boolean trackEntitiesChangedInRevision; + + // Revision listener class name. + private final Class revisionListenerClass; + + // Should Envers use modified property flags by default + private boolean globalWithModifiedFlag; + + // Indicates that user defined global behavior for modified flags feature + private boolean hasGlobalSettingForWithModifiedFlag; + + // Suffix to be used for modified flags columns + private String modifiedFlagSuffix; + + // Use revision entity with native id generator + private final boolean useRevisionEntityWithNativeId; + + /* + Which operator to use in correlated subqueries (when we want a property to be equal to the result of + a correlated subquery, for example: e.p (select max(e2.p) where e2.p2 = e.p2 ...). + Normally, this should be "=". However, HSQLDB has an issue related to that, so as a workaround, + "in" is used. See {@link org.hibernate.envers.test.various.HsqlTest}. + */ + private final String correlatedSubqueryOperator; + + public GlobalConfiguration(Properties properties, ClassLoaderService classLoaderService) { + generateRevisionsForCollections = ConfigurationHelper.getBoolean( + EnversSettings.REVISION_ON_COLLECTION_CHANGE, properties, true + ); + + doNotAuditOptimisticLockingField = ConfigurationHelper.getBoolean( + EnversSettings.DO_NOT_AUDIT_OPTIMISTIC_LOCKING_FIELD, properties, true + ); + + storeDataAtDelete = ConfigurationHelper.getBoolean( EnversSettings.STORE_DATA_AT_DELETE, properties, false ); + + defaultSchemaName = properties.getProperty( EnversSettings.DEFAULT_SCHEMA, null ); + defaultCatalogName = properties.getProperty( EnversSettings.DEFAULT_CATALOG, null ); + + correlatedSubqueryOperator = HSQLDialect.class.getName() + .equals( properties.get( Environment.DIALECT ) ) ? "in" : "="; + + trackEntitiesChangedInRevision = ConfigurationHelper.getBoolean( + EnversSettings.TRACK_ENTITIES_CHANGED_IN_REVISION, properties, false + ); + + useRevisionEntityWithNativeId = ConfigurationHelper.getBoolean( + EnversSettings.USE_REVISION_ENTITY_WITH_NATIVE_ID, properties, true + ); + + hasGlobalSettingForWithModifiedFlag = properties.get( EnversSettings.GLOBAL_WITH_MODIFIED_FLAG ) != null; + globalWithModifiedFlag = ConfigurationHelper.getBoolean( + EnversSettings.GLOBAL_WITH_MODIFIED_FLAG, properties, false + ); + modifiedFlagSuffix = ConfigurationHelper.getString( + EnversSettings.MODIFIED_FLAG_SUFFIX, properties, "_MOD" + ); + + String revisionListenerClassName = properties.getProperty( EnversSettings.REVISION_LISTENER, null ); + if ( revisionListenerClassName != null ) { + try { + revisionListenerClass = ReflectionTools.loadClass( revisionListenerClassName, classLoaderService ); + } + catch ( ClassLoadingException e ) { + throw new MappingException( "Revision listener class not found: " + revisionListenerClassName + ".", e ); + } + } + else { + revisionListenerClass = null; + } + } + + public boolean isGenerateRevisionsForCollections() { + return generateRevisionsForCollections; + } + + public boolean isDoNotAuditOptimisticLockingField() { + return doNotAuditOptimisticLockingField; + } + + public String getCorrelatedSubqueryOperator() { + return correlatedSubqueryOperator; + } + + public boolean isStoreDataAtDelete() { + return storeDataAtDelete; + } + + public String getDefaultSchemaName() { + return defaultSchemaName; + } + + public String getDefaultCatalogName() { + return defaultCatalogName; + } + + public boolean isTrackEntitiesChangedInRevision() { + return trackEntitiesChangedInRevision; + } + + public void setTrackEntitiesChangedInRevision(boolean trackEntitiesChangedInRevision) { + this.trackEntitiesChangedInRevision = trackEntitiesChangedInRevision; + } + + public Class getRevisionListenerClass() { + return revisionListenerClass; + } + + public boolean hasSettingForUsingModifiedFlag() { + return hasGlobalSettingForWithModifiedFlag; + } + + public boolean isGlobalWithModifiedFlag() { + return globalWithModifiedFlag; + } + + public String getModifiedFlagSuffix() { + return modifiedFlagSuffix; + } + + public boolean isUseRevisionEntityWithNativeId() { + return useRevisionEntityWithNativeId; + } +} diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/configuration/PersistentClassGraphDefiner.java b/hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/PersistentClassGraphDefiner.java similarity index 94% rename from hibernate-envers/src/main/java/org/hibernate/envers/configuration/PersistentClassGraphDefiner.java rename to hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/PersistentClassGraphDefiner.java index fc116123df..f82ef769a5 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/configuration/PersistentClassGraphDefiner.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/PersistentClassGraphDefiner.java @@ -21,14 +21,14 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.configuration; +package org.hibernate.envers.configuration.internal; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import org.hibernate.cfg.Configuration; -import org.hibernate.envers.tools.Tools; -import org.hibernate.envers.tools.graph.GraphDefiner; +import org.hibernate.envers.internal.tools.Tools; +import org.hibernate.envers.internal.tools.graph.GraphDefiner; import org.hibernate.mapping.PersistentClass; /** diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/configuration/RevisionInfoConfiguration.java b/hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/RevisionInfoConfiguration.java similarity index 83% rename from hibernate-envers/src/main/java/org/hibernate/envers/configuration/RevisionInfoConfiguration.java rename to hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/RevisionInfoConfiguration.java index 02ac460ba7..7e14efa32b 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/configuration/RevisionInfoConfiguration.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/RevisionInfoConfiguration.java @@ -21,7 +21,7 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.configuration; +package org.hibernate.envers.configuration.internal; import java.util.Date; import java.util.Iterator; import java.util.Set; @@ -43,18 +43,18 @@ import org.hibernate.envers.RevisionListener; import org.hibernate.envers.RevisionNumber; import org.hibernate.envers.RevisionTimestamp; -import org.hibernate.envers.configuration.metadata.AuditTableData; -import org.hibernate.envers.configuration.metadata.MetadataTools; +import org.hibernate.envers.configuration.internal.metadata.AuditTableData; +import org.hibernate.envers.configuration.internal.metadata.MetadataTools; import org.hibernate.envers.enhanced.SequenceIdRevisionEntity; import org.hibernate.envers.enhanced.SequenceIdTrackingModifiedEntitiesRevisionEntity; -import org.hibernate.envers.entities.PropertyData; -import org.hibernate.envers.revisioninfo.DefaultRevisionInfoGenerator; -import org.hibernate.envers.revisioninfo.DefaultTrackingModifiedEntitiesRevisionInfoGenerator; -import org.hibernate.envers.revisioninfo.ModifiedEntityNamesReader; -import org.hibernate.envers.revisioninfo.RevisionInfoGenerator; -import org.hibernate.envers.revisioninfo.RevisionInfoNumberReader; -import org.hibernate.envers.revisioninfo.RevisionInfoQueryCreator; -import org.hibernate.envers.tools.MutableBoolean; +import org.hibernate.envers.internal.entities.PropertyData; +import org.hibernate.envers.internal.revisioninfo.DefaultRevisionInfoGenerator; +import org.hibernate.envers.internal.revisioninfo.DefaultTrackingModifiedEntitiesRevisionInfoGenerator; +import org.hibernate.envers.internal.revisioninfo.ModifiedEntityNamesReader; +import org.hibernate.envers.internal.revisioninfo.RevisionInfoGenerator; +import org.hibernate.envers.internal.revisioninfo.RevisionInfoNumberReader; +import org.hibernate.envers.internal.revisioninfo.RevisionInfoQueryCreator; +import org.hibernate.envers.internal.tools.MutableBoolean; import org.hibernate.internal.util.xml.XMLHelper; import org.hibernate.mapping.PersistentClass; import org.hibernate.type.LongType; @@ -106,7 +106,7 @@ private Document generateDefaultRevisionInfoXmlMapping() { revisionInfoTimestampType.getName(), true, false); MetadataTools.addColumn(timestampProperty, "REVTSTMP", null, null, null, null, null, null, false); - if (globalCfg.isTrackEntitiesChangedInRevisionEnabled()) { + if (globalCfg.isTrackEntitiesChangedInRevision()) { generateEntityNamesTrackingTableMapping(class_mapping, "modifiedEntityNames", globalCfg.getDefaultSchemaName(), globalCfg.getDefaultCatalogName(), "REVCHANGES", "REV", "ENTITYNAME", "string"); @@ -297,7 +297,7 @@ public RevisionInfoConfigurationResult configure(Configuration cfg, ReflectionMa revisionInfoClass = pc.getMappedClass(); Class revisionListenerClass = getRevisionListenerClass(revisionEntity.value()); revisionInfoTimestampType = pc.getProperty(revisionInfoTimestampData.getName()).getType(); - if (globalCfg.isTrackEntitiesChangedInRevisionEnabled() + if (globalCfg.isTrackEntitiesChangedInRevision() || (globalCfg.isUseRevisionEntityWithNativeId() && DefaultTrackingModifiedEntitiesRevisionEntity.class.isAssignableFrom(revisionInfoClass)) || (!globalCfg.isUseRevisionEntityWithNativeId() && SequenceIdTrackingModifiedEntitiesRevisionEntity.class.isAssignableFrom(revisionInfoClass)) || modifiedEntityNamesFound.isSet()) { @@ -306,7 +306,7 @@ public RevisionInfoConfigurationResult configure(Configuration cfg, ReflectionMa revisionInfoGenerator = new DefaultTrackingModifiedEntitiesRevisionInfoGenerator(revisionInfoEntityName, revisionInfoClass, revisionListenerClass, revisionInfoTimestampData, isTimestampAsDate(), modifiedEntityNamesData); - globalCfg.setTrackEntitiesChangedInRevisionEnabled(true); + globalCfg.setTrackEntitiesChangedInRevision(true); } else { revisionInfoGenerator = new DefaultRevisionInfoGenerator(revisionInfoEntityName, revisionInfoClass, revisionListenerClass, revisionInfoTimestampData, isTimestampAsDate()); @@ -320,7 +320,7 @@ revisionInfoClass, revisionListenerClass, revisionInfoTimestampData, isTimestamp Class revisionListenerClass = getRevisionListenerClass(RevisionListener.class); if (revisionInfoGenerator == null) { - if (globalCfg.isTrackEntitiesChangedInRevisionEnabled()) { + if (globalCfg.isTrackEntitiesChangedInRevision()) { revisionInfoClass = globalCfg.isUseRevisionEntityWithNativeId() ? DefaultTrackingModifiedEntitiesRevisionEntity.class : SequenceIdTrackingModifiedEntitiesRevisionEntity.class; revisionInfoEntityName = revisionInfoClass.getName(); @@ -341,8 +341,8 @@ revisionInfoClass, revisionListenerClass, revisionInfoTimestampData, isTimestamp revisionInfoTimestampData.getName(), isTimestampAsDate()), generateRevisionInfoRelationMapping(), new RevisionInfoNumberReader(revisionInfoClass, revisionInfoIdData), - globalCfg.isTrackEntitiesChangedInRevisionEnabled() ? new ModifiedEntityNamesReader(revisionInfoClass, modifiedEntityNamesData) - : null, + globalCfg.isTrackEntitiesChangedInRevision() ? new ModifiedEntityNamesReader(revisionInfoClass, modifiedEntityNamesData) + : null, revisionInfoEntityName, revisionInfoClass, revisionInfoTimestampData); } @@ -363,67 +363,3 @@ private Class getRevisionListenerClass(Class revisionInfoClass; - private final PropertyData revisionInfoTimestampData; - - RevisionInfoConfigurationResult(RevisionInfoGenerator revisionInfoGenerator, - Document revisionInfoXmlMapping, RevisionInfoQueryCreator revisionInfoQueryCreator, - Element revisionInfoRelationMapping, RevisionInfoNumberReader revisionInfoNumberReader, - ModifiedEntityNamesReader modifiedEntityNamesReader, String revisionInfoEntityName, - Class revisionInfoClass, PropertyData revisionInfoTimestampData) { - this.revisionInfoGenerator = revisionInfoGenerator; - this.revisionInfoXmlMapping = revisionInfoXmlMapping; - this.revisionInfoQueryCreator = revisionInfoQueryCreator; - this.revisionInfoRelationMapping = revisionInfoRelationMapping; - this.revisionInfoNumberReader = revisionInfoNumberReader; - this.modifiedEntityNamesReader = modifiedEntityNamesReader; - this.revisionInfoEntityName = revisionInfoEntityName; - this.revisionInfoClass = revisionInfoClass; - this.revisionInfoTimestampData = revisionInfoTimestampData; - } - - public RevisionInfoGenerator getRevisionInfoGenerator() { - return revisionInfoGenerator; - } - - public Document getRevisionInfoXmlMapping() { - return revisionInfoXmlMapping; - } - - public RevisionInfoQueryCreator getRevisionInfoQueryCreator() { - return revisionInfoQueryCreator; - } - - public Element getRevisionInfoRelationMapping() { - return revisionInfoRelationMapping; - } - - public RevisionInfoNumberReader getRevisionInfoNumberReader() { - return revisionInfoNumberReader; - } - - public String getRevisionInfoEntityName() { - return revisionInfoEntityName; - } - - public Class getRevisionInfoClass() { - return revisionInfoClass; - } - - public PropertyData getRevisionInfoTimestampData() { - return revisionInfoTimestampData; - } - - public ModifiedEntityNamesReader getModifiedEntityNamesReader() { - return modifiedEntityNamesReader; - } -} diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/RevisionInfoConfigurationResult.java b/hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/RevisionInfoConfigurationResult.java new file mode 100644 index 0000000000..0b89067929 --- /dev/null +++ b/hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/RevisionInfoConfigurationResult.java @@ -0,0 +1,77 @@ +package org.hibernate.envers.configuration.internal; + +import org.dom4j.Document; +import org.dom4j.Element; + +import org.hibernate.envers.internal.entities.PropertyData; +import org.hibernate.envers.internal.revisioninfo.ModifiedEntityNamesReader; +import org.hibernate.envers.internal.revisioninfo.RevisionInfoGenerator; +import org.hibernate.envers.internal.revisioninfo.RevisionInfoNumberReader; +import org.hibernate.envers.internal.revisioninfo.RevisionInfoQueryCreator; + +/** + * @author Lukasz Antoniak (lukasz dot antoniak at gmail dot com) + */ +public class RevisionInfoConfigurationResult { + private final RevisionInfoGenerator revisionInfoGenerator; + private final Document revisionInfoXmlMapping; + private final RevisionInfoQueryCreator revisionInfoQueryCreator; + private final Element revisionInfoRelationMapping; + private final RevisionInfoNumberReader revisionInfoNumberReader; + private final ModifiedEntityNamesReader modifiedEntityNamesReader; + private final String revisionInfoEntityName; + private final Class revisionInfoClass; + private final PropertyData revisionInfoTimestampData; + + RevisionInfoConfigurationResult(RevisionInfoGenerator revisionInfoGenerator, + Document revisionInfoXmlMapping, RevisionInfoQueryCreator revisionInfoQueryCreator, + Element revisionInfoRelationMapping, RevisionInfoNumberReader revisionInfoNumberReader, + ModifiedEntityNamesReader modifiedEntityNamesReader, String revisionInfoEntityName, + Class revisionInfoClass, PropertyData revisionInfoTimestampData) { + this.revisionInfoGenerator = revisionInfoGenerator; + this.revisionInfoXmlMapping = revisionInfoXmlMapping; + this.revisionInfoQueryCreator = revisionInfoQueryCreator; + this.revisionInfoRelationMapping = revisionInfoRelationMapping; + this.revisionInfoNumberReader = revisionInfoNumberReader; + this.modifiedEntityNamesReader = modifiedEntityNamesReader; + this.revisionInfoEntityName = revisionInfoEntityName; + this.revisionInfoClass = revisionInfoClass; + this.revisionInfoTimestampData = revisionInfoTimestampData; + } + + public RevisionInfoGenerator getRevisionInfoGenerator() { + return revisionInfoGenerator; + } + + public Document getRevisionInfoXmlMapping() { + return revisionInfoXmlMapping; + } + + public RevisionInfoQueryCreator getRevisionInfoQueryCreator() { + return revisionInfoQueryCreator; + } + + public Element getRevisionInfoRelationMapping() { + return revisionInfoRelationMapping; + } + + public RevisionInfoNumberReader getRevisionInfoNumberReader() { + return revisionInfoNumberReader; + } + + public String getRevisionInfoEntityName() { + return revisionInfoEntityName; + } + + public Class getRevisionInfoClass() { + return revisionInfoClass; + } + + public PropertyData getRevisionInfoTimestampData() { + return revisionInfoTimestampData; + } + + public ModifiedEntityNamesReader getModifiedEntityNamesReader() { + return modifiedEntityNamesReader; + } +} diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/configuration/metadata/AuditEntityNameRegister.java b/hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/metadata/AuditEntityNameRegister.java similarity index 96% rename from hibernate-envers/src/main/java/org/hibernate/envers/configuration/metadata/AuditEntityNameRegister.java rename to hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/metadata/AuditEntityNameRegister.java index 53eb159a44..c2d00fdcf6 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/configuration/metadata/AuditEntityNameRegister.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/metadata/AuditEntityNameRegister.java @@ -1,4 +1,4 @@ -package org.hibernate.envers.configuration.metadata; +package org.hibernate.envers.configuration.internal.metadata; import java.util.HashSet; import java.util.Set; diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/configuration/metadata/AuditMetadataGenerator.java b/hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/metadata/AuditMetadataGenerator.java similarity index 95% rename from hibernate-envers/src/main/java/org/hibernate/envers/configuration/metadata/AuditMetadataGenerator.java rename to hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/metadata/AuditMetadataGenerator.java index 8695b69503..a0994f789e 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/configuration/metadata/AuditMetadataGenerator.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/metadata/AuditMetadataGenerator.java @@ -21,7 +21,8 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.configuration.metadata; +package org.hibernate.envers.configuration.internal.metadata; + import java.util.HashMap; import java.util.Iterator; import java.util.Map; @@ -30,23 +31,24 @@ import org.jboss.logging.Logger; import org.hibernate.MappingException; +import org.hibernate.boot.registry.classloading.spi.ClassLoaderService; import org.hibernate.cfg.Configuration; import org.hibernate.envers.RelationTargetAuditMode; -import org.hibernate.envers.configuration.AuditEntitiesConfiguration; -import org.hibernate.envers.configuration.GlobalConfiguration; -import org.hibernate.envers.configuration.metadata.reader.ClassAuditingData; -import org.hibernate.envers.configuration.metadata.reader.PropertyAuditingData; -import org.hibernate.envers.entities.EntityConfiguration; -import org.hibernate.envers.entities.IdMappingData; -import org.hibernate.envers.entities.mapper.CompositeMapperBuilder; -import org.hibernate.envers.entities.mapper.ExtendedPropertyMapper; -import org.hibernate.envers.entities.mapper.MultiPropertyMapper; -import org.hibernate.envers.entities.mapper.SubclassPropertyMapper; +import org.hibernate.envers.configuration.internal.AuditEntitiesConfiguration; +import org.hibernate.envers.configuration.internal.GlobalConfiguration; +import org.hibernate.envers.configuration.internal.metadata.reader.ClassAuditingData; +import org.hibernate.envers.configuration.internal.metadata.reader.PropertyAuditingData; import org.hibernate.envers.internal.EnversMessageLogger; +import org.hibernate.envers.internal.entities.EntityConfiguration; +import org.hibernate.envers.internal.entities.IdMappingData; +import org.hibernate.envers.internal.entities.mapper.CompositeMapperBuilder; +import org.hibernate.envers.internal.entities.mapper.ExtendedPropertyMapper; +import org.hibernate.envers.internal.entities.mapper.MultiPropertyMapper; +import org.hibernate.envers.internal.entities.mapper.SubclassPropertyMapper; +import org.hibernate.envers.internal.tools.StringTools; +import org.hibernate.envers.internal.tools.Triple; import org.hibernate.envers.strategy.AuditStrategy; import org.hibernate.envers.strategy.ValidityAuditStrategy; -import org.hibernate.envers.tools.StringTools; -import org.hibernate.envers.tools.Triple; import org.hibernate.mapping.Collection; import org.hibernate.mapping.Join; import org.hibernate.mapping.OneToOne; @@ -78,6 +80,7 @@ public final class AuditMetadataGenerator { private final GlobalConfiguration globalCfg; private final AuditEntitiesConfiguration verEntCfg; private final AuditStrategy auditStrategy; + private final ClassLoaderService classLoaderService; private final Element revisionInfoRelationMapping; /* @@ -101,13 +104,14 @@ public final class AuditMetadataGenerator { public AuditMetadataGenerator(Configuration cfg, GlobalConfiguration globalCfg, AuditEntitiesConfiguration verEntCfg, - AuditStrategy auditStrategy, + AuditStrategy auditStrategy, ClassLoaderService classLoaderService, Element revisionInfoRelationMapping, AuditEntityNameRegister auditEntityNameRegister) { this.cfg = cfg; this.globalCfg = globalCfg; this.verEntCfg = verEntCfg; this.auditStrategy = auditStrategy; + this.classLoaderService = classLoaderService; this.revisionInfoRelationMapping = revisionInfoRelationMapping; this.basicMetadataGenerator = new BasicMetadataGenerator(); @@ -143,7 +147,7 @@ void addRevisionInfoRelation(Element any_mapping) { void addRevisionType(Element any_mapping, Element any_mapping_end) { Element revTypeProperty = MetadataTools.addProperty(any_mapping, verEntCfg.getRevisionTypePropName(), verEntCfg.getRevisionTypePropType(), true, false); - revTypeProperty.addAttribute("type", "org.hibernate.envers.entities.RevisionTypeType"); + revTypeProperty.addAttribute("type", "org.hibernate.envers.internal.entities.RevisionTypeType"); // Adding the end revision, if appropriate addEndRevision(any_mapping_end); @@ -549,6 +553,10 @@ AuditStrategy getAuditStrategy() { return auditStrategy; } + ClassLoaderService getClassLoaderService() { + return classLoaderService; + } + AuditEntityNameRegister getAuditEntityNameRegister() { return auditEntityNameRegister; } diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/configuration/metadata/AuditTableData.java b/hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/metadata/AuditTableData.java similarity index 96% rename from hibernate-envers/src/main/java/org/hibernate/envers/configuration/metadata/AuditTableData.java rename to hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/metadata/AuditTableData.java index 2e21896d3c..3d68cfcd2b 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/configuration/metadata/AuditTableData.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/metadata/AuditTableData.java @@ -22,7 +22,7 @@ * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.configuration.metadata; +package org.hibernate.envers.configuration.internal.metadata; /** diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/configuration/metadata/BasicMetadataGenerator.java b/hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/metadata/BasicMetadataGenerator.java similarity index 96% rename from hibernate-envers/src/main/java/org/hibernate/envers/configuration/metadata/BasicMetadataGenerator.java rename to hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/metadata/BasicMetadataGenerator.java index d793d8bc7b..62cdf89678 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/configuration/metadata/BasicMetadataGenerator.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/metadata/BasicMetadataGenerator.java @@ -21,14 +21,14 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.configuration.metadata; +package org.hibernate.envers.configuration.internal.metadata; import java.util.Properties; import org.dom4j.Element; -import org.hibernate.envers.configuration.metadata.reader.PropertyAuditingData; -import org.hibernate.envers.entities.mapper.SimpleMapperBuilder; +import org.hibernate.envers.configuration.internal.metadata.reader.PropertyAuditingData; +import org.hibernate.envers.internal.entities.mapper.SimpleMapperBuilder; import org.hibernate.mapping.SimpleValue; import org.hibernate.mapping.Value; import org.hibernate.type.BasicType; diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/configuration/metadata/CollectionMetadataGenerator.java b/hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/metadata/CollectionMetadataGenerator.java similarity index 90% rename from hibernate-envers/src/main/java/org/hibernate/envers/configuration/metadata/CollectionMetadataGenerator.java rename to hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/metadata/CollectionMetadataGenerator.java index e10964cff2..ef2f1ccfd5 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/configuration/metadata/CollectionMetadataGenerator.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/metadata/CollectionMetadataGenerator.java @@ -21,7 +21,7 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.configuration.metadata; +package org.hibernate.envers.configuration.internal.metadata; import java.util.ArrayList; import java.util.HashMap; @@ -41,45 +41,46 @@ import org.hibernate.annotations.common.reflection.ReflectionManager; import org.hibernate.envers.ModificationStore; import org.hibernate.envers.RelationTargetAuditMode; -import org.hibernate.envers.configuration.metadata.reader.AuditedPropertiesReader; -import org.hibernate.envers.configuration.metadata.reader.ComponentAuditedPropertiesReader; -import org.hibernate.envers.configuration.metadata.reader.ComponentAuditingData; -import org.hibernate.envers.configuration.metadata.reader.PropertyAuditingData; -import org.hibernate.envers.entities.EntityConfiguration; -import org.hibernate.envers.entities.IdMappingData; -import org.hibernate.envers.entities.PropertyData; -import org.hibernate.envers.entities.mapper.CompositeMapperBuilder; -import org.hibernate.envers.entities.mapper.MultiPropertyMapper; -import org.hibernate.envers.entities.mapper.PropertyMapper; -import org.hibernate.envers.entities.mapper.SinglePropertyMapper; -import org.hibernate.envers.entities.mapper.id.IdMapper; -import org.hibernate.envers.entities.mapper.relation.BasicCollectionMapper; -import org.hibernate.envers.entities.mapper.relation.CommonCollectionMapperData; -import org.hibernate.envers.entities.mapper.relation.ListCollectionMapper; -import org.hibernate.envers.entities.mapper.relation.MapCollectionMapper; -import org.hibernate.envers.entities.mapper.relation.MiddleComponentData; -import org.hibernate.envers.entities.mapper.relation.MiddleIdData; -import org.hibernate.envers.entities.mapper.relation.SortedMapCollectionMapper; -import org.hibernate.envers.entities.mapper.relation.SortedSetCollectionMapper; -import org.hibernate.envers.entities.mapper.relation.ToOneIdMapper; -import org.hibernate.envers.entities.mapper.relation.component.MiddleDummyComponentMapper; -import org.hibernate.envers.entities.mapper.relation.component.MiddleEmbeddableComponentMapper; -import org.hibernate.envers.entities.mapper.relation.component.MiddleMapKeyIdComponentMapper; -import org.hibernate.envers.entities.mapper.relation.component.MiddleMapKeyPropertyComponentMapper; -import org.hibernate.envers.entities.mapper.relation.component.MiddleRelatedComponentMapper; -import org.hibernate.envers.entities.mapper.relation.component.MiddleSimpleComponentMapper; -import org.hibernate.envers.entities.mapper.relation.component.MiddleStraightComponentMapper; -import org.hibernate.envers.entities.mapper.relation.lazy.proxy.ListProxy; -import org.hibernate.envers.entities.mapper.relation.lazy.proxy.MapProxy; -import org.hibernate.envers.entities.mapper.relation.lazy.proxy.SetProxy; -import org.hibernate.envers.entities.mapper.relation.lazy.proxy.SortedMapProxy; -import org.hibernate.envers.entities.mapper.relation.lazy.proxy.SortedSetProxy; -import org.hibernate.envers.entities.mapper.relation.query.OneAuditEntityQueryGenerator; -import org.hibernate.envers.entities.mapper.relation.query.RelationQueryGenerator; +import org.hibernate.envers.configuration.internal.metadata.reader.AuditedPropertiesReader; +import org.hibernate.envers.configuration.internal.metadata.reader.ComponentAuditedPropertiesReader; +import org.hibernate.envers.configuration.internal.metadata.reader.ComponentAuditingData; +import org.hibernate.envers.configuration.internal.metadata.reader.PropertyAuditingData; import org.hibernate.envers.internal.EnversMessageLogger; -import org.hibernate.envers.tools.MappingTools; -import org.hibernate.envers.tools.StringTools; -import org.hibernate.envers.tools.Tools; +import org.hibernate.envers.internal.entities.EntityConfiguration; +import org.hibernate.envers.internal.entities.IdMappingData; +import org.hibernate.envers.internal.entities.PropertyData; +import org.hibernate.envers.internal.entities.mapper.CompositeMapperBuilder; +import org.hibernate.envers.internal.entities.mapper.MultiPropertyMapper; +import org.hibernate.envers.internal.entities.mapper.PropertyMapper; +import org.hibernate.envers.internal.entities.mapper.SinglePropertyMapper; +import org.hibernate.envers.internal.entities.mapper.id.IdMapper; +import org.hibernate.envers.internal.entities.mapper.relation.BasicCollectionMapper; +import org.hibernate.envers.internal.entities.mapper.relation.CommonCollectionMapperData; +import org.hibernate.envers.internal.entities.mapper.relation.ListCollectionMapper; +import org.hibernate.envers.internal.entities.mapper.relation.MapCollectionMapper; +import org.hibernate.envers.internal.entities.mapper.relation.MiddleComponentData; +import org.hibernate.envers.internal.entities.mapper.relation.MiddleIdData; +import org.hibernate.envers.internal.entities.mapper.relation.SortedMapCollectionMapper; +import org.hibernate.envers.internal.entities.mapper.relation.SortedSetCollectionMapper; +import org.hibernate.envers.internal.entities.mapper.relation.ToOneIdMapper; +import org.hibernate.envers.internal.entities.mapper.relation.component.MiddleDummyComponentMapper; +import org.hibernate.envers.internal.entities.mapper.relation.component.MiddleEmbeddableComponentMapper; +import org.hibernate.envers.internal.entities.mapper.relation.component.MiddleMapKeyIdComponentMapper; +import org.hibernate.envers.internal.entities.mapper.relation.component.MiddleMapKeyPropertyComponentMapper; +import org.hibernate.envers.internal.entities.mapper.relation.component.MiddleRelatedComponentMapper; +import org.hibernate.envers.internal.entities.mapper.relation.component.MiddleSimpleComponentMapper; +import org.hibernate.envers.internal.entities.mapper.relation.component.MiddleStraightComponentMapper; +import org.hibernate.envers.internal.entities.mapper.relation.lazy.proxy.ListProxy; +import org.hibernate.envers.internal.entities.mapper.relation.lazy.proxy.MapProxy; +import org.hibernate.envers.internal.entities.mapper.relation.lazy.proxy.SetProxy; +import org.hibernate.envers.internal.entities.mapper.relation.lazy.proxy.SortedMapProxy; +import org.hibernate.envers.internal.entities.mapper.relation.lazy.proxy.SortedSetProxy; +import org.hibernate.envers.internal.entities.mapper.relation.query.OneAuditEntityQueryGenerator; +import org.hibernate.envers.internal.entities.mapper.relation.query.RelationQueryGenerator; +import org.hibernate.envers.internal.tools.MappingTools; +import org.hibernate.envers.internal.tools.ReflectionTools; +import org.hibernate.envers.internal.tools.StringTools; +import org.hibernate.envers.internal.tools.Tools; import org.hibernate.mapping.Collection; import org.hibernate.mapping.Component; import org.hibernate.mapping.IndexedCollection; @@ -125,8 +126,7 @@ public final class CollectionMetadataGenerator { /** * @param mainGenerator Main generator, giving access to configuration and the basic mapper. * @param propertyValue Value of the collection, as mapped by Hibernate. - * @param currentMapper Mapper, to which the appropriate {@link org.hibernate.envers.entities.mapper.PropertyMapper} - * will be added. + * @param currentMapper Mapper, to which the appropriate {@link PropertyMapper} will be added. * @param referencingEntityName Name of the entity that owns this collection. * @param xmlMappingData In case this collection requires a middle table, additional mapping documents will * be created using this object. @@ -474,7 +474,8 @@ private MiddleComponentData addValueToMiddleTable(Value value, Element xmlMappin } else if ( type instanceof ComponentType ) { // Collection of embeddable elements. final Component component = (Component) value; - final MiddleEmbeddableComponentMapper componentMapper = new MiddleEmbeddableComponentMapper( new MultiPropertyMapper(), component.getComponentClassName() ); + final Class componentClass = ReflectionTools.loadClass( component.getComponentClassName(), mainGenerator.getClassLoaderService() ); + final MiddleEmbeddableComponentMapper componentMapper = new MiddleEmbeddableComponentMapper( new MultiPropertyMapper(), componentClass ); final Element parentXmlMapping = xmlMapping.getParent(); final ComponentAuditingData auditData = new ComponentAuditingData(); diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/configuration/metadata/ComponentMetadataGenerator.java b/hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/metadata/ComponentMetadataGenerator.java similarity index 71% rename from hibernate-envers/src/main/java/org/hibernate/envers/configuration/metadata/ComponentMetadataGenerator.java rename to hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/metadata/ComponentMetadataGenerator.java index 9f0d62525d..b1efd5c803 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/configuration/metadata/ComponentMetadataGenerator.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/metadata/ComponentMetadataGenerator.java @@ -1,11 +1,13 @@ -package org.hibernate.envers.configuration.metadata; +package org.hibernate.envers.configuration.internal.metadata; + import java.util.Iterator; import org.dom4j.Element; -import org.hibernate.envers.configuration.metadata.reader.ComponentAuditingData; -import org.hibernate.envers.configuration.metadata.reader.PropertyAuditingData; -import org.hibernate.envers.entities.mapper.CompositeMapperBuilder; +import org.hibernate.envers.configuration.internal.metadata.reader.ComponentAuditingData; +import org.hibernate.envers.configuration.internal.metadata.reader.PropertyAuditingData; +import org.hibernate.envers.internal.entities.mapper.CompositeMapperBuilder; +import org.hibernate.envers.internal.tools.ReflectionTools; import org.hibernate.mapping.Component; import org.hibernate.mapping.Property; import org.hibernate.mapping.Value; @@ -27,8 +29,8 @@ public void addComponent(Element parent, PropertyAuditingData propertyAuditingDa EntityXmlMappingData xmlMappingData, boolean firstPass) { Component prop_component = (Component) value; - CompositeMapperBuilder componentMapper = mapper.addComponent(propertyAuditingData.getPropertyData(), - prop_component.getComponentClassName()); + Class componentClass = ReflectionTools.loadClass( prop_component.getComponentClassName(), mainGenerator.getClassLoaderService() ); + CompositeMapperBuilder componentMapper = mapper.addComponent( propertyAuditingData.getPropertyData(), componentClass ); // The property auditing data must be for a component. ComponentAuditingData componentAuditingData = (ComponentAuditingData) propertyAuditingData; diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/configuration/metadata/EntityXmlMappingData.java b/hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/metadata/EntityXmlMappingData.java similarity index 97% rename from hibernate-envers/src/main/java/org/hibernate/envers/configuration/metadata/EntityXmlMappingData.java rename to hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/metadata/EntityXmlMappingData.java index 7982a0ceb0..7584d16643 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/configuration/metadata/EntityXmlMappingData.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/metadata/EntityXmlMappingData.java @@ -21,7 +21,7 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.configuration.metadata; +package org.hibernate.envers.configuration.internal.metadata; import java.util.ArrayList; import java.util.List; diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/configuration/metadata/IdMetadataGenerator.java b/hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/metadata/IdMetadataGenerator.java similarity index 85% rename from hibernate-envers/src/main/java/org/hibernate/envers/configuration/metadata/IdMetadataGenerator.java rename to hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/metadata/IdMetadataGenerator.java index 4e580db659..d0064390cc 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/configuration/metadata/IdMetadataGenerator.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/metadata/IdMetadataGenerator.java @@ -21,7 +21,7 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.configuration.metadata; +package org.hibernate.envers.configuration.internal.metadata; import java.util.Iterator; import org.dom4j.Element; @@ -30,14 +30,15 @@ import org.hibernate.MappingException; import org.hibernate.envers.ModificationStore; import org.hibernate.envers.RelationTargetAuditMode; -import org.hibernate.envers.configuration.metadata.reader.PropertyAuditingData; -import org.hibernate.envers.entities.IdMappingData; -import org.hibernate.envers.entities.PropertyData; -import org.hibernate.envers.entities.mapper.SimpleMapperBuilder; -import org.hibernate.envers.entities.mapper.id.EmbeddedIdMapper; -import org.hibernate.envers.entities.mapper.id.MultipleIdMapper; -import org.hibernate.envers.entities.mapper.id.SimpleIdMapperBuilder; -import org.hibernate.envers.entities.mapper.id.SingleIdMapper; +import org.hibernate.envers.configuration.internal.metadata.reader.PropertyAuditingData; +import org.hibernate.envers.internal.entities.IdMappingData; +import org.hibernate.envers.internal.entities.PropertyData; +import org.hibernate.envers.internal.entities.mapper.SimpleMapperBuilder; +import org.hibernate.envers.internal.entities.mapper.id.EmbeddedIdMapper; +import org.hibernate.envers.internal.entities.mapper.id.MultipleIdMapper; +import org.hibernate.envers.internal.entities.mapper.id.SimpleIdMapperBuilder; +import org.hibernate.envers.internal.entities.mapper.id.SingleIdMapper; +import org.hibernate.envers.internal.tools.ReflectionTools; import org.hibernate.mapping.Component; import org.hibernate.mapping.PersistentClass; import org.hibernate.mapping.Property; @@ -108,7 +109,10 @@ IdMappingData addId(PersistentClass pc, boolean audited) { if (id_mapper != null) { // Multiple id - mapper = new MultipleIdMapper(((Component) pc.getIdentifier()).getComponentClassName()); + Class componentClass = ReflectionTools.loadClass( + ( (Component) pc.getIdentifier() ).getComponentClassName(), mainGenerator.getClassLoaderService() + ); + mapper = new MultipleIdMapper( componentClass ); if (!addIdProperties(rel_id_mapping, (Iterator) id_mapper.getPropertyIterator(), mapper, false, audited)) { return null; } @@ -121,8 +125,10 @@ IdMappingData addId(PersistentClass pc, boolean audited) { // Embedded id Component id_component = (Component) id_prop.getValue(); - - mapper = new EmbeddedIdMapper(getIdPropertyData(id_prop), id_component.getComponentClassName()); + Class embeddableClass = ReflectionTools.loadClass( + id_component.getComponentClassName(), mainGenerator.getClassLoaderService() + ); + mapper = new EmbeddedIdMapper( getIdPropertyData(id_prop), embeddableClass ); if (!addIdProperties(rel_id_mapping, (Iterator) id_component.getPropertyIterator(), mapper, false, audited)) { return null; } diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/configuration/metadata/InheritanceType.java b/hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/metadata/InheritanceType.java similarity index 97% rename from hibernate-envers/src/main/java/org/hibernate/envers/configuration/metadata/InheritanceType.java rename to hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/metadata/InheritanceType.java index b29b899b0d..87cb5a7f0c 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/configuration/metadata/InheritanceType.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/metadata/InheritanceType.java @@ -21,7 +21,7 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.configuration.metadata; +package org.hibernate.envers.configuration.internal.metadata; import org.hibernate.MappingException; import org.hibernate.mapping.JoinedSubclass; import org.hibernate.mapping.PersistentClass; diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/configuration/metadata/MetadataTools.java b/hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/metadata/MetadataTools.java similarity index 99% rename from hibernate-envers/src/main/java/org/hibernate/envers/configuration/metadata/MetadataTools.java rename to hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/metadata/MetadataTools.java index c0e3315335..4b2c1058d8 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/configuration/metadata/MetadataTools.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/metadata/MetadataTools.java @@ -21,7 +21,7 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.configuration.metadata; +package org.hibernate.envers.configuration.internal.metadata; import java.util.Iterator; import javax.persistence.JoinColumn; @@ -29,7 +29,7 @@ import org.dom4j.Document; import org.dom4j.Element; -import org.hibernate.envers.tools.StringTools; +import org.hibernate.envers.internal.tools.StringTools; import org.hibernate.mapping.Column; import org.hibernate.mapping.Formula; diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/configuration/metadata/QueryGeneratorBuilder.java b/hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/metadata/QueryGeneratorBuilder.java similarity index 83% rename from hibernate-envers/src/main/java/org/hibernate/envers/configuration/metadata/QueryGeneratorBuilder.java rename to hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/metadata/QueryGeneratorBuilder.java index bc210a0af9..4312097d19 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/configuration/metadata/QueryGeneratorBuilder.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/metadata/QueryGeneratorBuilder.java @@ -21,20 +21,20 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.configuration.metadata; +package org.hibernate.envers.configuration.internal.metadata; import java.util.ArrayList; import java.util.List; import org.hibernate.MappingException; -import org.hibernate.envers.configuration.AuditEntitiesConfiguration; -import org.hibernate.envers.configuration.GlobalConfiguration; -import org.hibernate.envers.entities.mapper.relation.MiddleComponentData; -import org.hibernate.envers.entities.mapper.relation.MiddleIdData; -import org.hibernate.envers.entities.mapper.relation.query.OneEntityQueryGenerator; -import org.hibernate.envers.entities.mapper.relation.query.RelationQueryGenerator; -import org.hibernate.envers.entities.mapper.relation.query.ThreeEntityQueryGenerator; -import org.hibernate.envers.entities.mapper.relation.query.TwoEntityOneAuditedQueryGenerator; -import org.hibernate.envers.entities.mapper.relation.query.TwoEntityQueryGenerator; +import org.hibernate.envers.configuration.internal.AuditEntitiesConfiguration; +import org.hibernate.envers.configuration.internal.GlobalConfiguration; +import org.hibernate.envers.internal.entities.mapper.relation.MiddleComponentData; +import org.hibernate.envers.internal.entities.mapper.relation.MiddleIdData; +import org.hibernate.envers.internal.entities.mapper.relation.query.OneEntityQueryGenerator; +import org.hibernate.envers.internal.entities.mapper.relation.query.RelationQueryGenerator; +import org.hibernate.envers.internal.entities.mapper.relation.query.ThreeEntityQueryGenerator; +import org.hibernate.envers.internal.entities.mapper.relation.query.TwoEntityOneAuditedQueryGenerator; +import org.hibernate.envers.internal.entities.mapper.relation.query.TwoEntityQueryGenerator; import org.hibernate.envers.strategy.AuditStrategy; /** diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/configuration/metadata/ToOneRelationMetadataGenerator.java b/hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/metadata/ToOneRelationMetadataGenerator.java similarity index 90% rename from hibernate-envers/src/main/java/org/hibernate/envers/configuration/metadata/ToOneRelationMetadataGenerator.java rename to hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/metadata/ToOneRelationMetadataGenerator.java index 9a8501335e..2e644d8e11 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/configuration/metadata/ToOneRelationMetadataGenerator.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/metadata/ToOneRelationMetadataGenerator.java @@ -21,20 +21,20 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.configuration.metadata; +package org.hibernate.envers.configuration.internal.metadata; import org.dom4j.Element; import org.hibernate.MappingException; -import org.hibernate.envers.configuration.metadata.reader.PropertyAuditingData; -import org.hibernate.envers.entities.EntityConfiguration; -import org.hibernate.envers.entities.IdMappingData; -import org.hibernate.envers.entities.PropertyData; -import org.hibernate.envers.entities.mapper.CompositeMapperBuilder; -import org.hibernate.envers.entities.mapper.id.IdMapper; -import org.hibernate.envers.entities.mapper.relation.OneToOneNotOwningMapper; -import org.hibernate.envers.entities.mapper.relation.OneToOnePrimaryKeyJoinColumnMapper; -import org.hibernate.envers.entities.mapper.relation.ToOneIdMapper; -import org.hibernate.envers.tools.MappingTools; +import org.hibernate.envers.configuration.internal.metadata.reader.PropertyAuditingData; +import org.hibernate.envers.internal.entities.EntityConfiguration; +import org.hibernate.envers.internal.entities.IdMappingData; +import org.hibernate.envers.internal.entities.PropertyData; +import org.hibernate.envers.internal.entities.mapper.CompositeMapperBuilder; +import org.hibernate.envers.internal.entities.mapper.id.IdMapper; +import org.hibernate.envers.internal.entities.mapper.relation.OneToOneNotOwningMapper; +import org.hibernate.envers.internal.entities.mapper.relation.OneToOnePrimaryKeyJoinColumnMapper; +import org.hibernate.envers.internal.entities.mapper.relation.ToOneIdMapper; +import org.hibernate.envers.internal.tools.MappingTools; import org.hibernate.mapping.OneToOne; import org.hibernate.mapping.ToOne; import org.hibernate.mapping.Value; diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/configuration/metadata/reader/AnnotationsMetadataReader.java b/hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/metadata/reader/AnnotationsMetadataReader.java similarity index 97% rename from hibernate-envers/src/main/java/org/hibernate/envers/configuration/metadata/reader/AnnotationsMetadataReader.java rename to hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/metadata/reader/AnnotationsMetadataReader.java index ba384226f3..0a3b5d512e 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/configuration/metadata/reader/AnnotationsMetadataReader.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/metadata/reader/AnnotationsMetadataReader.java @@ -21,7 +21,7 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.configuration.metadata.reader; +package org.hibernate.envers.configuration.internal.metadata.reader; import java.lang.annotation.Annotation; import java.util.Iterator; @@ -33,7 +33,7 @@ import org.hibernate.envers.ModificationStore; import org.hibernate.envers.SecondaryAuditTable; import org.hibernate.envers.SecondaryAuditTables; -import org.hibernate.envers.configuration.GlobalConfiguration; +import org.hibernate.envers.configuration.internal.GlobalConfiguration; import org.hibernate.mapping.PersistentClass; import org.hibernate.mapping.Property; diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/configuration/metadata/reader/AuditedPropertiesHolder.java b/hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/metadata/reader/AuditedPropertiesHolder.java similarity index 92% rename from hibernate-envers/src/main/java/org/hibernate/envers/configuration/metadata/reader/AuditedPropertiesHolder.java rename to hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/metadata/reader/AuditedPropertiesHolder.java index dc91cb6c8f..5cd511c74b 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/configuration/metadata/reader/AuditedPropertiesHolder.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/metadata/reader/AuditedPropertiesHolder.java @@ -1,4 +1,4 @@ -package org.hibernate.envers.configuration.metadata.reader; +package org.hibernate.envers.configuration.internal.metadata.reader; /** diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/configuration/metadata/reader/AuditedPropertiesReader.java b/hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/metadata/reader/AuditedPropertiesReader.java similarity index 95% rename from hibernate-envers/src/main/java/org/hibernate/envers/configuration/metadata/reader/AuditedPropertiesReader.java rename to hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/metadata/reader/AuditedPropertiesReader.java index 96c1e21afd..6c54447d1c 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/configuration/metadata/reader/AuditedPropertiesReader.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/metadata/reader/AuditedPropertiesReader.java @@ -1,4 +1,5 @@ -package org.hibernate.envers.configuration.metadata.reader; +package org.hibernate.envers.configuration.internal.metadata.reader; + import java.lang.annotation.Annotation; import java.util.Arrays; import java.util.Collections; @@ -23,24 +24,22 @@ import org.hibernate.envers.ModificationStore; import org.hibernate.envers.NotAudited; import org.hibernate.envers.RelationTargetAuditMode; -import org.hibernate.envers.configuration.GlobalConfiguration; -import org.hibernate.envers.configuration.metadata.MetadataTools; -import org.hibernate.envers.tools.MappingTools; -import org.hibernate.envers.tools.StringTools; -import org.hibernate.envers.tools.Tools; +import org.hibernate.envers.configuration.internal.GlobalConfiguration; +import org.hibernate.envers.configuration.internal.metadata.MetadataTools; +import org.hibernate.envers.internal.tools.MappingTools; +import org.hibernate.envers.internal.tools.ReflectionTools; +import org.hibernate.envers.internal.tools.StringTools; import org.hibernate.mapping.Component; import org.hibernate.mapping.Property; import org.hibernate.mapping.Value; -import static org.hibernate.envers.tools.Tools.newHashMap; -import static org.hibernate.envers.tools.Tools.newHashSet; +import static org.hibernate.envers.internal.tools.Tools.newHashMap; +import static org.hibernate.envers.internal.tools.Tools.newHashSet; /** - * Reads persistent properties form a - * {@link org.hibernate.envers.configuration.metadata.reader.PersistentPropertiesSource} - * and adds the ones that are audited to a - * {@link org.hibernate.envers.configuration.metadata.reader.AuditedPropertiesHolder}, - * filling all the auditing data. + * Reads persistent properties form a {@link PersistentPropertiesSource} and adds the ones that are audited to a + * {@link AuditedPropertiesHolder}, filling all the auditing data. + * * @author Adam Warski (adam at warski dot org) * @author Erik-Berndt Scheper * @author Hern&aacut;n Chanfreau @@ -201,7 +200,7 @@ private void checkSuperclass(XClass child, XClass parent) { * @return Property object. */ private XProperty getProperty(XClass clazz, String propertyName) { - XProperty property = Tools.getProperty(clazz, propertyName); + XProperty property = ReflectionTools.getProperty(clazz, propertyName); if (property == null) { throw new MappingException("Property '" + propertyName + "' not found in class " + clazz.getName() + ". " + "Please revise Envers annotations applied to class " + persistentPropertiesSource.getXClass() + "."); @@ -478,7 +477,7 @@ private void addPropertyJoinTables(XProperty property, PropertyAuditingData prop } /*** - * Add the {@link org.hibernate.envers.AuditOverride} annotations. + * Add the {@link AuditOverride} annotations. * * @param property the property being processed * @param propertyData the Envers auditing data for this property @@ -495,10 +494,10 @@ private void addPropertyAuditingOverrides(XProperty property, PropertyAuditingDa } /** - * Process the {@link org.hibernate.envers.AuditOverride} annotations for this property. + * Process the {@link AuditOverride} annotations for this property. * * @param property - * the property for which the {@link org.hibernate.envers.AuditOverride} + * the property for which the {@link AuditOverride} * annotations are being processed * @param propertyData * the Envers auditing data for this property diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/configuration/metadata/reader/ClassAuditingData.java b/hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/metadata/reader/ClassAuditingData.java similarity index 95% rename from hibernate-envers/src/main/java/org/hibernate/envers/configuration/metadata/reader/ClassAuditingData.java rename to hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/metadata/reader/ClassAuditingData.java index 53b13f5010..785c11fd75 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/configuration/metadata/reader/ClassAuditingData.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/metadata/reader/ClassAuditingData.java @@ -21,12 +21,12 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.configuration.metadata.reader; +package org.hibernate.envers.configuration.internal.metadata.reader; import java.util.Map; import org.hibernate.envers.AuditTable; -import static org.hibernate.envers.tools.Tools.newHashMap; +import static org.hibernate.envers.internal.tools.Tools.newHashMap; /** * @author Adam Warski (adam at warski dot org) diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/configuration/metadata/reader/ComponentAuditedPropertiesReader.java b/hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/metadata/reader/ComponentAuditedPropertiesReader.java similarity index 90% rename from hibernate-envers/src/main/java/org/hibernate/envers/configuration/metadata/reader/ComponentAuditedPropertiesReader.java rename to hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/metadata/reader/ComponentAuditedPropertiesReader.java index bcf9b56b37..3e970cfe78 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/configuration/metadata/reader/ComponentAuditedPropertiesReader.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/metadata/reader/ComponentAuditedPropertiesReader.java @@ -1,9 +1,9 @@ -package org.hibernate.envers.configuration.metadata.reader; +package org.hibernate.envers.configuration.internal.metadata.reader; import org.hibernate.annotations.common.reflection.ReflectionManager; import org.hibernate.annotations.common.reflection.XProperty; import org.hibernate.envers.Audited; import org.hibernate.envers.ModificationStore; -import org.hibernate.envers.configuration.GlobalConfiguration; +import org.hibernate.envers.configuration.internal.GlobalConfiguration; /** * Reads the audited properties for components. diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/configuration/metadata/reader/ComponentAuditingData.java b/hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/metadata/reader/ComponentAuditingData.java similarity index 93% rename from hibernate-envers/src/main/java/org/hibernate/envers/configuration/metadata/reader/ComponentAuditingData.java rename to hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/metadata/reader/ComponentAuditingData.java index b6108477b5..60c3ff2299 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/configuration/metadata/reader/ComponentAuditingData.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/metadata/reader/ComponentAuditingData.java @@ -22,11 +22,11 @@ * Boston, MA 02110-1301 USA * */ -package org.hibernate.envers.configuration.metadata.reader; +package org.hibernate.envers.configuration.internal.metadata.reader; import java.util.Map; import java.util.Set; -import static org.hibernate.envers.tools.Tools.newHashMap; +import static org.hibernate.envers.internal.tools.Tools.newHashMap; /** * Audit mapping meta-data for component. diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/configuration/metadata/reader/PersistentPropertiesSource.java b/hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/metadata/reader/PersistentPropertiesSource.java similarity index 85% rename from hibernate-envers/src/main/java/org/hibernate/envers/configuration/metadata/reader/PersistentPropertiesSource.java rename to hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/metadata/reader/PersistentPropertiesSource.java index 8a92d46bf5..864d5382b7 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/configuration/metadata/reader/PersistentPropertiesSource.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/metadata/reader/PersistentPropertiesSource.java @@ -1,4 +1,4 @@ -package org.hibernate.envers.configuration.metadata.reader; +package org.hibernate.envers.configuration.internal.metadata.reader; import java.util.Iterator; import org.hibernate.annotations.common.reflection.XClass; diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/configuration/metadata/reader/PropertyAuditingData.java b/hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/metadata/reader/PropertyAuditingData.java similarity index 97% rename from hibernate-envers/src/main/java/org/hibernate/envers/configuration/metadata/reader/PropertyAuditingData.java rename to hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/metadata/reader/PropertyAuditingData.java index 68ccce4243..500ad95403 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/configuration/metadata/reader/PropertyAuditingData.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/metadata/reader/PropertyAuditingData.java @@ -22,7 +22,7 @@ * Boston, MA 02110-1301 USA * */ -package org.hibernate.envers.configuration.metadata.reader; +package org.hibernate.envers.configuration.internal.metadata.reader; import java.util.ArrayList; import java.util.List; @@ -31,7 +31,7 @@ import org.hibernate.envers.AuditOverrides; import org.hibernate.envers.ModificationStore; import org.hibernate.envers.RelationTargetAuditMode; -import org.hibernate.envers.entities.PropertyData; +import org.hibernate.envers.internal.entities.PropertyData; /** * @author Adam Warski (adam at warski dot org) diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/configuration/AuditConfiguration.java b/hibernate-envers/src/main/java/org/hibernate/envers/configuration/spi/AuditConfiguration.java similarity index 80% rename from hibernate-envers/src/main/java/org/hibernate/envers/configuration/AuditConfiguration.java rename to hibernate-envers/src/main/java/org/hibernate/envers/configuration/spi/AuditConfiguration.java index eb705e47cc..ccf294c410 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/configuration/AuditConfiguration.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/configuration/spi/AuditConfiguration.java @@ -21,7 +21,7 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.configuration; +package org.hibernate.envers.configuration.spi; import java.util.Map; import java.util.Properties; @@ -29,19 +29,24 @@ import org.hibernate.MappingException; import org.hibernate.annotations.common.reflection.ReflectionManager; +import org.hibernate.boot.registry.classloading.spi.ClassLoaderService; import org.hibernate.cfg.Configuration; -import org.hibernate.envers.entities.EntitiesConfigurations; -import org.hibernate.envers.entities.PropertyData; -import org.hibernate.envers.revisioninfo.ModifiedEntityNamesReader; -import org.hibernate.envers.revisioninfo.RevisionInfoNumberReader; -import org.hibernate.envers.revisioninfo.RevisionInfoQueryCreator; +import org.hibernate.envers.configuration.internal.AuditEntitiesConfiguration; +import org.hibernate.envers.configuration.internal.EntitiesConfigurator; +import org.hibernate.envers.configuration.internal.GlobalConfiguration; +import org.hibernate.envers.configuration.internal.RevisionInfoConfiguration; +import org.hibernate.envers.configuration.internal.RevisionInfoConfigurationResult; +import org.hibernate.envers.internal.entities.EntitiesConfigurations; +import org.hibernate.envers.internal.entities.PropertyData; +import org.hibernate.envers.internal.revisioninfo.ModifiedEntityNamesReader; +import org.hibernate.envers.internal.revisioninfo.RevisionInfoNumberReader; +import org.hibernate.envers.internal.revisioninfo.RevisionInfoQueryCreator; +import org.hibernate.envers.internal.synchronization.AuditProcessManager; +import org.hibernate.envers.internal.tools.ReflectionTools; import org.hibernate.envers.strategy.AuditStrategy; import org.hibernate.envers.strategy.ValidityAuditStrategy; -import org.hibernate.envers.synchronization.AuditProcessManager; -import org.hibernate.envers.tools.reflection.ReflectionTools; import org.hibernate.internal.util.ReflectHelper; import org.hibernate.property.Getter; -import org.hibernate.boot.registry.classloading.spi.ClassLoaderService; /** * @author Adam Warski (adam at warski dot org) @@ -90,6 +95,10 @@ public AuditStrategy getAuditStrategy() { return auditStrategy; } + public ClassLoaderService getClassLoaderService() { + return classLoaderService; + } + public AuditConfiguration(Configuration cfg) { this( cfg, null ); } @@ -98,7 +107,7 @@ public AuditConfiguration(Configuration cfg, ClassLoaderService classLoaderServi Properties properties = cfg.getProperties(); ReflectionManager reflectionManager = cfg.getReflectionManager(); - globalCfg = new GlobalConfiguration( properties ); + globalCfg = new GlobalConfiguration( properties, classLoaderService ); RevisionInfoConfiguration revInfoCfg = new RevisionInfoConfiguration( globalCfg ); RevisionInfoConfigurationResult revInfoCfgResult = revInfoCfg.configure( cfg, reflectionManager ); auditEntCfg = new AuditEntitiesConfiguration( properties, revInfoCfgResult.getRevisionInfoEntityName() ); @@ -112,7 +121,7 @@ public AuditConfiguration(Configuration cfg, ClassLoaderService classLoaderServi revInfoCfgResult.getRevisionInfoTimestampData() ); entCfg = new EntitiesConfigurator().configure( - cfg, reflectionManager, globalCfg, auditEntCfg, auditStrategy, + cfg, reflectionManager, globalCfg, auditEntCfg, auditStrategy, classLoaderService, revInfoCfgResult.getRevisionInfoXmlMapping(), revInfoCfgResult.getRevisionInfoRelationMapping() ); } @@ -121,15 +130,7 @@ private AuditStrategy initializeAuditStrategy(Class revisionInfoClass, Proper AuditStrategy strategy; try { - - Class auditStrategyClass = null; - if ( classLoaderService != null ) { - auditStrategyClass = classLoaderService.classForName( auditEntCfg.getAuditStrategyName() ); - } - else { - auditStrategyClass = ReflectHelper.classForName( auditEntCfg.getAuditStrategyName() ); - } - + Class auditStrategyClass = ReflectionTools.loadClass( auditEntCfg.getAuditStrategyName(), classLoaderService ); strategy = (AuditStrategy) ReflectHelper.getDefaultConstructor(auditStrategyClass).newInstance(); } catch ( Exception e ) { @@ -150,8 +151,7 @@ private AuditStrategy initializeAuditStrategy(Class revisionInfoClass, Proper // - private static Map cfgs - = new WeakHashMap(); + private static Map cfgs = new WeakHashMap(); public synchronized static AuditConfiguration getFor(Configuration cfg) { return getFor( cfg, null ); diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/enhanced/SequenceIdRevisionEntity.java b/hibernate-envers/src/main/java/org/hibernate/envers/enhanced/SequenceIdRevisionEntity.java index eb65728c88..41a78fdebc 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/enhanced/SequenceIdRevisionEntity.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/enhanced/SequenceIdRevisionEntity.java @@ -23,18 +23,18 @@ */ package org.hibernate.envers.enhanced; -import org.hibernate.annotations.GenericGenerator; -import org.hibernate.annotations.Parameter; -import org.hibernate.envers.RevisionNumber; -import org.hibernate.envers.RevisionTimestamp; - +import java.io.Serializable; +import java.text.DateFormat; +import java.util.Date; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.MappedSuperclass; import javax.persistence.Transient; -import java.io.Serializable; -import java.text.DateFormat; -import java.util.Date; + +import org.hibernate.annotations.GenericGenerator; +import org.hibernate.annotations.Parameter; +import org.hibernate.envers.RevisionNumber; +import org.hibernate.envers.RevisionTimestamp; /** * @author Adam Warski (adam at warski dot org) diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/enhanced/SequenceIdTrackingModifiedEntitiesRevisionEntity.java b/hibernate-envers/src/main/java/org/hibernate/envers/enhanced/SequenceIdTrackingModifiedEntitiesRevisionEntity.java index fd02295ea4..889cd723cb 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/enhanced/SequenceIdTrackingModifiedEntitiesRevisionEntity.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/enhanced/SequenceIdTrackingModifiedEntitiesRevisionEntity.java @@ -23,14 +23,19 @@ */ package org.hibernate.envers.enhanced; +import java.util.HashSet; +import java.util.Set; +import javax.persistence.Column; +import javax.persistence.ElementCollection; +import javax.persistence.FetchType; +import javax.persistence.JoinColumn; +import javax.persistence.JoinTable; +import javax.persistence.MappedSuperclass; + import org.hibernate.annotations.Fetch; import org.hibernate.annotations.FetchMode; import org.hibernate.envers.ModifiedEntityNames; -import javax.persistence.*; -import java.util.HashSet; -import java.util.Set; - /** * Extension of standard {@link SequenceIdRevisionEntity} that allows tracking entity names changed in each revision. * This revision entity is implicitly used when {@code org.hibernate.envers.track_entities_changed_in_revision} diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/event/BaseEnversCollectionEventListener.java b/hibernate-envers/src/main/java/org/hibernate/envers/event/spi/BaseEnversCollectionEventListener.java similarity index 93% rename from hibernate-envers/src/main/java/org/hibernate/envers/event/BaseEnversCollectionEventListener.java rename to hibernate-envers/src/main/java/org/hibernate/envers/event/spi/BaseEnversCollectionEventListener.java index 2cbd8a0553..b8fe96286f 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/event/BaseEnversCollectionEventListener.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/event/spi/BaseEnversCollectionEventListener.java @@ -21,7 +21,7 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.event; +package org.hibernate.envers.event.spi; import java.io.Serializable; import java.util.List; @@ -30,16 +30,16 @@ import org.hibernate.collection.spi.PersistentCollection; import org.hibernate.engine.spi.CollectionEntry; import org.hibernate.envers.RevisionType; -import org.hibernate.envers.configuration.AuditConfiguration; -import org.hibernate.envers.entities.EntityConfiguration; -import org.hibernate.envers.entities.RelationDescription; -import org.hibernate.envers.entities.mapper.PersistentCollectionChangeData; -import org.hibernate.envers.entities.mapper.id.IdMapper; -import org.hibernate.envers.synchronization.AuditProcess; -import org.hibernate.envers.synchronization.work.AuditWorkUnit; -import org.hibernate.envers.synchronization.work.CollectionChangeWorkUnit; -import org.hibernate.envers.synchronization.work.FakeBidirectionalRelationWorkUnit; -import org.hibernate.envers.synchronization.work.PersistentCollectionChangeWorkUnit; +import org.hibernate.envers.configuration.spi.AuditConfiguration; +import org.hibernate.envers.internal.entities.EntityConfiguration; +import org.hibernate.envers.internal.entities.RelationDescription; +import org.hibernate.envers.internal.entities.mapper.PersistentCollectionChangeData; +import org.hibernate.envers.internal.entities.mapper.id.IdMapper; +import org.hibernate.envers.internal.synchronization.AuditProcess; +import org.hibernate.envers.internal.synchronization.work.AuditWorkUnit; +import org.hibernate.envers.internal.synchronization.work.CollectionChangeWorkUnit; +import org.hibernate.envers.internal.synchronization.work.FakeBidirectionalRelationWorkUnit; +import org.hibernate.envers.internal.synchronization.work.PersistentCollectionChangeWorkUnit; import org.hibernate.event.spi.AbstractCollectionEvent; import org.hibernate.persister.collection.AbstractCollectionPersister; diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/event/BaseEnversEventListener.java b/hibernate-envers/src/main/java/org/hibernate/envers/event/spi/BaseEnversEventListener.java similarity index 88% rename from hibernate-envers/src/main/java/org/hibernate/envers/event/BaseEnversEventListener.java rename to hibernate-envers/src/main/java/org/hibernate/envers/event/spi/BaseEnversEventListener.java index 4443e5394d..6e4e4e2408 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/event/BaseEnversEventListener.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/event/spi/BaseEnversEventListener.java @@ -21,20 +21,20 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.event; +package org.hibernate.envers.event.spi; import java.io.Serializable; import java.util.Set; import org.hibernate.engine.spi.SessionImplementor; -import org.hibernate.envers.configuration.AuditConfiguration; -import org.hibernate.envers.entities.RelationDescription; -import org.hibernate.envers.entities.RelationType; -import org.hibernate.envers.entities.mapper.id.IdMapper; +import org.hibernate.envers.configuration.spi.AuditConfiguration; import org.hibernate.envers.exception.AuditException; -import org.hibernate.envers.synchronization.AuditProcess; -import org.hibernate.envers.synchronization.work.CollectionChangeWorkUnit; -import org.hibernate.envers.tools.Tools; +import org.hibernate.envers.internal.entities.RelationDescription; +import org.hibernate.envers.internal.entities.RelationType; +import org.hibernate.envers.internal.entities.mapper.id.IdMapper; +import org.hibernate.envers.internal.synchronization.AuditProcess; +import org.hibernate.envers.internal.synchronization.work.CollectionChangeWorkUnit; +import org.hibernate.envers.internal.tools.EntityTools; import org.hibernate.persister.entity.EntityPersister; import org.hibernate.proxy.HibernateProxy; @@ -84,7 +84,7 @@ protected final void generateBidirectionalCollectionChangeWorkUnits( Object oldValue = oldState == null ? null : oldState[i]; Object newValue = newState == null ? null : newState[i]; - if (!Tools.entitiesEqual( session, relDesc.getToEntityName(), oldValue, newValue )) { + if (!EntityTools.entitiesEqual( session, relDesc.getToEntityName(), oldValue, newValue )) { // We have to generate changes both in the old collection (size decreses) and new collection // (size increases). if (newValue != null) { @@ -111,7 +111,7 @@ private void addCollectionChangeWorkUnit(AuditProcess auditProcess, SessionImple toEntityName = session.bestGuessEntityName(value); id = hibernateProxy.getHibernateLazyInitializer().getIdentifier(); // We've got to initialize the object from the proxy to later read its state. - value = Tools.getTargetFromProxy(session.getFactory(), hibernateProxy); + value = EntityTools.getTargetFromProxy(session.getFactory(), hibernateProxy); } else { toEntityName = session.guessEntityName(value); diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/event/EnversIntegrator.java b/hibernate-envers/src/main/java/org/hibernate/envers/event/spi/EnversIntegrator.java similarity index 97% rename from hibernate-envers/src/main/java/org/hibernate/envers/event/EnversIntegrator.java rename to hibernate-envers/src/main/java/org/hibernate/envers/event/spi/EnversIntegrator.java index 65f84b1df0..36abe0f220 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/event/EnversIntegrator.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/event/spi/EnversIntegrator.java @@ -21,20 +21,20 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.event; +package org.hibernate.envers.event.spi; import org.jboss.logging.Logger; +import org.hibernate.boot.registry.classloading.spi.ClassLoaderService; import org.hibernate.cfg.Configuration; import org.hibernate.engine.spi.SessionFactoryImplementor; -import org.hibernate.envers.configuration.AuditConfiguration; +import org.hibernate.envers.configuration.spi.AuditConfiguration; import org.hibernate.event.service.spi.EventListenerRegistry; import org.hibernate.event.spi.EventType; import org.hibernate.integrator.spi.Integrator; import org.hibernate.internal.CoreMessageLogger; import org.hibernate.internal.util.config.ConfigurationHelper; import org.hibernate.metamodel.source.MetadataImplementor; -import org.hibernate.boot.registry.classloading.spi.ClassLoaderService; import org.hibernate.service.spi.SessionFactoryServiceRegistry; /** diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/event/EnversListener.java b/hibernate-envers/src/main/java/org/hibernate/envers/event/spi/EnversListener.java similarity index 92% rename from hibernate-envers/src/main/java/org/hibernate/envers/event/EnversListener.java rename to hibernate-envers/src/main/java/org/hibernate/envers/event/spi/EnversListener.java index 0a2ec6d215..9cd8086635 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/event/EnversListener.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/event/spi/EnversListener.java @@ -21,9 +21,9 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.event; +package org.hibernate.envers.event.spi; -import org.hibernate.envers.configuration.AuditConfiguration; +import org.hibernate.envers.configuration.spi.AuditConfiguration; /** * Marker interface for Envers listeners for duplication handling. diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/event/EnversListenerDuplicationStrategy.java b/hibernate-envers/src/main/java/org/hibernate/envers/event/spi/EnversListenerDuplicationStrategy.java similarity index 97% rename from hibernate-envers/src/main/java/org/hibernate/envers/event/EnversListenerDuplicationStrategy.java rename to hibernate-envers/src/main/java/org/hibernate/envers/event/spi/EnversListenerDuplicationStrategy.java index ae46616d89..d5442adc83 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/event/EnversListenerDuplicationStrategy.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/event/spi/EnversListenerDuplicationStrategy.java @@ -21,7 +21,7 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.event; +package org.hibernate.envers.event.spi; import org.hibernate.event.service.spi.DuplicationStrategy; diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/event/EnversPostCollectionRecreateEventListenerImpl.java b/hibernate-envers/src/main/java/org/hibernate/envers/event/spi/EnversPostCollectionRecreateEventListenerImpl.java similarity index 94% rename from hibernate-envers/src/main/java/org/hibernate/envers/event/EnversPostCollectionRecreateEventListenerImpl.java rename to hibernate-envers/src/main/java/org/hibernate/envers/event/spi/EnversPostCollectionRecreateEventListenerImpl.java index d4888da441..64c615dc4b 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/event/EnversPostCollectionRecreateEventListenerImpl.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/event/spi/EnversPostCollectionRecreateEventListenerImpl.java @@ -21,10 +21,10 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.event; +package org.hibernate.envers.event.spi; import org.hibernate.engine.spi.CollectionEntry; -import org.hibernate.envers.configuration.AuditConfiguration; +import org.hibernate.envers.configuration.spi.AuditConfiguration; import org.hibernate.event.spi.PostCollectionRecreateEvent; import org.hibernate.event.spi.PostCollectionRecreateEventListener; diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/event/EnversPostDeleteEventListenerImpl.java b/hibernate-envers/src/main/java/org/hibernate/envers/event/spi/EnversPostDeleteEventListenerImpl.java similarity index 89% rename from hibernate-envers/src/main/java/org/hibernate/envers/event/EnversPostDeleteEventListenerImpl.java rename to hibernate-envers/src/main/java/org/hibernate/envers/event/spi/EnversPostDeleteEventListenerImpl.java index 9a80ae803c..9782e25d79 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/event/EnversPostDeleteEventListenerImpl.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/event/spi/EnversPostDeleteEventListenerImpl.java @@ -21,12 +21,12 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.event; +package org.hibernate.envers.event.spi; -import org.hibernate.envers.configuration.AuditConfiguration; -import org.hibernate.envers.synchronization.AuditProcess; -import org.hibernate.envers.synchronization.work.AuditWorkUnit; -import org.hibernate.envers.synchronization.work.DelWorkUnit; +import org.hibernate.envers.configuration.spi.AuditConfiguration; +import org.hibernate.envers.internal.synchronization.AuditProcess; +import org.hibernate.envers.internal.synchronization.work.AuditWorkUnit; +import org.hibernate.envers.internal.synchronization.work.DelWorkUnit; import org.hibernate.event.spi.PostDeleteEvent; import org.hibernate.event.spi.PostDeleteEventListener; import org.hibernate.persister.entity.EntityPersister; diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/event/EnversPostInsertEventListenerImpl.java b/hibernate-envers/src/main/java/org/hibernate/envers/event/spi/EnversPostInsertEventListenerImpl.java similarity index 89% rename from hibernate-envers/src/main/java/org/hibernate/envers/event/EnversPostInsertEventListenerImpl.java rename to hibernate-envers/src/main/java/org/hibernate/envers/event/spi/EnversPostInsertEventListenerImpl.java index 7819b5b549..e0e8d48b2c 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/event/EnversPostInsertEventListenerImpl.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/event/spi/EnversPostInsertEventListenerImpl.java @@ -21,12 +21,12 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.event; +package org.hibernate.envers.event.spi; -import org.hibernate.envers.configuration.AuditConfiguration; -import org.hibernate.envers.synchronization.AuditProcess; -import org.hibernate.envers.synchronization.work.AddWorkUnit; -import org.hibernate.envers.synchronization.work.AuditWorkUnit; +import org.hibernate.envers.configuration.spi.AuditConfiguration; +import org.hibernate.envers.internal.synchronization.AuditProcess; +import org.hibernate.envers.internal.synchronization.work.AddWorkUnit; +import org.hibernate.envers.internal.synchronization.work.AuditWorkUnit; import org.hibernate.event.spi.PostInsertEvent; import org.hibernate.event.spi.PostInsertEventListener; import org.hibernate.persister.entity.EntityPersister; diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/event/EnversPostUpdateEventListenerImpl.java b/hibernate-envers/src/main/java/org/hibernate/envers/event/spi/EnversPostUpdateEventListenerImpl.java similarity index 91% rename from hibernate-envers/src/main/java/org/hibernate/envers/event/EnversPostUpdateEventListenerImpl.java rename to hibernate-envers/src/main/java/org/hibernate/envers/event/spi/EnversPostUpdateEventListenerImpl.java index d14819b3e4..ea399a5c63 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/event/EnversPostUpdateEventListenerImpl.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/event/spi/EnversPostUpdateEventListenerImpl.java @@ -21,12 +21,12 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.event; +package org.hibernate.envers.event.spi; -import org.hibernate.envers.configuration.AuditConfiguration; -import org.hibernate.envers.synchronization.AuditProcess; -import org.hibernate.envers.synchronization.work.AuditWorkUnit; -import org.hibernate.envers.synchronization.work.ModWorkUnit; +import org.hibernate.envers.configuration.spi.AuditConfiguration; +import org.hibernate.envers.internal.synchronization.AuditProcess; +import org.hibernate.envers.internal.synchronization.work.AuditWorkUnit; +import org.hibernate.envers.internal.synchronization.work.ModWorkUnit; import org.hibernate.event.spi.PostUpdateEvent; import org.hibernate.event.spi.PostUpdateEventListener; import org.hibernate.persister.entity.EntityPersister; diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/event/EnversPreCollectionRemoveEventListenerImpl.java b/hibernate-envers/src/main/java/org/hibernate/envers/event/spi/EnversPreCollectionRemoveEventListenerImpl.java similarity index 95% rename from hibernate-envers/src/main/java/org/hibernate/envers/event/EnversPreCollectionRemoveEventListenerImpl.java rename to hibernate-envers/src/main/java/org/hibernate/envers/event/spi/EnversPreCollectionRemoveEventListenerImpl.java index 84ed830874..aa4204f99a 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/event/EnversPreCollectionRemoveEventListenerImpl.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/event/spi/EnversPreCollectionRemoveEventListenerImpl.java @@ -21,12 +21,12 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.event; +package org.hibernate.envers.event.spi; import java.io.Serializable; import org.hibernate.engine.spi.CollectionEntry; -import org.hibernate.envers.configuration.AuditConfiguration; +import org.hibernate.envers.configuration.spi.AuditConfiguration; import org.hibernate.event.spi.PreCollectionRemoveEvent; import org.hibernate.event.spi.PreCollectionRemoveEventListener; diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/event/EnversPreCollectionUpdateEventListenerImpl.java b/hibernate-envers/src/main/java/org/hibernate/envers/event/spi/EnversPreCollectionUpdateEventListenerImpl.java similarity index 94% rename from hibernate-envers/src/main/java/org/hibernate/envers/event/EnversPreCollectionUpdateEventListenerImpl.java rename to hibernate-envers/src/main/java/org/hibernate/envers/event/spi/EnversPreCollectionUpdateEventListenerImpl.java index f494724956..a088c2c891 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/event/EnversPreCollectionUpdateEventListenerImpl.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/event/spi/EnversPreCollectionUpdateEventListenerImpl.java @@ -21,10 +21,10 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.event; +package org.hibernate.envers.event.spi; import org.hibernate.engine.spi.CollectionEntry; -import org.hibernate.envers.configuration.AuditConfiguration; +import org.hibernate.envers.configuration.spi.AuditConfiguration; import org.hibernate.event.spi.PreCollectionUpdateEvent; import org.hibernate.event.spi.PreCollectionUpdateEventListener; diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/entities/EntitiesConfigurations.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/EntitiesConfigurations.java similarity index 99% rename from hibernate-envers/src/main/java/org/hibernate/envers/entities/EntitiesConfigurations.java rename to hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/EntitiesConfigurations.java index 93a664e0af..0221e5229c 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/entities/EntitiesConfigurations.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/EntitiesConfigurations.java @@ -21,7 +21,7 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.entities; +package org.hibernate.envers.internal.entities; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/entities/EntityConfiguration.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/EntityConfiguration.java similarity index 95% rename from hibernate-envers/src/main/java/org/hibernate/envers/entities/EntityConfiguration.java rename to hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/EntityConfiguration.java index 97e5a3606c..ba5a59e81d 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/entities/EntityConfiguration.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/EntityConfiguration.java @@ -21,13 +21,13 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.entities; +package org.hibernate.envers.internal.entities; import java.util.HashMap; import java.util.Map; -import org.hibernate.envers.entities.mapper.ExtendedPropertyMapper; -import org.hibernate.envers.entities.mapper.PropertyMapper; -import org.hibernate.envers.entities.mapper.id.IdMapper; +import org.hibernate.envers.internal.entities.mapper.ExtendedPropertyMapper; +import org.hibernate.envers.internal.entities.mapper.PropertyMapper; +import org.hibernate.envers.internal.entities.mapper.id.IdMapper; /** * @author Adam Warski (adam at warski dot org) diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/entities/EntityInstantiator.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/EntityInstantiator.java similarity index 91% rename from hibernate-envers/src/main/java/org/hibernate/envers/entities/EntityInstantiator.java rename to hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/EntityInstantiator.java index 39f8f414ca..cf9cf211cb 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/entities/EntityInstantiator.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/EntityInstantiator.java @@ -21,23 +21,24 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.entities; - -import org.hibernate.envers.RevisionType; -import org.hibernate.envers.configuration.AuditConfiguration; -import org.hibernate.envers.entities.mapper.id.IdMapper; -import org.hibernate.envers.entities.mapper.relation.lazy.ToOneDelegateSessionImplementor; -import org.hibernate.envers.exception.AuditException; -import org.hibernate.envers.reader.AuditReaderImplementor; -import org.hibernate.internal.util.ReflectHelper; -import org.hibernate.proxy.HibernateProxy; -import org.hibernate.proxy.LazyInitializer; +package org.hibernate.envers.internal.entities; import java.io.Serializable; import java.util.Collection; import java.util.List; import java.util.Map; +import org.hibernate.envers.RevisionType; +import org.hibernate.envers.configuration.spi.AuditConfiguration; +import org.hibernate.envers.exception.AuditException; +import org.hibernate.envers.internal.entities.mapper.id.IdMapper; +import org.hibernate.envers.internal.entities.mapper.relation.lazy.ToOneDelegateSessionImplementor; +import org.hibernate.envers.internal.reader.AuditReaderImplementor; +import org.hibernate.envers.internal.tools.ReflectionTools; +import org.hibernate.internal.util.ReflectHelper; +import org.hibernate.proxy.HibernateProxy; +import org.hibernate.proxy.LazyInitializer; + /** * @author Adam Warski (adam at warski dot org) * @author Hernán Chanfreau @@ -96,7 +97,7 @@ public Object createInstanceFromVersionsEntity(String entityName, Map versionsEn entCfg = verCfg.getEntCfg().getNotVersionEntityConfiguration(entityName); } - Class cls = ReflectHelper.classForName(entCfg.getEntityClassName()); + Class cls = ReflectionTools.loadClass( entCfg.getEntityClassName(), verCfg.getClassLoaderService() ); ret = ReflectHelper.getDefaultConstructor(cls).newInstance(); } catch (Exception e) { throw new AuditException(e); @@ -128,13 +129,7 @@ private void replaceNonAuditIdProxies(Map versionsEntity, Number revision) { final Serializable entityId = initializer.getIdentifier(); if (verCfg.getEntCfg().isVersioned(entityName)) { final String entityClassName = verCfg.getEntCfg().get(entityName).getEntityClassName(); - Class entityClass; - try { - entityClass = ReflectHelper.classForName(entityClassName); - } - catch ( ClassNotFoundException e ) { - throw new AuditException( e ); - } + final Class entityClass = ReflectionTools.loadClass( entityClassName, verCfg.getClassLoaderService() ); final ToOneDelegateSessionImplementor delegate = new ToOneDelegateSessionImplementor( versionsReader, entityClass, entityId, revision, RevisionType.DEL.equals( versionsEntity.get( verCfg.getAuditEntCfg().getRevisionTypePropName() ) ), diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/entities/IdMappingData.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/IdMappingData.java similarity index 94% rename from hibernate-envers/src/main/java/org/hibernate/envers/entities/IdMappingData.java rename to hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/IdMappingData.java index ce1dd8671d..e554f28eeb 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/entities/IdMappingData.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/IdMappingData.java @@ -21,10 +21,10 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.entities; +package org.hibernate.envers.internal.entities; import org.dom4j.Element; -import org.hibernate.envers.entities.mapper.id.IdMapper; +import org.hibernate.envers.internal.entities.mapper.id.IdMapper; /** * @author Adam Warski (adam at warski dot org) diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/entities/PropertyData.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/PropertyData.java similarity index 98% rename from hibernate-envers/src/main/java/org/hibernate/envers/entities/PropertyData.java rename to hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/PropertyData.java index 672430d5e5..0494d2db7b 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/entities/PropertyData.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/PropertyData.java @@ -21,7 +21,7 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.entities; +package org.hibernate.envers.internal.entities; import org.hibernate.envers.ModificationStore; /** diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/entities/RelationDescription.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/RelationDescription.java similarity index 94% rename from hibernate-envers/src/main/java/org/hibernate/envers/entities/RelationDescription.java rename to hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/RelationDescription.java index ab0b12d241..b129500944 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/entities/RelationDescription.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/RelationDescription.java @@ -21,9 +21,9 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.entities; -import org.hibernate.envers.entities.mapper.PropertyMapper; -import org.hibernate.envers.entities.mapper.id.IdMapper; +package org.hibernate.envers.internal.entities; +import org.hibernate.envers.internal.entities.mapper.PropertyMapper; +import org.hibernate.envers.internal.entities.mapper.id.IdMapper; /** * @author Adam Warski (adam at warski dot org) diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/entities/RelationType.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/RelationType.java similarity index 97% rename from hibernate-envers/src/main/java/org/hibernate/envers/entities/RelationType.java rename to hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/RelationType.java index 93759b588f..449b4ecfd9 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/entities/RelationType.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/RelationType.java @@ -21,7 +21,7 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.entities; +package org.hibernate.envers.internal.entities; /** diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/entities/RevisionTypeType.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/RevisionTypeType.java similarity index 98% rename from hibernate-envers/src/main/java/org/hibernate/envers/entities/RevisionTypeType.java rename to hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/RevisionTypeType.java index 2fcef4f29d..0580c804c2 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/entities/RevisionTypeType.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/RevisionTypeType.java @@ -21,7 +21,7 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.entities; +package org.hibernate.envers.internal.entities; import java.io.Serializable; import java.sql.PreparedStatement; diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/ComponentPropertyMapper.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/ComponentPropertyMapper.java similarity index 89% rename from hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/ComponentPropertyMapper.java rename to hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/ComponentPropertyMapper.java index 045adf7813..52d0323998 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/ComponentPropertyMapper.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/ComponentPropertyMapper.java @@ -21,7 +21,7 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.entities.mapper; +package org.hibernate.envers.internal.entities.mapper; import java.io.Serializable; import java.util.HashMap; @@ -30,11 +30,11 @@ import org.hibernate.collection.spi.PersistentCollection; import org.hibernate.engine.spi.SessionImplementor; -import org.hibernate.envers.configuration.AuditConfiguration; -import org.hibernate.envers.entities.PropertyData; +import org.hibernate.envers.configuration.spi.AuditConfiguration; import org.hibernate.envers.exception.AuditException; -import org.hibernate.envers.reader.AuditReaderImplementor; -import org.hibernate.envers.tools.reflection.ReflectionTools; +import org.hibernate.envers.internal.entities.PropertyData; +import org.hibernate.envers.internal.reader.AuditReaderImplementor; +import org.hibernate.envers.internal.tools.ReflectionTools; import org.hibernate.internal.util.ReflectHelper; import org.hibernate.property.Setter; @@ -45,20 +45,20 @@ public class ComponentPropertyMapper implements PropertyMapper, CompositeMapperBuilder { private final PropertyData propertyData; private final MultiPropertyMapper delegate; - private final String componentClassName; + private final Class componentClass; - public ComponentPropertyMapper(PropertyData propertyData, String componentClassName) { + public ComponentPropertyMapper(PropertyData propertyData, Class componentClass) { this.propertyData = propertyData; this.delegate = new MultiPropertyMapper(); - this.componentClassName = componentClassName; + this.componentClass = componentClass; } public void add(PropertyData propertyData) { delegate.add(propertyData); } - public CompositeMapperBuilder addComponent(PropertyData propertyData, String componentClassName) { - return delegate.addComponent(propertyData, componentClassName); + public CompositeMapperBuilder addComponent(PropertyData propertyData, Class componentClass) { + return delegate.addComponent(propertyData, componentClass); } public void addComposite(PropertyData propertyData, PropertyMapper propertyMapper) { @@ -120,8 +120,7 @@ public void mapToEntityFromMap(AuditConfiguration verCfg, Object obj, Map data, } else { // set the component try { - Object subObj = ReflectHelper.getDefaultConstructor( - ReflectHelper.classForName(componentClassName)).newInstance(); + Object subObj = ReflectHelper.getDefaultConstructor(componentClass).newInstance(); setter.set(obj, subObj, null); delegate.mapToEntityFromMap(verCfg, subObj, data, primaryKey, versionsReader, revision); } catch (Exception e) { diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/CompositeMapperBuilder.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/CompositeMapperBuilder.java similarity index 90% rename from hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/CompositeMapperBuilder.java rename to hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/CompositeMapperBuilder.java index 420c47fe90..c863249ea0 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/CompositeMapperBuilder.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/CompositeMapperBuilder.java @@ -21,17 +21,17 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.entities.mapper; +package org.hibernate.envers.internal.entities.mapper; import java.util.Map; -import org.hibernate.envers.entities.PropertyData; +import org.hibernate.envers.internal.entities.PropertyData; /** * @author Adam Warski (adam at warski dot org) */ public interface CompositeMapperBuilder extends SimpleMapperBuilder { - public CompositeMapperBuilder addComponent(PropertyData propertyData, String componentClassName); + public CompositeMapperBuilder addComponent(PropertyData propertyData, Class componentClass); public void addComposite(PropertyData propertyData, PropertyMapper propertyMapper); public Map getProperties(); } diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/ExtendedPropertyMapper.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/ExtendedPropertyMapper.java similarity index 96% rename from hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/ExtendedPropertyMapper.java rename to hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/ExtendedPropertyMapper.java index a2644c74ac..a804087836 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/ExtendedPropertyMapper.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/ExtendedPropertyMapper.java @@ -21,7 +21,7 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.entities.mapper; +package org.hibernate.envers.internal.entities.mapper; import java.util.Map; import org.hibernate.engine.spi.SessionImplementor; diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/MultiPropertyMapper.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/MultiPropertyMapper.java similarity index 93% rename from hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/MultiPropertyMapper.java rename to hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/MultiPropertyMapper.java index 018a4c90ed..cff9d7aff1 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/MultiPropertyMapper.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/MultiPropertyMapper.java @@ -21,20 +21,21 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.entities.mapper; +package org.hibernate.envers.internal.entities.mapper; + import java.io.Serializable; import java.util.List; import java.util.Map; import org.hibernate.collection.spi.PersistentCollection; import org.hibernate.engine.spi.SessionImplementor; -import org.hibernate.envers.configuration.AuditConfiguration; -import org.hibernate.envers.entities.PropertyData; -import org.hibernate.envers.reader.AuditReaderImplementor; -import org.hibernate.envers.tools.MappingTools; +import org.hibernate.envers.configuration.spi.AuditConfiguration; +import org.hibernate.envers.internal.entities.PropertyData; +import org.hibernate.envers.internal.reader.AuditReaderImplementor; +import org.hibernate.envers.internal.tools.MappingTools; +import org.hibernate.envers.internal.tools.ReflectionTools; +import org.hibernate.envers.internal.tools.Tools; import org.hibernate.envers.tools.Pair; -import org.hibernate.envers.tools.Tools; -import org.hibernate.envers.tools.reflection.ReflectionTools; import org.hibernate.property.Getter; /** @@ -57,13 +58,13 @@ public void add(PropertyData propertyData) { propertyDatas.put(propertyData.getName(), propertyData); } - public CompositeMapperBuilder addComponent(PropertyData propertyData, String componentClassName) { + public CompositeMapperBuilder addComponent(PropertyData propertyData, Class componentClass) { if (properties.get(propertyData) != null) { // This is needed for second pass to work properly in the components mapper return (CompositeMapperBuilder) properties.get(propertyData); } - ComponentPropertyMapper componentMapperBuilder = new ComponentPropertyMapper(propertyData, componentClassName); + ComponentPropertyMapper componentMapperBuilder = new ComponentPropertyMapper(propertyData, componentClass); addComposite(propertyData, componentMapperBuilder); return componentMapperBuilder; diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/PersistentCollectionChangeData.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/PersistentCollectionChangeData.java similarity index 98% rename from hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/PersistentCollectionChangeData.java rename to hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/PersistentCollectionChangeData.java index 3c608771bc..cce22395ee 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/PersistentCollectionChangeData.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/PersistentCollectionChangeData.java @@ -21,7 +21,7 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.entities.mapper; +package org.hibernate.envers.internal.entities.mapper; import java.util.Map; import org.hibernate.envers.tools.Pair; diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/PropertyMapper.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/PropertyMapper.java similarity index 94% rename from hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/PropertyMapper.java rename to hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/PropertyMapper.java index d2b1bfcfb5..f8e23b044e 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/PropertyMapper.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/PropertyMapper.java @@ -21,15 +21,15 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.entities.mapper; +package org.hibernate.envers.internal.entities.mapper; import java.io.Serializable; import java.util.List; import java.util.Map; import org.hibernate.collection.spi.PersistentCollection; import org.hibernate.engine.spi.SessionImplementor; -import org.hibernate.envers.configuration.AuditConfiguration; -import org.hibernate.envers.reader.AuditReaderImplementor; +import org.hibernate.envers.configuration.spi.AuditConfiguration; +import org.hibernate.envers.internal.reader.AuditReaderImplementor; /** * @author Adam Warski (adam at warski dot org) diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/SimpleMapperBuilder.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/SimpleMapperBuilder.java similarity index 91% rename from hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/SimpleMapperBuilder.java rename to hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/SimpleMapperBuilder.java index d79eee1780..6843e62c63 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/SimpleMapperBuilder.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/SimpleMapperBuilder.java @@ -21,8 +21,8 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.entities.mapper; -import org.hibernate.envers.entities.PropertyData; +package org.hibernate.envers.internal.entities.mapper; +import org.hibernate.envers.internal.entities.PropertyData; /** * @author Adam Warski (adam at warski dot org) diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/SinglePropertyMapper.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/SinglePropertyMapper.java similarity index 92% rename from hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/SinglePropertyMapper.java rename to hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/SinglePropertyMapper.java index fd20bec1fe..329955604e 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/SinglePropertyMapper.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/SinglePropertyMapper.java @@ -21,7 +21,8 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.entities.mapper; +package org.hibernate.envers.internal.entities.mapper; + import java.io.Serializable; import java.util.List; import java.util.Map; @@ -30,13 +31,13 @@ import org.hibernate.collection.spi.PersistentCollection; import org.hibernate.dialect.Oracle8iDialect; import org.hibernate.engine.spi.SessionImplementor; -import org.hibernate.envers.configuration.AuditConfiguration; -import org.hibernate.envers.entities.PropertyData; +import org.hibernate.envers.configuration.spi.AuditConfiguration; import org.hibernate.envers.exception.AuditException; -import org.hibernate.envers.reader.AuditReaderImplementor; -import org.hibernate.envers.tools.StringTools; -import org.hibernate.envers.tools.Tools; -import org.hibernate.envers.tools.reflection.ReflectionTools; +import org.hibernate.envers.internal.entities.PropertyData; +import org.hibernate.envers.internal.reader.AuditReaderImplementor; +import org.hibernate.envers.internal.tools.ReflectionTools; +import org.hibernate.envers.internal.tools.StringTools; +import org.hibernate.envers.internal.tools.Tools; import org.hibernate.property.DirectPropertyAccessor; import org.hibernate.property.Setter; diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/SubclassPropertyMapper.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/SubclassPropertyMapper.java similarity index 93% rename from hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/SubclassPropertyMapper.java rename to hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/SubclassPropertyMapper.java index a9a703f936..f673d6e5a9 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/SubclassPropertyMapper.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/SubclassPropertyMapper.java @@ -21,7 +21,7 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.entities.mapper; +package org.hibernate.envers.internal.entities.mapper; import java.io.Serializable; import java.util.HashMap; import java.util.List; @@ -29,9 +29,9 @@ import org.hibernate.collection.spi.PersistentCollection; import org.hibernate.engine.spi.SessionImplementor; -import org.hibernate.envers.configuration.AuditConfiguration; -import org.hibernate.envers.entities.PropertyData; -import org.hibernate.envers.reader.AuditReaderImplementor; +import org.hibernate.envers.configuration.spi.AuditConfiguration; +import org.hibernate.envers.internal.entities.PropertyData; +import org.hibernate.envers.internal.reader.AuditReaderImplementor; /** * A mapper which maps from a parent mapper and a "main" one, but adds only to the "main". The "main" mapper @@ -98,8 +98,8 @@ public List mapCollectionChanges(SessionImplemen } } - public CompositeMapperBuilder addComponent(PropertyData propertyData, String componentClassName) { - return main.addComponent(propertyData, componentClassName); + public CompositeMapperBuilder addComponent(PropertyData propertyData, Class componentClass) { + return main.addComponent(propertyData, componentClass); } public void addComposite(PropertyData propertyData, PropertyMapper propertyMapper) { diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/id/AbstractCompositeIdMapper.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/id/AbstractCompositeIdMapper.java similarity index 83% rename from hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/id/AbstractCompositeIdMapper.java rename to hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/id/AbstractCompositeIdMapper.java index da020efd9f..c60531148a 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/id/AbstractCompositeIdMapper.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/id/AbstractCompositeIdMapper.java @@ -21,12 +21,13 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.entities.mapper.id; +package org.hibernate.envers.internal.entities.mapper.id; + import java.util.Map; -import org.hibernate.envers.entities.PropertyData; import org.hibernate.envers.exception.AuditException; -import org.hibernate.envers.tools.Tools; +import org.hibernate.envers.internal.entities.PropertyData; +import org.hibernate.envers.internal.tools.Tools; import org.hibernate.internal.util.ReflectHelper; /** @@ -35,11 +36,10 @@ */ public abstract class AbstractCompositeIdMapper extends AbstractIdMapper implements SimpleIdMapperBuilder { protected Map ids; - protected String compositeIdClass; + protected Class compositeIdClass; - protected AbstractCompositeIdMapper(String compositeIdClass) { + protected AbstractCompositeIdMapper(Class compositeIdClass) { ids = Tools.newLinkedHashMap(); - this.compositeIdClass = compositeIdClass; } @@ -54,8 +54,7 @@ public Object mapToIdFromMap(Map data) { Object ret; try { - final Class clazz = ReflectHelper.classForName(compositeIdClass); - ret = ReflectHelper.getDefaultConstructor(clazz).newInstance(); + ret = ReflectHelper.getDefaultConstructor(compositeIdClass).newInstance(); } catch (Exception e) { throw new AuditException(e); } diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/id/AbstractIdMapper.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/id/AbstractIdMapper.java similarity index 97% rename from hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/id/AbstractIdMapper.java rename to hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/id/AbstractIdMapper.java index d4f24ffe29..111c7b6c54 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/id/AbstractIdMapper.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/id/AbstractIdMapper.java @@ -21,11 +21,11 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.entities.mapper.id; +package org.hibernate.envers.internal.entities.mapper.id; import java.util.Iterator; import java.util.List; -import org.hibernate.envers.tools.query.Parameters; +import org.hibernate.envers.internal.tools.query.Parameters; /** * @author Adam Warski (adam at warski dot org) diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/id/EmbeddedIdMapper.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/id/EmbeddedIdMapper.java similarity index 93% rename from hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/id/EmbeddedIdMapper.java rename to hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/id/EmbeddedIdMapper.java index efa73cff27..4cdc539f91 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/id/EmbeddedIdMapper.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/id/EmbeddedIdMapper.java @@ -21,16 +21,16 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.entities.mapper.id; +package org.hibernate.envers.internal.entities.mapper.id; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; -import org.hibernate.envers.entities.PropertyData; import org.hibernate.envers.exception.AuditException; -import org.hibernate.envers.tools.reflection.ReflectionTools; +import org.hibernate.envers.internal.entities.PropertyData; +import org.hibernate.envers.internal.tools.ReflectionTools; import org.hibernate.internal.util.ReflectHelper; import org.hibernate.property.Getter; import org.hibernate.property.Setter; @@ -41,7 +41,7 @@ public class EmbeddedIdMapper extends AbstractCompositeIdMapper implements SimpleIdMapperBuilder { private PropertyData idPropertyData; - public EmbeddedIdMapper(PropertyData idPropertyData, String compositeIdClass) { + public EmbeddedIdMapper(PropertyData idPropertyData, Class compositeIdClass) { super(compositeIdClass); this.idPropertyData = idPropertyData; diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/id/IdMapper.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/id/IdMapper.java similarity index 97% rename from hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/id/IdMapper.java rename to hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/id/IdMapper.java index 3bdb1dd43d..c490b1ea1f 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/id/IdMapper.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/id/IdMapper.java @@ -21,11 +21,11 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.entities.mapper.id; +package org.hibernate.envers.internal.entities.mapper.id; import java.util.List; import java.util.Map; -import org.hibernate.envers.tools.query.Parameters; +import org.hibernate.envers.internal.tools.query.Parameters; /** * @author Adam Warski (adam at warski dot org) diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/id/MultipleIdMapper.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/id/MultipleIdMapper.java similarity index 91% rename from hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/id/MultipleIdMapper.java rename to hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/id/MultipleIdMapper.java index 1607971499..25f5e4a1a5 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/id/MultipleIdMapper.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/id/MultipleIdMapper.java @@ -21,21 +21,22 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.entities.mapper.id; +package org.hibernate.envers.internal.entities.mapper.id; + import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; -import org.hibernate.envers.entities.PropertyData; import org.hibernate.envers.exception.AuditException; +import org.hibernate.envers.internal.entities.PropertyData; import org.hibernate.internal.util.ReflectHelper; /** * @author Adam Warski (adam at warski dot org) */ public class MultipleIdMapper extends AbstractCompositeIdMapper implements SimpleIdMapperBuilder { - public MultipleIdMapper(String compositeIdClass) { + public MultipleIdMapper(Class compositeIdClass) { super(compositeIdClass); } @@ -76,8 +77,7 @@ public Object mapToIdFromEntity(Object data) { Object ret; try { - final Class clazz = ReflectHelper.classForName(compositeIdClass); - ret = ReflectHelper.getDefaultConstructor(clazz).newInstance(); + ret = ReflectHelper.getDefaultConstructor(compositeIdClass).newInstance(); } catch (Exception e) { throw new AuditException(e); } diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/id/QueryParameterData.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/id/QueryParameterData.java similarity index 97% rename from hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/id/QueryParameterData.java rename to hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/id/QueryParameterData.java index 62635a1a32..75201a220d 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/id/QueryParameterData.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/id/QueryParameterData.java @@ -21,7 +21,7 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.entities.mapper.id; +package org.hibernate.envers.internal.entities.mapper.id; import org.hibernate.Query; /** diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/id/SimpleIdMapperBuilder.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/id/SimpleIdMapperBuilder.java similarity index 90% rename from hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/id/SimpleIdMapperBuilder.java rename to hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/id/SimpleIdMapperBuilder.java index 332796c09d..12039e4de2 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/id/SimpleIdMapperBuilder.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/id/SimpleIdMapperBuilder.java @@ -21,8 +21,8 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.entities.mapper.id; -import org.hibernate.envers.entities.mapper.SimpleMapperBuilder; +package org.hibernate.envers.internal.entities.mapper.id; +import org.hibernate.envers.internal.entities.mapper.SimpleMapperBuilder; /** * @author Adam Warski (adam at warski dot org) diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/id/SingleIdMapper.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/id/SingleIdMapper.java similarity index 96% rename from hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/id/SingleIdMapper.java rename to hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/id/SingleIdMapper.java index 98f3b80fd7..0f14c16c4f 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/id/SingleIdMapper.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/id/SingleIdMapper.java @@ -21,14 +21,15 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.entities.mapper.id; +package org.hibernate.envers.internal.entities.mapper.id; + import java.util.ArrayList; import java.util.List; import java.util.Map; -import org.hibernate.envers.entities.PropertyData; import org.hibernate.envers.exception.AuditException; -import org.hibernate.envers.tools.reflection.ReflectionTools; +import org.hibernate.envers.internal.entities.PropertyData; +import org.hibernate.envers.internal.tools.ReflectionTools; import org.hibernate.property.Getter; import org.hibernate.property.Setter; import org.hibernate.proxy.HibernateProxy; diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/AbstractCollectionMapper.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/AbstractCollectionMapper.java similarity index 93% rename from hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/AbstractCollectionMapper.java rename to hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/AbstractCollectionMapper.java index 756f4b857d..8fa96a4113 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/AbstractCollectionMapper.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/AbstractCollectionMapper.java @@ -21,7 +21,7 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.entities.mapper.relation; +package org.hibernate.envers.internal.entities.mapper.relation; import java.io.Serializable; import java.lang.reflect.Constructor; @@ -37,15 +37,15 @@ import org.hibernate.collection.spi.PersistentCollection; import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.envers.RevisionType; -import org.hibernate.envers.configuration.AuditConfiguration; -import org.hibernate.envers.entities.PropertyData; -import org.hibernate.envers.entities.mapper.PersistentCollectionChangeData; -import org.hibernate.envers.entities.mapper.PropertyMapper; -import org.hibernate.envers.entities.mapper.relation.lazy.initializor.Initializor; +import org.hibernate.envers.configuration.spi.AuditConfiguration; import org.hibernate.envers.exception.AuditException; -import org.hibernate.envers.reader.AuditReaderImplementor; -import org.hibernate.envers.tools.Tools; -import org.hibernate.envers.tools.reflection.ReflectionTools; +import org.hibernate.envers.internal.entities.PropertyData; +import org.hibernate.envers.internal.entities.mapper.PersistentCollectionChangeData; +import org.hibernate.envers.internal.entities.mapper.PropertyMapper; +import org.hibernate.envers.internal.entities.mapper.relation.lazy.initializor.Initializor; +import org.hibernate.envers.internal.reader.AuditReaderImplementor; +import org.hibernate.envers.internal.tools.ReflectionTools; +import org.hibernate.envers.internal.tools.Tools; import org.hibernate.property.Setter; /** diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/AbstractOneToOneMapper.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/AbstractOneToOneMapper.java similarity index 91% rename from hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/AbstractOneToOneMapper.java rename to hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/AbstractOneToOneMapper.java index b1440b7305..31fe58fc19 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/AbstractOneToOneMapper.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/AbstractOneToOneMapper.java @@ -1,4 +1,4 @@ -package org.hibernate.envers.entities.mapper.relation; +package org.hibernate.envers.internal.entities.mapper.relation; import java.io.Serializable; import java.util.Map; @@ -6,10 +6,10 @@ import org.hibernate.NonUniqueResultException; import org.hibernate.engine.spi.SessionImplementor; -import org.hibernate.envers.configuration.AuditConfiguration; -import org.hibernate.envers.entities.PropertyData; +import org.hibernate.envers.configuration.spi.AuditConfiguration; import org.hibernate.envers.exception.AuditException; -import org.hibernate.envers.reader.AuditReaderImplementor; +import org.hibernate.envers.internal.entities.PropertyData; +import org.hibernate.envers.internal.reader.AuditReaderImplementor; /** * Template class for property mappers that manage one-to-one relation. diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/AbstractToOneMapper.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/AbstractToOneMapper.java similarity index 81% rename from hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/AbstractToOneMapper.java rename to hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/AbstractToOneMapper.java index b47a2cd3a7..80fcec3bbf 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/AbstractToOneMapper.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/AbstractToOneMapper.java @@ -1,4 +1,4 @@ -package org.hibernate.envers.entities.mapper.relation; +package org.hibernate.envers.internal.entities.mapper.relation; import java.io.Serializable; import java.util.List; @@ -6,15 +6,13 @@ import org.hibernate.collection.spi.PersistentCollection; import org.hibernate.engine.spi.SessionImplementor; -import org.hibernate.envers.configuration.AuditConfiguration; -import org.hibernate.envers.entities.EntityConfiguration; -import org.hibernate.envers.entities.PropertyData; -import org.hibernate.envers.entities.mapper.PersistentCollectionChangeData; -import org.hibernate.envers.entities.mapper.PropertyMapper; -import org.hibernate.envers.exception.AuditException; -import org.hibernate.envers.reader.AuditReaderImplementor; -import org.hibernate.envers.tools.reflection.ReflectionTools; -import org.hibernate.internal.util.ReflectHelper; +import org.hibernate.envers.configuration.spi.AuditConfiguration; +import org.hibernate.envers.internal.entities.EntityConfiguration; +import org.hibernate.envers.internal.entities.PropertyData; +import org.hibernate.envers.internal.entities.mapper.PersistentCollectionChangeData; +import org.hibernate.envers.internal.entities.mapper.PropertyMapper; +import org.hibernate.envers.internal.reader.AuditReaderImplementor; +import org.hibernate.envers.internal.tools.ReflectionTools; import org.hibernate.property.Setter; /** @@ -61,13 +59,7 @@ protected EntityInfo getEntityInfo(AuditConfiguration verCfg, String entityName) entCfg = verCfg.getEntCfg().getNotVersionEntityConfiguration(entityName); isRelationAudited = false; } - Class entityClass; - try { - entityClass = ReflectHelper.classForName(entCfg.getEntityClassName()); - } - catch ( ClassNotFoundException e ) { - throw new AuditException( e ); - } + Class entityClass = ReflectionTools.loadClass( entCfg.getEntityClassName(), verCfg.getClassLoaderService() ); return new EntityInfo(entityClass, entityName, isRelationAudited); } diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/BasicCollectionMapper.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/BasicCollectionMapper.java similarity index 86% rename from hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/BasicCollectionMapper.java rename to hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/BasicCollectionMapper.java index 1c934f6f7a..49a2db0ed9 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/BasicCollectionMapper.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/BasicCollectionMapper.java @@ -21,7 +21,7 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.entities.mapper.relation; +package org.hibernate.envers.internal.entities.mapper.relation; import java.io.Serializable; import java.util.Collection; @@ -29,11 +29,11 @@ import org.hibernate.collection.spi.PersistentCollection; import org.hibernate.engine.spi.SessionImplementor; -import org.hibernate.envers.configuration.AuditConfiguration; -import org.hibernate.envers.entities.mapper.PropertyMapper; -import org.hibernate.envers.entities.mapper.relation.lazy.initializor.BasicCollectionInitializor; -import org.hibernate.envers.entities.mapper.relation.lazy.initializor.Initializor; -import org.hibernate.envers.reader.AuditReaderImplementor; +import org.hibernate.envers.configuration.spi.AuditConfiguration; +import org.hibernate.envers.internal.entities.mapper.PropertyMapper; +import org.hibernate.envers.internal.entities.mapper.relation.lazy.initializor.BasicCollectionInitializor; +import org.hibernate.envers.internal.entities.mapper.relation.lazy.initializor.Initializor; +import org.hibernate.envers.internal.reader.AuditReaderImplementor; /** * @author Adam Warski (adam at warski dot org) diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/CommonCollectionMapperData.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/CommonCollectionMapperData.java similarity index 89% rename from hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/CommonCollectionMapperData.java rename to hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/CommonCollectionMapperData.java index fcb784885b..dc22be02d1 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/CommonCollectionMapperData.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/CommonCollectionMapperData.java @@ -21,10 +21,10 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.entities.mapper.relation; -import org.hibernate.envers.configuration.AuditEntitiesConfiguration; -import org.hibernate.envers.entities.PropertyData; -import org.hibernate.envers.entities.mapper.relation.query.RelationQueryGenerator; +package org.hibernate.envers.internal.entities.mapper.relation; +import org.hibernate.envers.configuration.internal.AuditEntitiesConfiguration; +import org.hibernate.envers.internal.entities.PropertyData; +import org.hibernate.envers.internal.entities.mapper.relation.query.RelationQueryGenerator; /** * Data that is used by all collection mappers, regardless of the type. diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/ListCollectionMapper.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/ListCollectionMapper.java similarity index 85% rename from hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/ListCollectionMapper.java rename to hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/ListCollectionMapper.java index f883e68a79..26d6ce3398 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/ListCollectionMapper.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/ListCollectionMapper.java @@ -21,7 +21,8 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.entities.mapper.relation; +package org.hibernate.envers.internal.entities.mapper.relation; + import java.io.Serializable; import java.util.Collection; import java.util.List; @@ -29,14 +30,14 @@ import org.hibernate.collection.spi.PersistentCollection; import org.hibernate.engine.spi.SessionImplementor; -import org.hibernate.envers.configuration.AuditConfiguration; -import org.hibernate.envers.entities.mapper.PropertyMapper; -import org.hibernate.envers.entities.mapper.relation.lazy.initializor.Initializor; -import org.hibernate.envers.entities.mapper.relation.lazy.initializor.ListCollectionInitializor; -import org.hibernate.envers.entities.mapper.relation.lazy.proxy.ListProxy; -import org.hibernate.envers.reader.AuditReaderImplementor; +import org.hibernate.envers.configuration.spi.AuditConfiguration; +import org.hibernate.envers.internal.entities.mapper.PropertyMapper; +import org.hibernate.envers.internal.entities.mapper.relation.lazy.initializor.Initializor; +import org.hibernate.envers.internal.entities.mapper.relation.lazy.initializor.ListCollectionInitializor; +import org.hibernate.envers.internal.entities.mapper.relation.lazy.proxy.ListProxy; +import org.hibernate.envers.internal.reader.AuditReaderImplementor; +import org.hibernate.envers.internal.tools.Tools; import org.hibernate.envers.tools.Pair; -import org.hibernate.envers.tools.Tools; /** * @author Adam Warski (adam at warski dot org) diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/MapCollectionMapper.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/MapCollectionMapper.java similarity index 87% rename from hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/MapCollectionMapper.java rename to hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/MapCollectionMapper.java index 44f1ec8827..a2f6d46ea4 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/MapCollectionMapper.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/MapCollectionMapper.java @@ -21,7 +21,7 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.entities.mapper.relation; +package org.hibernate.envers.internal.entities.mapper.relation; import java.io.Serializable; import java.util.Collection; @@ -29,11 +29,11 @@ import org.hibernate.collection.spi.PersistentCollection; import org.hibernate.engine.spi.SessionImplementor; -import org.hibernate.envers.configuration.AuditConfiguration; -import org.hibernate.envers.entities.mapper.PropertyMapper; -import org.hibernate.envers.entities.mapper.relation.lazy.initializor.Initializor; -import org.hibernate.envers.entities.mapper.relation.lazy.initializor.MapCollectionInitializor; -import org.hibernate.envers.reader.AuditReaderImplementor; +import org.hibernate.envers.configuration.spi.AuditConfiguration; +import org.hibernate.envers.internal.entities.mapper.PropertyMapper; +import org.hibernate.envers.internal.entities.mapper.relation.lazy.initializor.Initializor; +import org.hibernate.envers.internal.entities.mapper.relation.lazy.initializor.MapCollectionInitializor; +import org.hibernate.envers.internal.reader.AuditReaderImplementor; /** * @author Adam Warski (adam at warski dot org) diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/MiddleComponentData.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/MiddleComponentData.java similarity index 92% rename from hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/MiddleComponentData.java rename to hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/MiddleComponentData.java index 2a534ff5c5..7ac2ff25b1 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/MiddleComponentData.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/MiddleComponentData.java @@ -21,8 +21,8 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.entities.mapper.relation; -import org.hibernate.envers.entities.mapper.relation.component.MiddleComponentMapper; +package org.hibernate.envers.internal.entities.mapper.relation; +import org.hibernate.envers.internal.entities.mapper.relation.component.MiddleComponentMapper; /** * A data holder for a middle relation component (which is either the collection element or index): diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/MiddleIdData.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/MiddleIdData.java similarity index 91% rename from hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/MiddleIdData.java rename to hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/MiddleIdData.java index ecde6d77bd..8d688e541e 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/MiddleIdData.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/MiddleIdData.java @@ -21,10 +21,10 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.entities.mapper.relation; -import org.hibernate.envers.configuration.AuditEntitiesConfiguration; -import org.hibernate.envers.entities.IdMappingData; -import org.hibernate.envers.entities.mapper.id.IdMapper; +package org.hibernate.envers.internal.entities.mapper.relation; +import org.hibernate.envers.configuration.internal.AuditEntitiesConfiguration; +import org.hibernate.envers.internal.entities.IdMappingData; +import org.hibernate.envers.internal.entities.mapper.id.IdMapper; /** * A class holding information about ids, which form a virtual "relation" from a middle-table. Middle-tables are used diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/OneToOneNotOwningMapper.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/OneToOneNotOwningMapper.java similarity index 92% rename from hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/OneToOneNotOwningMapper.java rename to hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/OneToOneNotOwningMapper.java index 2eeb2ff2ef..c56754876b 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/OneToOneNotOwningMapper.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/OneToOneNotOwningMapper.java @@ -21,14 +21,14 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.entities.mapper.relation; +package org.hibernate.envers.internal.entities.mapper.relation; import java.io.Serializable; import javax.persistence.OneToOne; -import org.hibernate.envers.entities.PropertyData; +import org.hibernate.envers.internal.entities.PropertyData; +import org.hibernate.envers.internal.reader.AuditReaderImplementor; import org.hibernate.envers.query.AuditEntity; -import org.hibernate.envers.reader.AuditReaderImplementor; /** * Property mapper for not owning side of {@link OneToOne} relation. diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/OneToOnePrimaryKeyJoinColumnMapper.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/OneToOnePrimaryKeyJoinColumnMapper.java similarity index 93% rename from hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/OneToOnePrimaryKeyJoinColumnMapper.java rename to hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/OneToOnePrimaryKeyJoinColumnMapper.java index acbe0f6606..6ef8ff4d71 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/OneToOnePrimaryKeyJoinColumnMapper.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/OneToOnePrimaryKeyJoinColumnMapper.java @@ -1,13 +1,13 @@ -package org.hibernate.envers.entities.mapper.relation; +package org.hibernate.envers.internal.entities.mapper.relation; import java.io.Serializable; import javax.persistence.OneToOne; import javax.persistence.PrimaryKeyJoinColumn; import org.hibernate.envers.Audited; -import org.hibernate.envers.entities.PropertyData; +import org.hibernate.envers.internal.entities.PropertyData; +import org.hibernate.envers.internal.reader.AuditReaderImplementor; import org.hibernate.envers.query.AuditEntity; -import org.hibernate.envers.reader.AuditReaderImplementor; import org.hibernate.persister.entity.EntityPersister; /** diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/SortedMapCollectionMapper.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/SortedMapCollectionMapper.java similarity index 84% rename from hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/SortedMapCollectionMapper.java rename to hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/SortedMapCollectionMapper.java index a3a512ebd1..e7d0f14b5a 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/SortedMapCollectionMapper.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/SortedMapCollectionMapper.java @@ -21,15 +21,15 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.entities.mapper.relation; +package org.hibernate.envers.internal.entities.mapper.relation; import java.util.Comparator; import java.util.SortedMap; -import org.hibernate.envers.configuration.AuditConfiguration; -import org.hibernate.envers.entities.mapper.relation.lazy.initializor.Initializor; -import org.hibernate.envers.entities.mapper.relation.lazy.initializor.SortedMapCollectionInitializor; -import org.hibernate.envers.reader.AuditReaderImplementor; +import org.hibernate.envers.configuration.spi.AuditConfiguration; +import org.hibernate.envers.internal.entities.mapper.relation.lazy.initializor.Initializor; +import org.hibernate.envers.internal.entities.mapper.relation.lazy.initializor.SortedMapCollectionInitializor; +import org.hibernate.envers.internal.reader.AuditReaderImplementor; /** * @author Michal Skowronek (mskowr at o2 dot pl) diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/SortedSetCollectionMapper.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/SortedSetCollectionMapper.java similarity index 84% rename from hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/SortedSetCollectionMapper.java rename to hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/SortedSetCollectionMapper.java index 7c4a3b451a..66efdf3736 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/SortedSetCollectionMapper.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/SortedSetCollectionMapper.java @@ -21,15 +21,15 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.entities.mapper.relation; +package org.hibernate.envers.internal.entities.mapper.relation; import java.util.Comparator; import java.util.SortedSet; -import org.hibernate.envers.configuration.AuditConfiguration; -import org.hibernate.envers.entities.mapper.relation.lazy.initializor.Initializor; -import org.hibernate.envers.entities.mapper.relation.lazy.initializor.SortedSetCollectionInitializor; -import org.hibernate.envers.reader.AuditReaderImplementor; +import org.hibernate.envers.configuration.spi.AuditConfiguration; +import org.hibernate.envers.internal.entities.mapper.relation.lazy.initializor.Initializor; +import org.hibernate.envers.internal.entities.mapper.relation.lazy.initializor.SortedSetCollectionInitializor; +import org.hibernate.envers.internal.reader.AuditReaderImplementor; /** * @author Michal Skowronek (mskowr at o2 dot pl) diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/ToOneEntityLoader.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/ToOneEntityLoader.java similarity index 88% rename from hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/ToOneEntityLoader.java rename to hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/ToOneEntityLoader.java index 8c4c33fd91..3d9aeaa016 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/ToOneEntityLoader.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/ToOneEntityLoader.java @@ -1,10 +1,10 @@ -package org.hibernate.envers.entities.mapper.relation; +package org.hibernate.envers.internal.entities.mapper.relation; import java.io.Serializable; -import org.hibernate.envers.configuration.AuditConfiguration; -import org.hibernate.envers.entities.mapper.relation.lazy.ToOneDelegateSessionImplementor; -import org.hibernate.envers.reader.AuditReaderImplementor; +import org.hibernate.envers.configuration.spi.AuditConfiguration; +import org.hibernate.envers.internal.entities.mapper.relation.lazy.ToOneDelegateSessionImplementor; +import org.hibernate.envers.internal.reader.AuditReaderImplementor; import org.hibernate.persister.entity.EntityPersister; /** diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/ToOneIdMapper.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/ToOneIdMapper.java similarity index 87% rename from hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/ToOneIdMapper.java rename to hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/ToOneIdMapper.java index 1890ed078c..3382b0136d 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/ToOneIdMapper.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/ToOneIdMapper.java @@ -21,22 +21,19 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.entities.mapper.relation; +package org.hibernate.envers.internal.entities.mapper.relation; -import java.io.Serializable; import java.util.HashMap; import java.util.Map; import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.envers.RevisionType; -import org.hibernate.envers.configuration.AuditConfiguration; -import org.hibernate.envers.entities.PropertyData; -import org.hibernate.envers.entities.mapper.id.IdMapper; -import org.hibernate.envers.entities.mapper.relation.lazy.ToOneDelegateSessionImplementor; -import org.hibernate.envers.reader.AuditReaderImplementor; -import org.hibernate.envers.tools.Tools; -import org.hibernate.envers.tools.query.Parameters; -import org.hibernate.persister.entity.EntityPersister; +import org.hibernate.envers.configuration.spi.AuditConfiguration; +import org.hibernate.envers.internal.entities.PropertyData; +import org.hibernate.envers.internal.entities.mapper.id.IdMapper; +import org.hibernate.envers.internal.reader.AuditReaderImplementor; +import org.hibernate.envers.internal.tools.EntityTools; +import org.hibernate.envers.internal.tools.query.Parameters; /** * @author Adam Warski (adam at warski dot org) @@ -86,7 +83,7 @@ public void mapModifiedFlagsToMapForCollectionChange(String collectionPropertyNa protected boolean checkModified(SessionImplementor session, Object newObj, Object oldObj) { //noinspection SimplifiableConditionalExpression - return nonInsertableFake ? false : !Tools.entitiesEqual(session, referencedEntityName, newObj, oldObj); + return nonInsertableFake ? false : !EntityTools.entitiesEqual(session, referencedEntityName, newObj, oldObj); } public void nullSafeMapToEntityFromMap(AuditConfiguration verCfg, Object obj, Map data, Object primaryKey, diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/component/MiddleComponentMapper.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/component/MiddleComponentMapper.java similarity index 92% rename from hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/component/MiddleComponentMapper.java rename to hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/component/MiddleComponentMapper.java index 73775eb4c8..f9213ab8ac 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/component/MiddleComponentMapper.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/component/MiddleComponentMapper.java @@ -21,15 +21,13 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.entities.mapper.relation.component; +package org.hibernate.envers.internal.entities.mapper.relation.component; import java.util.Map; -import javax.persistence.ElementCollection; -import javax.persistence.Embeddable; import org.hibernate.engine.spi.SessionImplementor; -import org.hibernate.envers.entities.EntityInstantiator; -import org.hibernate.envers.tools.query.Parameters; +import org.hibernate.envers.internal.entities.EntityInstantiator; +import org.hibernate.envers.internal.tools.query.Parameters; /** * @author Adam Warski (adam at warski dot org) diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/component/MiddleDummyComponentMapper.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/component/MiddleDummyComponentMapper.java similarity index 89% rename from hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/component/MiddleDummyComponentMapper.java rename to hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/component/MiddleDummyComponentMapper.java index 8c681b937f..b4da4f3c37 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/component/MiddleDummyComponentMapper.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/component/MiddleDummyComponentMapper.java @@ -21,12 +21,12 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.entities.mapper.relation.component; +package org.hibernate.envers.internal.entities.mapper.relation.component; import java.util.Map; import org.hibernate.engine.spi.SessionImplementor; -import org.hibernate.envers.entities.EntityInstantiator; -import org.hibernate.envers.tools.query.Parameters; +import org.hibernate.envers.internal.entities.EntityInstantiator; +import org.hibernate.envers.internal.tools.query.Parameters; /** * @author Adam Warski (adam at warski dot org) diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/component/MiddleEmbeddableComponentMapper.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/component/MiddleEmbeddableComponentMapper.java similarity index 83% rename from hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/component/MiddleEmbeddableComponentMapper.java rename to hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/component/MiddleEmbeddableComponentMapper.java index c287ff6c8d..f599d81e8c 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/component/MiddleEmbeddableComponentMapper.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/component/MiddleEmbeddableComponentMapper.java @@ -21,19 +21,19 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.entities.mapper.relation.component; +package org.hibernate.envers.internal.entities.mapper.relation.component; import java.util.Map; import org.hibernate.engine.spi.SessionImplementor; -import org.hibernate.envers.entities.EntityInstantiator; -import org.hibernate.envers.entities.PropertyData; -import org.hibernate.envers.entities.mapper.CompositeMapperBuilder; -import org.hibernate.envers.entities.mapper.MultiPropertyMapper; -import org.hibernate.envers.entities.mapper.PropertyMapper; -import org.hibernate.envers.entities.mapper.relation.ToOneIdMapper; import org.hibernate.envers.exception.AuditException; -import org.hibernate.envers.tools.query.Parameters; +import org.hibernate.envers.internal.entities.EntityInstantiator; +import org.hibernate.envers.internal.entities.PropertyData; +import org.hibernate.envers.internal.entities.mapper.CompositeMapperBuilder; +import org.hibernate.envers.internal.entities.mapper.MultiPropertyMapper; +import org.hibernate.envers.internal.entities.mapper.PropertyMapper; +import org.hibernate.envers.internal.entities.mapper.relation.ToOneIdMapper; +import org.hibernate.envers.internal.tools.query.Parameters; import org.hibernate.internal.util.ReflectHelper; /** @@ -43,14 +43,9 @@ public class MiddleEmbeddableComponentMapper implements MiddleComponentMapper, C private final MultiPropertyMapper delegate; private final Class componentClass; - public MiddleEmbeddableComponentMapper(MultiPropertyMapper delegate, String componentClassName) { + public MiddleEmbeddableComponentMapper(MultiPropertyMapper delegate, Class componentClass) { this.delegate = delegate; - try { - componentClass = Thread.currentThread().getContextClassLoader().loadClass( componentClassName ); - } - catch ( Exception e ) { - throw new AuditException( e ); - } + this.componentClass = componentClass; } @Override @@ -95,8 +90,8 @@ else if ( nestedMapper instanceof ToOneIdMapper ) { } @Override - public CompositeMapperBuilder addComponent(PropertyData propertyData, String componentClassName) { - return delegate.addComponent( propertyData, componentClassName ); + public CompositeMapperBuilder addComponent(PropertyData propertyData, Class componentClass) { + return delegate.addComponent( propertyData, componentClass ); } @Override diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/component/MiddleMapKeyIdComponentMapper.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/component/MiddleMapKeyIdComponentMapper.java similarity index 87% rename from hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/component/MiddleMapKeyIdComponentMapper.java rename to hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/component/MiddleMapKeyIdComponentMapper.java index 464f9a2c24..cc9c899e75 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/component/MiddleMapKeyIdComponentMapper.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/component/MiddleMapKeyIdComponentMapper.java @@ -21,14 +21,14 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.entities.mapper.relation.component; +package org.hibernate.envers.internal.entities.mapper.relation.component; import java.util.Map; import org.hibernate.engine.spi.SessionImplementor; -import org.hibernate.envers.configuration.AuditEntitiesConfiguration; -import org.hibernate.envers.entities.EntityInstantiator; -import org.hibernate.envers.entities.mapper.id.IdMapper; -import org.hibernate.envers.tools.query.Parameters; +import org.hibernate.envers.configuration.internal.AuditEntitiesConfiguration; +import org.hibernate.envers.internal.entities.EntityInstantiator; +import org.hibernate.envers.internal.entities.mapper.id.IdMapper; +import org.hibernate.envers.internal.tools.query.Parameters; /** * A component mapper for the @MapKey mapping: the value of the map's key is the id of the entity. This diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/component/MiddleMapKeyPropertyComponentMapper.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/component/MiddleMapKeyPropertyComponentMapper.java similarity index 90% rename from hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/component/MiddleMapKeyPropertyComponentMapper.java rename to hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/component/MiddleMapKeyPropertyComponentMapper.java index f619e01ae7..943c22cab4 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/component/MiddleMapKeyPropertyComponentMapper.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/component/MiddleMapKeyPropertyComponentMapper.java @@ -21,13 +21,14 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.entities.mapper.relation.component; +package org.hibernate.envers.internal.entities.mapper.relation.component; + import java.util.Map; import org.hibernate.engine.spi.SessionImplementor; -import org.hibernate.envers.entities.EntityInstantiator; -import org.hibernate.envers.tools.query.Parameters; -import org.hibernate.envers.tools.reflection.ReflectionTools; +import org.hibernate.envers.internal.entities.EntityInstantiator; +import org.hibernate.envers.internal.tools.ReflectionTools; +import org.hibernate.envers.internal.tools.query.Parameters; /** * A component mapper for the @MapKey mapping with the name parameter specified: the value of the map's key diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/component/MiddleRelatedComponentMapper.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/component/MiddleRelatedComponentMapper.java similarity index 88% rename from hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/component/MiddleRelatedComponentMapper.java rename to hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/component/MiddleRelatedComponentMapper.java index fb43169c9b..de340038d0 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/component/MiddleRelatedComponentMapper.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/component/MiddleRelatedComponentMapper.java @@ -21,13 +21,13 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.entities.mapper.relation.component; +package org.hibernate.envers.internal.entities.mapper.relation.component; import java.util.Map; import org.hibernate.engine.spi.SessionImplementor; -import org.hibernate.envers.entities.EntityInstantiator; -import org.hibernate.envers.entities.mapper.relation.MiddleIdData; -import org.hibernate.envers.tools.query.Parameters; +import org.hibernate.envers.internal.entities.EntityInstantiator; +import org.hibernate.envers.internal.entities.mapper.relation.MiddleIdData; +import org.hibernate.envers.internal.tools.query.Parameters; /** * @author Adam Warski (adam at warski dot org) diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/component/MiddleSimpleComponentMapper.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/component/MiddleSimpleComponentMapper.java similarity index 89% rename from hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/component/MiddleSimpleComponentMapper.java rename to hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/component/MiddleSimpleComponentMapper.java index f6cc572943..4ccf1de192 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/component/MiddleSimpleComponentMapper.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/component/MiddleSimpleComponentMapper.java @@ -21,13 +21,13 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.entities.mapper.relation.component; +package org.hibernate.envers.internal.entities.mapper.relation.component; import java.util.Map; import org.hibernate.engine.spi.SessionImplementor; -import org.hibernate.envers.configuration.AuditEntitiesConfiguration; -import org.hibernate.envers.entities.EntityInstantiator; -import org.hibernate.envers.tools.query.Parameters; +import org.hibernate.envers.configuration.internal.AuditEntitiesConfiguration; +import org.hibernate.envers.internal.entities.EntityInstantiator; +import org.hibernate.envers.internal.tools.query.Parameters; /** * @author Adam Warski (adam at warski dot org) diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/component/MiddleStraightComponentMapper.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/component/MiddleStraightComponentMapper.java similarity index 91% rename from hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/component/MiddleStraightComponentMapper.java rename to hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/component/MiddleStraightComponentMapper.java index 30fdd16535..2457155d6d 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/component/MiddleStraightComponentMapper.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/component/MiddleStraightComponentMapper.java @@ -21,12 +21,12 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.entities.mapper.relation.component; +package org.hibernate.envers.internal.entities.mapper.relation.component; import java.util.Map; import org.hibernate.engine.spi.SessionImplementor; -import org.hibernate.envers.entities.EntityInstantiator; -import org.hibernate.envers.tools.query.Parameters; +import org.hibernate.envers.internal.entities.EntityInstantiator; +import org.hibernate.envers.internal.tools.query.Parameters; /** * A mapper for reading and writing a property straight to/from maps. This mapper cannot be used with middle tables, diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/lazy/AbstractDelegateSessionImplementor.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/lazy/AbstractDelegateSessionImplementor.java similarity index 99% rename from hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/lazy/AbstractDelegateSessionImplementor.java rename to hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/lazy/AbstractDelegateSessionImplementor.java index 59f2a92fa8..cd4823b78c 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/lazy/AbstractDelegateSessionImplementor.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/lazy/AbstractDelegateSessionImplementor.java @@ -21,7 +21,7 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.entities.mapper.relation.lazy; +package org.hibernate.envers.internal.entities.mapper.relation.lazy; import java.io.Serializable; import java.sql.Connection; diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/lazy/ToOneDelegateSessionImplementor.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/lazy/ToOneDelegateSessionImplementor.java similarity index 87% rename from hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/lazy/ToOneDelegateSessionImplementor.java rename to hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/lazy/ToOneDelegateSessionImplementor.java index 2a1721debb..13394d437f 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/lazy/ToOneDelegateSessionImplementor.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/lazy/ToOneDelegateSessionImplementor.java @@ -21,14 +21,12 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.entities.mapper.relation.lazy; -import java.io.Serializable; +package org.hibernate.envers.internal.entities.mapper.relation.lazy; import org.hibernate.HibernateException; -import org.hibernate.envers.configuration.AuditConfiguration; -import org.hibernate.envers.entities.EntitiesConfigurations; -import org.hibernate.envers.entities.mapper.relation.ToOneEntityLoader; -import org.hibernate.envers.reader.AuditReaderImplementor; +import org.hibernate.envers.configuration.spi.AuditConfiguration; +import org.hibernate.envers.internal.entities.mapper.relation.ToOneEntityLoader; +import org.hibernate.envers.internal.reader.AuditReaderImplementor; /** * @author Adam Warski (adam at warski dot org) diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/lazy/initializor/AbstractCollectionInitializor.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/lazy/initializor/AbstractCollectionInitializor.java similarity index 87% rename from hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/lazy/initializor/AbstractCollectionInitializor.java rename to hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/lazy/initializor/AbstractCollectionInitializor.java index 635b9a2720..bc6fd61688 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/lazy/initializor/AbstractCollectionInitializor.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/lazy/initializor/AbstractCollectionInitializor.java @@ -21,13 +21,13 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.entities.mapper.relation.lazy.initializor; +package org.hibernate.envers.internal.entities.mapper.relation.lazy.initializor; import java.util.List; -import org.hibernate.envers.configuration.AuditConfiguration; -import org.hibernate.envers.entities.EntityInstantiator; -import org.hibernate.envers.entities.mapper.relation.query.RelationQueryGenerator; -import org.hibernate.envers.reader.AuditReaderImplementor; +import org.hibernate.envers.configuration.spi.AuditConfiguration; +import org.hibernate.envers.internal.entities.EntityInstantiator; +import org.hibernate.envers.internal.entities.mapper.relation.query.RelationQueryGenerator; +import org.hibernate.envers.internal.reader.AuditReaderImplementor; /** * Initializes a persistent collection. diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/lazy/initializor/ArrayCollectionInitializor.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/lazy/initializor/ArrayCollectionInitializor.java similarity index 88% rename from hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/lazy/initializor/ArrayCollectionInitializor.java rename to hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/lazy/initializor/ArrayCollectionInitializor.java index 91c2888ce5..066906c796 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/lazy/initializor/ArrayCollectionInitializor.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/lazy/initializor/ArrayCollectionInitializor.java @@ -21,14 +21,14 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.entities.mapper.relation.lazy.initializor; +package org.hibernate.envers.internal.entities.mapper.relation.lazy.initializor; import java.util.List; import java.util.Map; -import org.hibernate.envers.configuration.AuditConfiguration; -import org.hibernate.envers.entities.mapper.relation.MiddleComponentData; -import org.hibernate.envers.entities.mapper.relation.query.RelationQueryGenerator; -import org.hibernate.envers.reader.AuditReaderImplementor; +import org.hibernate.envers.configuration.spi.AuditConfiguration; +import org.hibernate.envers.internal.entities.mapper.relation.MiddleComponentData; +import org.hibernate.envers.internal.entities.mapper.relation.query.RelationQueryGenerator; +import org.hibernate.envers.internal.reader.AuditReaderImplementor; /** * Initializes a map. diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/lazy/initializor/BasicCollectionInitializor.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/lazy/initializor/BasicCollectionInitializor.java similarity index 90% rename from hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/lazy/initializor/BasicCollectionInitializor.java rename to hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/lazy/initializor/BasicCollectionInitializor.java index 9a3bcda897..b0205eb304 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/lazy/initializor/BasicCollectionInitializor.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/lazy/initializor/BasicCollectionInitializor.java @@ -21,18 +21,18 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.entities.mapper.relation.lazy.initializor; +package org.hibernate.envers.internal.entities.mapper.relation.lazy.initializor; import java.lang.reflect.InvocationTargetException; import java.util.Collection; import java.util.List; import java.util.Map; -import org.hibernate.envers.configuration.AuditConfiguration; -import org.hibernate.envers.entities.mapper.relation.MiddleComponentData; -import org.hibernate.envers.entities.mapper.relation.query.RelationQueryGenerator; +import org.hibernate.envers.configuration.spi.AuditConfiguration; import org.hibernate.envers.exception.AuditException; -import org.hibernate.envers.reader.AuditReaderImplementor; +import org.hibernate.envers.internal.entities.mapper.relation.MiddleComponentData; +import org.hibernate.envers.internal.entities.mapper.relation.query.RelationQueryGenerator; +import org.hibernate.envers.internal.reader.AuditReaderImplementor; import org.hibernate.internal.util.ReflectHelper; /** diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/lazy/initializor/Initializor.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/lazy/initializor/Initializor.java similarity index 93% rename from hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/lazy/initializor/Initializor.java rename to hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/lazy/initializor/Initializor.java index 4f115dd4bb..a283eb1d57 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/lazy/initializor/Initializor.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/lazy/initializor/Initializor.java @@ -21,7 +21,7 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.entities.mapper.relation.lazy.initializor; +package org.hibernate.envers.internal.entities.mapper.relation.lazy.initializor; /** diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/lazy/initializor/ListCollectionInitializor.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/lazy/initializor/ListCollectionInitializor.java similarity index 90% rename from hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/lazy/initializor/ListCollectionInitializor.java rename to hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/lazy/initializor/ListCollectionInitializor.java index edee51b780..fd106fe583 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/lazy/initializor/ListCollectionInitializor.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/lazy/initializor/ListCollectionInitializor.java @@ -21,15 +21,15 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.entities.mapper.relation.lazy.initializor; +package org.hibernate.envers.internal.entities.mapper.relation.lazy.initializor; import java.util.ArrayList; import java.util.List; import java.util.Map; -import org.hibernate.envers.configuration.AuditConfiguration; -import org.hibernate.envers.entities.mapper.relation.MiddleComponentData; -import org.hibernate.envers.entities.mapper.relation.query.RelationQueryGenerator; -import org.hibernate.envers.reader.AuditReaderImplementor; +import org.hibernate.envers.configuration.spi.AuditConfiguration; +import org.hibernate.envers.internal.entities.mapper.relation.MiddleComponentData; +import org.hibernate.envers.internal.entities.mapper.relation.query.RelationQueryGenerator; +import org.hibernate.envers.internal.reader.AuditReaderImplementor; /** * Initializes a map. diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/lazy/initializor/MapCollectionInitializor.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/lazy/initializor/MapCollectionInitializor.java similarity index 90% rename from hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/lazy/initializor/MapCollectionInitializor.java rename to hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/lazy/initializor/MapCollectionInitializor.java index 5b75027a6b..bed9d90a98 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/lazy/initializor/MapCollectionInitializor.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/lazy/initializor/MapCollectionInitializor.java @@ -21,17 +21,17 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.entities.mapper.relation.lazy.initializor; +package org.hibernate.envers.internal.entities.mapper.relation.lazy.initializor; import java.lang.reflect.InvocationTargetException; import java.util.List; import java.util.Map; -import org.hibernate.envers.configuration.AuditConfiguration; -import org.hibernate.envers.entities.mapper.relation.MiddleComponentData; -import org.hibernate.envers.entities.mapper.relation.query.RelationQueryGenerator; +import org.hibernate.envers.configuration.spi.AuditConfiguration; import org.hibernate.envers.exception.AuditException; -import org.hibernate.envers.reader.AuditReaderImplementor; +import org.hibernate.envers.internal.entities.mapper.relation.MiddleComponentData; +import org.hibernate.envers.internal.entities.mapper.relation.query.RelationQueryGenerator; +import org.hibernate.envers.internal.reader.AuditReaderImplementor; import org.hibernate.internal.util.ReflectHelper; /** diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/lazy/initializor/SortedMapCollectionInitializor.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/lazy/initializor/SortedMapCollectionInitializor.java similarity index 86% rename from hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/lazy/initializor/SortedMapCollectionInitializor.java rename to hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/lazy/initializor/SortedMapCollectionInitializor.java index 021432184c..faba2f4c1e 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/lazy/initializor/SortedMapCollectionInitializor.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/lazy/initializor/SortedMapCollectionInitializor.java @@ -21,17 +21,17 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.entities.mapper.relation.lazy.initializor; +package org.hibernate.envers.internal.entities.mapper.relation.lazy.initializor; import java.lang.reflect.InvocationTargetException; import java.util.Comparator; import java.util.SortedMap; -import org.hibernate.envers.configuration.AuditConfiguration; -import org.hibernate.envers.entities.mapper.relation.MiddleComponentData; -import org.hibernate.envers.entities.mapper.relation.query.RelationQueryGenerator; +import org.hibernate.envers.configuration.spi.AuditConfiguration; import org.hibernate.envers.exception.AuditException; -import org.hibernate.envers.reader.AuditReaderImplementor; +import org.hibernate.envers.internal.entities.mapper.relation.MiddleComponentData; +import org.hibernate.envers.internal.entities.mapper.relation.query.RelationQueryGenerator; +import org.hibernate.envers.internal.reader.AuditReaderImplementor; /** * Initializes SortedMap collection with proper Comparator diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/lazy/initializor/SortedSetCollectionInitializor.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/lazy/initializor/SortedSetCollectionInitializor.java similarity index 86% rename from hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/lazy/initializor/SortedSetCollectionInitializor.java rename to hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/lazy/initializor/SortedSetCollectionInitializor.java index 21f6bb32a8..cf70f8c6ac 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/lazy/initializor/SortedSetCollectionInitializor.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/lazy/initializor/SortedSetCollectionInitializor.java @@ -21,17 +21,17 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.entities.mapper.relation.lazy.initializor; +package org.hibernate.envers.internal.entities.mapper.relation.lazy.initializor; import java.lang.reflect.InvocationTargetException; import java.util.Comparator; import java.util.SortedSet; -import org.hibernate.envers.configuration.AuditConfiguration; -import org.hibernate.envers.entities.mapper.relation.MiddleComponentData; -import org.hibernate.envers.entities.mapper.relation.query.RelationQueryGenerator; +import org.hibernate.envers.configuration.spi.AuditConfiguration; import org.hibernate.envers.exception.AuditException; -import org.hibernate.envers.reader.AuditReaderImplementor; +import org.hibernate.envers.internal.entities.mapper.relation.MiddleComponentData; +import org.hibernate.envers.internal.entities.mapper.relation.query.RelationQueryGenerator; +import org.hibernate.envers.internal.reader.AuditReaderImplementor; /** * Initializes SortedSet collection with proper Comparator diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/lazy/proxy/CollectionProxy.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/lazy/proxy/CollectionProxy.java similarity index 92% rename from hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/lazy/proxy/CollectionProxy.java rename to hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/lazy/proxy/CollectionProxy.java index 1753bc3617..d44180cbe0 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/lazy/proxy/CollectionProxy.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/lazy/proxy/CollectionProxy.java @@ -21,12 +21,12 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.entities.mapper.relation.lazy.proxy; +package org.hibernate.envers.internal.entities.mapper.relation.lazy.proxy; import java.io.Serializable; import java.util.Collection; import java.util.Iterator; -import org.hibernate.envers.entities.mapper.relation.lazy.initializor.Initializor; +import org.hibernate.envers.internal.entities.mapper.relation.lazy.initializor.Initializor; /** * @author Adam Warski (adam at warski dot org) @@ -34,7 +34,7 @@ public abstract class CollectionProxy> implements Collection, Serializable { private static final long serialVersionUID = 8698249863871832402L; - private transient org.hibernate.envers.entities.mapper.relation.lazy.initializor.Initializor initializor; + private transient org.hibernate.envers.internal.entities.mapper.relation.lazy.initializor.Initializor initializor; protected T delegate; protected CollectionProxy() { diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/lazy/proxy/ListProxy.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/lazy/proxy/ListProxy.java similarity index 92% rename from hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/lazy/proxy/ListProxy.java rename to hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/lazy/proxy/ListProxy.java index be2289995f..348f778711 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/lazy/proxy/ListProxy.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/lazy/proxy/ListProxy.java @@ -21,7 +21,7 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.entities.mapper.relation.lazy.proxy; +package org.hibernate.envers.internal.entities.mapper.relation.lazy.proxy; import java.util.Collection; import java.util.List; import java.util.ListIterator; @@ -35,7 +35,7 @@ public class ListProxy extends CollectionProxy> implements List public ListProxy() { } - public ListProxy(org.hibernate.envers.entities.mapper.relation.lazy.initializor.Initializor> initializor) { + public ListProxy(org.hibernate.envers.internal.entities.mapper.relation.lazy.initializor.Initializor> initializor) { super(initializor); } diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/lazy/proxy/MapProxy.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/lazy/proxy/MapProxy.java similarity index 91% rename from hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/lazy/proxy/MapProxy.java rename to hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/lazy/proxy/MapProxy.java index 39ff01e4b5..bbc4e97386 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/lazy/proxy/MapProxy.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/lazy/proxy/MapProxy.java @@ -21,13 +21,13 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.entities.mapper.relation.lazy.proxy; +package org.hibernate.envers.internal.entities.mapper.relation.lazy.proxy; import java.io.Serializable; import java.util.Collection; import java.util.Map; import java.util.Set; -import org.hibernate.envers.entities.mapper.relation.lazy.initializor.Initializor; +import org.hibernate.envers.internal.entities.mapper.relation.lazy.initializor.Initializor; /** * @author Adam Warski (adam at warski dot org) @@ -41,7 +41,7 @@ public class MapProxy implements Map, Serializable { public MapProxy() { } - public MapProxy(org.hibernate.envers.entities.mapper.relation.lazy.initializor.Initializor> initializor) { + public MapProxy(org.hibernate.envers.internal.entities.mapper.relation.lazy.initializor.Initializor> initializor) { this.initializor = initializor; } diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/lazy/proxy/SetProxy.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/lazy/proxy/SetProxy.java similarity index 87% rename from hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/lazy/proxy/SetProxy.java rename to hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/lazy/proxy/SetProxy.java index 0cfb5f20c5..e57473b887 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/lazy/proxy/SetProxy.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/lazy/proxy/SetProxy.java @@ -21,7 +21,7 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.entities.mapper.relation.lazy.proxy; +package org.hibernate.envers.internal.entities.mapper.relation.lazy.proxy; import java.util.Set; /** @@ -33,7 +33,7 @@ public class SetProxy extends CollectionProxy> implements Set { public SetProxy() { } - public SetProxy(org.hibernate.envers.entities.mapper.relation.lazy.initializor.Initializor> initializor) { + public SetProxy(org.hibernate.envers.internal.entities.mapper.relation.lazy.initializor.Initializor> initializor) { super(initializor); } } diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/lazy/proxy/SortedMapProxy.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/lazy/proxy/SortedMapProxy.java similarity index 92% rename from hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/lazy/proxy/SortedMapProxy.java rename to hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/lazy/proxy/SortedMapProxy.java index 2eb47cdacc..51a199125f 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/lazy/proxy/SortedMapProxy.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/lazy/proxy/SortedMapProxy.java @@ -21,7 +21,7 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.entities.mapper.relation.lazy.proxy; +package org.hibernate.envers.internal.entities.mapper.relation.lazy.proxy; import java.io.Serializable; import java.util.Collection; import java.util.Comparator; @@ -29,7 +29,7 @@ import java.util.Set; import java.util.SortedMap; -import org.hibernate.envers.entities.mapper.relation.lazy.initializor.Initializor; +import org.hibernate.envers.internal.entities.mapper.relation.lazy.initializor.Initializor; /** * @author Adam Warski (adam at warski dot org) @@ -43,7 +43,7 @@ public class SortedMapProxy implements SortedMap, Serializable { public SortedMapProxy() { } - public SortedMapProxy(org.hibernate.envers.entities.mapper.relation.lazy.initializor.Initializor> initializor) { + public SortedMapProxy(org.hibernate.envers.internal.entities.mapper.relation.lazy.initializor.Initializor> initializor) { this.initializor = initializor; } diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/lazy/proxy/SortedSetProxy.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/lazy/proxy/SortedSetProxy.java similarity index 90% rename from hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/lazy/proxy/SortedSetProxy.java rename to hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/lazy/proxy/SortedSetProxy.java index a5ed381254..962a754094 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/lazy/proxy/SortedSetProxy.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/lazy/proxy/SortedSetProxy.java @@ -21,7 +21,7 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.entities.mapper.relation.lazy.proxy; +package org.hibernate.envers.internal.entities.mapper.relation.lazy.proxy; import java.util.Comparator; import java.util.SortedSet; @@ -34,7 +34,7 @@ public class SortedSetProxy extends CollectionProxy> implemen public SortedSetProxy() { } - public SortedSetProxy(org.hibernate.envers.entities.mapper.relation.lazy.initializor.Initializor> initializor) { + public SortedSetProxy(org.hibernate.envers.internal.entities.mapper.relation.lazy.initializor.Initializor> initializor) { super(initializor); } diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/query/AbstractRelationQueryGenerator.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/query/AbstractRelationQueryGenerator.java similarity index 80% rename from hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/query/AbstractRelationQueryGenerator.java rename to hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/query/AbstractRelationQueryGenerator.java index cb3fe4a696..6d59852d21 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/query/AbstractRelationQueryGenerator.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/query/AbstractRelationQueryGenerator.java @@ -21,17 +21,17 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.entities.mapper.relation.query; +package org.hibernate.envers.internal.entities.mapper.relation.query; import org.hibernate.Query; import org.hibernate.envers.RevisionType; -import org.hibernate.envers.configuration.AuditEntitiesConfiguration; -import org.hibernate.envers.entities.mapper.id.QueryParameterData; -import org.hibernate.envers.entities.mapper.relation.MiddleIdData; -import org.hibernate.envers.reader.AuditReaderImplementor; +import org.hibernate.envers.configuration.internal.AuditEntitiesConfiguration; +import org.hibernate.envers.internal.entities.mapper.id.QueryParameterData; +import org.hibernate.envers.internal.entities.mapper.relation.MiddleIdData; +import org.hibernate.envers.internal.reader.AuditReaderImplementor; -import static org.hibernate.envers.entities.mapper.relation.query.QueryConstants.DEL_REVISION_TYPE_PARAMETER; -import static org.hibernate.envers.entities.mapper.relation.query.QueryConstants.REVISION_PARAMETER; +import static org.hibernate.envers.internal.entities.mapper.relation.query.QueryConstants.DEL_REVISION_TYPE_PARAMETER; +import static org.hibernate.envers.internal.entities.mapper.relation.query.QueryConstants.REVISION_PARAMETER; /** * Base class for implementers of {@code RelationQueryGenerator} contract. diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/query/OneAuditEntityQueryGenerator.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/query/OneAuditEntityQueryGenerator.java similarity index 80% rename from hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/query/OneAuditEntityQueryGenerator.java rename to hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/query/OneAuditEntityQueryGenerator.java index 953be5ee0d..68f8d04d93 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/query/OneAuditEntityQueryGenerator.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/query/OneAuditEntityQueryGenerator.java @@ -21,25 +21,20 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.entities.mapper.relation.query; +package org.hibernate.envers.internal.entities.mapper.relation.query; import java.util.Collections; -import org.hibernate.Query; -import org.hibernate.envers.RevisionType; -import org.hibernate.envers.configuration.AuditEntitiesConfiguration; -import org.hibernate.envers.configuration.GlobalConfiguration; -import org.hibernate.envers.entities.mapper.id.QueryParameterData; -import org.hibernate.envers.entities.mapper.relation.MiddleIdData; -import org.hibernate.envers.reader.AuditReaderImplementor; +import org.hibernate.envers.configuration.internal.AuditEntitiesConfiguration; +import org.hibernate.envers.configuration.internal.GlobalConfiguration; +import org.hibernate.envers.internal.entities.mapper.relation.MiddleIdData; +import org.hibernate.envers.internal.tools.query.Parameters; +import org.hibernate.envers.internal.tools.query.QueryBuilder; import org.hibernate.envers.strategy.AuditStrategy; -import org.hibernate.envers.tools.query.Parameters; -import org.hibernate.envers.tools.query.QueryBuilder; -import static org.hibernate.envers.entities.mapper.relation.query.QueryConstants.DEL_REVISION_TYPE_PARAMETER; -import static org.hibernate.envers.entities.mapper.relation.query.QueryConstants.REFERENCED_ENTITY_ALIAS; -import static org.hibernate.envers.entities.mapper.relation.query.QueryConstants.REFERENCED_ENTITY_ALIAS_DEF_AUD_STR; -import static org.hibernate.envers.entities.mapper.relation.query.QueryConstants.REVISION_PARAMETER; +import static org.hibernate.envers.internal.entities.mapper.relation.query.QueryConstants.DEL_REVISION_TYPE_PARAMETER; +import static org.hibernate.envers.internal.entities.mapper.relation.query.QueryConstants.REFERENCED_ENTITY_ALIAS; +import static org.hibernate.envers.internal.entities.mapper.relation.query.QueryConstants.REFERENCED_ENTITY_ALIAS_DEF_AUD_STR; /** * Selects data from an audit entity. diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/query/OneEntityQueryGenerator.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/query/OneEntityQueryGenerator.java similarity index 82% rename from hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/query/OneEntityQueryGenerator.java rename to hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/query/OneEntityQueryGenerator.java index 45d8e47728..d3bb6e554d 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/query/OneEntityQueryGenerator.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/query/OneEntityQueryGenerator.java @@ -21,24 +21,19 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.entities.mapper.relation.query; +package org.hibernate.envers.internal.entities.mapper.relation.query; import java.util.Collections; -import org.hibernate.Query; -import org.hibernate.envers.RevisionType; -import org.hibernate.envers.configuration.AuditEntitiesConfiguration; -import org.hibernate.envers.entities.mapper.id.QueryParameterData; -import org.hibernate.envers.entities.mapper.relation.MiddleComponentData; -import org.hibernate.envers.entities.mapper.relation.MiddleIdData; -import org.hibernate.envers.reader.AuditReaderImplementor; +import org.hibernate.envers.configuration.internal.AuditEntitiesConfiguration; +import org.hibernate.envers.internal.entities.mapper.relation.MiddleComponentData; +import org.hibernate.envers.internal.entities.mapper.relation.MiddleIdData; +import org.hibernate.envers.internal.tools.query.Parameters; +import org.hibernate.envers.internal.tools.query.QueryBuilder; import org.hibernate.envers.strategy.AuditStrategy; -import org.hibernate.envers.tools.query.Parameters; -import org.hibernate.envers.tools.query.QueryBuilder; -import static org.hibernate.envers.entities.mapper.relation.query.QueryConstants.DEL_REVISION_TYPE_PARAMETER; -import static org.hibernate.envers.entities.mapper.relation.query.QueryConstants.MIDDLE_ENTITY_ALIAS; -import static org.hibernate.envers.entities.mapper.relation.query.QueryConstants.REVISION_PARAMETER; +import static org.hibernate.envers.internal.entities.mapper.relation.query.QueryConstants.DEL_REVISION_TYPE_PARAMETER; +import static org.hibernate.envers.internal.entities.mapper.relation.query.QueryConstants.MIDDLE_ENTITY_ALIAS; /** * Selects data from a relation middle-table only. diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/query/QueryConstants.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/query/QueryConstants.java similarity index 90% rename from hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/query/QueryConstants.java rename to hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/query/QueryConstants.java index 81014bd7e5..bb01740dd4 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/query/QueryConstants.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/query/QueryConstants.java @@ -1,4 +1,4 @@ -package org.hibernate.envers.entities.mapper.relation.query; +package org.hibernate.envers.internal.entities.mapper.relation.query; /** * Constants used in JPQL queries. diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/query/RelationQueryGenerator.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/query/RelationQueryGenerator.java similarity index 92% rename from hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/query/RelationQueryGenerator.java rename to hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/query/RelationQueryGenerator.java index 9957454b22..5368a11b42 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/query/RelationQueryGenerator.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/query/RelationQueryGenerator.java @@ -21,9 +21,9 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.entities.mapper.relation.query; +package org.hibernate.envers.internal.entities.mapper.relation.query; import org.hibernate.Query; -import org.hibernate.envers.reader.AuditReaderImplementor; +import org.hibernate.envers.internal.reader.AuditReaderImplementor; /** * TODO: cleanup implementations and extract common code diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/query/ThreeEntityQueryGenerator.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/query/ThreeEntityQueryGenerator.java similarity index 85% rename from hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/query/ThreeEntityQueryGenerator.java rename to hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/query/ThreeEntityQueryGenerator.java index 782d12cea3..122d869b16 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/query/ThreeEntityQueryGenerator.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/query/ThreeEntityQueryGenerator.java @@ -21,29 +21,24 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.entities.mapper.relation.query; +package org.hibernate.envers.internal.entities.mapper.relation.query; import java.util.Collections; -import org.hibernate.Query; -import org.hibernate.envers.RevisionType; -import org.hibernate.envers.configuration.AuditEntitiesConfiguration; -import org.hibernate.envers.configuration.GlobalConfiguration; -import org.hibernate.envers.entities.mapper.id.QueryParameterData; -import org.hibernate.envers.entities.mapper.relation.MiddleComponentData; -import org.hibernate.envers.entities.mapper.relation.MiddleIdData; -import org.hibernate.envers.reader.AuditReaderImplementor; +import org.hibernate.envers.configuration.internal.AuditEntitiesConfiguration; +import org.hibernate.envers.configuration.internal.GlobalConfiguration; +import org.hibernate.envers.internal.entities.mapper.relation.MiddleComponentData; +import org.hibernate.envers.internal.entities.mapper.relation.MiddleIdData; +import org.hibernate.envers.internal.tools.query.Parameters; +import org.hibernate.envers.internal.tools.query.QueryBuilder; import org.hibernate.envers.strategy.AuditStrategy; -import org.hibernate.envers.tools.query.Parameters; -import org.hibernate.envers.tools.query.QueryBuilder; -import static org.hibernate.envers.entities.mapper.relation.query.QueryConstants.DEL_REVISION_TYPE_PARAMETER; -import static org.hibernate.envers.entities.mapper.relation.query.QueryConstants.INDEX_ENTITY_ALIAS; -import static org.hibernate.envers.entities.mapper.relation.query.QueryConstants.INDEX_ENTITY_ALIAS_DEF_AUD_STR; -import static org.hibernate.envers.entities.mapper.relation.query.QueryConstants.MIDDLE_ENTITY_ALIAS; -import static org.hibernate.envers.entities.mapper.relation.query.QueryConstants.REFERENCED_ENTITY_ALIAS; -import static org.hibernate.envers.entities.mapper.relation.query.QueryConstants.REFERENCED_ENTITY_ALIAS_DEF_AUD_STR; -import static org.hibernate.envers.entities.mapper.relation.query.QueryConstants.REVISION_PARAMETER; +import static org.hibernate.envers.internal.entities.mapper.relation.query.QueryConstants.DEL_REVISION_TYPE_PARAMETER; +import static org.hibernate.envers.internal.entities.mapper.relation.query.QueryConstants.INDEX_ENTITY_ALIAS; +import static org.hibernate.envers.internal.entities.mapper.relation.query.QueryConstants.INDEX_ENTITY_ALIAS_DEF_AUD_STR; +import static org.hibernate.envers.internal.entities.mapper.relation.query.QueryConstants.MIDDLE_ENTITY_ALIAS; +import static org.hibernate.envers.internal.entities.mapper.relation.query.QueryConstants.REFERENCED_ENTITY_ALIAS; +import static org.hibernate.envers.internal.entities.mapper.relation.query.QueryConstants.REFERENCED_ENTITY_ALIAS_DEF_AUD_STR; /** * Selects data from a relation middle-table and a two related versions entity. diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/query/TwoEntityOneAuditedQueryGenerator.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/query/TwoEntityOneAuditedQueryGenerator.java similarity index 82% rename from hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/query/TwoEntityOneAuditedQueryGenerator.java rename to hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/query/TwoEntityOneAuditedQueryGenerator.java index d5402cd5cd..dc0748519d 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/query/TwoEntityOneAuditedQueryGenerator.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/query/TwoEntityOneAuditedQueryGenerator.java @@ -21,25 +21,20 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.entities.mapper.relation.query; +package org.hibernate.envers.internal.entities.mapper.relation.query; import java.util.Collections; -import org.hibernate.Query; -import org.hibernate.envers.RevisionType; -import org.hibernate.envers.configuration.AuditEntitiesConfiguration; -import org.hibernate.envers.entities.mapper.id.QueryParameterData; -import org.hibernate.envers.entities.mapper.relation.MiddleComponentData; -import org.hibernate.envers.entities.mapper.relation.MiddleIdData; -import org.hibernate.envers.reader.AuditReaderImplementor; +import org.hibernate.envers.configuration.internal.AuditEntitiesConfiguration; +import org.hibernate.envers.internal.entities.mapper.relation.MiddleComponentData; +import org.hibernate.envers.internal.entities.mapper.relation.MiddleIdData; +import org.hibernate.envers.internal.tools.query.Parameters; +import org.hibernate.envers.internal.tools.query.QueryBuilder; import org.hibernate.envers.strategy.AuditStrategy; -import org.hibernate.envers.tools.query.Parameters; -import org.hibernate.envers.tools.query.QueryBuilder; -import static org.hibernate.envers.entities.mapper.relation.query.QueryConstants.DEL_REVISION_TYPE_PARAMETER; -import static org.hibernate.envers.entities.mapper.relation.query.QueryConstants.MIDDLE_ENTITY_ALIAS; -import static org.hibernate.envers.entities.mapper.relation.query.QueryConstants.REFERENCED_ENTITY_ALIAS; -import static org.hibernate.envers.entities.mapper.relation.query.QueryConstants.REVISION_PARAMETER; +import static org.hibernate.envers.internal.entities.mapper.relation.query.QueryConstants.DEL_REVISION_TYPE_PARAMETER; +import static org.hibernate.envers.internal.entities.mapper.relation.query.QueryConstants.MIDDLE_ENTITY_ALIAS; +import static org.hibernate.envers.internal.entities.mapper.relation.query.QueryConstants.REFERENCED_ENTITY_ALIAS; /** * Selects data from a relation middle-table and a related non-audited entity. diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/query/TwoEntityQueryGenerator.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/query/TwoEntityQueryGenerator.java similarity index 83% rename from hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/query/TwoEntityQueryGenerator.java rename to hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/query/TwoEntityQueryGenerator.java index 42642bd7c6..93b108e8f2 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/entities/mapper/relation/query/TwoEntityQueryGenerator.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/query/TwoEntityQueryGenerator.java @@ -21,27 +21,22 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.entities.mapper.relation.query; +package org.hibernate.envers.internal.entities.mapper.relation.query; import java.util.Collections; -import org.hibernate.Query; -import org.hibernate.envers.RevisionType; -import org.hibernate.envers.configuration.AuditEntitiesConfiguration; -import org.hibernate.envers.configuration.GlobalConfiguration; -import org.hibernate.envers.entities.mapper.id.QueryParameterData; -import org.hibernate.envers.entities.mapper.relation.MiddleComponentData; -import org.hibernate.envers.entities.mapper.relation.MiddleIdData; -import org.hibernate.envers.reader.AuditReaderImplementor; +import org.hibernate.envers.configuration.internal.AuditEntitiesConfiguration; +import org.hibernate.envers.configuration.internal.GlobalConfiguration; +import org.hibernate.envers.internal.entities.mapper.relation.MiddleComponentData; +import org.hibernate.envers.internal.entities.mapper.relation.MiddleIdData; +import org.hibernate.envers.internal.tools.query.Parameters; +import org.hibernate.envers.internal.tools.query.QueryBuilder; import org.hibernate.envers.strategy.AuditStrategy; -import org.hibernate.envers.tools.query.Parameters; -import org.hibernate.envers.tools.query.QueryBuilder; -import static org.hibernate.envers.entities.mapper.relation.query.QueryConstants.DEL_REVISION_TYPE_PARAMETER; -import static org.hibernate.envers.entities.mapper.relation.query.QueryConstants.MIDDLE_ENTITY_ALIAS; -import static org.hibernate.envers.entities.mapper.relation.query.QueryConstants.REFERENCED_ENTITY_ALIAS; -import static org.hibernate.envers.entities.mapper.relation.query.QueryConstants.REFERENCED_ENTITY_ALIAS_DEF_AUD_STR; -import static org.hibernate.envers.entities.mapper.relation.query.QueryConstants.REVISION_PARAMETER; +import static org.hibernate.envers.internal.entities.mapper.relation.query.QueryConstants.DEL_REVISION_TYPE_PARAMETER; +import static org.hibernate.envers.internal.entities.mapper.relation.query.QueryConstants.MIDDLE_ENTITY_ALIAS; +import static org.hibernate.envers.internal.entities.mapper.relation.query.QueryConstants.REFERENCED_ENTITY_ALIAS; +import static org.hibernate.envers.internal.entities.mapper.relation.query.QueryConstants.REFERENCED_ENTITY_ALIAS_DEF_AUD_STR; /** * Selects data from a relation middle-table and a related versions entity. diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/reader/AuditReaderImpl.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/reader/AuditReaderImpl.java similarity index 96% rename from hibernate-envers/src/main/java/org/hibernate/envers/reader/AuditReaderImpl.java rename to hibernate-envers/src/main/java/org/hibernate/envers/internal/reader/AuditReaderImpl.java index 784c7b0160..7a64945109 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/reader/AuditReaderImpl.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/reader/AuditReaderImpl.java @@ -21,7 +21,8 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.reader; +package org.hibernate.envers.internal.reader; + import java.util.Date; import java.util.HashMap; import java.util.HashSet; @@ -36,19 +37,19 @@ import org.hibernate.Session; import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.envers.CrossTypeRevisionChangesReader; -import org.hibernate.envers.configuration.AuditConfiguration; +import org.hibernate.envers.configuration.spi.AuditConfiguration; import org.hibernate.envers.exception.AuditException; import org.hibernate.envers.exception.NotAuditedException; import org.hibernate.envers.exception.RevisionDoesNotExistException; +import org.hibernate.envers.internal.synchronization.AuditProcess; import org.hibernate.envers.query.AuditEntity; import org.hibernate.envers.query.AuditQueryCreator; -import org.hibernate.envers.synchronization.AuditProcess; import org.hibernate.event.spi.EventSource; import org.hibernate.proxy.HibernateProxy; -import static org.hibernate.envers.tools.ArgumentsTools.checkNotNull; -import static org.hibernate.envers.tools.ArgumentsTools.checkPositive; -import static org.hibernate.envers.tools.Tools.getTargetClassIfProxied; +import static org.hibernate.envers.internal.tools.ArgumentsTools.checkNotNull; +import static org.hibernate.envers.internal.tools.ArgumentsTools.checkPositive; +import static org.hibernate.envers.internal.tools.EntityTools.getTargetClassIfProxied; /** * @author Adam Warski (adam at warski dot org) @@ -254,7 +255,7 @@ public Map findRevisions(Class revisionEntityClass, Set> findEntityTypes(Number revision) throws IllegalS // Generate result that contains entity names and corresponding Java classes. Set> result = new HashSet>(); for (String entityName : entityNames) { - result.add(Pair.make(entityName, Tools.getEntityClass(sessionImplementor, session, entityName))); + result.add(Pair.make(entityName, EntityTools.getEntityClass(sessionImplementor, session, entityName))); } return result; } diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/reader/FirstLevelCache.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/reader/FirstLevelCache.java similarity index 95% rename from hibernate-envers/src/main/java/org/hibernate/envers/reader/FirstLevelCache.java rename to hibernate-envers/src/main/java/org/hibernate/envers/internal/reader/FirstLevelCache.java index a145c1dc43..db9a4a4ab6 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/reader/FirstLevelCache.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/reader/FirstLevelCache.java @@ -21,16 +21,16 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.reader; +package org.hibernate.envers.internal.reader; import java.util.Map; import org.jboss.logging.Logger; import org.hibernate.envers.internal.EnversMessageLogger; -import org.hibernate.envers.tools.Triple; +import org.hibernate.envers.internal.tools.Triple; -import static org.hibernate.envers.tools.Tools.newHashMap; -import static org.hibernate.envers.tools.Triple.make; +import static org.hibernate.envers.internal.tools.Tools.newHashMap; +import static org.hibernate.envers.internal.tools.Triple.make; /** * First level cache for versioned entities, versions reader-scoped. Each entity is uniquely identified by a diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/revisioninfo/DefaultRevisionInfoGenerator.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/revisioninfo/DefaultRevisionInfoGenerator.java similarity index 94% rename from hibernate-envers/src/main/java/org/hibernate/envers/revisioninfo/DefaultRevisionInfoGenerator.java rename to hibernate-envers/src/main/java/org/hibernate/envers/internal/revisioninfo/DefaultRevisionInfoGenerator.java index bda9b8788b..b3d480c71a 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/revisioninfo/DefaultRevisionInfoGenerator.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/revisioninfo/DefaultRevisionInfoGenerator.java @@ -21,7 +21,7 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.revisioninfo; +package org.hibernate.envers.internal.revisioninfo; import java.io.Serializable; import java.lang.reflect.InvocationTargetException; @@ -32,9 +32,9 @@ import org.hibernate.envers.EntityTrackingRevisionListener; import org.hibernate.envers.RevisionListener; import org.hibernate.envers.RevisionType; -import org.hibernate.envers.entities.PropertyData; -import org.hibernate.envers.synchronization.SessionCacheCleaner; -import org.hibernate.envers.tools.reflection.ReflectionTools; +import org.hibernate.envers.internal.entities.PropertyData; +import org.hibernate.envers.internal.synchronization.SessionCacheCleaner; +import org.hibernate.envers.internal.tools.ReflectionTools; import org.hibernate.internal.util.ReflectHelper; import org.hibernate.property.Setter; diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/revisioninfo/DefaultTrackingModifiedEntitiesRevisionInfoGenerator.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/revisioninfo/DefaultTrackingModifiedEntitiesRevisionInfoGenerator.java similarity index 93% rename from hibernate-envers/src/main/java/org/hibernate/envers/revisioninfo/DefaultTrackingModifiedEntitiesRevisionInfoGenerator.java rename to hibernate-envers/src/main/java/org/hibernate/envers/internal/revisioninfo/DefaultTrackingModifiedEntitiesRevisionInfoGenerator.java index e63b0b767d..f3da3f4d1a 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/revisioninfo/DefaultTrackingModifiedEntitiesRevisionInfoGenerator.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/revisioninfo/DefaultTrackingModifiedEntitiesRevisionInfoGenerator.java @@ -1,4 +1,4 @@ -package org.hibernate.envers.revisioninfo; +package org.hibernate.envers.internal.revisioninfo; import java.io.Serializable; import java.util.HashSet; @@ -8,8 +8,8 @@ import org.hibernate.envers.ModifiedEntityNames; import org.hibernate.envers.RevisionListener; import org.hibernate.envers.RevisionType; -import org.hibernate.envers.entities.PropertyData; -import org.hibernate.envers.tools.reflection.ReflectionTools; +import org.hibernate.envers.internal.entities.PropertyData; +import org.hibernate.envers.internal.tools.ReflectionTools; import org.hibernate.property.Getter; import org.hibernate.property.Setter; diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/revisioninfo/ModifiedEntityNamesReader.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/revisioninfo/ModifiedEntityNamesReader.java similarity index 80% rename from hibernate-envers/src/main/java/org/hibernate/envers/revisioninfo/ModifiedEntityNamesReader.java rename to hibernate-envers/src/main/java/org/hibernate/envers/internal/revisioninfo/ModifiedEntityNamesReader.java index fb642c679a..f29f6846d4 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/revisioninfo/ModifiedEntityNamesReader.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/revisioninfo/ModifiedEntityNamesReader.java @@ -1,9 +1,9 @@ -package org.hibernate.envers.revisioninfo; +package org.hibernate.envers.internal.revisioninfo; import java.util.Set; -import org.hibernate.envers.entities.PropertyData; -import org.hibernate.envers.tools.reflection.ReflectionTools; +import org.hibernate.envers.internal.entities.PropertyData; +import org.hibernate.envers.internal.tools.ReflectionTools; import org.hibernate.property.Getter; /** diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/revisioninfo/RevisionInfoGenerator.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/revisioninfo/RevisionInfoGenerator.java similarity index 97% rename from hibernate-envers/src/main/java/org/hibernate/envers/revisioninfo/RevisionInfoGenerator.java rename to hibernate-envers/src/main/java/org/hibernate/envers/internal/revisioninfo/RevisionInfoGenerator.java index ff08605900..cef1a14a3b 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/revisioninfo/RevisionInfoGenerator.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/revisioninfo/RevisionInfoGenerator.java @@ -21,7 +21,7 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.revisioninfo; +package org.hibernate.envers.internal.revisioninfo; import java.io.Serializable; diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/revisioninfo/RevisionInfoNumberReader.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/revisioninfo/RevisionInfoNumberReader.java similarity index 90% rename from hibernate-envers/src/main/java/org/hibernate/envers/revisioninfo/RevisionInfoNumberReader.java rename to hibernate-envers/src/main/java/org/hibernate/envers/internal/revisioninfo/RevisionInfoNumberReader.java index 603c90e0bd..69f17ad8fb 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/revisioninfo/RevisionInfoNumberReader.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/revisioninfo/RevisionInfoNumberReader.java @@ -21,9 +21,9 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.revisioninfo; -import org.hibernate.envers.entities.PropertyData; -import org.hibernate.envers.tools.reflection.ReflectionTools; +package org.hibernate.envers.internal.revisioninfo; +import org.hibernate.envers.internal.entities.PropertyData; +import org.hibernate.envers.internal.tools.ReflectionTools; import org.hibernate.property.Getter; /** diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/revisioninfo/RevisionInfoQueryCreator.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/revisioninfo/RevisionInfoQueryCreator.java similarity index 98% rename from hibernate-envers/src/main/java/org/hibernate/envers/revisioninfo/RevisionInfoQueryCreator.java rename to hibernate-envers/src/main/java/org/hibernate/envers/internal/revisioninfo/RevisionInfoQueryCreator.java index b1eb11ed0b..005d29db58 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/revisioninfo/RevisionInfoQueryCreator.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/revisioninfo/RevisionInfoQueryCreator.java @@ -21,7 +21,7 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.revisioninfo; +package org.hibernate.envers.internal.revisioninfo; import java.util.Date; import java.util.Set; diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/synchronization/AuditProcess.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/synchronization/AuditProcess.java similarity index 96% rename from hibernate-envers/src/main/java/org/hibernate/envers/synchronization/AuditProcess.java rename to hibernate-envers/src/main/java/org/hibernate/envers/internal/synchronization/AuditProcess.java index b74c39feae..d8e79979b6 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/synchronization/AuditProcess.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/synchronization/AuditProcess.java @@ -21,7 +21,7 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.synchronization; +package org.hibernate.envers.internal.synchronization; import java.util.HashMap; import java.util.LinkedList; @@ -33,8 +33,8 @@ import org.hibernate.Session; import org.hibernate.action.spi.BeforeTransactionCompletionProcess; import org.hibernate.engine.spi.SessionImplementor; -import org.hibernate.envers.revisioninfo.RevisionInfoGenerator; -import org.hibernate.envers.synchronization.work.AuditWorkUnit; +import org.hibernate.envers.internal.revisioninfo.RevisionInfoGenerator; +import org.hibernate.envers.internal.synchronization.work.AuditWorkUnit; import org.hibernate.envers.tools.Pair; /** diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/synchronization/AuditProcessManager.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/synchronization/AuditProcessManager.java similarity index 95% rename from hibernate-envers/src/main/java/org/hibernate/envers/synchronization/AuditProcessManager.java rename to hibernate-envers/src/main/java/org/hibernate/envers/internal/synchronization/AuditProcessManager.java index dc39a15003..0f9c447d00 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/synchronization/AuditProcessManager.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/synchronization/AuditProcessManager.java @@ -21,14 +21,14 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.synchronization; +package org.hibernate.envers.internal.synchronization; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import org.hibernate.Transaction; import org.hibernate.action.spi.AfterTransactionCompletionProcess; import org.hibernate.engine.spi.SessionImplementor; -import org.hibernate.envers.revisioninfo.RevisionInfoGenerator; +import org.hibernate.envers.internal.revisioninfo.RevisionInfoGenerator; import org.hibernate.event.spi.EventSource; /** diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/synchronization/EntityChangeNotifier.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/synchronization/EntityChangeNotifier.java similarity index 79% rename from hibernate-envers/src/main/java/org/hibernate/envers/synchronization/EntityChangeNotifier.java rename to hibernate-envers/src/main/java/org/hibernate/envers/internal/synchronization/EntityChangeNotifier.java index 1cc89e7636..c9dc6cad76 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/synchronization/EntityChangeNotifier.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/synchronization/EntityChangeNotifier.java @@ -1,14 +1,14 @@ -package org.hibernate.envers.synchronization; +package org.hibernate.envers.internal.synchronization; import java.io.Serializable; import org.hibernate.Session; import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.envers.RevisionType; -import org.hibernate.envers.revisioninfo.RevisionInfoGenerator; -import org.hibernate.envers.synchronization.work.AuditWorkUnit; -import org.hibernate.envers.synchronization.work.PersistentCollectionChangeWorkUnit; -import org.hibernate.envers.tools.Tools; +import org.hibernate.envers.internal.revisioninfo.RevisionInfoGenerator; +import org.hibernate.envers.internal.synchronization.work.AuditWorkUnit; +import org.hibernate.envers.internal.synchronization.work.PersistentCollectionChangeWorkUnit; +import org.hibernate.envers.internal.tools.EntityTools; /** * Notifies {@link RevisionInfoGenerator} about changes made in the current revision. @@ -36,7 +36,7 @@ public void entityChanged(Session session, Object currentRevisionData, AuditWork // Notify about a change in collection owner entity. entityId = ((PersistentCollectionChangeWorkUnit.PersistentCollectionChangeWorkUnitId) entityId).getOwnerId(); } - Class entityClass = Tools.getEntityClass(sessionImplementor, session, vwu.getEntityName()); + Class entityClass = EntityTools.getEntityClass(sessionImplementor, session, vwu.getEntityName()); revisionInfoGenerator.entityChanged(entityClass, vwu.getEntityName(), entityId, vwu.getRevisionType(), currentRevisionData); } diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/synchronization/SessionCacheCleaner.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/synchronization/SessionCacheCleaner.java similarity index 95% rename from hibernate-envers/src/main/java/org/hibernate/envers/synchronization/SessionCacheCleaner.java rename to hibernate-envers/src/main/java/org/hibernate/envers/internal/synchronization/SessionCacheCleaner.java index fe7d1b4569..4c9c8c40fe 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/synchronization/SessionCacheCleaner.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/synchronization/SessionCacheCleaner.java @@ -1,4 +1,4 @@ -package org.hibernate.envers.synchronization; +package org.hibernate.envers.internal.synchronization; import org.hibernate.Session; import org.hibernate.action.spi.AfterTransactionCompletionProcess; diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/synchronization/work/AbstractAuditWorkUnit.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/synchronization/work/AbstractAuditWorkUnit.java similarity index 94% rename from hibernate-envers/src/main/java/org/hibernate/envers/synchronization/work/AbstractAuditWorkUnit.java rename to hibernate-envers/src/main/java/org/hibernate/envers/internal/synchronization/work/AbstractAuditWorkUnit.java index 1cc9373cd8..29bd8ce032 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/synchronization/work/AbstractAuditWorkUnit.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/synchronization/work/AbstractAuditWorkUnit.java @@ -21,7 +21,7 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.synchronization.work; +package org.hibernate.envers.internal.synchronization.work; import java.io.Serializable; import java.util.HashMap; @@ -30,8 +30,8 @@ import org.hibernate.Session; import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.envers.RevisionType; -import org.hibernate.envers.configuration.AuditConfiguration; -import org.hibernate.envers.configuration.AuditEntitiesConfiguration; +import org.hibernate.envers.configuration.internal.AuditEntitiesConfiguration; +import org.hibernate.envers.configuration.spi.AuditConfiguration; import org.hibernate.envers.strategy.AuditStrategy; /** diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/synchronization/work/AddWorkUnit.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/synchronization/work/AddWorkUnit.java similarity index 93% rename from hibernate-envers/src/main/java/org/hibernate/envers/synchronization/work/AddWorkUnit.java rename to hibernate-envers/src/main/java/org/hibernate/envers/internal/synchronization/work/AddWorkUnit.java index 507756690e..2650661ae7 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/synchronization/work/AddWorkUnit.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/synchronization/work/AddWorkUnit.java @@ -21,15 +21,16 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.synchronization.work; +package org.hibernate.envers.internal.synchronization.work; + import java.io.Serializable; import java.util.HashMap; import java.util.Map; import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.envers.RevisionType; -import org.hibernate.envers.configuration.AuditConfiguration; -import org.hibernate.envers.tools.Tools; +import org.hibernate.envers.configuration.spi.AuditConfiguration; +import org.hibernate.envers.internal.tools.ArraysTools; import org.hibernate.persister.entity.EntityPersister; /** @@ -56,7 +57,7 @@ public AddWorkUnit(SessionImplementor sessionImplementor, String entityName, Aud this.data = data; final String[] propertyNames = sessionImplementor.getFactory().getEntityPersister(getEntityName()).getPropertyNames(); - this.state = Tools.mapToArray(data, propertyNames); + this.state = ArraysTools.mapToArray(data, propertyNames); } public boolean containsWork() { diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/synchronization/work/AuditWorkUnit.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/synchronization/work/AuditWorkUnit.java similarity index 97% rename from hibernate-envers/src/main/java/org/hibernate/envers/synchronization/work/AuditWorkUnit.java rename to hibernate-envers/src/main/java/org/hibernate/envers/internal/synchronization/work/AuditWorkUnit.java index eb50f80ab8..f247f21bee 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/synchronization/work/AuditWorkUnit.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/synchronization/work/AuditWorkUnit.java @@ -21,7 +21,7 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.synchronization.work; +package org.hibernate.envers.internal.synchronization.work; import java.io.Serializable; import java.util.Map; diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/synchronization/work/CollectionChangeWorkUnit.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/synchronization/work/CollectionChangeWorkUnit.java similarity index 96% rename from hibernate-envers/src/main/java/org/hibernate/envers/synchronization/work/CollectionChangeWorkUnit.java rename to hibernate-envers/src/main/java/org/hibernate/envers/internal/synchronization/work/CollectionChangeWorkUnit.java index f4f73786f3..eb06f1f8c1 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/synchronization/work/CollectionChangeWorkUnit.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/synchronization/work/CollectionChangeWorkUnit.java @@ -21,7 +21,7 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.synchronization.work; +package org.hibernate.envers.internal.synchronization.work; import java.io.Serializable; import java.util.HashMap; @@ -29,7 +29,7 @@ import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.envers.RevisionType; -import org.hibernate.envers.configuration.AuditConfiguration; +import org.hibernate.envers.configuration.spi.AuditConfiguration; /** * @author Adam Warski (adam at warski dot org) diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/synchronization/work/DelWorkUnit.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/synchronization/work/DelWorkUnit.java similarity index 93% rename from hibernate-envers/src/main/java/org/hibernate/envers/synchronization/work/DelWorkUnit.java rename to hibernate-envers/src/main/java/org/hibernate/envers/internal/synchronization/work/DelWorkUnit.java index 98771d32d6..2f131f8375 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/synchronization/work/DelWorkUnit.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/synchronization/work/DelWorkUnit.java @@ -21,15 +21,16 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.synchronization.work; +package org.hibernate.envers.internal.synchronization.work; + import java.io.Serializable; import java.util.HashMap; import java.util.Map; import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.envers.RevisionType; -import org.hibernate.envers.configuration.AuditConfiguration; -import org.hibernate.envers.tools.Tools; +import org.hibernate.envers.configuration.spi.AuditConfiguration; +import org.hibernate.envers.internal.tools.ArraysTools; import org.hibernate.persister.entity.EntityPersister; /** @@ -70,7 +71,7 @@ public Map generateData(Object revisionData) { } public AuditWorkUnit merge(AddWorkUnit second) { - if (Tools.arraysEqual(second.getState(), state)) { + if (ArraysTools.arraysEqual(second.getState(), state)) { return null; // Return null if object's state has not changed. } return new ModWorkUnit(sessionImplementor, entityName, verCfg, id, entityPersister, second.getState(), state); diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/synchronization/work/FakeBidirectionalRelationWorkUnit.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/synchronization/work/FakeBidirectionalRelationWorkUnit.java similarity index 97% rename from hibernate-envers/src/main/java/org/hibernate/envers/synchronization/work/FakeBidirectionalRelationWorkUnit.java rename to hibernate-envers/src/main/java/org/hibernate/envers/internal/synchronization/work/FakeBidirectionalRelationWorkUnit.java index eaa2c25efc..f5c5f58e3d 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/synchronization/work/FakeBidirectionalRelationWorkUnit.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/synchronization/work/FakeBidirectionalRelationWorkUnit.java @@ -1,4 +1,4 @@ -package org.hibernate.envers.synchronization.work; +package org.hibernate.envers.internal.synchronization.work; import java.io.Serializable; import java.util.HashMap; import java.util.HashSet; @@ -7,8 +7,8 @@ import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.envers.RevisionType; -import org.hibernate.envers.configuration.AuditConfiguration; -import org.hibernate.envers.entities.RelationDescription; +import org.hibernate.envers.configuration.spi.AuditConfiguration; +import org.hibernate.envers.internal.entities.RelationDescription; /** * A work unit that handles "fake" bidirectional one-to-many relations (mapped with {@code @OneToMany+@JoinColumn} and diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/synchronization/work/ModWorkUnit.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/synchronization/work/ModWorkUnit.java similarity index 96% rename from hibernate-envers/src/main/java/org/hibernate/envers/synchronization/work/ModWorkUnit.java rename to hibernate-envers/src/main/java/org/hibernate/envers/internal/synchronization/work/ModWorkUnit.java index 5b2454b0fa..77129d9c6a 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/synchronization/work/ModWorkUnit.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/synchronization/work/ModWorkUnit.java @@ -21,7 +21,7 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.synchronization.work; +package org.hibernate.envers.internal.synchronization.work; import java.io.Serializable; import java.util.HashMap; @@ -29,7 +29,7 @@ import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.envers.RevisionType; -import org.hibernate.envers.configuration.AuditConfiguration; +import org.hibernate.envers.configuration.spi.AuditConfiguration; import org.hibernate.persister.entity.EntityPersister; /** diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/synchronization/work/PersistentCollectionChangeWorkUnit.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/synchronization/work/PersistentCollectionChangeWorkUnit.java similarity index 97% rename from hibernate-envers/src/main/java/org/hibernate/envers/synchronization/work/PersistentCollectionChangeWorkUnit.java rename to hibernate-envers/src/main/java/org/hibernate/envers/internal/synchronization/work/PersistentCollectionChangeWorkUnit.java index 4728690502..6f87f1d19b 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/synchronization/work/PersistentCollectionChangeWorkUnit.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/synchronization/work/PersistentCollectionChangeWorkUnit.java @@ -21,7 +21,8 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.synchronization.work; +package org.hibernate.envers.internal.synchronization.work; + import java.io.Serializable; import java.util.ArrayList; import java.util.HashMap; @@ -33,9 +34,9 @@ import org.hibernate.engine.spi.CollectionEntry; import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.envers.RevisionType; -import org.hibernate.envers.configuration.AuditConfiguration; -import org.hibernate.envers.configuration.AuditEntitiesConfiguration; -import org.hibernate.envers.entities.mapper.PersistentCollectionChangeData; +import org.hibernate.envers.configuration.internal.AuditEntitiesConfiguration; +import org.hibernate.envers.configuration.spi.AuditConfiguration; +import org.hibernate.envers.internal.entities.mapper.PersistentCollectionChangeData; /** * @author Adam Warski (adam at warski dot org) diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/synchronization/work/WorkUnitMergeDispatcher.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/synchronization/work/WorkUnitMergeDispatcher.java similarity index 96% rename from hibernate-envers/src/main/java/org/hibernate/envers/synchronization/work/WorkUnitMergeDispatcher.java rename to hibernate-envers/src/main/java/org/hibernate/envers/internal/synchronization/work/WorkUnitMergeDispatcher.java index 6a85ed8fd2..0359343771 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/synchronization/work/WorkUnitMergeDispatcher.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/synchronization/work/WorkUnitMergeDispatcher.java @@ -21,7 +21,7 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.synchronization.work; +package org.hibernate.envers.internal.synchronization.work; /** diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/synchronization/work/WorkUnitMergeVisitor.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/synchronization/work/WorkUnitMergeVisitor.java similarity index 96% rename from hibernate-envers/src/main/java/org/hibernate/envers/synchronization/work/WorkUnitMergeVisitor.java rename to hibernate-envers/src/main/java/org/hibernate/envers/internal/synchronization/work/WorkUnitMergeVisitor.java index b01e1a8b92..c47840ed00 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/synchronization/work/WorkUnitMergeVisitor.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/synchronization/work/WorkUnitMergeVisitor.java @@ -21,7 +21,7 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.synchronization.work; +package org.hibernate.envers.internal.synchronization.work; /** diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/tools/ArraysTools.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/tools/ArgumentsTools.java similarity index 72% rename from hibernate-envers/src/main/java/org/hibernate/envers/tools/ArraysTools.java rename to hibernate-envers/src/main/java/org/hibernate/envers/internal/tools/ArgumentsTools.java index f24fdee4fa..d4d50ca54c 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/tools/ArraysTools.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/tools/ArgumentsTools.java @@ -21,20 +21,21 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.tools; - +package org.hibernate.envers.internal.tools; /** * @author Adam Warski (adam at warski dot org) */ -public class ArraysTools { - public static boolean arrayIncludesInstanceOf(T[] array, Class cls) { - for (T obj : array) { - if (cls.isAssignableFrom(obj.getClass())) { - return true; - } - } +public abstract class ArgumentsTools { + public static void checkNotNull(Object o, String paramName) { + if ( o == null ) { + throw new IllegalArgumentException( paramName + " cannot be null." ); + } + } - return false; - } + public static void checkPositive(Number i, String paramName) { + if ( i.longValue() <= 0l ) { + throw new IllegalArgumentException( paramName + " has to be greater than 0." ); + } + } } diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/internal/tools/ArraysTools.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/tools/ArraysTools.java new file mode 100644 index 0000000000..8b3e5d4b71 --- /dev/null +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/tools/ArraysTools.java @@ -0,0 +1,71 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * indicated by the @author tags or express copyright attribution + * statements applied by the authors. All third-party contributions are + * distributed under license by Red Hat Middleware LLC. + * + * This copyrighted material is made available to anyone wishing to use, modify, + * copy, or redistribute it subject to the terms and conditions of the GNU + * Lesser General Public License, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this distribution; if not, write to: + * Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor + * Boston, MA 02110-1301 USA + */ +package org.hibernate.envers.internal.tools; + +import java.util.Map; + +/** + * @author Adam Warski (adam at warski dot org) + */ +public abstract class ArraysTools { + public static boolean arrayIncludesInstanceOf(T[] array, Class cls) { + for ( T obj : array ) { + if ( cls.isAssignableFrom( obj.getClass() ) ) { + return true; + } + } + + return false; + } + + public static boolean arraysEqual(Object[] array1, Object[] array2) { + if ( array1 == null ) { + return array2 == null; + } + if ( array2 == null || array1.length != array2.length ) { + return false; + } + for ( int i = 0; i < array1.length; ++i ) { + if ( array1[i] != null ? !array1[i].equals( array2[i] ) : array2[i] != null ) { + return false; + } + } + return true; + } + + /** + * Converts map's value set to an array. {@code keys} parameter specifies requested elements and their order. + * @param data Source map. + * @param keys Array of keys that represent requested map values. + * @return Array of values stored in the map under specified keys. If map does not contain requested key, + * {@code null} is inserted. + */ + public static Object[] mapToArray(Map data, String[] keys) { + Object[] ret = new Object[keys.length]; + for ( int i = 0; i < keys.length; ++i ) { + ret[i] = data.get( keys[i] ); + } + return ret; + } +} diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/internal/tools/EntityTools.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/tools/EntityTools.java new file mode 100644 index 0000000000..f0d36f41d1 --- /dev/null +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/tools/EntityTools.java @@ -0,0 +1,86 @@ +package org.hibernate.envers.internal.tools; + +import javassist.util.proxy.ProxyFactory; + +import org.hibernate.Session; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.engine.spi.SessionImplementor; +import org.hibernate.persister.entity.EntityPersister; +import org.hibernate.proxy.HibernateProxy; + +/** + * @author Lukasz Antoniak (lukasz dot antoniak at gmail dot com) + */ +public abstract class EntityTools { + public static boolean entitiesEqual(SessionImplementor session, String entityName, Object obj1, Object obj2) { + Object id1 = getIdentifier( session, entityName, obj1 ); + Object id2 = getIdentifier( session, entityName, obj2 ); + + return Tools.objectsEqual( id1, id2 ); + } + + public static Object getIdentifier(SessionImplementor session, String entityName, Object obj) { + if ( obj == null ) { + return null; + } + + if ( obj instanceof HibernateProxy ) { + HibernateProxy hibernateProxy = (HibernateProxy) obj; + return hibernateProxy.getHibernateLazyInitializer().getIdentifier(); + } + + return session.getEntityPersister( entityName, obj ).getIdentifier( obj, session ); + } + + public static Object getTargetFromProxy(SessionFactoryImplementor sessionFactoryImplementor, HibernateProxy proxy) { + if ( !proxy.getHibernateLazyInitializer().isUninitialized() || activeProxySession( proxy ) ) { + return proxy.getHibernateLazyInitializer().getImplementation(); + } + + SessionImplementor sessionImplementor = proxy.getHibernateLazyInitializer().getSession(); + Session tempSession = sessionImplementor == null + ? sessionFactoryImplementor.openTemporarySession() + : sessionImplementor.getFactory().openTemporarySession(); + try { + Object target = tempSession.get( + proxy.getHibernateLazyInitializer().getEntityName(), + proxy.getHibernateLazyInitializer().getIdentifier() + ); + return target; + } + finally { + tempSession.close(); + } + } + + private static boolean activeProxySession(HibernateProxy proxy) { + Session session = (Session) proxy.getHibernateLazyInitializer().getSession(); + return session != null && session.isOpen() && session.isConnected(); + } + + /** + * @param clazz Class wrapped with a proxy or not. + * @param Class type. + * @return Returns target class in case it has been wrapped with a proxy. If {@code null} reference is passed, + * method returns {@code null}. + */ + @SuppressWarnings({ "unchecked" }) + public static Class getTargetClassIfProxied(Class clazz) { + if ( clazz == null ) { + return null; + } + else if ( ProxyFactory.isProxyClass( clazz ) ) { + // Get the source class of Javassist proxy instance. + return (Class) clazz.getSuperclass(); + } + return clazz; + } + + /** + * @return Java class mapped to specified entity name. + */ + public static Class getEntityClass(SessionImplementor sessionImplementor, Session session, String entityName) { + EntityPersister entityPersister = sessionImplementor.getFactory().getEntityPersister( entityName ); + return entityPersister.getMappedClass(); + } +} diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/internal/tools/MappingTools.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/tools/MappingTools.java new file mode 100644 index 0000000000..5060e96eb5 --- /dev/null +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/tools/MappingTools.java @@ -0,0 +1,43 @@ +package org.hibernate.envers.internal.tools; + +import org.hibernate.mapping.Collection; +import org.hibernate.mapping.OneToMany; +import org.hibernate.mapping.ToOne; +import org.hibernate.mapping.Value; + +/** + * @author Adam Warski (adam at warski dot org) + */ +public abstract class MappingTools { + /** + * @param componentName Name of the component, that is, name of the property in the entity that references the component. + * + * @return A prefix for properties in the given component. + */ + public static String createComponentPrefix(String componentName) { + return componentName + "_"; + } + + /** + * @param referencePropertyName The name of the property that holds the relation to the entity. + * + * @return A prefix which should be used to prefix an id mapper for the related entity. + */ + public static String createToOneRelationPrefix(String referencePropertyName) { + return referencePropertyName + "_"; + } + + public static String getReferencedEntityName(Value value) { + if ( value instanceof ToOne ) { + return ( (ToOne) value ).getReferencedEntityName(); + } + else if ( value instanceof OneToMany ) { + return ( (OneToMany) value ).getReferencedEntityName(); + } + else if ( value instanceof Collection ) { + return getReferencedEntityName( ( (Collection) value ).getElement() ); + } + + return null; + } +} diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/tools/MutableBoolean.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/tools/MutableBoolean.java similarity index 97% rename from hibernate-envers/src/main/java/org/hibernate/envers/tools/MutableBoolean.java rename to hibernate-envers/src/main/java/org/hibernate/envers/internal/tools/MutableBoolean.java index 0d1f5d6242..d0db6c9220 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/tools/MutableBoolean.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/tools/MutableBoolean.java @@ -21,7 +21,7 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.tools; +package org.hibernate.envers.internal.tools; /** diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/tools/MutableInteger.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/tools/MutableInteger.java similarity index 96% rename from hibernate-envers/src/main/java/org/hibernate/envers/tools/MutableInteger.java rename to hibernate-envers/src/main/java/org/hibernate/envers/internal/tools/MutableInteger.java index cbfc2ccd78..bc48be544a 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/tools/MutableInteger.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/tools/MutableInteger.java @@ -21,7 +21,7 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.tools; +package org.hibernate.envers.internal.tools; /** diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/internal/tools/ReflectionTools.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/tools/ReflectionTools.java new file mode 100644 index 0000000000..653013aafe --- /dev/null +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/tools/ReflectionTools.java @@ -0,0 +1,142 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * indicated by the @author tags or express copyright attribution + * statements applied by the authors. All third-party contributions are + * distributed under license by Red Hat Middleware LLC. + * + * This copyrighted material is made available to anyone wishing to use, modify, + * copy, or redistribute it subject to the terms and conditions of the GNU + * Lesser General Public License, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this distribution; if not, write to: + * Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor + * Boston, MA 02110-1301 USA + */ +package org.hibernate.envers.internal.tools; + +import java.util.Map; + +import org.hibernate.annotations.common.reflection.XClass; +import org.hibernate.annotations.common.reflection.XProperty; +import org.hibernate.boot.registry.classloading.spi.ClassLoaderService; +import org.hibernate.boot.registry.classloading.spi.ClassLoadingException; +import org.hibernate.cfg.Configuration; +import org.hibernate.envers.configuration.spi.AuditConfiguration; +import org.hibernate.envers.internal.entities.PropertyData; +import org.hibernate.envers.tools.Pair; +import org.hibernate.internal.util.collections.ConcurrentReferenceHashMap; +import org.hibernate.property.Getter; +import org.hibernate.property.PropertyAccessor; +import org.hibernate.property.PropertyAccessorFactory; +import org.hibernate.property.Setter; + +/** + * @author Adam Warski (adam at warski dot org) + * @author Lukasz Antoniak (lukasz dot antoniak at gmail dot com) + */ +public abstract class ReflectionTools { + private static final Map, Getter> getterCache = + new ConcurrentReferenceHashMap, Getter>( + 10, ConcurrentReferenceHashMap.ReferenceType.SOFT, ConcurrentReferenceHashMap.ReferenceType.SOFT + ); + private static final Map, Setter> setterCache = + new ConcurrentReferenceHashMap, Setter>( + 10, ConcurrentReferenceHashMap.ReferenceType.SOFT, ConcurrentReferenceHashMap.ReferenceType.SOFT + ); + + private static PropertyAccessor getAccessor(String accessorType) { + return PropertyAccessorFactory.getPropertyAccessor( accessorType ); + } + + public static Getter getGetter(Class cls, PropertyData propertyData) { + return getGetter( cls, propertyData.getBeanName(), propertyData.getAccessType() ); + } + + public static Getter getGetter(Class cls, String propertyName, String accessorType) { + Pair key = Pair.make( cls, propertyName ); + Getter value = getterCache.get( key ); + if ( value == null ) { + value = getAccessor( accessorType ).getGetter( cls, propertyName ); + // It's ok if two getters are generated concurrently + getterCache.put( key, value ); + } + + return value; + } + + public static Setter getSetter(Class cls, PropertyData propertyData) { + return getSetter( cls, propertyData.getBeanName(), propertyData.getAccessType() ); + } + + private static Setter getSetter(Class cls, String propertyName, String accessorType) { + Pair key = Pair.make( cls, propertyName ); + Setter value = setterCache.get( key ); + if ( value == null ) { + value = getAccessor( accessorType ).getSetter( cls, propertyName ); + // It's ok if two setters are generated concurrently + setterCache.put( key, value ); + } + + return value; + } + + /** + * @param clazz Source class. + * @param propertyName Property name. + * @return Property object or {@code null} if none with expected name has been found. + */ + public static XProperty getProperty(XClass clazz, String propertyName) { + XProperty property = getProperty( clazz, propertyName, "field" ); + if ( property == null ) { + property = getProperty( clazz, propertyName, "property" ); + } + return property; + } + + /** + * @param clazz Source class. + * @param propertyName Property name. + * @param accessType Expected access type. Legal values are field and property. + * @return Property object or {@code null} if none with expected name and access type has been found. + */ + public static XProperty getProperty(XClass clazz, String propertyName, String accessType) { + for ( XProperty property : clazz.getDeclaredProperties( accessType ) ) { + if ( propertyName.equals( property.getName() ) ) { + return property; + } + } + return null; + } + + /** + * Locate class with a given name. + * @param name Fully qualified class name. + * @param classLoaderService Class loading service. Passing {@code null} reference + * in case of {@link AuditConfiguration#getFor(Configuration)} usage. + * @return The cass reference. + * @throws ClassLoadingException Indicates the class could not be found. + */ + @SuppressWarnings("unchecked") + public static Class loadClass(String name, ClassLoaderService classLoaderService) throws ClassLoadingException { + try { + if ( classLoaderService != null ) { + return classLoaderService.classForName( name ); + } + else { + return (Class) Thread.currentThread().getContextClassLoader().loadClass( name ); + } + } + catch ( Exception e ) { + throw new ClassLoadingException( "Unable to load class [" + name + "]", e ); + } + } +} diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/internal/tools/StringTools.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/tools/StringTools.java new file mode 100644 index 0000000000..e44d78f3e2 --- /dev/null +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/tools/StringTools.java @@ -0,0 +1,77 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * indicated by the @author tags or express copyright attribution + * statements applied by the authors. All third-party contributions are + * distributed under license by Red Hat Middleware LLC. + * + * This copyrighted material is made available to anyone wishing to use, modify, + * copy, or redistribute it subject to the terms and conditions of the GNU + * Lesser General Public License, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this distribution; if not, write to: + * Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor + * Boston, MA 02110-1301 USA + */ +package org.hibernate.envers.internal.tools; + +import java.util.Iterator; + +/** + * @author Adam Warski (adam at warski dot org) + */ +public abstract class StringTools { + public static boolean isEmpty(String s) { + return s == null || "".equals( s ); + } + + public static boolean isEmpty(Object o) { + return o == null || "".equals( o ); + } + + /** + * @param s String, from which to get the last component. + * + * @return The last component of the dot-separated string s. For example, for a string + * "a.b.c", the result is "c". + */ + public static String getLastComponent(String s) { + if ( s == null ) { + return null; + } + int lastDot = s.lastIndexOf( "." ); + if ( lastDot == -1 ) { + return s; + } + else { + return s.substring( lastDot + 1 ); + } + } + + /** + * To the given string builder, appends all strings in the given iterator, separating them with the given + * separator. For example, for an interator "a" "b" "c" and separator ":" the output is "a:b:c". + * + * @param sb String builder, to which to append. + * @param contents Strings to be appended. + * @param separator Separator between subsequent content. + */ + public static void append(StringBuilder sb, Iterator contents, String separator) { + boolean isFirst = true; + while ( contents.hasNext() ) { + if ( !isFirst ) { + sb.append( separator ); + } + sb.append( contents.next() ); + isFirst = false; + } + } +} diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/internal/tools/Tools.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/tools/Tools.java new file mode 100644 index 0000000000..da7e29937e --- /dev/null +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/tools/Tools.java @@ -0,0 +1,103 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * indicated by the @author tags or express copyright attribution + * statements applied by the authors. All third-party contributions are + * distributed under license by Red Hat Middleware LLC. + * + * This copyrighted material is made available to anyone wishing to use, modify, + * copy, or redistribute it subject to the terms and conditions of the GNU + * Lesser General Public License, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this distribution; if not, write to: + * Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor + * Boston, MA 02110-1301 USA + */ +package org.hibernate.envers.internal.tools; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.hibernate.envers.tools.Pair; + +/** + * @author Adam Warski (adam at warski dot org) + * @author HernпїЅn Chanfreau + * @author Lukasz Antoniak (lukasz dot antoniak at gmail dot com) + */ +public abstract class Tools { + public static Map newHashMap() { + return new HashMap(); + } + + public static Set newHashSet() { + return new HashSet(); + } + + public static Map newLinkedHashMap() { + return new LinkedHashMap(); + } + + public static boolean objectsEqual(Object obj1, Object obj2) { + if ( obj1 == null ) { + return obj2 == null; + } + + return obj1.equals( obj2 ); + } + + public static List iteratorToList(Iterator iter) { + List ret = new ArrayList(); + while ( iter.hasNext() ) { + ret.add( iter.next() ); + } + + return ret; + } + + public static boolean iteratorsContentEqual(Iterator iter1, Iterator iter2) { + while ( iter1.hasNext() && iter2.hasNext() ) { + if ( !iter1.next().equals( iter2.next() ) ) { + return false; + } + } + + //noinspection RedundantIfStatement + if ( iter1.hasNext() || iter2.hasNext() ) { + return false; + } + + return true; + } + + /** + * Transforms a list of arbitrary elements to a list of index-element pairs. + * + * @param list List to transform. + * + * @return A list of pairs: ((0, element_at_index_0), (1, element_at_index_1), ...) + */ + public static List> listToIndexElementPairList(List list) { + List> ret = new ArrayList>(); + Iterator listIter = list.iterator(); + for ( int i = 0; i < list.size(); i++ ) { + ret.add( Pair.make( i, listIter.next() ) ); + } + + return ret; + } +} diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/tools/Triple.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/tools/Triple.java similarity index 98% rename from hibernate-envers/src/main/java/org/hibernate/envers/tools/Triple.java rename to hibernate-envers/src/main/java/org/hibernate/envers/internal/tools/Triple.java index a64df2a027..c63c30f560 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/tools/Triple.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/tools/Triple.java @@ -21,8 +21,7 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.tools; - +package org.hibernate.envers.internal.tools; /** * A triple of objects. diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/tools/graph/GraphDefiner.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/tools/graph/GraphDefiner.java similarity index 96% rename from hibernate-envers/src/main/java/org/hibernate/envers/tools/graph/GraphDefiner.java rename to hibernate-envers/src/main/java/org/hibernate/envers/internal/tools/graph/GraphDefiner.java index b5b3d9c394..81856b16cd 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/tools/graph/GraphDefiner.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/tools/graph/GraphDefiner.java @@ -21,7 +21,7 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.tools.graph; +package org.hibernate.envers.internal.tools.graph; import java.util.List; /** diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/tools/graph/GraphTopologicalSort.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/tools/graph/GraphTopologicalSort.java similarity index 97% rename from hibernate-envers/src/main/java/org/hibernate/envers/tools/graph/GraphTopologicalSort.java rename to hibernate-envers/src/main/java/org/hibernate/envers/internal/tools/graph/GraphTopologicalSort.java index fca60751e7..bd79f46540 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/tools/graph/GraphTopologicalSort.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/tools/graph/GraphTopologicalSort.java @@ -21,7 +21,7 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.tools.graph; +package org.hibernate.envers.internal.tools.graph; import java.util.ArrayList; import java.util.HashMap; import java.util.List; diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/tools/graph/TopologicalSort.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/tools/graph/TopologicalSort.java similarity index 97% rename from hibernate-envers/src/main/java/org/hibernate/envers/tools/graph/TopologicalSort.java rename to hibernate-envers/src/main/java/org/hibernate/envers/internal/tools/graph/TopologicalSort.java index 5d1b12349d..da68cdebea 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/tools/graph/TopologicalSort.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/tools/graph/TopologicalSort.java @@ -21,7 +21,7 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.tools.graph; +package org.hibernate.envers.internal.tools.graph; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/tools/graph/Vertex.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/tools/graph/Vertex.java similarity index 97% rename from hibernate-envers/src/main/java/org/hibernate/envers/tools/graph/Vertex.java rename to hibernate-envers/src/main/java/org/hibernate/envers/internal/tools/graph/Vertex.java index 1d394017e6..c15035d7b7 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/tools/graph/Vertex.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/tools/graph/Vertex.java @@ -21,7 +21,7 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.tools.graph; +package org.hibernate.envers.internal.tools.graph; import java.util.ArrayList; import java.util.List; diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/tools/query/Parameters.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/tools/query/Parameters.java similarity index 98% rename from hibernate-envers/src/main/java/org/hibernate/envers/tools/query/Parameters.java rename to hibernate-envers/src/main/java/org/hibernate/envers/internal/tools/query/Parameters.java index 45bdc34581..929b8b116f 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/tools/query/Parameters.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/tools/query/Parameters.java @@ -21,14 +21,14 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.tools.query; +package org.hibernate.envers.internal.tools.query; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; -import org.hibernate.envers.tools.MutableBoolean; -import org.hibernate.envers.tools.MutableInteger; +import org.hibernate.envers.internal.tools.MutableBoolean; +import org.hibernate.envers.internal.tools.MutableInteger; /** * Parameters of a query, built using {@link QueryBuilder}. diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/tools/query/QueryBuilder.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/tools/query/QueryBuilder.java similarity index 97% rename from hibernate-envers/src/main/java/org/hibernate/envers/tools/query/QueryBuilder.java rename to hibernate-envers/src/main/java/org/hibernate/envers/internal/tools/query/QueryBuilder.java index 10cef5731b..21414a4a0b 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/tools/query/QueryBuilder.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/tools/query/QueryBuilder.java @@ -21,7 +21,8 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.tools.query; +package org.hibernate.envers.internal.tools.query; + import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -29,9 +30,9 @@ import org.hibernate.Query; import org.hibernate.Session; -import org.hibernate.envers.tools.MutableInteger; +import org.hibernate.envers.internal.tools.MutableInteger; +import org.hibernate.envers.internal.tools.StringTools; import org.hibernate.envers.tools.Pair; -import org.hibernate.envers.tools.StringTools; /** * A class for incrementaly building a HQL query. diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/tools/query/UpdateBuilder.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/tools/query/UpdateBuilder.java similarity index 91% rename from hibernate-envers/src/main/java/org/hibernate/envers/tools/query/UpdateBuilder.java rename to hibernate-envers/src/main/java/org/hibernate/envers/internal/tools/query/UpdateBuilder.java index 0707e81a4f..99729fd1eb 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/tools/query/UpdateBuilder.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/tools/query/UpdateBuilder.java @@ -1,15 +1,11 @@ -package org.hibernate.envers.tools.query; +package org.hibernate.envers.internal.tools.query; + +import java.util.HashMap; +import java.util.Map; import org.hibernate.Query; import org.hibernate.Session; -import org.hibernate.envers.tools.MutableInteger; -import org.hibernate.envers.tools.Pair; -import org.hibernate.envers.tools.StringTools; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import org.hibernate.envers.internal.tools.MutableInteger; /** * @author Lukasz Antoniak (lukasz dot antoniak at gmail dot com) diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/query/AuditEntity.java b/hibernate-envers/src/main/java/org/hibernate/envers/query/AuditEntity.java index a59f1b9eb7..a6df9c09e3 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/query/AuditEntity.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/query/AuditEntity.java @@ -31,12 +31,12 @@ import org.hibernate.envers.query.criteria.AuditId; import org.hibernate.envers.query.criteria.AuditProperty; import org.hibernate.envers.query.criteria.AuditRelatedId; -import org.hibernate.envers.query.criteria.LogicalAuditExpression; -import org.hibernate.envers.query.criteria.NotAuditExpression; -import org.hibernate.envers.query.property.EntityPropertyName; -import org.hibernate.envers.query.property.RevisionNumberPropertyName; -import org.hibernate.envers.query.property.RevisionPropertyPropertyName; -import org.hibernate.envers.query.property.RevisionTypePropertyName; +import org.hibernate.envers.query.criteria.internal.LogicalAuditExpression; +import org.hibernate.envers.query.criteria.internal.NotAuditExpression; +import org.hibernate.envers.query.internal.property.EntityPropertyName; +import org.hibernate.envers.query.internal.property.RevisionNumberPropertyName; +import org.hibernate.envers.query.internal.property.RevisionPropertyPropertyName; +import org.hibernate.envers.query.internal.property.RevisionTypePropertyName; /** * TODO: ilike diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/query/AuditQueryCreator.java b/hibernate-envers/src/main/java/org/hibernate/envers/query/AuditQueryCreator.java index 0bd8c4f063..a682cc8dd6 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/query/AuditQueryCreator.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/query/AuditQueryCreator.java @@ -23,15 +23,15 @@ */ package org.hibernate.envers.query; -import org.hibernate.envers.configuration.AuditConfiguration; -import org.hibernate.envers.query.impl.EntitiesAtRevisionQuery; -import org.hibernate.envers.query.impl.EntitiesModifiedAtRevisionQuery; -import org.hibernate.envers.query.impl.RevisionsOfEntityQuery; -import org.hibernate.envers.reader.AuditReaderImplementor; +import org.hibernate.envers.configuration.spi.AuditConfiguration; +import org.hibernate.envers.internal.reader.AuditReaderImplementor; +import org.hibernate.envers.query.internal.impl.EntitiesAtRevisionQuery; +import org.hibernate.envers.query.internal.impl.EntitiesModifiedAtRevisionQuery; +import org.hibernate.envers.query.internal.impl.RevisionsOfEntityQuery; -import static org.hibernate.envers.tools.ArgumentsTools.checkNotNull; -import static org.hibernate.envers.tools.ArgumentsTools.checkPositive; -import static org.hibernate.envers.tools.Tools.getTargetClassIfProxied; +import static org.hibernate.envers.internal.tools.ArgumentsTools.checkNotNull; +import static org.hibernate.envers.internal.tools.ArgumentsTools.checkPositive; +import static org.hibernate.envers.internal.tools.EntityTools.getTargetClassIfProxied; /** * @author Adam Warski (adam at warski dot org) diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/AggregatedAuditExpression.java b/hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/AggregatedAuditExpression.java index 23077445a4..1bd81eae31 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/AggregatedAuditExpression.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/AggregatedAuditExpression.java @@ -22,14 +22,16 @@ * Boston, MA 02110-1301 USA */ package org.hibernate.envers.query.criteria; + import java.util.ArrayList; import java.util.List; -import org.hibernate.envers.configuration.AuditConfiguration; -import org.hibernate.envers.query.property.PropertyNameGetter; -import org.hibernate.envers.reader.AuditReaderImplementor; -import org.hibernate.envers.tools.query.Parameters; -import org.hibernate.envers.tools.query.QueryBuilder; +import org.hibernate.envers.configuration.spi.AuditConfiguration; +import org.hibernate.envers.internal.reader.AuditReaderImplementor; +import org.hibernate.envers.internal.tools.query.Parameters; +import org.hibernate.envers.internal.tools.query.QueryBuilder; +import org.hibernate.envers.query.criteria.internal.CriteriaTools; +import org.hibernate.envers.query.internal.property.PropertyNameGetter; /** * @author Adam Warski (adam at warski dot org) diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/AuditConjunction.java b/hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/AuditConjunction.java index 8c5b28d460..88db0426c5 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/AuditConjunction.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/AuditConjunction.java @@ -22,13 +22,14 @@ * Boston, MA 02110-1301 USA */ package org.hibernate.envers.query.criteria; + import java.util.ArrayList; import java.util.List; -import org.hibernate.envers.configuration.AuditConfiguration; -import org.hibernate.envers.reader.AuditReaderImplementor; -import org.hibernate.envers.tools.query.Parameters; -import org.hibernate.envers.tools.query.QueryBuilder; +import org.hibernate.envers.configuration.spi.AuditConfiguration; +import org.hibernate.envers.internal.reader.AuditReaderImplementor; +import org.hibernate.envers.internal.tools.query.Parameters; +import org.hibernate.envers.internal.tools.query.QueryBuilder; /** * @author Adam Warski (adam at warski dot org) diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/AuditCriterion.java b/hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/AuditCriterion.java index cdc53caa8b..5be631cb23 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/AuditCriterion.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/AuditCriterion.java @@ -23,10 +23,10 @@ */ package org.hibernate.envers.query.criteria; -import org.hibernate.envers.configuration.AuditConfiguration; -import org.hibernate.envers.reader.AuditReaderImplementor; -import org.hibernate.envers.tools.query.Parameters; -import org.hibernate.envers.tools.query.QueryBuilder; +import org.hibernate.envers.configuration.spi.AuditConfiguration; +import org.hibernate.envers.internal.reader.AuditReaderImplementor; +import org.hibernate.envers.internal.tools.query.Parameters; +import org.hibernate.envers.internal.tools.query.QueryBuilder; /** * @author Adam Warski (adam at warski dot org) diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/AuditDisjunction.java b/hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/AuditDisjunction.java index 401bcfa0d5..4693f6374c 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/AuditDisjunction.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/AuditDisjunction.java @@ -22,13 +22,14 @@ * Boston, MA 02110-1301 USA */ package org.hibernate.envers.query.criteria; + import java.util.ArrayList; import java.util.List; -import org.hibernate.envers.configuration.AuditConfiguration; -import org.hibernate.envers.reader.AuditReaderImplementor; -import org.hibernate.envers.tools.query.Parameters; -import org.hibernate.envers.tools.query.QueryBuilder; +import org.hibernate.envers.configuration.spi.AuditConfiguration; +import org.hibernate.envers.internal.reader.AuditReaderImplementor; +import org.hibernate.envers.internal.tools.query.Parameters; +import org.hibernate.envers.internal.tools.query.QueryBuilder; /** * @author Adam Warski (adam at warski dot org) diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/AuditId.java b/hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/AuditId.java index 08f5bd5823..08e5f138b4 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/AuditId.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/AuditId.java @@ -23,11 +23,12 @@ */ package org.hibernate.envers.query.criteria; +import org.hibernate.envers.query.criteria.internal.IdentifierEqAuditExpression; import org.hibernate.envers.query.projection.AuditProjection; -import org.hibernate.envers.query.projection.PropertyAuditProjection; -import org.hibernate.envers.query.property.EntityPropertyName; -import org.hibernate.envers.query.property.OriginalIdPropertyName; -import org.hibernate.envers.query.property.PropertyNameGetter; +import org.hibernate.envers.query.projection.internal.PropertyAuditProjection; +import org.hibernate.envers.query.internal.property.EntityPropertyName; +import org.hibernate.envers.query.internal.property.OriginalIdPropertyName; +import org.hibernate.envers.query.internal.property.PropertyNameGetter; /** * Create restrictions and projections for the id of an audited entity. diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/AuditProperty.java b/hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/AuditProperty.java index 1b2211e2a8..a7824ea494 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/AuditProperty.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/AuditProperty.java @@ -21,19 +21,25 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ - package org.hibernate.envers.query.criteria; + import java.util.Collection; import org.hibernate.criterion.MatchMode; -import org.hibernate.envers.configuration.AuditConfiguration; +import org.hibernate.envers.configuration.spi.AuditConfiguration; +import org.hibernate.envers.internal.tools.Triple; +import org.hibernate.envers.query.criteria.internal.BetweenAuditExpression; +import org.hibernate.envers.query.criteria.internal.InAuditExpression; +import org.hibernate.envers.query.criteria.internal.NotNullAuditExpression; +import org.hibernate.envers.query.criteria.internal.NullAuditExpression; +import org.hibernate.envers.query.criteria.internal.PropertyAuditExpression; +import org.hibernate.envers.query.criteria.internal.SimpleAuditExpression; import org.hibernate.envers.query.order.AuditOrder; -import org.hibernate.envers.query.order.PropertyAuditOrder; +import org.hibernate.envers.query.order.internal.PropertyAuditOrder; import org.hibernate.envers.query.projection.AuditProjection; -import org.hibernate.envers.query.projection.PropertyAuditProjection; -import org.hibernate.envers.query.property.ModifiedFlagPropertyName; -import org.hibernate.envers.query.property.PropertyNameGetter; -import org.hibernate.envers.tools.Triple; +import org.hibernate.envers.query.projection.internal.PropertyAuditProjection; +import org.hibernate.envers.query.internal.property.ModifiedFlagPropertyName; +import org.hibernate.envers.query.internal.property.PropertyNameGetter; /** * Create restrictions, projections and specify order for a property of an audited entity. @@ -194,8 +200,7 @@ public AuditCriterion isNotNull() { * property */ public AggregatedAuditExpression maximize() { - return new AggregatedAuditExpression(propertyNameGetter, - AggregatedAuditExpression.AggregatedMode.MAX); + return new AggregatedAuditExpression(propertyNameGetter, AggregatedAuditExpression.AggregatedMode.MAX); } /** @@ -203,8 +208,7 @@ public AggregatedAuditExpression maximize() { * property */ public AggregatedAuditExpression minimize() { - return new AggregatedAuditExpression(propertyNameGetter, - AggregatedAuditExpression.AggregatedMode.MIN); + return new AggregatedAuditExpression(propertyNameGetter, AggregatedAuditExpression.AggregatedMode.MIN); } // Projections diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/AuditRelatedId.java b/hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/AuditRelatedId.java index 60a81d178d..c18cac02eb 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/AuditRelatedId.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/AuditRelatedId.java @@ -21,9 +21,10 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ - package org.hibernate.envers.query.criteria; -import org.hibernate.envers.query.property.PropertyNameGetter; + +import org.hibernate.envers.query.criteria.internal.RelatedAuditExpression; +import org.hibernate.envers.query.internal.property.PropertyNameGetter; /** * Create restrictions on an id of an entity related to an audited entity. diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/BetweenAuditExpression.java b/hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/internal/BetweenAuditExpression.java similarity index 82% rename from hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/BetweenAuditExpression.java rename to hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/internal/BetweenAuditExpression.java index 14f44a81e1..e86e65744b 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/BetweenAuditExpression.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/internal/BetweenAuditExpression.java @@ -21,12 +21,14 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.query.criteria; -import org.hibernate.envers.configuration.AuditConfiguration; -import org.hibernate.envers.query.property.PropertyNameGetter; -import org.hibernate.envers.reader.AuditReaderImplementor; -import org.hibernate.envers.tools.query.Parameters; -import org.hibernate.envers.tools.query.QueryBuilder; +package org.hibernate.envers.query.criteria.internal; + +import org.hibernate.envers.configuration.spi.AuditConfiguration; +import org.hibernate.envers.internal.reader.AuditReaderImplementor; +import org.hibernate.envers.internal.tools.query.Parameters; +import org.hibernate.envers.internal.tools.query.QueryBuilder; +import org.hibernate.envers.query.criteria.AuditCriterion; +import org.hibernate.envers.query.internal.property.PropertyNameGetter; /** * @author Adam Warski (adam at warski dot org) diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/CriteriaTools.java b/hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/internal/CriteriaTools.java similarity index 86% rename from hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/CriteriaTools.java rename to hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/internal/CriteriaTools.java index 46bb2ebfde..6bf447f165 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/CriteriaTools.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/internal/CriteriaTools.java @@ -21,21 +21,20 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.query.criteria; +package org.hibernate.envers.query.criteria.internal; -import org.hibernate.envers.configuration.AuditConfiguration; -import org.hibernate.envers.entities.RelationDescription; -import org.hibernate.envers.entities.RelationType; +import org.hibernate.envers.configuration.spi.AuditConfiguration; import org.hibernate.envers.exception.AuditException; -import org.hibernate.envers.query.property.PropertyNameGetter; -import org.hibernate.envers.reader.AuditReaderImplementor; +import org.hibernate.envers.internal.entities.RelationDescription; +import org.hibernate.envers.internal.entities.RelationType; +import org.hibernate.envers.internal.reader.AuditReaderImplementor; +import org.hibernate.envers.query.criteria.AuditId; +import org.hibernate.envers.query.internal.property.PropertyNameGetter; /** * @author Adam Warski (adam at warski dot org) */ -public class CriteriaTools { - private CriteriaTools() { } - +public abstract class CriteriaTools { public static void checkPropertyNotARelation(AuditConfiguration verCfg, String entityName, String propertyName) throws AuditException { if (verCfg.getEntCfg().get(entityName).isRelation(propertyName)) { @@ -73,7 +72,7 @@ public static String determinePropertyName(AuditConfiguration auditCfg, AuditRea * @param versionsReader Versions reader. * @param entityName Original entity name (not audited). * @param propertyName Property name or placeholder. - * @return Path to property. Handles identifier placeholder used by {@link AuditId}. + * @return Path to property. Handles identifier placeholder used by {@link org.hibernate.envers.query.criteria.AuditId}. */ public static String determinePropertyName(AuditConfiguration auditCfg, AuditReaderImplementor versionsReader, String entityName, String propertyName) { diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/IdentifierEqAuditExpression.java b/hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/internal/IdentifierEqAuditExpression.java similarity index 83% rename from hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/IdentifierEqAuditExpression.java rename to hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/internal/IdentifierEqAuditExpression.java index a6346aad01..1e916c987c 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/IdentifierEqAuditExpression.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/internal/IdentifierEqAuditExpression.java @@ -21,11 +21,13 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.query.criteria; -import org.hibernate.envers.configuration.AuditConfiguration; -import org.hibernate.envers.reader.AuditReaderImplementor; -import org.hibernate.envers.tools.query.Parameters; -import org.hibernate.envers.tools.query.QueryBuilder; +package org.hibernate.envers.query.criteria.internal; + +import org.hibernate.envers.configuration.spi.AuditConfiguration; +import org.hibernate.envers.internal.reader.AuditReaderImplementor; +import org.hibernate.envers.internal.tools.query.Parameters; +import org.hibernate.envers.internal.tools.query.QueryBuilder; +import org.hibernate.envers.query.criteria.AuditCriterion; /** * A criterion that expresses that the id of an entity is equal or not equal to some specified value. diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/InAuditExpression.java b/hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/internal/InAuditExpression.java similarity index 78% rename from hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/InAuditExpression.java rename to hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/internal/InAuditExpression.java index 1c2e5b3165..ea009093e4 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/InAuditExpression.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/internal/InAuditExpression.java @@ -21,13 +21,15 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.query.criteria; +package org.hibernate.envers.query.criteria.internal; -import org.hibernate.envers.configuration.AuditConfiguration; -import org.hibernate.envers.query.property.PropertyNameGetter; -import org.hibernate.envers.reader.AuditReaderImplementor; -import org.hibernate.envers.tools.query.Parameters; -import org.hibernate.envers.tools.query.QueryBuilder; +import org.hibernate.envers.configuration.spi.AuditConfiguration; +import org.hibernate.envers.internal.reader.AuditReaderImplementor; +import org.hibernate.envers.internal.tools.query.Parameters; +import org.hibernate.envers.internal.tools.query.QueryBuilder; +import org.hibernate.envers.query.criteria.AuditCriterion; +import org.hibernate.envers.query.criteria.internal.CriteriaTools; +import org.hibernate.envers.query.internal.property.PropertyNameGetter; /** * @author Adam Warski (adam at warski dot org) diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/LogicalAuditExpression.java b/hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/internal/LogicalAuditExpression.java similarity index 83% rename from hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/LogicalAuditExpression.java rename to hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/internal/LogicalAuditExpression.java index 5ab9f0612e..d0f213965e 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/LogicalAuditExpression.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/internal/LogicalAuditExpression.java @@ -21,11 +21,13 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.query.criteria; -import org.hibernate.envers.configuration.AuditConfiguration; -import org.hibernate.envers.reader.AuditReaderImplementor; -import org.hibernate.envers.tools.query.Parameters; -import org.hibernate.envers.tools.query.QueryBuilder; +package org.hibernate.envers.query.criteria.internal; + +import org.hibernate.envers.configuration.spi.AuditConfiguration; +import org.hibernate.envers.internal.reader.AuditReaderImplementor; +import org.hibernate.envers.internal.tools.query.Parameters; +import org.hibernate.envers.internal.tools.query.QueryBuilder; +import org.hibernate.envers.query.criteria.AuditCriterion; /** * @author Adam Warski (adam at warski dot org) diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/NotAuditExpression.java b/hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/internal/NotAuditExpression.java similarity index 81% rename from hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/NotAuditExpression.java rename to hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/internal/NotAuditExpression.java index 85e1ac5dbf..cfb5d016ba 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/NotAuditExpression.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/internal/NotAuditExpression.java @@ -21,12 +21,13 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.query.criteria; +package org.hibernate.envers.query.criteria.internal; -import org.hibernate.envers.configuration.AuditConfiguration; -import org.hibernate.envers.reader.AuditReaderImplementor; -import org.hibernate.envers.tools.query.Parameters; -import org.hibernate.envers.tools.query.QueryBuilder; +import org.hibernate.envers.configuration.spi.AuditConfiguration; +import org.hibernate.envers.internal.reader.AuditReaderImplementor; +import org.hibernate.envers.internal.tools.query.Parameters; +import org.hibernate.envers.internal.tools.query.QueryBuilder; +import org.hibernate.envers.query.criteria.AuditCriterion; /** * @author Adam Warski (adam at warski dot org) diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/NotNullAuditExpression.java b/hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/internal/NotNullAuditExpression.java similarity index 79% rename from hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/NotNullAuditExpression.java rename to hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/internal/NotNullAuditExpression.java index 6c6f1806d3..1a3bfc855e 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/NotNullAuditExpression.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/internal/NotNullAuditExpression.java @@ -21,14 +21,15 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.query.criteria; +package org.hibernate.envers.query.criteria.internal; -import org.hibernate.envers.configuration.AuditConfiguration; -import org.hibernate.envers.entities.RelationDescription; -import org.hibernate.envers.query.property.PropertyNameGetter; -import org.hibernate.envers.reader.AuditReaderImplementor; -import org.hibernate.envers.tools.query.Parameters; -import org.hibernate.envers.tools.query.QueryBuilder; +import org.hibernate.envers.configuration.spi.AuditConfiguration; +import org.hibernate.envers.internal.entities.RelationDescription; +import org.hibernate.envers.internal.reader.AuditReaderImplementor; +import org.hibernate.envers.internal.tools.query.Parameters; +import org.hibernate.envers.internal.tools.query.QueryBuilder; +import org.hibernate.envers.query.criteria.AuditCriterion; +import org.hibernate.envers.query.internal.property.PropertyNameGetter; /** * @author Adam Warski (adam at warski dot org) diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/NullAuditExpression.java b/hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/internal/NullAuditExpression.java similarity index 79% rename from hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/NullAuditExpression.java rename to hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/internal/NullAuditExpression.java index d18a183bf4..5bfa5d97db 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/NullAuditExpression.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/internal/NullAuditExpression.java @@ -21,14 +21,15 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.query.criteria; +package org.hibernate.envers.query.criteria.internal; -import org.hibernate.envers.configuration.AuditConfiguration; -import org.hibernate.envers.entities.RelationDescription; -import org.hibernate.envers.query.property.PropertyNameGetter; -import org.hibernate.envers.reader.AuditReaderImplementor; -import org.hibernate.envers.tools.query.Parameters; -import org.hibernate.envers.tools.query.QueryBuilder; +import org.hibernate.envers.configuration.spi.AuditConfiguration; +import org.hibernate.envers.internal.entities.RelationDescription; +import org.hibernate.envers.internal.reader.AuditReaderImplementor; +import org.hibernate.envers.internal.tools.query.Parameters; +import org.hibernate.envers.internal.tools.query.QueryBuilder; +import org.hibernate.envers.query.criteria.AuditCriterion; +import org.hibernate.envers.query.internal.property.PropertyNameGetter; /** * @author Adam Warski (adam at warski dot org) diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/PropertyAuditExpression.java b/hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/internal/PropertyAuditExpression.java similarity index 82% rename from hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/PropertyAuditExpression.java rename to hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/internal/PropertyAuditExpression.java index e3347c38f9..ba2e6d741d 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/PropertyAuditExpression.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/internal/PropertyAuditExpression.java @@ -21,13 +21,14 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.query.criteria; +package org.hibernate.envers.query.criteria.internal; -import org.hibernate.envers.configuration.AuditConfiguration; -import org.hibernate.envers.query.property.PropertyNameGetter; -import org.hibernate.envers.reader.AuditReaderImplementor; -import org.hibernate.envers.tools.query.Parameters; -import org.hibernate.envers.tools.query.QueryBuilder; +import org.hibernate.envers.configuration.spi.AuditConfiguration; +import org.hibernate.envers.internal.reader.AuditReaderImplementor; +import org.hibernate.envers.internal.tools.query.Parameters; +import org.hibernate.envers.internal.tools.query.QueryBuilder; +import org.hibernate.envers.query.criteria.AuditCriterion; +import org.hibernate.envers.query.internal.property.PropertyNameGetter; /** * @author Adam Warski (adam at warski dot org) diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/RelatedAuditExpression.java b/hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/internal/RelatedAuditExpression.java similarity index 81% rename from hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/RelatedAuditExpression.java rename to hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/internal/RelatedAuditExpression.java index 6d2bb74b9e..8feefad4ac 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/RelatedAuditExpression.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/internal/RelatedAuditExpression.java @@ -21,15 +21,16 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.query.criteria; +package org.hibernate.envers.query.criteria.internal; -import org.hibernate.envers.configuration.AuditConfiguration; -import org.hibernate.envers.entities.RelationDescription; +import org.hibernate.envers.configuration.spi.AuditConfiguration; import org.hibernate.envers.exception.AuditException; -import org.hibernate.envers.query.property.PropertyNameGetter; -import org.hibernate.envers.reader.AuditReaderImplementor; -import org.hibernate.envers.tools.query.Parameters; -import org.hibernate.envers.tools.query.QueryBuilder; +import org.hibernate.envers.internal.entities.RelationDescription; +import org.hibernate.envers.internal.reader.AuditReaderImplementor; +import org.hibernate.envers.internal.tools.query.Parameters; +import org.hibernate.envers.internal.tools.query.QueryBuilder; +import org.hibernate.envers.query.criteria.AuditCriterion; +import org.hibernate.envers.query.internal.property.PropertyNameGetter; /** * @author Adam Warski (adam at warski dot org) diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/RevisionTypeAuditExpression.java b/hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/internal/RevisionTypeAuditExpression.java similarity index 81% rename from hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/RevisionTypeAuditExpression.java rename to hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/internal/RevisionTypeAuditExpression.java index ece2c48226..59f7b1b802 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/RevisionTypeAuditExpression.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/internal/RevisionTypeAuditExpression.java @@ -21,12 +21,13 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.query.criteria; +package org.hibernate.envers.query.criteria.internal; -import org.hibernate.envers.configuration.AuditConfiguration; -import org.hibernate.envers.reader.AuditReaderImplementor; -import org.hibernate.envers.tools.query.Parameters; -import org.hibernate.envers.tools.query.QueryBuilder; +import org.hibernate.envers.configuration.spi.AuditConfiguration; +import org.hibernate.envers.internal.reader.AuditReaderImplementor; +import org.hibernate.envers.internal.tools.query.Parameters; +import org.hibernate.envers.internal.tools.query.QueryBuilder; +import org.hibernate.envers.query.criteria.AuditCriterion; /** * @author Adam Warski (adam at warski dot org) diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/SimpleAuditExpression.java b/hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/internal/SimpleAuditExpression.java similarity index 83% rename from hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/SimpleAuditExpression.java rename to hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/internal/SimpleAuditExpression.java index 121deef5b2..8307a90654 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/SimpleAuditExpression.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/internal/SimpleAuditExpression.java @@ -21,15 +21,16 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.query.criteria; +package org.hibernate.envers.query.criteria.internal; -import org.hibernate.envers.configuration.AuditConfiguration; -import org.hibernate.envers.entities.RelationDescription; +import org.hibernate.envers.configuration.spi.AuditConfiguration; import org.hibernate.envers.exception.AuditException; -import org.hibernate.envers.query.property.PropertyNameGetter; -import org.hibernate.envers.reader.AuditReaderImplementor; -import org.hibernate.envers.tools.query.Parameters; -import org.hibernate.envers.tools.query.QueryBuilder; +import org.hibernate.envers.internal.entities.RelationDescription; +import org.hibernate.envers.internal.reader.AuditReaderImplementor; +import org.hibernate.envers.internal.tools.query.Parameters; +import org.hibernate.envers.internal.tools.query.QueryBuilder; +import org.hibernate.envers.query.criteria.AuditCriterion; +import org.hibernate.envers.query.internal.property.PropertyNameGetter; /** * @author Adam Warski (adam at warski dot org) diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/query/impl/AbstractAuditQuery.java b/hibernate-envers/src/main/java/org/hibernate/envers/query/internal/impl/AbstractAuditQuery.java similarity index 93% rename from hibernate-envers/src/main/java/org/hibernate/envers/query/impl/AbstractAuditQuery.java rename to hibernate-envers/src/main/java/org/hibernate/envers/query/internal/impl/AbstractAuditQuery.java index a3d8863a26..ec891363a0 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/query/impl/AbstractAuditQuery.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/query/internal/impl/AbstractAuditQuery.java @@ -21,7 +21,7 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.query.impl; +package org.hibernate.envers.query.internal.impl; import java.util.ArrayList; import java.util.List; @@ -33,20 +33,20 @@ import org.hibernate.LockMode; import org.hibernate.LockOptions; import org.hibernate.Query; -import org.hibernate.envers.configuration.AuditConfiguration; -import org.hibernate.envers.entities.EntityInstantiator; +import org.hibernate.envers.configuration.spi.AuditConfiguration; import org.hibernate.envers.exception.AuditException; +import org.hibernate.envers.internal.entities.EntityInstantiator; +import org.hibernate.envers.internal.reader.AuditReaderImplementor; +import org.hibernate.envers.internal.tools.Triple; +import org.hibernate.envers.internal.tools.query.QueryBuilder; import org.hibernate.envers.query.AuditQuery; import org.hibernate.envers.query.criteria.AuditCriterion; -import org.hibernate.envers.query.criteria.CriteriaTools; +import org.hibernate.envers.query.criteria.internal.CriteriaTools; import org.hibernate.envers.query.order.AuditOrder; import org.hibernate.envers.query.projection.AuditProjection; -import org.hibernate.envers.reader.AuditReaderImplementor; import org.hibernate.envers.tools.Pair; -import org.hibernate.envers.tools.Triple; -import org.hibernate.envers.tools.query.QueryBuilder; -import static org.hibernate.envers.entities.mapper.relation.query.QueryConstants.REFERENCED_ENTITY_ALIAS; +import static org.hibernate.envers.internal.entities.mapper.relation.query.QueryConstants.REFERENCED_ENTITY_ALIAS; /** * @author Adam Warski (adam at warski dot org) diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/query/impl/EntitiesAtRevisionQuery.java b/hibernate-envers/src/main/java/org/hibernate/envers/query/internal/impl/EntitiesAtRevisionQuery.java similarity index 87% rename from hibernate-envers/src/main/java/org/hibernate/envers/query/impl/EntitiesAtRevisionQuery.java rename to hibernate-envers/src/main/java/org/hibernate/envers/query/internal/impl/EntitiesAtRevisionQuery.java index e2df3aafe2..4f05d4f568 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/query/impl/EntitiesAtRevisionQuery.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/query/internal/impl/EntitiesAtRevisionQuery.java @@ -21,7 +21,7 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.query.impl; +package org.hibernate.envers.query.internal.impl; import java.util.ArrayList; import java.util.Arrays; @@ -29,15 +29,15 @@ import org.hibernate.Query; import org.hibernate.envers.RevisionType; -import org.hibernate.envers.configuration.AuditConfiguration; -import org.hibernate.envers.configuration.AuditEntitiesConfiguration; -import org.hibernate.envers.entities.mapper.relation.MiddleIdData; +import org.hibernate.envers.configuration.internal.AuditEntitiesConfiguration; +import org.hibernate.envers.configuration.spi.AuditConfiguration; +import org.hibernate.envers.internal.entities.mapper.relation.MiddleIdData; +import org.hibernate.envers.internal.reader.AuditReaderImplementor; import org.hibernate.envers.query.criteria.AuditCriterion; -import org.hibernate.envers.reader.AuditReaderImplementor; -import static org.hibernate.envers.entities.mapper.relation.query.QueryConstants.REFERENCED_ENTITY_ALIAS; -import static org.hibernate.envers.entities.mapper.relation.query.QueryConstants.REFERENCED_ENTITY_ALIAS_DEF_AUD_STR; -import static org.hibernate.envers.entities.mapper.relation.query.QueryConstants.REVISION_PARAMETER; +import static org.hibernate.envers.internal.entities.mapper.relation.query.QueryConstants.REFERENCED_ENTITY_ALIAS; +import static org.hibernate.envers.internal.entities.mapper.relation.query.QueryConstants.REFERENCED_ENTITY_ALIAS_DEF_AUD_STR; +import static org.hibernate.envers.internal.entities.mapper.relation.query.QueryConstants.REVISION_PARAMETER; /** * @author Adam Warski (adam at warski dot org) diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/query/impl/EntitiesModifiedAtRevisionQuery.java b/hibernate-envers/src/main/java/org/hibernate/envers/query/internal/impl/EntitiesModifiedAtRevisionQuery.java similarity index 89% rename from hibernate-envers/src/main/java/org/hibernate/envers/query/impl/EntitiesModifiedAtRevisionQuery.java rename to hibernate-envers/src/main/java/org/hibernate/envers/query/internal/impl/EntitiesModifiedAtRevisionQuery.java index 391df73533..deb8f41b06 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/query/impl/EntitiesModifiedAtRevisionQuery.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/query/internal/impl/EntitiesModifiedAtRevisionQuery.java @@ -1,13 +1,13 @@ -package org.hibernate.envers.query.impl; +package org.hibernate.envers.query.internal.impl; import java.util.ArrayList; import java.util.List; import org.hibernate.Query; -import org.hibernate.envers.configuration.AuditConfiguration; -import org.hibernate.envers.configuration.AuditEntitiesConfiguration; +import org.hibernate.envers.configuration.internal.AuditEntitiesConfiguration; +import org.hibernate.envers.configuration.spi.AuditConfiguration; +import org.hibernate.envers.internal.reader.AuditReaderImplementor; import org.hibernate.envers.query.criteria.AuditCriterion; -import org.hibernate.envers.reader.AuditReaderImplementor; /** * In comparison to {@link EntitiesAtRevisionQuery} this query returns an empty collection if an entity diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/query/impl/RevisionsOfEntityQuery.java b/hibernate-envers/src/main/java/org/hibernate/envers/query/internal/impl/RevisionsOfEntityQuery.java similarity index 95% rename from hibernate-envers/src/main/java/org/hibernate/envers/query/impl/RevisionsOfEntityQuery.java rename to hibernate-envers/src/main/java/org/hibernate/envers/query/internal/impl/RevisionsOfEntityQuery.java index a33eb533c0..93ca0742d3 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/query/impl/RevisionsOfEntityQuery.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/query/internal/impl/RevisionsOfEntityQuery.java @@ -21,17 +21,18 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.query.impl; +package org.hibernate.envers.query.internal.impl; + import java.util.ArrayList; import java.util.List; import java.util.Map; import org.hibernate.envers.RevisionType; -import org.hibernate.envers.configuration.AuditConfiguration; -import org.hibernate.envers.configuration.AuditEntitiesConfiguration; +import org.hibernate.envers.configuration.internal.AuditEntitiesConfiguration; +import org.hibernate.envers.configuration.spi.AuditConfiguration; import org.hibernate.envers.exception.AuditException; +import org.hibernate.envers.internal.reader.AuditReaderImplementor; import org.hibernate.envers.query.criteria.AuditCriterion; -import org.hibernate.envers.reader.AuditReaderImplementor; import org.hibernate.proxy.HibernateProxy; /** diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/query/property/EntityPropertyName.java b/hibernate-envers/src/main/java/org/hibernate/envers/query/internal/property/EntityPropertyName.java similarity index 92% rename from hibernate-envers/src/main/java/org/hibernate/envers/query/property/EntityPropertyName.java rename to hibernate-envers/src/main/java/org/hibernate/envers/query/internal/property/EntityPropertyName.java index e872cf233f..7174136bca 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/query/property/EntityPropertyName.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/query/internal/property/EntityPropertyName.java @@ -21,9 +21,9 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ +package org.hibernate.envers.query.internal.property; -package org.hibernate.envers.query.property; -import org.hibernate.envers.configuration.AuditConfiguration; +import org.hibernate.envers.configuration.spi.AuditConfiguration; /** * Used for specifying restrictions on a property of an audited entity. diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/query/property/ModifiedFlagPropertyName.java b/hibernate-envers/src/main/java/org/hibernate/envers/query/internal/property/ModifiedFlagPropertyName.java similarity index 89% rename from hibernate-envers/src/main/java/org/hibernate/envers/query/property/ModifiedFlagPropertyName.java rename to hibernate-envers/src/main/java/org/hibernate/envers/query/internal/property/ModifiedFlagPropertyName.java index af9deb170c..de4cedef35 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/query/property/ModifiedFlagPropertyName.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/query/internal/property/ModifiedFlagPropertyName.java @@ -21,10 +21,10 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ +package org.hibernate.envers.query.internal.property; -package org.hibernate.envers.query.property; -import org.hibernate.envers.configuration.AuditConfiguration; -import org.hibernate.envers.configuration.metadata.MetadataTools; +import org.hibernate.envers.configuration.internal.metadata.MetadataTools; +import org.hibernate.envers.configuration.spi.AuditConfiguration; /** * PropertyNameGetter for modified flags diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/query/property/OriginalIdPropertyName.java b/hibernate-envers/src/main/java/org/hibernate/envers/query/internal/property/OriginalIdPropertyName.java similarity index 93% rename from hibernate-envers/src/main/java/org/hibernate/envers/query/property/OriginalIdPropertyName.java rename to hibernate-envers/src/main/java/org/hibernate/envers/query/internal/property/OriginalIdPropertyName.java index 58044944d1..a6cbcbd462 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/query/property/OriginalIdPropertyName.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/query/internal/property/OriginalIdPropertyName.java @@ -21,9 +21,9 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.envers.query.property; +package org.hibernate.envers.query.internal.property; -import org.hibernate.envers.configuration.AuditConfiguration; +import org.hibernate.envers.configuration.spi.AuditConfiguration; import org.hibernate.envers.query.criteria.AuditId; /** diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/query/property/PropertyNameGetter.java b/hibernate-envers/src/main/java/org/hibernate/envers/query/internal/property/PropertyNameGetter.java similarity index 92% rename from hibernate-envers/src/main/java/org/hibernate/envers/query/property/PropertyNameGetter.java rename to hibernate-envers/src/main/java/org/hibernate/envers/query/internal/property/PropertyNameGetter.java index 9729c1edea..e49475e23e 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/query/property/PropertyNameGetter.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/query/internal/property/PropertyNameGetter.java @@ -21,9 +21,9 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ +package org.hibernate.envers.query.internal.property; -package org.hibernate.envers.query.property; -import org.hibernate.envers.configuration.AuditConfiguration; +import org.hibernate.envers.configuration.spi.AuditConfiguration; /** * Provides a function to get the name of a property, which is used in a query, to apply some restrictions on it. diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/query/property/RevisionNumberPropertyName.java b/hibernate-envers/src/main/java/org/hibernate/envers/query/internal/property/RevisionNumberPropertyName.java similarity index 92% rename from hibernate-envers/src/main/java/org/hibernate/envers/query/property/RevisionNumberPropertyName.java rename to hibernate-envers/src/main/java/org/hibernate/envers/query/internal/property/RevisionNumberPropertyName.java index 62e2d230e2..60530df288 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/query/property/RevisionNumberPropertyName.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/query/internal/property/RevisionNumberPropertyName.java @@ -21,9 +21,9 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ +package org.hibernate.envers.query.internal.property; -package org.hibernate.envers.query.property; -import org.hibernate.envers.configuration.AuditConfiguration; +import org.hibernate.envers.configuration.spi.AuditConfiguration; /** * Used for specifying restrictions on the revision number, corresponding to an audit entity. diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/query/property/RevisionPropertyPropertyName.java b/hibernate-envers/src/main/java/org/hibernate/envers/query/internal/property/RevisionPropertyPropertyName.java similarity index 92% rename from hibernate-envers/src/main/java/org/hibernate/envers/query/property/RevisionPropertyPropertyName.java rename to hibernate-envers/src/main/java/org/hibernate/envers/query/internal/property/RevisionPropertyPropertyName.java index f5feed0486..93d300e223 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/query/property/RevisionPropertyPropertyName.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/query/internal/property/RevisionPropertyPropertyName.java @@ -21,9 +21,9 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ +package org.hibernate.envers.query.internal.property; -package org.hibernate.envers.query.property; -import org.hibernate.envers.configuration.AuditConfiguration; +import org.hibernate.envers.configuration.spi.AuditConfiguration; /** * Used for specifying restrictions on a property of the revision entity, which is associated with an audit entity. diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/query/property/RevisionTypePropertyName.java b/hibernate-envers/src/main/java/org/hibernate/envers/query/internal/property/RevisionTypePropertyName.java similarity index 92% rename from hibernate-envers/src/main/java/org/hibernate/envers/query/property/RevisionTypePropertyName.java rename to hibernate-envers/src/main/java/org/hibernate/envers/query/internal/property/RevisionTypePropertyName.java index ff8c96c5e2..772015d0ee 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/query/property/RevisionTypePropertyName.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/query/internal/property/RevisionTypePropertyName.java @@ -21,9 +21,9 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ +package org.hibernate.envers.query.internal.property; -package org.hibernate.envers.query.property; -import org.hibernate.envers.configuration.AuditConfiguration; +import org.hibernate.envers.configuration.spi.AuditConfiguration; /** * Used for specifying restrictions on the revision number, corresponding to an audit entity. diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/query/order/AuditOrder.java b/hibernate-envers/src/main/java/org/hibernate/envers/query/order/AuditOrder.java index be0ae95e13..8575fc7115 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/query/order/AuditOrder.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/query/order/AuditOrder.java @@ -22,7 +22,8 @@ * Boston, MA 02110-1301 USA */ package org.hibernate.envers.query.order; -import org.hibernate.envers.configuration.AuditConfiguration; + +import org.hibernate.envers.configuration.spi.AuditConfiguration; import org.hibernate.envers.tools.Pair; /** diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/query/order/PropertyAuditOrder.java b/hibernate-envers/src/main/java/org/hibernate/envers/query/order/internal/PropertyAuditOrder.java similarity index 86% rename from hibernate-envers/src/main/java/org/hibernate/envers/query/order/PropertyAuditOrder.java rename to hibernate-envers/src/main/java/org/hibernate/envers/query/order/internal/PropertyAuditOrder.java index b2c05c864b..77ec0470f1 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/query/order/PropertyAuditOrder.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/query/order/internal/PropertyAuditOrder.java @@ -21,10 +21,11 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ +package org.hibernate.envers.query.order.internal; -package org.hibernate.envers.query.order; -import org.hibernate.envers.configuration.AuditConfiguration; -import org.hibernate.envers.query.property.PropertyNameGetter; +import org.hibernate.envers.configuration.spi.AuditConfiguration; +import org.hibernate.envers.query.internal.property.PropertyNameGetter; +import org.hibernate.envers.query.order.AuditOrder; import org.hibernate.envers.tools.Pair; /** diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/query/projection/AuditProjection.java b/hibernate-envers/src/main/java/org/hibernate/envers/query/projection/AuditProjection.java index 4fae8ced65..469909787c 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/query/projection/AuditProjection.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/query/projection/AuditProjection.java @@ -22,8 +22,9 @@ * Boston, MA 02110-1301 USA */ package org.hibernate.envers.query.projection; -import org.hibernate.envers.configuration.AuditConfiguration; -import org.hibernate.envers.tools.Triple; + +import org.hibernate.envers.configuration.spi.AuditConfiguration; +import org.hibernate.envers.internal.tools.Triple; /** * @author Adam Warski (adam at warski dot org) diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/query/projection/PropertyAuditProjection.java b/hibernate-envers/src/main/java/org/hibernate/envers/query/projection/internal/PropertyAuditProjection.java similarity index 85% rename from hibernate-envers/src/main/java/org/hibernate/envers/query/projection/PropertyAuditProjection.java rename to hibernate-envers/src/main/java/org/hibernate/envers/query/projection/internal/PropertyAuditProjection.java index 7038ed2fac..9e3a4ee2a6 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/query/projection/PropertyAuditProjection.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/query/projection/internal/PropertyAuditProjection.java @@ -21,11 +21,12 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ +package org.hibernate.envers.query.projection.internal; -package org.hibernate.envers.query.projection; -import org.hibernate.envers.configuration.AuditConfiguration; -import org.hibernate.envers.query.property.PropertyNameGetter; -import org.hibernate.envers.tools.Triple; +import org.hibernate.envers.configuration.spi.AuditConfiguration; +import org.hibernate.envers.internal.tools.Triple; +import org.hibernate.envers.query.internal.property.PropertyNameGetter; +import org.hibernate.envers.query.projection.AuditProjection; /** * @author Adam Warski (adam at warski dot org) diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/strategy/AuditStrategy.java b/hibernate-envers/src/main/java/org/hibernate/envers/strategy/AuditStrategy.java index 3a84d1ecb3..d5c37fb119 100755 --- a/hibernate-envers/src/main/java/org/hibernate/envers/strategy/AuditStrategy.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/strategy/AuditStrategy.java @@ -4,12 +4,12 @@ import org.hibernate.Session; import org.hibernate.collection.spi.PersistentCollection; -import org.hibernate.envers.configuration.AuditConfiguration; -import org.hibernate.envers.configuration.GlobalConfiguration; -import org.hibernate.envers.entities.mapper.PersistentCollectionChangeData; -import org.hibernate.envers.entities.mapper.relation.MiddleComponentData; -import org.hibernate.envers.entities.mapper.relation.MiddleIdData; -import org.hibernate.envers.tools.query.QueryBuilder; +import org.hibernate.envers.configuration.internal.GlobalConfiguration; +import org.hibernate.envers.configuration.spi.AuditConfiguration; +import org.hibernate.envers.internal.entities.mapper.PersistentCollectionChangeData; +import org.hibernate.envers.internal.entities.mapper.relation.MiddleComponentData; +import org.hibernate.envers.internal.entities.mapper.relation.MiddleIdData; +import org.hibernate.envers.internal.tools.query.QueryBuilder; /** * Behaviours of different audit strategy for populating audit data. diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/strategy/DefaultAuditStrategy.java b/hibernate-envers/src/main/java/org/hibernate/envers/strategy/DefaultAuditStrategy.java index 5959c75d94..5e0cf2e4e5 100755 --- a/hibernate-envers/src/main/java/org/hibernate/envers/strategy/DefaultAuditStrategy.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/strategy/DefaultAuditStrategy.java @@ -3,17 +3,17 @@ import java.io.Serializable; import org.hibernate.Session; -import org.hibernate.envers.configuration.AuditConfiguration; -import org.hibernate.envers.configuration.GlobalConfiguration; -import org.hibernate.envers.entities.mapper.PersistentCollectionChangeData; -import org.hibernate.envers.entities.mapper.relation.MiddleComponentData; -import org.hibernate.envers.entities.mapper.relation.MiddleIdData; -import org.hibernate.envers.synchronization.SessionCacheCleaner; -import org.hibernate.envers.tools.query.Parameters; -import org.hibernate.envers.tools.query.QueryBuilder; +import org.hibernate.envers.configuration.internal.GlobalConfiguration; +import org.hibernate.envers.configuration.spi.AuditConfiguration; +import org.hibernate.envers.internal.entities.mapper.PersistentCollectionChangeData; +import org.hibernate.envers.internal.entities.mapper.relation.MiddleComponentData; +import org.hibernate.envers.internal.entities.mapper.relation.MiddleIdData; +import org.hibernate.envers.internal.synchronization.SessionCacheCleaner; +import org.hibernate.envers.internal.tools.query.Parameters; +import org.hibernate.envers.internal.tools.query.QueryBuilder; -import static org.hibernate.envers.entities.mapper.relation.query.QueryConstants.MIDDLE_ENTITY_ALIAS_DEF_AUD_STR; -import static org.hibernate.envers.entities.mapper.relation.query.QueryConstants.REVISION_PARAMETER; +import static org.hibernate.envers.internal.entities.mapper.relation.query.QueryConstants.MIDDLE_ENTITY_ALIAS_DEF_AUD_STR; +import static org.hibernate.envers.internal.entities.mapper.relation.query.QueryConstants.REVISION_PARAMETER; /** * Default strategy is to simply persist the audit data. diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/strategy/ValidityAuditStrategy.java b/hibernate-envers/src/main/java/org/hibernate/envers/strategy/ValidityAuditStrategy.java index 6e2c6cc808..4fb451473d 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/strategy/ValidityAuditStrategy.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/strategy/ValidityAuditStrategy.java @@ -1,8 +1,5 @@ package org.hibernate.envers.strategy; -import static org.hibernate.envers.entities.mapper.relation.query.QueryConstants.MIDDLE_ENTITY_ALIAS; -import static org.hibernate.envers.entities.mapper.relation.query.QueryConstants.REVISION_PARAMETER; - import java.io.Serializable; import java.sql.Connection; import java.sql.PreparedStatement; @@ -13,21 +10,23 @@ import java.util.Map; import java.util.Set; +import org.jboss.logging.Logger; + import org.hibernate.LockOptions; import org.hibernate.Session; import org.hibernate.dialect.Dialect; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.envers.RevisionType; -import org.hibernate.envers.configuration.AuditConfiguration; -import org.hibernate.envers.configuration.AuditEntitiesConfiguration; -import org.hibernate.envers.configuration.GlobalConfiguration; -import org.hibernate.envers.entities.mapper.PersistentCollectionChangeData; -import org.hibernate.envers.entities.mapper.relation.MiddleComponentData; -import org.hibernate.envers.entities.mapper.relation.MiddleIdData; -import org.hibernate.envers.synchronization.SessionCacheCleaner; -import org.hibernate.envers.tools.query.Parameters; -import org.hibernate.envers.tools.query.QueryBuilder; +import org.hibernate.envers.configuration.internal.AuditEntitiesConfiguration; +import org.hibernate.envers.configuration.internal.GlobalConfiguration; +import org.hibernate.envers.configuration.spi.AuditConfiguration; +import org.hibernate.envers.internal.entities.mapper.PersistentCollectionChangeData; +import org.hibernate.envers.internal.entities.mapper.relation.MiddleComponentData; +import org.hibernate.envers.internal.entities.mapper.relation.MiddleIdData; +import org.hibernate.envers.internal.synchronization.SessionCacheCleaner; +import org.hibernate.envers.internal.tools.query.Parameters; +import org.hibernate.envers.internal.tools.query.QueryBuilder; import org.hibernate.event.service.spi.EventListenerRegistry; import org.hibernate.event.spi.AutoFlushEvent; import org.hibernate.event.spi.AutoFlushEventListener; @@ -41,7 +40,9 @@ import org.hibernate.type.CollectionType; import org.hibernate.type.ComponentType; import org.hibernate.type.Type; -import org.jboss.logging.Logger; + +import static org.hibernate.envers.internal.entities.mapper.relation.query.QueryConstants.MIDDLE_ENTITY_ALIAS; +import static org.hibernate.envers.internal.entities.mapper.relation.query.QueryConstants.REVISION_PARAMETER; /** * Audit strategy which persists and retrieves audit information using a validity algorithm, based on the diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/tools/ArgumentsTools.java b/hibernate-envers/src/main/java/org/hibernate/envers/tools/ArgumentsTools.java deleted file mode 100644 index 688b18367e..0000000000 --- a/hibernate-envers/src/main/java/org/hibernate/envers/tools/ArgumentsTools.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Hibernate, Relational Persistence for Idiomatic Java - * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as - * indicated by the @author tags or express copyright attribution - * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. - * - * This copyrighted material is made available to anyone wishing to use, modify, - * copy, or redistribute it subject to the terms and conditions of the GNU - * Lesser General Public License, as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this distribution; if not, write to: - * Free Software Foundation, Inc. - * 51 Franklin Street, Fifth Floor - * Boston, MA 02110-1301 USA - */ -package org.hibernate.envers.tools; - - -/** - * @author Adam Warski (adam at warski dot org) - */ -public class ArgumentsTools { - public static void checkNotNull(Object o, String paramName) { - if (o == null) { - throw new IllegalArgumentException(paramName + " cannot be null."); - } - } - - public static void checkPositive(Number i, String paramName) { - if (i.longValue() <= 0l) { - throw new IllegalArgumentException(paramName + " has to be greater than 0."); - } - } -} diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/tools/MappingTools.java b/hibernate-envers/src/main/java/org/hibernate/envers/tools/MappingTools.java deleted file mode 100644 index 71a69a9457..0000000000 --- a/hibernate-envers/src/main/java/org/hibernate/envers/tools/MappingTools.java +++ /dev/null @@ -1,39 +0,0 @@ -package org.hibernate.envers.tools; -import org.hibernate.mapping.Collection; -import org.hibernate.mapping.OneToMany; -import org.hibernate.mapping.ToOne; -import org.hibernate.mapping.Value; - -/** - * @author Adam Warski (adam at warski dot org) - */ -public class MappingTools { - /** - * @param componentName Name of the component, that is, name of the property in the entity that references the - * component. - * @return A prefix for properties in the given component. - */ - public static String createComponentPrefix(String componentName) { - return componentName + "_"; - } - - /** - * @param referencePropertyName The name of the property that holds the relation to the entity. - * @return A prefix which should be used to prefix an id mapper for the related entity. - */ - public static String createToOneRelationPrefix(String referencePropertyName) { - return referencePropertyName + "_"; - } - - public static String getReferencedEntityName(Value value) { - if (value instanceof ToOne) { - return ((ToOne) value).getReferencedEntityName(); - } else if (value instanceof OneToMany) { - return ((OneToMany) value).getReferencedEntityName(); - } else if (value instanceof Collection) { - return getReferencedEntityName(((Collection) value).getElement()); - } - - return null; - } -} diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/tools/Pair.java b/hibernate-envers/src/main/java/org/hibernate/envers/tools/Pair.java index af968ebdff..7ac039ba00 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/tools/Pair.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/tools/Pair.java @@ -23,7 +23,6 @@ */ package org.hibernate.envers.tools; - /** * A pair of objects. * @param diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/tools/StringTools.java b/hibernate-envers/src/main/java/org/hibernate/envers/tools/StringTools.java deleted file mode 100644 index 09f955064e..0000000000 --- a/hibernate-envers/src/main/java/org/hibernate/envers/tools/StringTools.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Hibernate, Relational Persistence for Idiomatic Java - * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as - * indicated by the @author tags or express copyright attribution - * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. - * - * This copyrighted material is made available to anyone wishing to use, modify, - * copy, or redistribute it subject to the terms and conditions of the GNU - * Lesser General Public License, as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this distribution; if not, write to: - * Free Software Foundation, Inc. - * 51 Franklin Street, Fifth Floor - * Boston, MA 02110-1301 USA - */ -package org.hibernate.envers.tools; -import java.util.Iterator; - -/** - * @author Adam Warski (adam at warski dot org) - */ -public class StringTools { - public static boolean isEmpty(String s) { - return s == null || "".equals(s); - } - - public static boolean isEmpty(Object o) { - return o == null || "".equals(o); - } - - /** - * @param s String, from which to get the last component. - * @return The last component of the dot-separated string s. For example, for a string - * "a.b.c", the result is "c". - */ - public static String getLastComponent(String s) { - if (s == null) { - return null; - } - - int lastDot = s.lastIndexOf("."); - if (lastDot == -1) { - return s; - } else { - return s.substring(lastDot + 1); - } - } - - /** - * To the given string builder, appends all strings in the given iterator, separating them with the given - * separator. For example, for an interator "a" "b" "c" and separator ":" the output is "a:b:c". - * @param sb String builder, to which to append. - * @param contents Strings to be appended. - * @param separator Separator between subsequent content. - */ - public static void append(StringBuilder sb, Iterator contents, String separator) { - boolean isFirst = true; - - while (contents.hasNext()) { - if (!isFirst) { - sb.append(separator); - } - - sb.append(contents.next()); - - isFirst = false; - } - } -} diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/tools/Tools.java b/hibernate-envers/src/main/java/org/hibernate/envers/tools/Tools.java deleted file mode 100644 index 5f388b9075..0000000000 --- a/hibernate-envers/src/main/java/org/hibernate/envers/tools/Tools.java +++ /dev/null @@ -1,253 +0,0 @@ -/* - * Hibernate, Relational Persistence for Idiomatic Java - * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as - * indicated by the @author tags or express copyright attribution - * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. - * - * This copyrighted material is made available to anyone wishing to use, modify, - * copy, or redistribute it subject to the terms and conditions of the GNU - * Lesser General Public License, as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this distribution; if not, write to: - * Free Software Foundation, Inc. - * 51 Franklin Street, Fifth Floor - * Boston, MA 02110-1301 USA - */ -package org.hibernate.envers.tools; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.Properties; -import java.util.Set; - -import javassist.util.proxy.ProxyFactory; - -import org.hibernate.Session; -import org.hibernate.annotations.common.reflection.XClass; -import org.hibernate.annotations.common.reflection.XProperty; -import org.hibernate.engine.spi.SessionFactoryImplementor; -import org.hibernate.engine.spi.SessionImplementor; -import org.hibernate.persister.entity.EntityPersister; -import org.hibernate.proxy.HibernateProxy; - -/** - * @author Adam Warski (adam at warski dot org) - * @author HernпїЅn Chanfreau - * @author Lukasz Antoniak (lukasz dot antoniak at gmail dot com) - */ -public class Tools { - public static Map newHashMap() { - return new HashMap(); - } - - public static Set newHashSet() { - return new HashSet(); - } - - public static Map newLinkedHashMap() { - return new LinkedHashMap(); - } - - public static boolean entitiesEqual(SessionImplementor session, String entityName, Object obj1, Object obj2) { - Object id1 = getIdentifier(session, entityName, obj1); - Object id2 = getIdentifier(session, entityName, obj2); - - return objectsEqual(id1, id2); - } - - public static Object getIdentifier(SessionImplementor session, String entityName, Object obj) { - if (obj == null) { - return null; - } - - if (obj instanceof HibernateProxy) { - HibernateProxy hibernateProxy = (HibernateProxy) obj; - return hibernateProxy.getHibernateLazyInitializer().getIdentifier(); - } - - return session.getEntityPersister(entityName, obj).getIdentifier(obj, session); - } - - - public static Object getTargetFromProxy(SessionFactoryImplementor sessionFactoryImplementor, HibernateProxy proxy) { - if (!proxy.getHibernateLazyInitializer().isUninitialized() || activeProxySession(proxy)) { - return proxy.getHibernateLazyInitializer().getImplementation(); - } - - SessionImplementor sessionImplementor = proxy.getHibernateLazyInitializer().getSession(); - Session tempSession = sessionImplementor==null - ? sessionFactoryImplementor.openTemporarySession() - : sessionImplementor.getFactory().openTemporarySession(); - try { - Object target = tempSession.get( - proxy.getHibernateLazyInitializer().getEntityName(), - proxy.getHibernateLazyInitializer().getIdentifier() - ); - return target; - } - finally { - tempSession.close(); - } - } - - private static boolean activeProxySession(HibernateProxy proxy) { - Session session = (Session) proxy.getHibernateLazyInitializer().getSession(); - return session != null && session.isOpen() && session.isConnected(); - } - - /** - * @param clazz Class wrapped with a proxy or not. - * @param Class type. - * @return Returns target class in case it has been wrapped with a proxy. If {@code null} reference is passed, - * method returns {@code null}. - */ - @SuppressWarnings({"unchecked"}) - public static Class getTargetClassIfProxied(Class clazz) { - if (clazz == null) { - return null; - } else if (ProxyFactory.isProxyClass(clazz)) { - // Get the source class of Javassist proxy instance. - return (Class) clazz.getSuperclass(); - } - return clazz; - } - - public static boolean objectsEqual(Object obj1, Object obj2) { - if (obj1 == null) { - return obj2 == null; - } - - return obj1.equals(obj2); - } - - public static boolean arraysEqual(Object[] array1, Object[] array2) { - if (array1 == null) return array2 == null; - if (array2 == null || array1.length != array2.length) return false; - for (int i = 0; i < array1.length; ++i) { - if (array1[i] != null ? !array1[i].equals(array2[i]) : array2[i] != null) { - return false; - } - } - return true; - } - - public static List iteratorToList(Iterator iter) { - List ret = new ArrayList(); - while (iter.hasNext()) { - ret.add(iter.next()); - } - - return ret; - } - - public static boolean iteratorsContentEqual(Iterator iter1, Iterator iter2) { - while (iter1.hasNext() && iter2.hasNext()) { - if (!iter1.next().equals(iter2.next())) { - return false; - } - } - - //noinspection RedundantIfStatement - if (iter1.hasNext() || iter2.hasNext()) { - return false; - } - - return true; - } - - /** - * Transforms a list of arbitrary elements to a list of index-element pairs. - * @param list List to transform. - * @return A list of pairs: ((0, element_at_index_0), (1, element_at_index_1), ...) - */ - public static List> listToIndexElementPairList(List list) { - List> ret = new ArrayList>(); - Iterator listIter = list.iterator(); - for (int i=0; i data, String[] keys) { - Object[] ret = new Object[keys.length]; - for (int i = 0; i < keys.length; ++i) { - ret[i] = data.get(keys[i]); - } - return ret; - } - - /** - * @param clazz Source class. - * @param propertyName Property name. - * @return Property object or {@code null} if none with expected name has been found. - */ - public static XProperty getProperty(XClass clazz, String propertyName) { - XProperty property = getProperty(clazz, propertyName, "field"); - if (property == null) { - property = getProperty(clazz, propertyName, "property"); - } - return property; - } - - /** - * @param clazz Source class. - * @param propertyName Property name. - * @param accessType Expected access type. Legal values are field and property. - * @return Property object or {@code null} if none with expected name and access type has been found. - */ - public static XProperty getProperty(XClass clazz, String propertyName, String accessType) { - for (XProperty property : clazz.getDeclaredProperties(accessType)) { - if (propertyName.equals(property.getName())) { - return property; - } - } - return null; - } -} diff --git a/hibernate-envers/src/main/java/org/hibernate/tool/EnversSchemaGenerator.java b/hibernate-envers/src/main/java/org/hibernate/envers/tools/hbm2ddl/EnversSchemaGenerator.java similarity index 93% rename from hibernate-envers/src/main/java/org/hibernate/tool/EnversSchemaGenerator.java rename to hibernate-envers/src/main/java/org/hibernate/envers/tools/hbm2ddl/EnversSchemaGenerator.java index c5701cb244..de20ea4463 100644 --- a/hibernate-envers/src/main/java/org/hibernate/tool/EnversSchemaGenerator.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/tools/hbm2ddl/EnversSchemaGenerator.java @@ -1,11 +1,11 @@ -package org.hibernate.tool; +package org.hibernate.envers.tools.hbm2ddl; import java.sql.Connection; import java.util.Properties; import org.hibernate.HibernateException; import org.hibernate.cfg.Configuration; -import org.hibernate.envers.configuration.AuditConfiguration; +import org.hibernate.envers.configuration.spi.AuditConfiguration; import org.hibernate.service.ServiceRegistry; import org.hibernate.tool.hbm2ddl.SchemaExport; diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/tools/reflection/ReflectionTools.java b/hibernate-envers/src/main/java/org/hibernate/envers/tools/reflection/ReflectionTools.java deleted file mode 100644 index da7908aa1d..0000000000 --- a/hibernate-envers/src/main/java/org/hibernate/envers/tools/reflection/ReflectionTools.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Hibernate, Relational Persistence for Idiomatic Java - * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as - * indicated by the @author tags or express copyright attribution - * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. - * - * This copyrighted material is made available to anyone wishing to use, modify, - * copy, or redistribute it subject to the terms and conditions of the GNU - * Lesser General Public License, as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this distribution; if not, write to: - * Free Software Foundation, Inc. - * 51 Franklin Street, Fifth Floor - * Boston, MA 02110-1301 USA - */ -package org.hibernate.envers.tools.reflection; -import static org.hibernate.envers.tools.Pair.make; - -import java.util.Map; - -import org.hibernate.envers.entities.PropertyData; -import org.hibernate.envers.tools.Pair; -import org.hibernate.internal.util.collections.ConcurrentReferenceHashMap; -import org.hibernate.property.Getter; -import org.hibernate.property.PropertyAccessor; -import org.hibernate.property.PropertyAccessorFactory; -import org.hibernate.property.Setter; - -/** - * @author Adam Warski (adam at warski dot org) - */ -public class ReflectionTools { - private static final Map, Getter> getterCache = - new ConcurrentReferenceHashMap, Getter>(10, - ConcurrentReferenceHashMap.ReferenceType.SOFT, - ConcurrentReferenceHashMap.ReferenceType.SOFT); - private static final Map, Setter> setterCache = - new ConcurrentReferenceHashMap, Setter>(10, - ConcurrentReferenceHashMap.ReferenceType.SOFT, - ConcurrentReferenceHashMap.ReferenceType.SOFT); - - private static PropertyAccessor getAccessor(String accessorType) { - return PropertyAccessorFactory.getPropertyAccessor(accessorType); - } - - public static Getter getGetter(Class cls, PropertyData propertyData) { - return getGetter(cls, propertyData.getBeanName(), propertyData.getAccessType()); - } - - public static Getter getGetter(Class cls, String propertyName, String accessorType) { - Pair key = make(cls, propertyName); - Getter value = getterCache.get(key); - if (value == null) { - value = getAccessor(accessorType).getGetter(cls, propertyName); - // It's ok if two getters are generated concurrently - getterCache.put(key, value); - } - - return value; - } - - public static Setter getSetter(Class cls, PropertyData propertyData) { - return getSetter(cls, propertyData.getBeanName(), propertyData.getAccessType()); - } - - private static Setter getSetter(Class cls, String propertyName, String accessorType) { - Pair key = make(cls, propertyName); - Setter value = setterCache.get(key); - if (value == null) { - value = getAccessor(accessorType).getSetter(cls, propertyName); - // It's ok if two setters are generated concurrently - setterCache.put(key, value); - } - - return value; - } -} diff --git a/hibernate-envers/src/main/java/org/hibernate/tool/ant/EnversHibernateToolTask.java b/hibernate-envers/src/main/java/org/hibernate/tool/ant/EnversHibernateToolTask.java deleted file mode 100644 index 81c609010f..0000000000 --- a/hibernate-envers/src/main/java/org/hibernate/tool/ant/EnversHibernateToolTask.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Hibernate, Relational Persistence for Idiomatic Java - * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as - * indicated by the @author tags or express copyright attribution - * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. - * - * This copyrighted material is made available to anyone wishing to use, modify, - * copy, or redistribute it subject to the terms and conditions of the GNU - * Lesser General Public License, as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this distribution; if not, write to: - * Free Software Foundation, Inc. - * 51 Franklin Street, Fifth Floor - * Boston, MA 02110-1301 USA - */ -package org.hibernate.tool.ant; -import org.apache.tools.ant.BuildException; - -import org.hibernate.envers.ant.AnnotationConfigurationTaskWithEnvers; -import org.hibernate.envers.ant.ConfigurationTaskWithEnvers; -import org.hibernate.envers.ant.JPAConfigurationTaskWithEnvers; - -/** - * @author Adam Warski (adam at warski dot org) - */ -public class EnversHibernateToolTask extends HibernateToolTask { - private void checkConfiguration() { - if (configurationTask!=null) { - throw new BuildException("Only a single configuration is allowed."); - } - } - - public JPAConfigurationTask createJpaConfiguration() { - checkConfiguration(); - JPAConfigurationTask task = new JPAConfigurationTaskWithEnvers(); - configurationTask = task; - return task; - } - - public ConfigurationTask createConfiguration() { - checkConfiguration(); - ConfigurationTaskWithEnvers task = new ConfigurationTaskWithEnvers(); - configurationTask = task; - return task; - } - - public AnnotationConfigurationTask createAnnotationConfiguration() { - checkConfiguration(); - AnnotationConfigurationTaskWithEnvers task = new AnnotationConfigurationTaskWithEnvers(); - configurationTask = task; - return task; - } -} diff --git a/hibernate-envers/src/main/resources/META-INF/services/org.hibernate.integrator.spi.Integrator b/hibernate-envers/src/main/resources/META-INF/services/org.hibernate.integrator.spi.Integrator index dac1b598b9..4155dd7232 100644 --- a/hibernate-envers/src/main/resources/META-INF/services/org.hibernate.integrator.spi.Integrator +++ b/hibernate-envers/src/main/resources/META-INF/services/org.hibernate.integrator.spi.Integrator @@ -1 +1 @@ -org.hibernate.envers.event.EnversIntegrator \ No newline at end of file +org.hibernate.envers.event.spi.EnversIntegrator \ No newline at end of file diff --git a/hibernate-envers/src/test/java/org/hibernate/envers/test/AbstractOneSessionTest.java b/hibernate-envers/src/test/java/org/hibernate/envers/test/AbstractOneSessionTest.java index f14de44b5b..9ece4924be 100644 --- a/hibernate-envers/src/test/java/org/hibernate/envers/test/AbstractOneSessionTest.java +++ b/hibernate-envers/src/test/java/org/hibernate/envers/test/AbstractOneSessionTest.java @@ -4,15 +4,16 @@ import java.net.URISyntaxException; import java.net.URL; -import org.hibernate.cfg.Environment; import org.junit.Before; import org.hibernate.MappingException; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration; +import org.hibernate.cfg.Environment; import org.hibernate.envers.AuditReader; import org.hibernate.envers.AuditReaderFactory; +import org.hibernate.envers.configuration.EnversSettings; import org.hibernate.service.ServiceRegistry; import org.hibernate.testing.AfterClassOnce; import org.hibernate.testing.BeforeClassOnce; @@ -40,10 +41,10 @@ public void init() throws URISyntaxException { String auditStrategy = getAuditStrategy(); if (auditStrategy != null && !"".equals(auditStrategy)) { - config.setProperty("org.hibernate.envers.audit_strategy", auditStrategy); + config.setProperty(EnversSettings.AUDIT_STRATEGY, auditStrategy); } config.setProperty( Environment.USE_NEW_ID_GENERATOR_MAPPINGS, "true" ); - config.setProperty("org.hibernate.envers.use_revision_entity_with_native_id", "false"); + config.setProperty(EnversSettings.USE_REVISION_ENTITY_WITH_NATIVE_ID, "false"); addProperties(config); this.initMappings(); diff --git a/hibernate-envers/src/test/java/org/hibernate/envers/test/BaseEnversFunctionalTestCase.java b/hibernate-envers/src/test/java/org/hibernate/envers/test/BaseEnversFunctionalTestCase.java index 963a57db23..e6b91a26f5 100644 --- a/hibernate-envers/src/test/java/org/hibernate/envers/test/BaseEnversFunctionalTestCase.java +++ b/hibernate-envers/src/test/java/org/hibernate/envers/test/BaseEnversFunctionalTestCase.java @@ -3,13 +3,14 @@ import java.util.Arrays; import java.util.List; -import org.hibernate.cfg.Configuration; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import org.hibernate.Session; +import org.hibernate.cfg.Configuration; import org.hibernate.envers.AuditReader; import org.hibernate.envers.AuditReaderFactory; +import org.hibernate.envers.configuration.EnversSettings; import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; /** @@ -49,7 +50,7 @@ protected AuditReader getAuditReader(){ @Override protected Configuration constructConfiguration() { Configuration configuration = super.constructConfiguration(); - configuration.setProperty("org.hibernate.envers.use_revision_entity_with_native_id", "false"); + configuration.setProperty(EnversSettings.USE_REVISION_ENTITY_WITH_NATIVE_ID, "false"); return configuration; } diff --git a/hibernate-envers/src/test/java/org/hibernate/envers/test/BaseEnversJPAFunctionalTestCase.java b/hibernate-envers/src/test/java/org/hibernate/envers/test/BaseEnversJPAFunctionalTestCase.java index 242761b26c..0590352301 100644 --- a/hibernate-envers/src/test/java/org/hibernate/envers/test/BaseEnversJPAFunctionalTestCase.java +++ b/hibernate-envers/src/test/java/org/hibernate/envers/test/BaseEnversJPAFunctionalTestCase.java @@ -23,34 +23,33 @@ */ package org.hibernate.envers.test; -import javax.persistence.EntityManager; -import javax.persistence.EntityManagerFactory; -import javax.transaction.SystemException; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.Map; +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.transaction.SystemException; import org.jboss.logging.Logger; +import org.junit.After; +import org.hibernate.boot.registry.internal.StandardServiceRegistryImpl; import org.hibernate.cfg.Configuration; import org.hibernate.dialect.Dialect; import org.hibernate.dialect.H2Dialect; -import org.hibernate.jpa.test.PersistenceUnitDescriptorAdapter; import org.hibernate.engine.transaction.internal.jta.JtaStatusHelper; import org.hibernate.envers.AuditReader; import org.hibernate.envers.AuditReaderFactory; -import org.hibernate.envers.event.EnversIntegrator; +import org.hibernate.envers.configuration.EnversSettings; +import org.hibernate.envers.event.spi.EnversIntegrator; import org.hibernate.internal.util.StringHelper; import org.hibernate.jpa.AvailableSettings; import org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl; import org.hibernate.jpa.boot.spi.Bootstrap; import org.hibernate.jpa.boot.spi.PersistenceUnitDescriptor; import org.hibernate.jpa.internal.EntityManagerFactoryImpl; -import org.hibernate.boot.registry.internal.StandardServiceRegistryImpl; - -import org.junit.After; - +import org.hibernate.jpa.test.PersistenceUnitDescriptorAdapter; import org.hibernate.testing.AfterClassOnce; import org.hibernate.testing.BeforeClassOnce; import org.hibernate.testing.jta.TestingJtaPlatformImpl; @@ -126,14 +125,14 @@ private Map buildSettings() { } if ( StringHelper.isNotEmpty( getAuditStrategy() ) ) { - settings.put( "org.hibernate.envers.audit_strategy", getAuditStrategy() ); + settings.put( EnversSettings.AUDIT_STRATEGY, getAuditStrategy() ); } if ( ! autoRegisterListeners() ) { settings.put( EnversIntegrator.AUTO_REGISTER, "false" ); } - settings.put( "org.hibernate.envers.use_revision_entity_with_native_id", "false" ); + settings.put( EnversSettings.USE_REVISION_ENTITY_WITH_NATIVE_ID, "false" ); settings.put( org.hibernate.cfg.AvailableSettings.USE_NEW_ID_GENERATOR_MAPPINGS, "true" ); settings.put( org.hibernate.cfg.AvailableSettings.DIALECT, getDialect().getClass().getName() ); diff --git a/hibernate-envers/src/test/java/org/hibernate/envers/test/entities/reventity/trackmodifiedentities/ExtendedRevisionEntity.java b/hibernate-envers/src/test/java/org/hibernate/envers/test/entities/reventity/trackmodifiedentities/ExtendedRevisionEntity.java index 17330e46ea..65e838148a 100644 --- a/hibernate-envers/src/test/java/org/hibernate/envers/test/entities/reventity/trackmodifiedentities/ExtendedRevisionEntity.java +++ b/hibernate-envers/src/test/java/org/hibernate/envers/test/entities/reventity/trackmodifiedentities/ExtendedRevisionEntity.java @@ -3,8 +3,8 @@ import javax.persistence.Column; import javax.persistence.Entity; -import org.hibernate.envers.enhanced.SequenceIdTrackingModifiedEntitiesRevisionEntity; import org.hibernate.envers.RevisionEntity; +import org.hibernate.envers.enhanced.SequenceIdTrackingModifiedEntitiesRevisionEntity; /** * @author Lukasz Antoniak (lukasz dot antoniak at gmail dot com) diff --git a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/basic/Delete.java b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/basic/Delete.java index 259331a5be..d3589e03cc 100644 --- a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/basic/Delete.java +++ b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/basic/Delete.java @@ -28,7 +28,7 @@ import org.junit.Test; -import org.hibernate.envers.test.BaseEnversJPAFunctionalTestCase ; +import org.hibernate.envers.test.BaseEnversJPAFunctionalTestCase; import org.hibernate.envers.test.Priority; /** diff --git a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/basic/OutsideTransactionTest.java b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/basic/OutsideTransactionTest.java index 1c00e7f7c8..7eeffd735f 100644 --- a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/basic/OutsideTransactionTest.java +++ b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/basic/OutsideTransactionTest.java @@ -1,14 +1,16 @@ package org.hibernate.envers.test.integration.basic; +import org.junit.Test; + import org.hibernate.Session; import org.hibernate.cfg.Configuration; +import org.hibernate.envers.configuration.EnversSettings; import org.hibernate.envers.exception.AuditException; import org.hibernate.envers.test.BaseEnversFunctionalTestCase; import org.hibernate.envers.test.entities.StrTestEntity; import org.hibernate.envers.test.integration.collection.norevision.Name; import org.hibernate.envers.test.integration.collection.norevision.Person; import org.hibernate.testing.TestForIssue; -import org.junit.Test; /** * @author Lukasz Antoniak (lukasz dot antoniak at gmail dot com) @@ -22,8 +24,8 @@ protected Class[] getAnnotatedClasses() { @Override protected void configure(Configuration configuration) { - configuration.setProperty("org.hibernate.envers.store_data_at_delete", "true"); - configuration.setProperty("org.hibernate.envers.revision_on_collection_change", "true"); + configuration.setProperty(EnversSettings.STORE_DATA_AT_DELETE, "true"); + configuration.setProperty(EnversSettings.REVISION_ON_COLLECTION_CHANGE, "true"); } @Test(expected = AuditException.class) diff --git a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/basic/TransactionRollbackBehaviour.java b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/basic/TransactionRollbackBehaviour.java index b6622af69b..46c1d7a383 100644 --- a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/basic/TransactionRollbackBehaviour.java +++ b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/basic/TransactionRollbackBehaviour.java @@ -1,13 +1,13 @@ package org.hibernate.envers.test.integration.basic; import java.util.List; - import javax.persistence.EntityManager; +import org.junit.Assert; +import org.junit.Test; + import org.hibernate.envers.test.BaseEnversJPAFunctionalTestCase; import org.hibernate.envers.test.entities.IntTestEntity; -import org.junit.Assert; -import org.junit.Test; /** * @author Tomasz Dziurko (tdziurko at gmail dot com) diff --git a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/basic/UnversionedProperty.java b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/basic/UnversionedProperty.java index 1fe190b602..7ecb37da29 100644 --- a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/basic/UnversionedProperty.java +++ b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/basic/UnversionedProperty.java @@ -28,7 +28,7 @@ import org.junit.Test; -import org.hibernate.envers.test.BaseEnversJPAFunctionalTestCase ; +import org.hibernate.envers.test.BaseEnversJPAFunctionalTestCase; import org.hibernate.envers.test.Priority; import org.hibernate.envers.test.entities.UnversionedEntity; diff --git a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/collection/EnumSet.java b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/collection/EnumSet.java index 842c1396fe..92239ec28c 100644 --- a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/collection/EnumSet.java +++ b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/collection/EnumSet.java @@ -30,7 +30,7 @@ import org.junit.Assert; import org.junit.Test; -import org.hibernate.envers.test.BaseEnversJPAFunctionalTestCase ; +import org.hibernate.envers.test.BaseEnversJPAFunctionalTestCase; import org.hibernate.envers.test.Priority; import org.hibernate.envers.test.entities.collection.EnumSetEntity; import org.hibernate.envers.test.entities.collection.EnumSetEntity.E1; diff --git a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/collection/embeddable/EmbeddableList2.java b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/collection/embeddable/EmbeddableList2.java index 4d325b8504..7cfc454008 100644 --- a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/collection/embeddable/EmbeddableList2.java +++ b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/collection/embeddable/EmbeddableList2.java @@ -24,7 +24,6 @@ package org.hibernate.envers.test.integration.collection.embeddable; import java.util.Arrays; -import java.util.Date; import javax.persistence.EntityManager; import org.junit.Test; diff --git a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/collection/embeddable/EmbeddableMap.java b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/collection/embeddable/EmbeddableMap.java index 2a2895dd77..869c908cc2 100644 --- a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/collection/embeddable/EmbeddableMap.java +++ b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/collection/embeddable/EmbeddableMap.java @@ -25,9 +25,11 @@ import java.util.Arrays; import java.util.Collections; - import javax.persistence.EntityManager; +import org.junit.Assert; +import org.junit.Test; + import org.hibernate.envers.test.BaseEnversJPAFunctionalTestCase; import org.hibernate.envers.test.Priority; import org.hibernate.envers.test.entities.collection.EmbeddableMapEntity; @@ -36,9 +38,6 @@ import org.hibernate.envers.test.tools.TestTools; import org.hibernate.testing.TestForIssue; -import org.junit.Assert; -import org.junit.Test; - /** * @author Kristoffer Lundberg (kristoffer at cambio dot se) */ diff --git a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/collection/norevision/AbstractCollectionChangeTest.java b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/collection/norevision/AbstractCollectionChangeTest.java index 950a6981ef..194bf6cbe7 100644 --- a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/collection/norevision/AbstractCollectionChangeTest.java +++ b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/collection/norevision/AbstractCollectionChangeTest.java @@ -1,19 +1,21 @@ package org.hibernate.envers.test.integration.collection.norevision; +import java.util.List; + +import org.junit.Test; + import org.hibernate.Session; import org.hibernate.cfg.Configuration; +import org.hibernate.envers.configuration.EnversSettings; import org.hibernate.envers.test.BaseEnversFunctionalTestCase; import org.hibernate.envers.test.Priority; -import org.junit.Test; - -import java.util.List; public abstract class AbstractCollectionChangeTest extends BaseEnversFunctionalTestCase { protected Integer personId; @Override protected void configure(Configuration configuration) { - configuration.setProperty("org.hibernate.envers.revision_on_collection_change", getCollectionChangeValue()); + configuration.setProperty(EnversSettings.REVISION_ON_COLLECTION_CHANGE, getCollectionChangeValue()); } @Override diff --git a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/components/Components.java b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/components/Components.java index ca82f31884..56ed7f0d76 100644 --- a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/components/Components.java +++ b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/components/Components.java @@ -28,7 +28,7 @@ import org.junit.Test; -import org.hibernate.envers.test.BaseEnversJPAFunctionalTestCase ; +import org.hibernate.envers.test.BaseEnversJPAFunctionalTestCase; import org.hibernate.envers.test.Priority; import org.hibernate.envers.test.entities.components.Component1; import org.hibernate.envers.test.entities.components.Component2; diff --git a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/components/PropertiesGroupTest.java b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/components/PropertiesGroupTest.java index 7c09e7c644..34c6b0e4a6 100644 --- a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/components/PropertiesGroupTest.java +++ b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/components/PropertiesGroupTest.java @@ -1,14 +1,9 @@ package org.hibernate.envers.test.integration.components; -import java.io.File; -import java.net.URISyntaxException; -import java.net.URL; - -import org.hibernate.Session; import org.junit.Assert; import org.junit.Test; -import org.hibernate.MappingException; +import org.hibernate.Session; import org.hibernate.envers.test.BaseEnversFunctionalTestCase; import org.hibernate.envers.test.Priority; import org.hibernate.envers.test.entities.components.UniquePropsEntity; diff --git a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/components/relations/ManyToOneInComponent.java b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/components/relations/ManyToOneInComponent.java index 3c2679030f..4ef4e24211 100644 --- a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/components/relations/ManyToOneInComponent.java +++ b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/components/relations/ManyToOneInComponent.java @@ -28,7 +28,7 @@ import org.junit.Test; -import org.hibernate.envers.test.BaseEnversJPAFunctionalTestCase ; +import org.hibernate.envers.test.BaseEnversJPAFunctionalTestCase; import org.hibernate.envers.test.Priority; import org.hibernate.envers.test.entities.StrTestEntity; import org.hibernate.envers.test.entities.components.relations.ManyToOneComponent; diff --git a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/components/relations/OneToManyInComponent.java b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/components/relations/OneToManyInComponent.java index 9d277b2bff..480c1a277f 100644 --- a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/components/relations/OneToManyInComponent.java +++ b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/components/relations/OneToManyInComponent.java @@ -28,7 +28,7 @@ import org.junit.Test; -import org.hibernate.envers.test.BaseEnversJPAFunctionalTestCase ; +import org.hibernate.envers.test.BaseEnversJPAFunctionalTestCase; import org.hibernate.envers.test.Priority; import org.hibernate.envers.test.entities.StrTestEntity; import org.hibernate.envers.test.entities.components.relations.OneToManyComponent; diff --git a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/customtype/ObjectUserTypeTest.java b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/customtype/ObjectUserTypeTest.java index 45ddd3efd6..f6d7a87613 100644 --- a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/customtype/ObjectUserTypeTest.java +++ b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/customtype/ObjectUserTypeTest.java @@ -8,6 +8,7 @@ import org.junit.Test; import org.hibernate.dialect.Oracle8iDialect; +import org.hibernate.envers.configuration.EnversSettings; import org.hibernate.envers.test.BaseEnversJPAFunctionalTestCase; import org.hibernate.envers.test.Priority; import org.hibernate.testing.RequiresDialect; @@ -29,7 +30,7 @@ protected Class[] getAnnotatedClasses() { @Override protected void addConfigOptions(Map options) { super.addConfigOptions( options ); - options.put( "org.hibernate.envers.store_data_at_delete", "true" ); + options.put( EnversSettings.STORE_DATA_AT_DELETE, "true" ); } @Test diff --git a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/data/LobSerializables.java b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/data/LobSerializables.java index c4f2bc7aa2..07402f1fcd 100644 --- a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/data/LobSerializables.java +++ b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/data/LobSerializables.java @@ -27,9 +27,9 @@ import java.util.Map; import javax.persistence.EntityManager; -import org.hibernate.dialect.PostgreSQL82Dialect; import org.junit.Test; +import org.hibernate.dialect.PostgreSQL82Dialect; import org.hibernate.envers.test.BaseEnversJPAFunctionalTestCase; import org.hibernate.testing.DialectChecks; import org.hibernate.testing.RequiresDialectFeature; diff --git a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/data/Lobs.java b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/data/Lobs.java index 5a914e8d62..03663d91ed 100644 --- a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/data/Lobs.java +++ b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/data/Lobs.java @@ -27,9 +27,9 @@ import java.util.Map; import javax.persistence.EntityManager; -import org.hibernate.dialect.PostgreSQL82Dialect; import org.junit.Test; +import org.hibernate.dialect.PostgreSQL82Dialect; import org.hibernate.envers.test.BaseEnversJPAFunctionalTestCase; import org.hibernate.envers.test.Priority; import org.hibernate.testing.DialectChecks; diff --git a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/flush/ManualFlushAutoCommitDisabled.java b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/flush/ManualFlushAutoCommitDisabled.java index c12e3f4e56..d6f94a5fdf 100644 --- a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/flush/ManualFlushAutoCommitDisabled.java +++ b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/flush/ManualFlushAutoCommitDisabled.java @@ -1,9 +1,9 @@ package org.hibernate.envers.test.integration.flush; -import org.hibernate.testing.TestForIssue; - import java.util.Map; +import org.hibernate.testing.TestForIssue; + /** * @author Lukasz Antoniak (lukasz dot antoniak at gmail dot com) */ diff --git a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/ids/embeddedid/Item.java b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/ids/embeddedid/Item.java index 6372a5d337..b95b70d5ea 100644 --- a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/ids/embeddedid/Item.java +++ b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/ids/embeddedid/Item.java @@ -1,11 +1,11 @@ package org.hibernate.envers.test.integration.ids.embeddedid; -import org.hibernate.envers.Audited; - import java.io.Serializable; import javax.persistence.EmbeddedId; import javax.persistence.Entity; +import org.hibernate.envers.Audited; + /** * @author Lukasz Antoniak (lukasz dot antoniak at gmail dot com) */ diff --git a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/ids/embeddedid/Producer.java b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/ids/embeddedid/Producer.java index 8df7a5d974..27538a6d0b 100644 --- a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/ids/embeddedid/Producer.java +++ b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/ids/embeddedid/Producer.java @@ -1,12 +1,12 @@ package org.hibernate.envers.test.integration.ids.embeddedid; -import org.hibernate.envers.Audited; - import java.io.Serializable; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Id; +import org.hibernate.envers.Audited; + /** * @author Lukasz Antoniak (lukasz dot antoniak at gmail dot com) */ diff --git a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/ids/embeddedid/PurchaseOrder.java b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/ids/embeddedid/PurchaseOrder.java index b322221442..892e32da72 100644 --- a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/ids/embeddedid/PurchaseOrder.java +++ b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/ids/embeddedid/PurchaseOrder.java @@ -1,9 +1,15 @@ package org.hibernate.envers.test.integration.ids.embeddedid; -import org.hibernate.envers.Audited; - -import javax.persistence.*; import java.io.Serializable; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.JoinColumns; +import javax.persistence.ManyToOne; + +import org.hibernate.envers.Audited; /** * @author Lukasz Antoniak (lukasz dot antoniak at gmail dot com) diff --git a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/ids/embeddedid/RelationInsideEmbeddableTest.java b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/ids/embeddedid/RelationInsideEmbeddableTest.java index ff55496404..28ee8adacc 100644 --- a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/ids/embeddedid/RelationInsideEmbeddableTest.java +++ b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/ids/embeddedid/RelationInsideEmbeddableTest.java @@ -1,13 +1,14 @@ package org.hibernate.envers.test.integration.ids.embeddedid; +import java.util.Arrays; +import javax.persistence.EntityManager; + +import org.junit.Assert; +import org.junit.Test; + import org.hibernate.envers.test.BaseEnversJPAFunctionalTestCase; import org.hibernate.envers.test.Priority; import org.hibernate.testing.TestForIssue; -import org.junit.Assert; -import org.junit.Test; - -import javax.persistence.EntityManager; -import java.util.Arrays; /** * @author Lukasz Antoniak (lukasz dot antoniak at gmail dot com) diff --git a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/ids/idclass/ClassType.java b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/ids/idclass/ClassType.java index b077b2d6e4..f4a75f2ca4 100644 --- a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/ids/idclass/ClassType.java +++ b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/ids/idclass/ClassType.java @@ -4,7 +4,6 @@ import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Id; -import javax.persistence.Table; import org.hibernate.envers.Audited; diff --git a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/ids/idclass/IdClassWithRelationTest.java b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/ids/idclass/IdClassWithRelationTest.java index 7556b990e1..e76ab25a00 100644 --- a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/ids/idclass/IdClassWithRelationTest.java +++ b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/ids/idclass/IdClassWithRelationTest.java @@ -1,13 +1,14 @@ package org.hibernate.envers.test.integration.ids.idclass; +import java.util.Arrays; +import javax.persistence.EntityManager; + import junit.framework.Assert; +import org.junit.Test; + import org.hibernate.envers.test.BaseEnversJPAFunctionalTestCase; import org.hibernate.envers.test.Priority; import org.hibernate.testing.TestForIssue; -import org.junit.Test; - -import javax.persistence.EntityManager; -import java.util.Arrays; /** * @author Lukasz Antoniak (lukasz dot antoniak at gmail dot com) diff --git a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/inheritance/mixed/MixedInheritanceStrategiesEntityTest.java b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/inheritance/mixed/MixedInheritanceStrategiesEntityTest.java index 28e2afc886..e676e3659d 100644 --- a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/inheritance/mixed/MixedInheritanceStrategiesEntityTest.java +++ b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/inheritance/mixed/MixedInheritanceStrategiesEntityTest.java @@ -4,7 +4,7 @@ import org.junit.Test; -import org.hibernate.envers.test.BaseEnversJPAFunctionalTestCase ; +import org.hibernate.envers.test.BaseEnversJPAFunctionalTestCase; import org.hibernate.envers.test.Priority; import org.hibernate.envers.test.integration.inheritance.mixed.entities.AbstractActivity; import org.hibernate.envers.test.integration.inheritance.mixed.entities.AbstractCheckActivity; diff --git a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/interfaces/hbm/propertiesAudited/AbstractPropertiesAuditedTest.java b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/interfaces/hbm/propertiesAudited/AbstractPropertiesAuditedTest.java index 6889fe0dca..f85c393403 100644 --- a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/interfaces/hbm/propertiesAudited/AbstractPropertiesAuditedTest.java +++ b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/interfaces/hbm/propertiesAudited/AbstractPropertiesAuditedTest.java @@ -5,7 +5,7 @@ import org.junit.Test; import org.hibernate.envers.exception.NotAuditedException; -import org.hibernate.envers.test.BaseEnversJPAFunctionalTestCase ; +import org.hibernate.envers.test.BaseEnversJPAFunctionalTestCase; import org.hibernate.envers.test.Priority; /** diff --git a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/jta/JtaExceptionListener.java b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/jta/JtaExceptionListener.java index 720d6dcd3b..643f41bf35 100644 --- a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/jta/JtaExceptionListener.java +++ b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/jta/JtaExceptionListener.java @@ -34,7 +34,6 @@ import org.hibernate.envers.test.Priority; import org.hibernate.envers.test.entities.StrTestEntity; import org.hibernate.envers.test.integration.reventity.ExceptionListenerRevEntity; - import org.hibernate.testing.jta.TestingJtaBootstrap; import org.hibernate.testing.jta.TestingJtaPlatformImpl; diff --git a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/jta/JtaTransaction.java b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/jta/JtaTransaction.java index 67f87c50b8..529749f7b7 100644 --- a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/jta/JtaTransaction.java +++ b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/jta/JtaTransaction.java @@ -2,16 +2,16 @@ import java.util.List; import java.util.Map; - import javax.persistence.EntityManager; +import org.junit.Assert; +import org.junit.Test; + import org.hibernate.envers.test.BaseEnversJPAFunctionalTestCase; import org.hibernate.envers.test.Priority; import org.hibernate.envers.test.entities.IntTestEntity; import org.hibernate.testing.jta.TestingJtaBootstrap; import org.hibernate.testing.jta.TestingJtaPlatformImpl; -import org.junit.Assert; -import org.junit.Test; /** * Same as {@link org.hibernate.envers.test.integration.basic.Simple}, but in a JTA environment. diff --git a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/manytomany/BasicSet.java b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/manytomany/BasicSet.java index 0a8d2e82fc..0355e817e4 100644 --- a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/manytomany/BasicSet.java +++ b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/manytomany/BasicSet.java @@ -30,7 +30,7 @@ import org.junit.Test; -import org.hibernate.envers.test.BaseEnversJPAFunctionalTestCase ; +import org.hibernate.envers.test.BaseEnversJPAFunctionalTestCase; import org.hibernate.envers.test.Priority; import org.hibernate.envers.test.entities.manytomany.SetOwnedEntity; import org.hibernate.envers.test.entities.manytomany.SetOwningEntity; diff --git a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/manytomany/inverseToSuperclass/ManyToManyInverseToSuperclassTest.java b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/manytomany/inverseToSuperclass/ManyToManyInverseToSuperclassTest.java index f1dfac71d5..16deaf5b4f 100644 --- a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/manytomany/inverseToSuperclass/ManyToManyInverseToSuperclassTest.java +++ b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/manytomany/inverseToSuperclass/ManyToManyInverseToSuperclassTest.java @@ -1,13 +1,13 @@ package org.hibernate.envers.test.integration.manytomany.inverseToSuperclass; -import javax.persistence.EntityManager; import java.util.ArrayList; +import javax.persistence.EntityManager; + +import org.junit.Test; import org.hibernate.envers.test.BaseEnversJPAFunctionalTestCase; import org.hibernate.envers.test.Priority; -import org.junit.Test; - /** * @author Hern�n Chanfreau * diff --git a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/manytomany/sametable/BasicSametable.java b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/manytomany/sametable/BasicSametable.java index 32f3f74c02..df91a972f9 100644 --- a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/manytomany/sametable/BasicSametable.java +++ b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/manytomany/sametable/BasicSametable.java @@ -31,7 +31,7 @@ import org.junit.Test; import org.hibernate.Session; -import org.hibernate.envers.test.BaseEnversJPAFunctionalTestCase ; +import org.hibernate.envers.test.BaseEnversJPAFunctionalTestCase; import org.hibernate.envers.test.Priority; import org.hibernate.envers.test.entities.manytomany.sametable.Child1Entity; import org.hibernate.envers.test.entities.manytomany.sametable.Child2Entity; diff --git a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/merge/AddDelTest.java b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/merge/AddDelTest.java index 57f464138e..fc0530472e 100644 --- a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/merge/AddDelTest.java +++ b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/merge/AddDelTest.java @@ -2,10 +2,10 @@ import java.util.Arrays; -import org.hibernate.Session; import org.junit.Assert; import org.junit.Test; +import org.hibernate.Session; import org.hibernate.envers.test.BaseEnversFunctionalTestCase; import org.hibernate.envers.test.Priority; import org.hibernate.envers.test.entities.StrTestEntity; diff --git a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/modifiedflags/AbstractModifiedFlagsEntityTest.java b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/modifiedflags/AbstractModifiedFlagsEntityTest.java index 801c06d9b4..59998f8ad5 100644 --- a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/modifiedflags/AbstractModifiedFlagsEntityTest.java +++ b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/modifiedflags/AbstractModifiedFlagsEntityTest.java @@ -26,7 +26,7 @@ import java.util.List; import java.util.Map; -import org.hibernate.envers.configuration.GlobalConfiguration; +import org.hibernate.envers.configuration.EnversSettings; import org.hibernate.envers.query.AuditEntity; import org.hibernate.envers.query.AuditQuery; import org.hibernate.envers.test.BaseEnversJPAFunctionalTestCase; @@ -41,7 +41,7 @@ public abstract class AbstractModifiedFlagsEntityTest extends BaseEnversJPAFunct protected void addConfigOptions(Map options) { super.addConfigOptions(options); if (forceModifiedFlags()) { - options.put(GlobalConfiguration.GLOBAL_WITH_MODIFIED_FLAG_PROPERTY, "true"); + options.put(EnversSettings.GLOBAL_WITH_MODIFIED_FLAG, "true"); } } diff --git a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/modifiedflags/AbstractModifiedFlagsOneSessionTest.java b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/modifiedflags/AbstractModifiedFlagsOneSessionTest.java index 5a606bd154..48372fbead 100644 --- a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/modifiedflags/AbstractModifiedFlagsOneSessionTest.java +++ b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/modifiedflags/AbstractModifiedFlagsOneSessionTest.java @@ -24,7 +24,7 @@ package org.hibernate.envers.test.integration.modifiedflags; import org.hibernate.cfg.Configuration; -import org.hibernate.envers.configuration.GlobalConfiguration; +import org.hibernate.envers.configuration.EnversSettings; import org.hibernate.envers.test.AbstractOneSessionTest; /** @@ -39,8 +39,7 @@ public abstract class AbstractModifiedFlagsOneSessionTest extends protected void addProperties(Configuration configuration) { super.addProperties(configuration); if (forceModifiedFlags()) { - configuration.setProperty( - GlobalConfiguration.GLOBAL_WITH_MODIFIED_FLAG_PROPERTY, "true"); + configuration.setProperty(EnversSettings.GLOBAL_WITH_MODIFIED_FLAG, "true"); } } diff --git a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/modifiedflags/HasChangedComponentCollection.java b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/modifiedflags/HasChangedComponentCollection.java index cfb4953b00..29de8400cd 100644 --- a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/modifiedflags/HasChangedComponentCollection.java +++ b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/modifiedflags/HasChangedComponentCollection.java @@ -11,9 +11,9 @@ import org.hibernate.envers.test.entities.components.Component4; import org.hibernate.testing.TestForIssue; -import static org.junit.Assert.assertEquals; import static org.hibernate.envers.test.tools.TestTools.extractRevisionNumbers; import static org.hibernate.envers.test.tools.TestTools.makeList; +import static org.junit.Assert.assertEquals; /** * @author Lukasz Antoniak (lukasz dot antoniak at gmail dot com) diff --git a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/modifiedflags/HasChangedDetachedMultipleCollection.java b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/modifiedflags/HasChangedDetachedMultipleCollection.java index 05602fba00..7c6036b562 100644 --- a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/modifiedflags/HasChangedDetachedMultipleCollection.java +++ b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/modifiedflags/HasChangedDetachedMultipleCollection.java @@ -14,9 +14,9 @@ import org.hibernate.testing.SkipForDialect; import org.hibernate.testing.TestForIssue; -import static org.junit.Assert.assertEquals; import static org.hibernate.envers.test.tools.TestTools.extractRevisionNumbers; import static org.hibernate.envers.test.tools.TestTools.makeList; +import static org.junit.Assert.assertEquals; /** * @author Lukasz Antoniak (lukasz dot antoniak at gmail dot com) diff --git a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/modifiedflags/ModifiedFlagSuffix.java b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/modifiedflags/ModifiedFlagSuffix.java index d6c005958f..dcef9d8aa5 100644 --- a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/modifiedflags/ModifiedFlagSuffix.java +++ b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/modifiedflags/ModifiedFlagSuffix.java @@ -29,7 +29,7 @@ import org.junit.Test; -import org.hibernate.envers.configuration.GlobalConfiguration; +import org.hibernate.envers.configuration.EnversSettings; import org.hibernate.envers.query.AuditEntity; import org.hibernate.envers.test.Priority; import org.hibernate.envers.test.integration.basic.BasicTestEntity1; @@ -54,7 +54,7 @@ protected Class[] getAnnotatedClasses() { @Override protected void addConfigOptions(Map options) { super.addConfigOptions(options); - options.put(GlobalConfiguration.MODIFIED_FLAG_SUFFIX_PROPERTY, "_CHANGED"); + options.put(EnversSettings.MODIFIED_FLAG_SUFFIX, "_CHANGED"); } private Integer addNewEntity(String str, long lng) { diff --git a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/naming/ids/JoinMulIdNamingRefIngEntity.java b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/naming/ids/JoinMulIdNamingRefIngEntity.java index d9ccfd1aa4..a211b42ba5 100644 --- a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/naming/ids/JoinMulIdNamingRefIngEntity.java +++ b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/naming/ids/JoinMulIdNamingRefIngEntity.java @@ -22,8 +22,8 @@ * Boston, MA 02110-1301 USA */ package org.hibernate.envers.test.integration.naming.ids; + import javax.persistence.Entity; -import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.IdClass; import javax.persistence.JoinColumn; diff --git a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/notupdatable/PropertyNotUpdatableTest.java b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/notupdatable/PropertyNotUpdatableTest.java index 5ef6cbf9fd..e9abc7425c 100644 --- a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/notupdatable/PropertyNotUpdatableTest.java +++ b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/notupdatable/PropertyNotUpdatableTest.java @@ -1,16 +1,17 @@ package org.hibernate.envers.test.integration.notupdatable; -import junit.framework.Assert; - -import org.hibernate.envers.test.BaseEnversJPAFunctionalTestCase; -import org.hibernate.envers.test.Priority; -import org.hibernate.testing.TestForIssue; -import org.junit.Test; - -import javax.persistence.EntityManager; import java.util.Arrays; import java.util.List; import java.util.Map; +import javax.persistence.EntityManager; + +import junit.framework.Assert; +import org.junit.Test; + +import org.hibernate.envers.configuration.EnversSettings; +import org.hibernate.envers.test.BaseEnversJPAFunctionalTestCase; +import org.hibernate.envers.test.Priority; +import org.hibernate.testing.TestForIssue; /** * @author Lukasz Antoniak (lukasz dot antoniak at gmail dot com) @@ -21,7 +22,7 @@ public class PropertyNotUpdatableTest extends BaseEnversJPAFunctionalTestCase { @Override protected void addConfigOptions(Map options) { - options.put("org.hibernate.envers.store_data_at_delete", "true"); + options.put(EnversSettings.STORE_DATA_AT_DELETE, "true"); } @Override diff --git a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/onetomany/BasicList.java b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/onetomany/BasicList.java index f1935f0c11..e2ae66a345 100644 --- a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/onetomany/BasicList.java +++ b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/onetomany/BasicList.java @@ -28,7 +28,7 @@ import org.junit.Test; -import org.hibernate.envers.test.BaseEnversJPAFunctionalTestCase ; +import org.hibernate.envers.test.BaseEnversJPAFunctionalTestCase; import org.hibernate.envers.test.Priority; import org.hibernate.envers.test.entities.onetomany.ListRefEdEntity; import org.hibernate.envers.test.entities.onetomany.ListRefIngEntity; diff --git a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/onetomany/detached/DataChangesDetachedSet.java b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/onetomany/detached/DataChangesDetachedSet.java index 34abc270a0..0f7645de26 100644 --- a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/onetomany/detached/DataChangesDetachedSet.java +++ b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/onetomany/detached/DataChangesDetachedSet.java @@ -29,7 +29,7 @@ import org.junit.Test; -import org.hibernate.envers.test.BaseEnversJPAFunctionalTestCase ; +import org.hibernate.envers.test.BaseEnversJPAFunctionalTestCase; import org.hibernate.envers.test.Priority; import org.hibernate.envers.test.entities.StrTestEntity; import org.hibernate.envers.test.entities.onetomany.detached.SetRefCollEntity; diff --git a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/onetomany/embeddedid/Constant.java b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/onetomany/embeddedid/Constant.java index 14ed0b0665..9db330a594 100644 --- a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/onetomany/embeddedid/Constant.java +++ b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/onetomany/embeddedid/Constant.java @@ -1,11 +1,11 @@ package org.hibernate.envers.test.integration.onetomany.embeddedid; -import org.hibernate.envers.Audited; - +import java.io.Serializable; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Id; -import java.io.Serializable; + +import org.hibernate.envers.Audited; /** * @author Lukasz Antoniak (lukasz dot antoniak at gmail dot com) diff --git a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/onetomany/embeddedid/MapsIdTest.java b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/onetomany/embeddedid/MapsIdTest.java index b5964d4fd0..a785b53263 100644 --- a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/onetomany/embeddedid/MapsIdTest.java +++ b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/onetomany/embeddedid/MapsIdTest.java @@ -1,15 +1,14 @@ package org.hibernate.envers.test.integration.onetomany.embeddedid; +import java.util.Arrays; import javax.persistence.EntityManager; -import org.hibernate.envers.test.Priority; -import org.hibernate.testing.TestForIssue; import org.junit.Assert; import org.junit.Test; import org.hibernate.envers.test.BaseEnversJPAFunctionalTestCase; - -import java.util.Arrays; +import org.hibernate.envers.test.Priority; +import org.hibernate.testing.TestForIssue; /** * @author Lukasz Antoniak (lukasz dot antoniak at gmail dot com) diff --git a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/onetomany/embeddedid/Person.java b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/onetomany/embeddedid/Person.java index f38fea9ee8..5c834a651d 100644 --- a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/onetomany/embeddedid/Person.java +++ b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/onetomany/embeddedid/Person.java @@ -1,11 +1,14 @@ package org.hibernate.envers.test.integration.onetomany.embeddedid; -import org.hibernate.envers.Audited; - -import javax.persistence.*; import java.io.Serializable; import java.util.HashSet; import java.util.Set; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.OneToMany; + +import org.hibernate.envers.Audited; /** * @author Lukasz Antoniak (lukasz dot antoniak at gmail dot com) diff --git a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/onetomany/embeddedid/PersonTuple.java b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/onetomany/embeddedid/PersonTuple.java index 4305a52c3f..0767999040 100644 --- a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/onetomany/embeddedid/PersonTuple.java +++ b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/onetomany/embeddedid/PersonTuple.java @@ -1,9 +1,15 @@ package org.hibernate.envers.test.integration.onetomany.embeddedid; -import org.hibernate.envers.Audited; - -import javax.persistence.*; import java.io.Serializable; +import javax.persistence.Column; +import javax.persistence.Embeddable; +import javax.persistence.EmbeddedId; +import javax.persistence.Entity; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.MapsId; + +import org.hibernate.envers.Audited; /** * @author Lukasz Antoniak (lukasz dot antoniak at gmail dot com) diff --git a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/onetomany/inverseToSuperclass/OneToManyInverseToSuperclassTest.java b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/onetomany/inverseToSuperclass/OneToManyInverseToSuperclassTest.java index 5c3f401797..0097db671b 100644 --- a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/onetomany/inverseToSuperclass/OneToManyInverseToSuperclassTest.java +++ b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/onetomany/inverseToSuperclass/OneToManyInverseToSuperclassTest.java @@ -1,13 +1,13 @@ package org.hibernate.envers.test.integration.onetomany.inverseToSuperclass; -import javax.persistence.EntityManager; import java.util.ArrayList; +import javax.persistence.EntityManager; + +import org.junit.Test; import org.hibernate.envers.test.BaseEnversJPAFunctionalTestCase; import org.hibernate.envers.test.Priority; -import org.junit.Test; - /** * @author Hern�n Chanfreau * diff --git a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/properties/UnversionedOptimisticLockingField.java b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/properties/UnversionedOptimisticLockingField.java index 767c85face..eef446a43d 100644 --- a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/properties/UnversionedOptimisticLockingField.java +++ b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/properties/UnversionedOptimisticLockingField.java @@ -30,6 +30,7 @@ import org.junit.Test; +import org.hibernate.envers.configuration.EnversSettings; import org.hibernate.envers.test.BaseEnversJPAFunctionalTestCase; import org.hibernate.envers.test.Priority; import org.hibernate.mapping.PersistentClass; @@ -44,14 +45,12 @@ public class UnversionedOptimisticLockingField extends BaseEnversJPAFunctionalTe @Override protected Class[] getAnnotatedClasses() { return new Class[] { UnversionedOptimisticLockingFieldEntity.class }; - } @Override public void addConfigOptions(Map configuration) { super.addConfigOptions( configuration ); - configuration.put("org.hibernate.envers.doNotAuditOptimisticLockingField", "true"); - + configuration.put(EnversSettings.DO_NOT_AUDIT_OPTIMISTIC_LOCKING_FIELD, "true"); } @Test diff --git a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/properties/VersionsProperties.java b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/properties/VersionsProperties.java index 8d9ac6fba3..92c51d991a 100644 --- a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/properties/VersionsProperties.java +++ b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/properties/VersionsProperties.java @@ -29,6 +29,7 @@ import org.junit.Test; +import org.hibernate.envers.configuration.EnversSettings; import org.hibernate.envers.test.BaseEnversJPAFunctionalTestCase; import org.hibernate.envers.test.Priority; @@ -46,10 +47,10 @@ protected Class[] getAnnotatedClasses() { @Override protected void addConfigOptions(Map options) { super.addConfigOptions( options ); - options.put("org.hibernate.envers.auditTablePrefix", "VP_"); - options.put("org.hibernate.envers.auditTableSuffix", "_VS"); - options.put("org.hibernate.envers.revisionFieldName", "ver_rev"); - options.put("org.hibernate.envers.revisionTypeFieldName", "ver_rev_type"); + options.put(EnversSettings.AUDIT_TABLE_PREFIX, "VP_"); + options.put(EnversSettings.AUDIT_TABLE_SUFFIX, "_VS"); + options.put(EnversSettings.REVISION_FIELD_NAME, "ver_rev"); + options.put(EnversSettings.REVISION_TYPE_FIELD_NAME, "ver_rev_type"); } @Test diff --git a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/proxy/QueryingWithProxyObjectTest.java b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/proxy/QueryingWithProxyObjectTest.java index 49d435e382..effb0f3958 100644 --- a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/proxy/QueryingWithProxyObjectTest.java +++ b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/proxy/QueryingWithProxyObjectTest.java @@ -1,13 +1,11 @@ package org.hibernate.envers.test.integration.proxy; -import java.net.URISyntaxException; import java.util.Arrays; import java.util.List; import org.junit.Assert; import org.junit.Test; -import org.hibernate.MappingException; import org.hibernate.envers.test.BaseEnversFunctionalTestCase; import org.hibernate.envers.test.Priority; import org.hibernate.envers.test.entities.StrTestEntity; diff --git a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/proxy/RemovedObjectQueryTest.java b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/proxy/RemovedObjectQueryTest.java index 9ff95b3429..0c0a1be181 100644 --- a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/proxy/RemovedObjectQueryTest.java +++ b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/proxy/RemovedObjectQueryTest.java @@ -1,7 +1,15 @@ package org.hibernate.envers.test.integration.proxy; +import java.util.List; +import java.util.Map; +import javax.persistence.EntityManager; + +import org.junit.Assert; +import org.junit.Test; + import org.hibernate.Hibernate; import org.hibernate.envers.RevisionType; +import org.hibernate.envers.configuration.EnversSettings; import org.hibernate.envers.query.AuditEntity; import org.hibernate.envers.query.AuditQuery; import org.hibernate.envers.test.BaseEnversJPAFunctionalTestCase; @@ -11,20 +19,13 @@ import org.hibernate.envers.test.tools.TestTools; import org.hibernate.testing.FailureExpected; import org.hibernate.testing.TestForIssue; -import org.junit.Assert; -import org.junit.Test; - -import java.util.List; -import java.util.Map; - -import javax.persistence.EntityManager; @TestForIssue(jiraKey = "HHH-5845") public class RemovedObjectQueryTest extends BaseEnversJPAFunctionalTestCase { @Override @SuppressWarnings("unchecked") protected void addConfigOptions(Map options) { - options.put("org.hibernate.envers.store_data_at_delete", "true"); + options.put(EnversSettings.STORE_DATA_AT_DELETE, "true"); } @Override diff --git a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/query/CustomRevEntityQuery.java b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/query/CustomRevEntityQuery.java index 6b83d16139..5403661968 100644 --- a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/query/CustomRevEntityQuery.java +++ b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/query/CustomRevEntityQuery.java @@ -26,10 +26,10 @@ import java.util.List; import javax.persistence.EntityManager; -import org.hibernate.envers.test.BaseEnversJPAFunctionalTestCase; import org.junit.Test; import org.hibernate.envers.query.AuditEntity; +import org.hibernate.envers.test.BaseEnversJPAFunctionalTestCase; import org.hibernate.envers.test.Priority; import org.hibernate.envers.test.entities.StrIntTestEntity; import org.hibernate.envers.test.entities.reventity.CustomRevEntity; diff --git a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/query/DeletedEntities.java b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/query/DeletedEntities.java index ea1f3a36f3..88961086c4 100644 --- a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/query/DeletedEntities.java +++ b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/query/DeletedEntities.java @@ -28,8 +28,8 @@ import org.junit.Test; -import org.hibernate.envers.enhanced.SequenceIdRevisionEntity; import org.hibernate.envers.RevisionType; +import org.hibernate.envers.enhanced.SequenceIdRevisionEntity; import org.hibernate.envers.query.AuditEntity; import org.hibernate.envers.test.BaseEnversJPAFunctionalTestCase; import org.hibernate.envers.test.Priority; diff --git a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/query/MaximalizePropertyQuery.java b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/query/MaximalizePropertyQuery.java index 764075cc45..ed80431564 100644 --- a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/query/MaximalizePropertyQuery.java +++ b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/query/MaximalizePropertyQuery.java @@ -27,9 +27,11 @@ import java.util.HashSet; import java.util.List; import java.util.Set; - import javax.persistence.EntityManager; +import org.junit.Assert; +import org.junit.Test; + import org.hibernate.envers.RevisionType; import org.hibernate.envers.enhanced.SequenceIdRevisionEntity; import org.hibernate.envers.query.AuditEntity; @@ -39,9 +41,6 @@ import org.hibernate.envers.test.entities.StrIntTestEntity; import org.hibernate.testing.TestForIssue; -import org.junit.Assert; -import org.junit.Test; - /** * @author Adam Warski (adam at warski dot org) * @author Lukasz Antoniak (lukasz dot antoniak at gmail dot com) diff --git a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/query/RevisionConstraintQuery.java b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/query/RevisionConstraintQuery.java index c0870036fb..e8b361ea3b 100644 --- a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/query/RevisionConstraintQuery.java +++ b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/query/RevisionConstraintQuery.java @@ -28,7 +28,6 @@ import java.util.List; import javax.persistence.EntityManager; -import org.hibernate.envers.test.tools.TestTools; import org.junit.Assert; import org.junit.Test; @@ -37,6 +36,7 @@ import org.hibernate.envers.test.BaseEnversJPAFunctionalTestCase; import org.hibernate.envers.test.Priority; import org.hibernate.envers.test.entities.StrIntTestEntity; +import org.hibernate.envers.test.tools.TestTools; /** * @author Adam Warski (adam at warski dot org) diff --git a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/query/SimpleQuery.java b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/query/SimpleQuery.java index c3515dec45..f74e9667a8 100644 --- a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/query/SimpleQuery.java +++ b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/query/SimpleQuery.java @@ -31,8 +31,8 @@ import org.junit.Assert; import org.junit.Test; -import org.hibernate.envers.enhanced.SequenceIdRevisionEntity; import org.hibernate.envers.RevisionType; +import org.hibernate.envers.enhanced.SequenceIdRevisionEntity; import org.hibernate.envers.query.AuditEntity; import org.hibernate.envers.test.BaseEnversJPAFunctionalTestCase; import org.hibernate.envers.test.Priority; diff --git a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/query/StoreDeletedData.java b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/query/StoreDeletedData.java index 6e9d3763c7..9ba7e07231 100644 --- a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/query/StoreDeletedData.java +++ b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/query/StoreDeletedData.java @@ -32,6 +32,7 @@ import org.junit.Test; import org.hibernate.envers.RevisionType; +import org.hibernate.envers.configuration.EnversSettings; import org.hibernate.envers.enhanced.SequenceIdRevisionEntity; import org.hibernate.envers.query.AuditEntity; import org.hibernate.envers.query.criteria.AuditCriterion; @@ -59,7 +60,7 @@ protected Class[] getAnnotatedClasses() { @Override protected void addConfigOptions(Map options) { super.addConfigOptions( options ); - options.put( "org.hibernate.envers.storeDataAtDelete", "true" ); + options.put( EnversSettings.STORE_DATA_AT_DELETE, "true" ); } @Test diff --git a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/readwriteexpression/ReadWriteExpressionChange.java b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/readwriteexpression/ReadWriteExpressionChange.java index 446a6122d1..d1a6edf212 100644 --- a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/readwriteexpression/ReadWriteExpressionChange.java +++ b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/readwriteexpression/ReadWriteExpressionChange.java @@ -4,10 +4,10 @@ import java.util.List; import javax.persistence.EntityManager; -import org.hibernate.dialect.Oracle8iDialect; import org.junit.Assert; import org.junit.Test; +import org.hibernate.dialect.Oracle8iDialect; import org.hibernate.envers.test.BaseEnversJPAFunctionalTestCase; import org.hibernate.envers.test.Priority; diff --git a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/reventity/DifferentDBSchemaTest.java b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/reventity/DifferentDBSchemaTest.java index 32a1ea6b88..4fb540ad74 100644 --- a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/reventity/DifferentDBSchemaTest.java +++ b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/reventity/DifferentDBSchemaTest.java @@ -8,6 +8,7 @@ import org.hibernate.cfg.Environment; import org.hibernate.dialect.H2Dialect; +import org.hibernate.envers.configuration.EnversSettings; import org.hibernate.envers.test.BaseEnversJPAFunctionalTestCase; import org.hibernate.envers.test.Priority; import org.hibernate.envers.test.entities.StrTestEntity; @@ -29,7 +30,7 @@ protected void addConfigOptions(Map options) { super.addConfigOptions(options); // Creates new schema after establishing connection options.putAll(Environment.getProperties()); - options.put("org.hibernate.envers.default_schema", SCHEMA_NAME); + options.put(EnversSettings.DEFAULT_SCHEMA, SCHEMA_NAME); } @Override diff --git a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/reventity/GloballyConfiguredRevListenerTest.java b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/reventity/GloballyConfiguredRevListenerTest.java index 1630895f08..00acda9ede 100644 --- a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/reventity/GloballyConfiguredRevListenerTest.java +++ b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/reventity/GloballyConfiguredRevListenerTest.java @@ -6,6 +6,7 @@ import org.junit.Assert; import org.junit.Test; +import org.hibernate.envers.configuration.EnversSettings; import org.hibernate.envers.test.BaseEnversJPAFunctionalTestCase; import org.hibernate.envers.test.Priority; import org.hibernate.envers.test.entities.StrTestEntity; @@ -24,7 +25,7 @@ protected Class[] getAnnotatedClasses() { @Override protected void addConfigOptions(Map options) { super.addConfigOptions( options ); - options.put("org.hibernate.envers.revision_listener", "org.hibernate.envers.test.integration.reventity.CountingRevisionListener"); + options.put(EnversSettings.REVISION_LISTENER, CountingRevisionListener.class.getName()); } @Test diff --git a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/reventity/InheritedRevEntity.java b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/reventity/InheritedRevEntity.java index 285b705dea..a356408c48 100644 --- a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/reventity/InheritedRevEntity.java +++ b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/reventity/InheritedRevEntity.java @@ -22,10 +22,11 @@ * Boston, MA 02110-1301 USA */ package org.hibernate.envers.test.integration.reventity; + import javax.persistence.Entity; -import org.hibernate.envers.enhanced.SequenceIdRevisionEntity; import org.hibernate.envers.RevisionEntity; +import org.hibernate.envers.enhanced.SequenceIdRevisionEntity; /** * @author Adam Warski (adam at warski dot org) diff --git a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/reventity/OverrideCustomRevListenerTest.java b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/reventity/OverrideCustomRevListenerTest.java index f992ca2bea..ccaf0f5aea 100644 --- a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/reventity/OverrideCustomRevListenerTest.java +++ b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/reventity/OverrideCustomRevListenerTest.java @@ -1,7 +1,6 @@ package org.hibernate.envers.test.integration.reventity; import org.hibernate.internal.util.collections.ArrayHelper; - import org.hibernate.testing.TestForIssue; /** diff --git a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/reventity/OverrideDefaultRevListenerTest.java b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/reventity/OverrideDefaultRevListenerTest.java index bc7af2ee23..097dd41932 100644 --- a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/reventity/OverrideDefaultRevListenerTest.java +++ b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/reventity/OverrideDefaultRevListenerTest.java @@ -1,7 +1,6 @@ package org.hibernate.envers.test.integration.reventity; import org.hibernate.internal.util.collections.ArrayHelper; - import org.hibernate.testing.TestForIssue; /** diff --git a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/reventity/trackmodifiedentities/AnnotatedTrackingEntitiesTest.java b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/reventity/trackmodifiedentities/AnnotatedTrackingEntitiesTest.java index d772cf1bab..2d1255dcd4 100644 --- a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/reventity/trackmodifiedentities/AnnotatedTrackingEntitiesTest.java +++ b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/reventity/trackmodifiedentities/AnnotatedTrackingEntitiesTest.java @@ -3,6 +3,7 @@ import java.util.Map; import org.hibernate.envers.ModifiedEntityNames; +import org.hibernate.envers.configuration.EnversSettings; import org.hibernate.envers.test.entities.reventity.trackmodifiedentities.AnnotatedTrackingRevisionEntity; import org.hibernate.internal.util.collections.ArrayHelper; @@ -19,6 +20,6 @@ protected Class[] getAnnotatedClasses() { @Override public void addConfigOptions(Map configuration) { super.addConfigOptions( configuration ); - configuration.put("org.hibernate.envers.track_entities_changed_in_revision", "false"); + configuration.put(EnversSettings.TRACK_ENTITIES_CHANGED_IN_REVISION, "false"); } } diff --git a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/reventity/trackmodifiedentities/DefaultTrackingEntitiesTest.java b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/reventity/trackmodifiedentities/DefaultTrackingEntitiesTest.java index ed0669ef75..3865b63b90 100644 --- a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/reventity/trackmodifiedentities/DefaultTrackingEntitiesTest.java +++ b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/reventity/trackmodifiedentities/DefaultTrackingEntitiesTest.java @@ -9,6 +9,7 @@ import org.hibernate.envers.CrossTypeRevisionChangesReader; import org.hibernate.envers.RevisionType; +import org.hibernate.envers.configuration.EnversSettings; import org.hibernate.envers.test.BaseEnversJPAFunctionalTestCase; import org.hibernate.envers.test.Priority; import org.hibernate.envers.test.entities.StrIntTestEntity; @@ -36,7 +37,7 @@ protected Class[] getAnnotatedClasses() { @Override public void addConfigOptions(Map configuration) { super.addConfigOptions( configuration ); - configuration.put("org.hibernate.envers.track_entities_changed_in_revision", "true"); + configuration.put(EnversSettings.TRACK_ENTITIES_CHANGED_IN_REVISION, "true"); } @Test diff --git a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/reventity/trackmodifiedentities/EntityNamesTest.java b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/reventity/trackmodifiedentities/EntityNamesTest.java index ea326bf556..1f9c245d9c 100644 --- a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/reventity/trackmodifiedentities/EntityNamesTest.java +++ b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/reventity/trackmodifiedentities/EntityNamesTest.java @@ -1,16 +1,18 @@ package org.hibernate.envers.test.integration.reventity.trackmodifiedentities; +import java.util.ArrayList; +import java.util.List; + +import org.junit.Test; + import org.hibernate.cfg.Configuration; +import org.hibernate.envers.configuration.EnversSettings; import org.hibernate.envers.test.BaseEnversFunctionalTestCase; import org.hibernate.envers.test.Priority; import org.hibernate.envers.test.integration.entityNames.manyToManyAudited.Car; import org.hibernate.envers.test.integration.entityNames.manyToManyAudited.Person; import org.hibernate.envers.test.tools.TestTools; import org.hibernate.envers.tools.Pair; -import org.junit.Test; - -import java.util.ArrayList; -import java.util.List; /** * @author Lukasz Antoniak (lukasz dot antoniak at gmail dot com) @@ -23,7 +25,7 @@ protected String[] getMappings() { @Override protected void configure(Configuration configuration) { - configuration.setProperty("org.hibernate.envers.track_entities_changed_in_revision", "true"); + configuration.setProperty(EnversSettings.TRACK_ENTITIES_CHANGED_IN_REVISION, "true"); } @Test diff --git a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/reventity/trackmodifiedentities/ExtendedRevisionEntityTest.java b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/reventity/trackmodifiedentities/ExtendedRevisionEntityTest.java index 101a96afb2..39f3385e9b 100644 --- a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/reventity/trackmodifiedentities/ExtendedRevisionEntityTest.java +++ b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/reventity/trackmodifiedentities/ExtendedRevisionEntityTest.java @@ -6,6 +6,7 @@ import org.junit.Test; import org.hibernate.envers.DefaultTrackingModifiedEntitiesRevisionEntity; +import org.hibernate.envers.configuration.EnversSettings; import org.hibernate.envers.test.entities.reventity.trackmodifiedentities.ExtendedRevisionEntity; import org.hibernate.envers.test.entities.reventity.trackmodifiedentities.ExtendedRevisionListener; import org.hibernate.internal.util.collections.ArrayHelper; @@ -23,7 +24,7 @@ protected Class[] getAnnotatedClasses() { @Override public void addConfigOptions(Map configuration) { super.addConfigOptions(configuration); - configuration.put("org.hibernate.envers.track_entities_changed_in_revision", "false"); + configuration.put(EnversSettings.TRACK_ENTITIES_CHANGED_IN_REVISION, "false"); } @Test diff --git a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/reventity/trackmodifiedentities/TrackingEntitiesMultipleChangesTest.java b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/reventity/trackmodifiedentities/TrackingEntitiesMultipleChangesTest.java index 32a2d900d5..59f947b103 100644 --- a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/reventity/trackmodifiedentities/TrackingEntitiesMultipleChangesTest.java +++ b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/reventity/trackmodifiedentities/TrackingEntitiesMultipleChangesTest.java @@ -8,6 +8,7 @@ import org.junit.Test; import org.hibernate.envers.CrossTypeRevisionChangesReader; +import org.hibernate.envers.configuration.EnversSettings; import org.hibernate.envers.test.BaseEnversJPAFunctionalTestCase; import org.hibernate.envers.test.Priority; import org.hibernate.envers.test.entities.StrTestEntity; @@ -28,7 +29,7 @@ protected Class[] getAnnotatedClasses() { @Override protected void addConfigOptions(Map options) { super.addConfigOptions( options ); - options.put( "org.hibernate.envers.track_entities_changed_in_revision", "true" ) ; + options.put( EnversSettings.TRACK_ENTITIES_CHANGED_IN_REVISION, "true" ) ; } @Test diff --git a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/strategy/ValidityAuditStrategyManyToManyTest.java b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/strategy/ValidityAuditStrategyManyToManyTest.java index e9358313a4..2e96ea9a7f 100644 --- a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/strategy/ValidityAuditStrategyManyToManyTest.java +++ b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/strategy/ValidityAuditStrategyManyToManyTest.java @@ -7,6 +7,7 @@ import org.junit.Test; +import org.hibernate.envers.configuration.EnversSettings; import org.hibernate.envers.test.BaseEnversJPAFunctionalTestCase; import org.hibernate.envers.test.Priority; import org.hibernate.envers.test.entities.manytomany.SetOwnedEntity; @@ -36,7 +37,7 @@ protected Class[] getAnnotatedClasses() { @Override protected void addConfigOptions(Map options) { - options.put("org.hibernate.envers.audit_strategy", "org.hibernate.envers.strategy.ValidityAuditStrategy"); + options.put(EnversSettings.AUDIT_STRATEGY, "org.hibernate.envers.strategy.ValidityAuditStrategy"); } @Test diff --git a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/strategy/ValidityAuditStrategyRevEndTestCustomRevEnt.java b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/strategy/ValidityAuditStrategyRevEndTestCustomRevEnt.java index 21526d4b84..d0d6007575 100644 --- a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/strategy/ValidityAuditStrategyRevEndTestCustomRevEnt.java +++ b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/strategy/ValidityAuditStrategyRevEndTestCustomRevEnt.java @@ -36,6 +36,7 @@ import org.junit.Test; import org.hibernate.Session; +import org.hibernate.envers.configuration.EnversSettings; import org.hibernate.envers.strategy.ValidityAuditStrategy; import org.hibernate.envers.test.BaseEnversJPAFunctionalTestCase; import org.hibernate.envers.test.Priority; @@ -75,9 +76,9 @@ protected Class[] getAnnotatedClasses() { @Override protected void addConfigOptions(Map options) { super.addConfigOptions( options ); - options.put("org.hibernate.envers.audit_strategy", "org.hibernate.envers.strategy.ValidityAuditStrategy"); - options.put("org.hibernate.envers.audit_strategy_validity_store_revend_timestamp", "true"); - options.put("org.hibernate.envers.audit_strategy_validity_revend_timestamp_field_name", revendTimestampColumName); + options.put(EnversSettings.AUDIT_STRATEGY, "org.hibernate.envers.strategy.ValidityAuditStrategy"); + options.put(EnversSettings.AUDIT_STRATEGY_VALIDITY_STORE_REVEND_TIMESTAMP, "true"); + options.put(EnversSettings.AUDIT_STRATEGY_VALIDITY_REVEND_TIMESTAMP_FIELD_NAME, revendTimestampColumName); } @Test diff --git a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/strategy/ValidityAuditStrategyRevEndTsTest.java b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/strategy/ValidityAuditStrategyRevEndTsTest.java index cb7bb7d462..6c79992434 100644 --- a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/strategy/ValidityAuditStrategyRevEndTsTest.java +++ b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/strategy/ValidityAuditStrategyRevEndTsTest.java @@ -39,6 +39,7 @@ import org.hibernate.Session; import org.hibernate.dialect.MySQL5Dialect; import org.hibernate.dialect.SybaseASE15Dialect; +import org.hibernate.envers.configuration.EnversSettings; import org.hibernate.envers.enhanced.SequenceIdRevisionEntity; import org.hibernate.envers.strategy.ValidityAuditStrategy; import org.hibernate.envers.test.BaseEnversJPAFunctionalTestCase; @@ -73,9 +74,9 @@ protected Class[] getAnnotatedClasses() { @Override protected void addConfigOptions(Map options) { super.addConfigOptions( options ); - options.put("org.hibernate.envers.audit_strategy", "org.hibernate.envers.strategy.ValidityAuditStrategy"); - options.put("org.hibernate.envers.audit_strategy_validity_store_revend_timestamp", "true"); - options.put("org.hibernate.envers.audit_strategy_validity_revend_timestamp_field_name", revendTimestampColumName); + options.put(EnversSettings.AUDIT_STRATEGY, "org.hibernate.envers.strategy.ValidityAuditStrategy"); + options.put(EnversSettings.AUDIT_STRATEGY_VALIDITY_STORE_REVEND_TIMESTAMP, "true"); + options.put(EnversSettings.AUDIT_STRATEGY_VALIDITY_REVEND_TIMESTAMP_FIELD_NAME, revendTimestampColumName); } @Test diff --git a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/tools/SchemaExportTest.java b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/tools/SchemaExportTest.java index 5b9a1476b4..130eea54a4 100644 --- a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/tools/SchemaExportTest.java +++ b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/tools/SchemaExportTest.java @@ -1,15 +1,16 @@ package org.hibernate.envers.test.integration.tools; +import java.util.Arrays; + +import org.junit.Assert; +import org.junit.Test; + import org.hibernate.Session; import org.hibernate.envers.test.BaseEnversFunctionalTestCase; import org.hibernate.envers.test.Priority; import org.hibernate.envers.test.entities.StrTestEntity; +import org.hibernate.envers.tools.hbm2ddl.EnversSchemaGenerator; import org.hibernate.testing.TestForIssue; -import org.hibernate.tool.EnversSchemaGenerator; -import org.junit.Assert; -import org.junit.Test; - -import java.util.Arrays; /** * @author Lukasz Antoniak (lukasz dot antoniak at gmail dot com) diff --git a/hibernate-envers/src/test/java/org/hibernate/envers/test/performance/AbstractEntityManagerTest.java b/hibernate-envers/src/test/java/org/hibernate/envers/test/performance/AbstractEntityManagerTest.java index 1f823d2254..d388dc9ecf 100644 --- a/hibernate-envers/src/test/java/org/hibernate/envers/test/performance/AbstractEntityManagerTest.java +++ b/hibernate-envers/src/test/java/org/hibernate/envers/test/performance/AbstractEntityManagerTest.java @@ -28,21 +28,22 @@ import java.util.Properties; import javax.persistence.EntityManager; -import org.hibernate.boot.registry.BootstrapServiceRegistryBuilder; -import org.hibernate.jpa.test.PersistenceUnitDescriptorAdapter; -import org.hibernate.envers.test.AbstractEnversTest; import org.junit.Before; +import org.hibernate.boot.registry.BootstrapServiceRegistryBuilder; +import org.hibernate.boot.registry.internal.StandardServiceRegistryImpl; import org.hibernate.cfg.Environment; import org.hibernate.dialect.Dialect; +import org.hibernate.envers.AuditReader; +import org.hibernate.envers.AuditReaderFactory; +import org.hibernate.envers.configuration.EnversSettings; +import org.hibernate.envers.event.spi.EnversIntegrator; +import org.hibernate.envers.test.AbstractEnversTest; import org.hibernate.jpa.AvailableSettings; import org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl; import org.hibernate.jpa.boot.spi.Bootstrap; import org.hibernate.jpa.internal.EntityManagerFactoryImpl; -import org.hibernate.envers.AuditReader; -import org.hibernate.envers.AuditReaderFactory; -import org.hibernate.envers.event.EnversIntegrator; -import org.hibernate.boot.registry.internal.StandardServiceRegistryImpl; +import org.hibernate.jpa.test.PersistenceUnitDescriptorAdapter; import org.hibernate.testing.AfterClassOnce; import org.hibernate.testing.BeforeClassOnce; @@ -96,12 +97,12 @@ protected void init(boolean audited, String auditStrategy) throws IOException { Properties configurationProperties = new Properties(); configurationProperties.putAll( Environment.getProperties() ); if (!audited) { - configurationProperties.setProperty(EnversIntegrator.AUTO_REGISTER, "false"); + configurationProperties.setProperty( EnversIntegrator.AUTO_REGISTER, "false"); } if ( createSchema() ) { configurationProperties.setProperty( Environment.HBM2DDL_AUTO, "create-drop" ); configurationProperties.setProperty( Environment.USE_NEW_ID_GENERATOR_MAPPINGS, "true" ); - configurationProperties.setProperty("org.hibernate.envers.use_revision_entity_with_native_id", "false"); + configurationProperties.setProperty( EnversSettings.USE_REVISION_ENTITY_WITH_NATIVE_ID, "false" ); } if (auditStrategy != null && !"".equals(auditStrategy)) { configurationProperties.setProperty("org.hibernate.envers.audit_strategy", auditStrategy); diff --git a/hibernate-envers/src/test/java/org/hibernate/envers/test/tools/TestTools.java b/hibernate-envers/src/test/java/org/hibernate/envers/test/tools/TestTools.java index ae3dfcd492..1e1e6108e2 100644 --- a/hibernate-envers/src/test/java/org/hibernate/envers/test/tools/TestTools.java +++ b/hibernate-envers/src/test/java/org/hibernate/envers/test/tools/TestTools.java @@ -33,7 +33,6 @@ import java.util.Set; import org.hibernate.envers.enhanced.SequenceIdRevisionEntity; -import org.hibernate.envers.configuration.GlobalConfiguration; import org.hibernate.mapping.PersistentClass; import org.hibernate.mapping.Property; @@ -41,70 +40,61 @@ * @author Adam Warski (adam at warski dot org) */ public class TestTools { - public static Set makeSet(T... objects) { - Set ret = new HashSet(); - //noinspection ManualArrayToCollectionCopy - for (T o : objects) { - ret.add(o); - } + public static Set makeSet(T... objects) { + final Set ret = new HashSet(); + //noinspection ManualArrayToCollectionCopy + for ( T o : objects ) { + ret.add( o ); + } + return ret; + } - return ret; - } + public static List makeList(T... objects) { + return Arrays.asList( objects ); + } - public static List makeList(T... objects) { - return Arrays.asList(objects); - } + public static Map makeMap(Object... objects) { + final Map ret = new HashMap(); + // The number of objects must be divisable by 2. + //noinspection ManualArrayToCollectionCopy + for ( int i = 0; i < objects.length; i += 2 ) { + ret.put( objects[i], objects[i + 1] ); + } + return ret; + } - public static Map makeMap(Object... objects) { - Map ret = new HashMap(); - // The number of objects must be divisable by 2. - //noinspection ManualArrayToCollectionCopy - for (int i=0; i boolean checkList(List list, T... objects) { - if (list.size() != objects.length) { - return false; - } - - for (T obj : objects) { - if (!list.contains(obj)) { - return false; - } - } - - return true; - } + public static boolean checkList(List list, T... objects) { + if ( list.size() != objects.length ) { + return false; + } + for ( T obj : objects ) { + if ( !list.contains( obj ) ) { + return false; + } + } + return true; + } public static List extractRevisionNumbers(List queryResults) { - List result = new ArrayList(); - for (Object queryResult : queryResults) { - result.add(((SequenceIdRevisionEntity) ((Object[]) queryResult)[1]) - .getId()); + final List result = new ArrayList(); + for ( Object queryResult : queryResults ) { + result.add( ( (SequenceIdRevisionEntity) ( (Object[]) queryResult )[1] ).getId() ); } return result; } - public static Set extractModProperties( - PersistentClass persistentClass) { - return extractModProperties(persistentClass, - GlobalConfiguration.DEFAULT_MODIFIED_FLAG_SUFFIX); + public static Set extractModProperties(PersistentClass persistentClass) { + return extractModProperties( persistentClass, "_MOD" ); } - public static Set extractModProperties( - PersistentClass persistentClass, String suffix) { - Set result = new HashSet(); - Iterator iterator = persistentClass.getPropertyIterator(); - - while (iterator.hasNext()) { - Property property = (Property) iterator.next(); - String propertyName = property.getName(); - if (propertyName.endsWith(suffix)) { - result.add(propertyName); + public static Set extractModProperties(PersistentClass persistentClass, String suffix) { + final Set result = new HashSet(); + final Iterator iterator = persistentClass.getPropertyIterator(); + while ( iterator.hasNext() ) { + final Property property = (Property) iterator.next(); + final String propertyName = property.getName(); + if ( propertyName.endsWith( suffix ) ) { + result.add( propertyName ); } } return result; From cf921df1d06c684fafd2c0a38949333de3f7ba6b Mon Sep 17 00:00:00 2001 From: Brett Meyer Date: Fri, 5 Apr 2013 12:15:48 -0400 Subject: [PATCH 06/54] HHH-8092 Added comment about unique constraints in schema update. --- .../src/main/java/org/hibernate/cfg/Configuration.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/Configuration.java b/hibernate-core/src/main/java/org/hibernate/cfg/Configuration.java index c62ef69eff..aa8b52fd6f 100644 --- a/hibernate-core/src/main/java/org/hibernate/cfg/Configuration.java +++ b/hibernate-core/src/main/java/org/hibernate/cfg/Configuration.java @@ -1190,7 +1190,9 @@ public String[] generateSchemaUpdateScript(Dialect dialect, DatabaseMetadata dat Iterator uniqueIter = table.getUniqueKeyIterator(); while ( uniqueIter.hasNext() ) { final UniqueKey uniqueKey = (UniqueKey) uniqueIter.next(); - // Skip if index already exists + // Skip if index already exists. Most of the time, this + // won't work since most Dialects use Constraints. However, + // keep it for the few that do use Indexes. if ( tableInfo != null && StringHelper.isNotEmpty( uniqueKey.getName() ) ) { final IndexMetadata meta = tableInfo.getIndexMetadata( uniqueKey.getName() ); if ( meta != null ) { From 38556485fe7c0cd22c1cf2eed229b7c7699eeb90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbyn=C4=9Bk=20Roubal=C3=ADk?= Date: Mon, 8 Apr 2013 17:00:50 +0200 Subject: [PATCH 07/54] HHH-8157 Adding DBAllocator labels for Postgresql 9.2, Postgres Plus 9.2 and IBM DB2 10 --- .../org/hibernate/build/qalab/DatabaseAllocator.groovy | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/buildSrc/src/main/groovy/org/hibernate/build/qalab/DatabaseAllocator.groovy b/buildSrc/src/main/groovy/org/hibernate/build/qalab/DatabaseAllocator.groovy index 0b86ce7b0d..8edb9dc7ff 100644 --- a/buildSrc/src/main/groovy/org/hibernate/build/qalab/DatabaseAllocator.groovy +++ b/buildSrc/src/main/groovy/org/hibernate/build/qalab/DatabaseAllocator.groovy @@ -51,9 +51,10 @@ class DatabaseAllocator { public static def SUPPORTED_DB_NAMES = [ "oracle9i", "oracle10g", "oracle11gR1", "oracle11gR2", "oracle11gR2RAC", "oracle11gR1RAC", - "postgresql82", "postgresql83", "postgresql84", "postgresql91", + "postgresql82", "postgresql83", "postgresql84", "postgresql91", "postgresql92", + "postgresplus92", "mysql50", "mysql51","mysql55", - "db2-91", "db2-97", + "db2-91", "db2-97", "db2-10", "mssql2005", "mssql2008R1", "mssql2008R2", "mssql2012", "sybase155", "sybase157" ]; From e019c2ac19d41fe75afbaf6482f1aa7a73c87485 Mon Sep 17 00:00:00 2001 From: Steve Ebersole Date: Fri, 5 Apr 2013 16:53:29 -0500 Subject: [PATCH 08/54] HHH-8147 - Update to use distribution plugin for createing release bundles --- release/release.gradle | 3 +++ 1 file changed, 3 insertions(+) diff --git a/release/release.gradle b/release/release.gradle index 5e093039a0..ac9de6cd40 100644 --- a/release/release.gradle +++ b/release/release.gradle @@ -182,6 +182,9 @@ distributions { distZip.dependsOn prepareReleaseBundles distTar.dependsOn prepareReleaseBundles +distTar { + compression = Compression.GZIP +} task buildReleaseBundles( dependsOn: [distZip,distTar] ) { description = "Build release bundle in all formats" From 826aa6301fbacb5567fdca05d64f81abd0284b62 Mon Sep 17 00:00:00 2001 From: Steve Ebersole Date: Mon, 8 Apr 2013 14:27:47 -0500 Subject: [PATCH 09/54] HHH-8156 - Apply new Gradle plugins --- build.gradle | 63 ++++++++---- shared/config/checkstyle/checkstyle.xml | 129 ++++++++++++++++++++++++ 2 files changed, 170 insertions(+), 22 deletions(-) create mode 100644 shared/config/checkstyle/checkstyle.xml diff --git a/build.gradle b/build.gradle index b5140f7576..fa641fe643 100644 --- a/build.gradle +++ b/build.gradle @@ -72,8 +72,14 @@ subprojects { subProject -> apply plugin: 'maven' // for install task as well as deploy dependencies apply plugin: 'uploadAuth' apply plugin: 'osgi' + apply from: "../utilities.gradle" + apply plugin: 'findbugs' + apply plugin: 'checkstyle' + apply plugin: 'build-dashboard' + apply plugin: 'project-report' + configurations { provided { // todo : need to make sure these are non-exported @@ -194,33 +200,33 @@ subprojects { subProject -> jar { Set exportPackages = new HashSet() Set privatePackages = new HashSet() - + // TODO: Could more of this be pulled into utilities.gradle? sourceSets.each { sourceSet -> - // skip certain source sets - if ( ! ['test','matrix'].contains( sourceSet.name ) ) { - sourceSet.java.each { javaFile -> - // - org.hibernate.boot.registry.classloading.internal - // until EntityManagerFactoryBuilderImpl no longer imports ClassLoaderServiceImpl - // - .util for external module use (especially envers) - final String[] temporaryExports = [ - 'org.hibernate.boot.registry.classloading.internal', - 'org.hibernate.internal.util' ] + // skip certain source sets + if ( ! ['test','matrix'].contains( sourceSet.name ) ) { + sourceSet.java.each { javaFile -> + // - org.hibernate.boot.registry.classloading.internal + // until EntityManagerFactoryBuilderImpl no longer imports ClassLoaderServiceImpl + // - .util for external module use (especially envers) + final String[] temporaryExports = [ + 'org.hibernate.boot.registry.classloading.internal', + 'org.hibernate.internal.util' ] - final String packageName = determinePackageName( sourceSet.java, javaFile ); - if ( ! temporaryExports.contains( packageName ) - && ( packageName.endsWith( ".internal" ) - || packageName.contains( ".internal." ) - || packageName.endsWith( ".test" ) - || packageName.contains( ".test." ) ) ) { - privatePackages.add( packageName ); - } - else { - exportPackages.add( packageName ); - } - } + final String packageName = determinePackageName( sourceSet.java, javaFile ); + if ( ! temporaryExports.contains( packageName ) + && ( packageName.endsWith( ".internal" ) + || packageName.contains( ".internal." ) + || packageName.endsWith( ".test" ) + || packageName.contains( ".test." ) ) ) { + privatePackages.add( packageName ); + } + else { + exportPackages.add( packageName ); } } + } + } manifest = osgiManifest { // GRADLE-1411: Even if we override Imports and Exports @@ -294,6 +300,19 @@ subprojects { subProject -> } } + // Report configs ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + checkstyle { + configFile = rootProject.file( 'shared/config/checkstyle/checkstyle.xml' ) + showViolations = false + ignoreFailures = true + } + findbugs { + ignoreFailures = true + } + buildDashboard.dependsOn check + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + // elements used to customize the generated POM used during upload def pomConfig = { name 'A Hibernate O/RM Module' diff --git a/shared/config/checkstyle/checkstyle.xml b/shared/config/checkstyle/checkstyle.xml new file mode 100644 index 0000000000..7e74a79d35 --- /dev/null +++ b/shared/config/checkstyle/checkstyle.xml @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 96aa4a623911a7525e6a44a5ec8e83383abd8b5a Mon Sep 17 00:00:00 2001 From: Steve Ebersole Date: Mon, 8 Apr 2013 21:23:51 -0500 Subject: [PATCH 10/54] HHH-8159 - Apply fixups indicated by analysis tools --- .../org/hibernate/AnnotationException.java | 29 ++-- .../java/org/hibernate/AssertionFailure.java | 25 ++- .../org/hibernate/BasicQueryContract.java | 16 +- .../main/java/org/hibernate/CacheMode.java | 37 +++-- .../java/org/hibernate/CallbackException.java | 48 +++--- .../org/hibernate/ConnectionReleaseMode.java | 15 +- .../src/main/java/org/hibernate/Criteria.java | 6 +- .../CustomEntityDirtinessStrategy.java | 4 +- .../hibernate/DuplicateMappingException.java | 50 +++++- .../java/org/hibernate/EmptyInterceptor.java | 68 ++++++--- .../main/java/org/hibernate/EntityMode.java | 10 +- .../main/java/org/hibernate/FetchMode.java | 18 +-- .../main/java/org/hibernate/FlushMode.java | 43 +++++- .../main/java/org/hibernate/Hibernate.java | 46 ++++-- .../org/hibernate/HibernateException.java | 29 +++- .../org/hibernate/IdentifierLoadAccess.java | 2 +- .../org/hibernate/InstantiationException.java | 70 ++++++--- .../main/java/org/hibernate/Interceptor.java | 27 ++-- .../hibernate/InvalidMappingException.java | 78 +++++++++- .../java/org/hibernate/JDBCException.java | 40 ++--- .../LazyInitializationException.java | 28 ++-- .../main/java/org/hibernate/LobHelper.java | 4 +- .../main/java/org/hibernate/LockOptions.java | 28 ++-- .../java/org/hibernate/MappingException.java | 35 +++-- .../hibernate/MappingNotFoundException.java | 41 ++++- .../org/hibernate/MultiTenancyStrategy.java | 16 +- .../org/hibernate/NaturalIdLoadAccess.java | 2 +- .../hibernate/NonUniqueObjectException.java | 60 +++++--- .../hibernate/NonUniqueResultException.java | 14 +- .../java/org/hibernate/NullPrecedence.java | 51 ++++++- .../org/hibernate/ObjectDeletedException.java | 21 ++- .../hibernate/ObjectNotFoundException.java | 17 ++- .../hibernate/OptimisticLockException.java | 11 +- .../hibernate/PersistentObjectException.java | 16 +- .../hibernate/PessimisticLockException.java | 13 +- .../hibernate/PropertyAccessException.java | 24 ++- .../hibernate/PropertyNotFoundException.java | 17 ++- .../org/hibernate/PropertyValueException.java | 38 ++--- .../src/main/java/org/hibernate/Query.java | 143 +++++++++++++----- .../java/org/hibernate/QueryException.java | 65 ++++++-- .../org/hibernate/cfg/Ejb3JoinColumn.java | 2 +- .../hibernate/cfg/RecoverableException.java | 32 ++-- .../hibernate/internal/AbstractQueryImpl.java | 4 +- shared/config/checkstyle/checkstyle.xml | 11 +- 44 files changed, 957 insertions(+), 397 deletions(-) diff --git a/hibernate-core/src/main/java/org/hibernate/AnnotationException.java b/hibernate-core/src/main/java/org/hibernate/AnnotationException.java index d371dc58ca..c5d2dc7176 100644 --- a/hibernate-core/src/main/java/org/hibernate/AnnotationException.java +++ b/hibernate-core/src/main/java/org/hibernate/AnnotationException.java @@ -23,25 +23,30 @@ */ package org.hibernate; - /** * Annotation related exception. - * The EJB3 EG will probably set a generic exception. - * I'll then use this one. + * + * The EJB3 EG will probably set a generic exception. I'll then use this one. * * @author Emmanuel Bernard */ public class AnnotationException extends MappingException { - - public AnnotationException(String msg, Throwable root) { - super( msg, root ); + /** + * Constructs an AnnotationException using the given message and cause. + * + * @param msg The message explaining the reason for the exception. + * @param cause The underlying cause. + */ + public AnnotationException(String msg, Throwable cause) { + super( msg, cause ); } - public AnnotationException(Throwable root) { - super( root ); - } - - public AnnotationException(String s) { - super( s ); + /** + * Constructs an AnnotationException using the given message. + * + * @param msg The message explaining the reason for the exception. + */ + public AnnotationException(String msg) { + super( msg ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/AssertionFailure.java b/hibernate-core/src/main/java/org/hibernate/AssertionFailure.java index cf0ee1a7e7..cc36bccf64 100644 --- a/hibernate-core/src/main/java/org/hibernate/AssertionFailure.java +++ b/hibernate-core/src/main/java/org/hibernate/AssertionFailure.java @@ -33,19 +33,28 @@ * @author Gavin King */ public class AssertionFailure extends RuntimeException { - private static final long serialVersionUID = 1L; private static final CoreMessageLogger LOG = Logger.getMessageLogger(CoreMessageLogger.class, AssertionFailure.class.getName()); - public AssertionFailure( String s ) { - super(s); - LOG.failed(this); + /** + * Creates an instance of AssertionFailure using the given message. + * + * @param message The message explaining the reason for the exception + */ + public AssertionFailure(String message) { + super( message ); + LOG.failed( this ); } - public AssertionFailure( String s, - Throwable t ) { - super(s, t); - LOG.failed(t); + /** + * Creates an instance of AssertionFailure using the given message and underlying cause. + * + * @param message The message explaining the reason for the exception + * @param cause The underlying cause. + */ + public AssertionFailure(String message, Throwable cause) { + super( message, cause ); + LOG.failed( cause ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/BasicQueryContract.java b/hibernate-core/src/main/java/org/hibernate/BasicQueryContract.java index 524299c4ac..97e4b7446a 100644 --- a/hibernate-core/src/main/java/org/hibernate/BasicQueryContract.java +++ b/hibernate-core/src/main/java/org/hibernate/BasicQueryContract.java @@ -47,6 +47,8 @@ public interface BasicQueryContract { * * @param flushMode The new FlushMode to use. * + * @return {@code this}, for method chaining + * * @see #getFlushMode() */ public BasicQueryContract setFlushMode(FlushMode flushMode); @@ -70,6 +72,8 @@ public interface BasicQueryContract { * * @param cacheMode The new CacheMode to use. * + * @return {@code this}, for method chaining + * * @see #getCacheMode() */ public BasicQueryContract setCacheMode(CacheMode cacheMode); @@ -93,6 +97,8 @@ public interface BasicQueryContract { * * @param cacheable Should the query results be cacheable? * + * @return {@code this}, for method chaining + * * @see #isCacheable */ public BasicQueryContract setCacheable(boolean cacheable); @@ -113,6 +119,8 @@ public interface BasicQueryContract { * @param cacheRegion the name of a query cache region, or {@code null} to indicate that the default region * should be used. * + * @return {@code this}, for method chaining + * * @see #getCacheRegion() */ public BasicQueryContract setCacheRegion(String cacheRegion); @@ -136,6 +144,8 @@ public interface BasicQueryContract { * * @param timeout the timeout in seconds * + * @return {@code this}, for method chaining + * * @see #getTimeout() */ public BasicQueryContract setTimeout(int timeout); @@ -160,6 +170,8 @@ public interface BasicQueryContract { * * @param fetchSize the fetch size hint * + * @return {@code this}, for method chaining + * * @see #getFetchSize() */ public BasicQueryContract setFetchSize(int fetchSize); @@ -201,6 +213,8 @@ public interface BasicQueryContract { * The read-only/modifiable setting has no impact on entities/proxies * returned by the query that existed in the session before the query was executed. * + * @return {@code this}, for method chaining + * * @param readOnly true, entities and proxies loaded by the query will be put in read-only mode * false, entities and proxies loaded by the query will be put in modifiable mode */ @@ -211,5 +225,5 @@ public interface BasicQueryContract { * * @return an array of types */ - public Type[] getReturnTypes() throws HibernateException; + public Type[] getReturnTypes(); } diff --git a/hibernate-core/src/main/java/org/hibernate/CacheMode.java b/hibernate-core/src/main/java/org/hibernate/CacheMode.java index 91e8848a01..54ebf079a9 100755 --- a/hibernate-core/src/main/java/org/hibernate/CacheMode.java +++ b/hibernate-core/src/main/java/org/hibernate/CacheMode.java @@ -23,30 +23,26 @@ */ package org.hibernate; -import org.hibernate.tool.hbm2ddl.SchemaExportTask; - /** - * Controls how the session interacts with the second-level - * cache and query cache. + * Controls how the session interacts with the second-level cache and query cache. * * @author Gavin King * @author Strong Liu * @see Session#setCacheMode(CacheMode) */ public enum CacheMode { - /** - * The session may read items from the cache, and add items to the cache + * The session may read items from the cache, and add items to the cache. */ NORMAL( true, true ), /** * The session will never interact with the cache, except to invalidate - * cache items when updates occur + * cache items when updates occur. */ IGNORE( false, false ), /** * The session may read items from the cache, but will not add items, - * except to invalidate items when updates occur + * except to invalidate items when updates occur. */ GET( false, true ), /** @@ -56,9 +52,9 @@ public enum CacheMode { PUT( true, false ), /** * The session will never read items from the cache, but will add items - * to the cache as it reads them from the database. In this mode, the + * to the cache as it reads them from the database. In this mode, the * effect of hibernate.cache.use_minimal_puts is bypassed, in - * order to force a cache refresh + * order to force a cache refresh. */ REFRESH( true, false ); @@ -66,19 +62,38 @@ public enum CacheMode { private final boolean isPutEnabled; private final boolean isGetEnabled; - CacheMode( boolean isPutEnabled, boolean isGetEnabled) { + private CacheMode( boolean isPutEnabled, boolean isGetEnabled) { this.isPutEnabled = isPutEnabled; this.isGetEnabled = isGetEnabled; } + /** + * Does this cache mode indicate that reads are allowed? + * + * @return {@code true} if cache reads are allowed; {@code false} otherwise. + */ public boolean isGetEnabled() { return isGetEnabled; } + /** + * Does this cache mode indicate that writes are allowed? + * + * @return {@code true} if cache writes are allowed; {@code false} otherwise. + */ public boolean isPutEnabled() { return isPutEnabled; } + /** + * Used to interpret externalized forms of this enum. + * + * @param setting The externalized form. + * + * @return The matching enum value. + * + * @throws MappingException Indicates the external form was not recognized as a valid enum value. + */ public static CacheMode interpretExternalSetting(String setting) { if (setting == null) { return null; diff --git a/hibernate-core/src/main/java/org/hibernate/CallbackException.java b/hibernate-core/src/main/java/org/hibernate/CallbackException.java index c28a401f56..325afd0782 100644 --- a/hibernate-core/src/main/java/org/hibernate/CallbackException.java +++ b/hibernate-core/src/main/java/org/hibernate/CallbackException.java @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2008, 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,38 +20,44 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate; - /** - * Should be thrown by persistent objects from Lifecycle - * or Interceptor callbacks. + * Intended to be thrown from {@link org.hibernate.classic.Lifecycle} and {@link Interceptor} callbacks. + *

+ * IMPL NOTE : This is a legacy exception type from back in the day before Hibernate moved to a untyped (runtime) + * exception strategy. * - * @see org.hibernate.classic.Lifecycle - * @see Interceptor * @author Gavin King */ - public class CallbackException extends HibernateException { - - public CallbackException(Exception root) { - super("An exception occurred in a callback", root); + /** + * Creates a CallbackException using the given underlying cause. + * + * @param cause The underlying cause + */ + public CallbackException(Exception cause) { + this( "An exception occurred in a callback", cause ); } + /** + * Creates a CallbackException using the given message. + * + * @param message The message explaining the reason for the exception + */ public CallbackException(String message) { - super(message); + super( message ); } - public CallbackException(String message, Exception e) { - super(message, e); + /** + * Creates a CallbackException using the given message and underlying cause. + * + * @param message The message explaining the reason for the exception + * @param cause The underlying cause + */ + public CallbackException(String message, Exception cause) { + super( message, cause ); } } - - - - - - diff --git a/hibernate-core/src/main/java/org/hibernate/ConnectionReleaseMode.java b/hibernate-core/src/main/java/org/hibernate/ConnectionReleaseMode.java index 972621a6f7..700e0b1bd5 100644 --- a/hibernate-core/src/main/java/org/hibernate/ConnectionReleaseMode.java +++ b/hibernate-core/src/main/java/org/hibernate/ConnectionReleaseMode.java @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2008, 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; @@ -31,7 +30,6 @@ * @author Steve Ebersole */ public enum ConnectionReleaseMode{ - /** * Indicates that JDBC connection should be aggressively released after each * SQL statement is executed. In this mode, the application must @@ -55,7 +53,14 @@ public enum ConnectionReleaseMode{ */ ON_CLOSE; - public static ConnectionReleaseMode parse(String name){ + /** + * Alias for {@link ConnectionReleaseMode#valueOf(String)} using upper-case version of the incoming name. + * + * @param name The name to parse + * + * @return The matched enum value. + */ + public static ConnectionReleaseMode parse(final String name){ return ConnectionReleaseMode.valueOf( name.toUpperCase() ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/Criteria.java b/hibernate-core/src/main/java/org/hibernate/Criteria.java index 1a10390cc2..17152825dc 100644 --- a/hibernate-core/src/main/java/org/hibernate/Criteria.java +++ b/hibernate-core/src/main/java/org/hibernate/Criteria.java @@ -143,7 +143,7 @@ public interface Criteria extends CriteriaSpecification { public Criteria setFetchMode(String associationPath, FetchMode mode) throws HibernateException; /** - * Set the lock mode of the current entity + * Set the lock mode of the current entity. * * @param lockMode The lock mode to be applied * @@ -152,7 +152,7 @@ public interface Criteria extends CriteriaSpecification { public Criteria setLockMode(LockMode lockMode); /** - * Set the lock mode of the aliased entity + * Set the lock mode of the aliased entity. * * @param alias The previously assigned alias representing the entity to * which the given lock mode should apply. @@ -533,7 +533,7 @@ public interface Criteria extends CriteriaSpecification { public List list() throws HibernateException; /** - * Get the results as an instance of {@link ScrollableResults} + * Get the results as an instance of {@link ScrollableResults}. * * @return The {@link ScrollableResults} representing the matched * query results. diff --git a/hibernate-core/src/main/java/org/hibernate/CustomEntityDirtinessStrategy.java b/hibernate-core/src/main/java/org/hibernate/CustomEntityDirtinessStrategy.java index dbec870c1b..7a52a0a9d9 100644 --- a/hibernate-core/src/main/java/org/hibernate/CustomEntityDirtinessStrategy.java +++ b/hibernate-core/src/main/java/org/hibernate/CustomEntityDirtinessStrategy.java @@ -94,7 +94,7 @@ public interface CustomEntityDirtinessStrategy { public static interface DirtyCheckContext { /** * The callback to indicate that dirty checking (the dirty attribute determination phase) should be handled - * by the calling {@link CustomEntityDirtinessStrategy} using the given {@link AttributeChecker} + * by the calling {@link CustomEntityDirtinessStrategy} using the given {@link AttributeChecker}. * * @param attributeChecker The delegate usable by the context for determining which attributes are dirty. */ @@ -139,7 +139,7 @@ public static interface AttributeInformation { public int getAttributeIndex(); /** - * Get the name of this attribute + * Get the name of this attribute. * * @return The attribute name */ diff --git a/hibernate-core/src/main/java/org/hibernate/DuplicateMappingException.java b/hibernate-core/src/main/java/org/hibernate/DuplicateMappingException.java index f9c865d098..e837a4995b 100644 --- a/hibernate-core/src/main/java/org/hibernate/DuplicateMappingException.java +++ b/hibernate-core/src/main/java/org/hibernate/DuplicateMappingException.java @@ -1,7 +1,7 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008-2011, Red Hat Inc. or third-party contributors as + * Copyright (c) 2008, 2011, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are * distributed under license by Red Hat Inc. @@ -24,36 +24,80 @@ package org.hibernate; /** - * Raised whenever a duplicate for a certain type occurs. - * Duplicate class, table, property name etc. + * Raised whenever a duplicate for a certain type occurs. Duplicate class, table, property name etc. * * @author Max Rydahl Andersen * @author Steve Ebersole */ public class DuplicateMappingException extends MappingException { + /** + * Enumeration of the types of things that can be duplicated. + */ public static enum Type { + /** + * A duplicate entity definition was encountered. + */ ENTITY, + /** + * A duplicate table definition was encountered. + */ TABLE, + /** + * A duplicate property/attribute definition was encountered. + */ PROPERTY, + /** + * A duplicate column definition was encountered. + */ COLUMN } private final String name; private final String type; + /** + * Creates a DuplicateMappingException using the given type and name. + * + * @param type The type of the duplicated thing. + * @param name The name of the duplicated thing. + */ public DuplicateMappingException(Type type, String name) { this( type.name(), name ); } + /** + * Creates a DuplicateMappingException using the given type and name. + * + * @param type The type of the duplicated thing. + * @param name The name of the duplicated thing. + * + * @deprecated Use the for taking {@link Type} instead. + */ @Deprecated public DuplicateMappingException(String type, String name) { this( "Duplicate " + type + " mapping " + name, type, name ); } + /** + * Creates a DuplicateMappingException using the given customMessage, type and name. + * + * @param customMessage A custom exception message explaining the exception condition + * @param type The type of the duplicated thing. + * @param name The name of the duplicated thing. + */ public DuplicateMappingException(String customMessage, Type type, String name) { this( customMessage, type.name(), name ); } + /** + * Creates a DuplicateMappingException using the given customMessage, type and name. + * + * @param customMessage A custom exception message explaining the exception condition + * @param type The type of the duplicated thing. + * @param name The name of the duplicated thing. + * + * @deprecated Use the for taking {@link Type} instead. + */ @Deprecated public DuplicateMappingException(String customMessage, String type, String name) { super( customMessage ); diff --git a/hibernate-core/src/main/java/org/hibernate/EmptyInterceptor.java b/hibernate-core/src/main/java/org/hibernate/EmptyInterceptor.java index b3e0dc56f3..cc583c35cd 100755 --- a/hibernate-core/src/main/java/org/hibernate/EmptyInterceptor.java +++ b/hibernate-core/src/main/java/org/hibernate/EmptyInterceptor.java @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2008, 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,26 +20,29 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate; + import java.io.Serializable; import java.util.Iterator; import org.hibernate.type.Type; /** - * An interceptor that does nothing. May be used as a base class - * for application-defined custom interceptors. + * An interceptor that does nothing. May be used as a base class for application-defined custom interceptors. * * @author Gavin King */ public class EmptyInterceptor implements Interceptor, Serializable { - + /** + * The singleton reference. + */ public static final Interceptor INSTANCE = new EmptyInterceptor(); - - protected EmptyInterceptor() {} + protected EmptyInterceptor() { + } + + @Override public void onDelete( Object entity, Serializable id, @@ -47,6 +50,7 @@ public void onDelete( String[] propertyNames, Type[] types) {} + @Override public boolean onFlushDirty( Object entity, Serializable id, @@ -57,6 +61,7 @@ public boolean onFlushDirty( return false; } + @Override public boolean onLoad( Object entity, Serializable id, @@ -66,6 +71,7 @@ public boolean onLoad( return false; } + @Override public boolean onSave( Object entity, Serializable id, @@ -75,18 +81,27 @@ public boolean onSave( return false; } - public void postFlush(Iterator entities) {} - public void preFlush(Iterator entities) {} + @Override + public void postFlush(Iterator entities) { + } + @Override + public void preFlush(Iterator entities) { + } + + @Override public Boolean isTransient(Object entity) { return null; } + @Override public Object instantiate(String entityName, EntityMode entityMode, Serializable id) { return null; } - public int[] findDirty(Object entity, + @Override + public int[] findDirty( + Object entity, Serializable id, Object[] currentState, Object[] previousState, @@ -95,26 +110,43 @@ public int[] findDirty(Object entity, return null; } + @Override public String getEntityName(Object object) { return null; } + @Override public Object getEntity(String entityName, Serializable id) { return null; } - public void afterTransactionBegin(Transaction tx) {} - public void afterTransactionCompletion(Transaction tx) {} - public void beforeTransactionCompletion(Transaction tx) {} + @Override + public void afterTransactionBegin(Transaction tx) { + } + @Override + public void afterTransactionCompletion(Transaction tx) { + } + + @Override + public void beforeTransactionCompletion(Transaction tx) { + } + + @Override public String onPrepareStatement(String sql) { return sql; } - public void onCollectionRemove(Object collection, Serializable key) throws CallbackException {} + @Override + public void onCollectionRemove(Object collection, Serializable key) throws CallbackException { + } - public void onCollectionRecreate(Object collection, Serializable key) throws CallbackException {} + @Override + public void onCollectionRecreate(Object collection, Serializable key) throws CallbackException { + } - public void onCollectionUpdate(Object collection, Serializable key) throws CallbackException {} + @Override + public void onCollectionUpdate(Object collection, Serializable key) throws CallbackException { + } -} \ No newline at end of file +} diff --git a/hibernate-core/src/main/java/org/hibernate/EntityMode.java b/hibernate-core/src/main/java/org/hibernate/EntityMode.java index f9e9ee9d07..d8d1e784f3 100644 --- a/hibernate-core/src/main/java/org/hibernate/EntityMode.java +++ b/hibernate-core/src/main/java/org/hibernate/EntityMode.java @@ -29,12 +29,20 @@ * @author Steve Ebersole */ public enum EntityMode { + /** + * The {@code pojo} entity mode describes an entity model made up of entity classes (loosely) following + * the java bean convention. + */ POJO( "pojo" ), + + /** + * The {@code dynamic-map} entity mode describes an entity model defined using {@link java.util.Map} references. + */ MAP( "dynamic-map" ); private final String name; - EntityMode(String name) { + private EntityMode(String name) { this.name = name; } diff --git a/hibernate-core/src/main/java/org/hibernate/FetchMode.java b/hibernate-core/src/main/java/org/hibernate/FetchMode.java index 635ca99e83..97aac87aa5 100644 --- a/hibernate-core/src/main/java/org/hibernate/FetchMode.java +++ b/hibernate-core/src/main/java/org/hibernate/FetchMode.java @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2008, 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; @@ -32,6 +31,7 @@ * For HQL queries, use the FETCH keyword instead. * * @see Criteria#setFetchMode(java.lang.String, FetchMode) + * * @author Gavin King */ public enum FetchMode { @@ -52,18 +52,16 @@ public enum FetchMode { /** * Fetch lazily. Equivalent to outer-join="false". + * * @deprecated use FetchMode.SELECT */ + @Deprecated public static final FetchMode LAZY = SELECT; /** - * Fetch eagerly, using an outer join. Equivalent to - * outer-join="true". + * Fetch eagerly, using an outer join. Equivalent to outer-join="true". + * * @deprecated use FetchMode.JOIN */ + @Deprecated public static final FetchMode EAGER = JOIN; } - - - - - diff --git a/hibernate-core/src/main/java/org/hibernate/FlushMode.java b/hibernate-core/src/main/java/org/hibernate/FlushMode.java index f3f886f1b9..f1ad4f76a1 100644 --- a/hibernate-core/src/main/java/org/hibernate/FlushMode.java +++ b/hibernate-core/src/main/java/org/hibernate/FlushMode.java @@ -35,13 +35,14 @@ * @author Gavin King */ public enum FlushMode { - /** + /** * The {@link Session} is never flushed unless {@link Session#flush} * is explicitly called by the application. This mode is very * efficient for read only transactions. * * @deprecated use {@link #MANUAL} instead. */ + @Deprecated NEVER ( 0 ), /** @@ -75,25 +76,53 @@ public enum FlushMode { private FlushMode(int level) { this.level = level; } - + + /** + * Checks to see if {@code this} flush mode is less than the given flush mode. + * + * @param other THe flush mode value to be checked against {@code this} + * + * @return {@code true} indicates {@code other} is less than {@code this}; {@code false} otherwise + */ public boolean lessThan(FlushMode other) { - return this.levelnull * @return true if the argument is already initialized, or is not a proxy or collection */ + @SuppressWarnings("SimplifiableIfStatement") public static boolean isInitialized(Object proxy) { if ( proxy instanceof HibernateProxy ) { - return !( ( HibernateProxy ) proxy ).getHibernateLazyInitializer().isUninitialized(); + return !( (HibernateProxy) proxy ).getHibernateLazyInitializer().isUninitialized(); } else if ( proxy instanceof PersistentCollection ) { - return ( ( PersistentCollection ) proxy ).wasInitialized(); + return ( (PersistentCollection) proxy ).wasInitialized(); } else { return true; @@ -106,7 +108,7 @@ else if ( proxy instanceof PersistentCollection ) { */ public static Class getClass(Object proxy) { if ( proxy instanceof HibernateProxy ) { - return ( ( HibernateProxy ) proxy ).getHibernateLazyInitializer() + return ( (HibernateProxy) proxy ).getHibernateLazyInitializer() .getImplementation() .getClass(); } @@ -115,10 +117,24 @@ public static Class getClass(Object proxy) { } } + /** + * Obtain a lob creator for the given session. + * + * @param session The session for which to obtain a lob creator + * + * @return The log creator reference + */ public static LobCreator getLobCreator(Session session) { return getLobCreator( (SessionImplementor) session ); } + /** + * Obtain a lob creator for the given session. + * + * @param session The session for which to obtain a lob creator + * + * @return The log creator reference + */ public static LobCreator getLobCreator(SessionImplementor session) { return session.getFactory() .getJdbcServices() @@ -126,17 +142,19 @@ public static LobCreator getLobCreator(SessionImplementor session) { } /** - * Close an Iterator created by iterate() immediately, + * Close an {@link Iterator} instances obtained from {@link org.hibernate.Query#iterate()} immediately * instead of waiting until the session is closed or disconnected. * - * @param iterator an Iterator created by iterate() - * @throws HibernateException - * @see org.hibernate.Query#iterate + * @param iterator an Iterator created by iterate() + * + * @throws HibernateException Indicates a problem closing the Hibernate iterator. + * @throws IllegalArgumentException If the Iterator is not a "Hibernate Iterator". + * * @see Query#iterate() */ public static void close(Iterator iterator) throws HibernateException { if ( iterator instanceof HibernateIterator ) { - ( ( HibernateIterator ) iterator ).close(); + ( (HibernateIterator) iterator ).close(); } else { throw new IllegalArgumentException( "not a Hibernate iterator" ); @@ -152,10 +170,9 @@ public static void close(Iterator iterator) throws HibernateException { * @return true if the named property of the object is not listed as uninitialized; false otherwise */ public static boolean isPropertyInitialized(Object proxy, String propertyName) { - - Object entity; + final Object entity; if ( proxy instanceof HibernateProxy ) { - LazyInitializer li = ( ( HibernateProxy ) proxy ).getHibernateLazyInitializer(); + final LazyInitializer li = ( (HibernateProxy) proxy ).getHibernateLazyInitializer(); if ( li.isUninitialized() ) { return false; } @@ -168,13 +185,12 @@ public static boolean isPropertyInitialized(Object proxy, String propertyName) { } if ( FieldInterceptionHelper.isInstrumented( entity ) ) { - FieldInterceptor interceptor = FieldInterceptionHelper.extractFieldInterceptor( entity ); + final FieldInterceptor interceptor = FieldInterceptionHelper.extractFieldInterceptor( entity ); return interceptor == null || interceptor.isInitialized( propertyName ); } else { return true; } - } } diff --git a/hibernate-core/src/main/java/org/hibernate/HibernateException.java b/hibernate-core/src/main/java/org/hibernate/HibernateException.java index 52be3448b4..542e81df31 100644 --- a/hibernate-core/src/main/java/org/hibernate/HibernateException.java +++ b/hibernate-core/src/main/java/org/hibernate/HibernateException.java @@ -1,7 +1,7 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2007-2011, Red Hat Inc. or third-party contributors as + * Copyright (c) 2007,2011, 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. @@ -23,9 +23,8 @@ */ package org.hibernate; - /** - * The base {@link Throwable} type for Hibernate. + * The base exception type for Hibernate exceptions. *

* Note that all {@link java.sql.SQLException SQLExceptions} will be wrapped in some form of * {@link JDBCException}. @@ -35,16 +34,32 @@ * @author Gavin King */ public class HibernateException extends RuntimeException { + /** + * Constructs a HibernateException using the given exception message. + * + * @param message The message explaining the reason for the exception + */ public HibernateException(String message) { super( message ); } - public HibernateException(Throwable root) { - super( root ); + /** + * Constructs a HibernateException using the given message and underlying cause. + * + * @param cause The underlying cause. + */ + public HibernateException(Throwable cause) { + super( cause ); } - public HibernateException(String message, Throwable root) { - super( message, root ); + /** + * Constructs a HibernateException using the given message and underlying cause. + * + * @param message The message explaining the reason for the exception. + * @param cause The underlying cause. + */ + public HibernateException(String message, Throwable cause) { + super( message, cause ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/IdentifierLoadAccess.java b/hibernate-core/src/main/java/org/hibernate/IdentifierLoadAccess.java index f4fae2178f..72c2e12cee 100644 --- a/hibernate-core/src/main/java/org/hibernate/IdentifierLoadAccess.java +++ b/hibernate-core/src/main/java/org/hibernate/IdentifierLoadAccess.java @@ -26,7 +26,7 @@ import java.io.Serializable; /** - * Loads an entity by its primary identifier + * Loads an entity by its primary identifier. * * @author Eric Dalquist * @author Steve Ebersole diff --git a/hibernate-core/src/main/java/org/hibernate/InstantiationException.java b/hibernate-core/src/main/java/org/hibernate/InstantiationException.java index 9a1c668964..3489ad649d 100644 --- a/hibernate-core/src/main/java/org/hibernate/InstantiationException.java +++ b/hibernate-core/src/main/java/org/hibernate/InstantiationException.java @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2008, 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,49 +20,71 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate; - /** - * Thrown if Hibernate can't instantiate an entity or component - * class at runtime. + * Thrown if Hibernate can't instantiate a class at runtime. * * @author Gavin King */ - public class InstantiationException extends HibernateException { - private final Class clazz; - public InstantiationException(String s, Class clazz, Throwable root) { - super(s, root); + /** + * Constructs a InstantiationException. + * + * @param message A message explaining the exception condition + * @param clazz The Class we are attempting to instantiate + * @param cause The underlying exception + */ + public InstantiationException(String message, Class clazz, Throwable cause) { + super( message, cause ); this.clazz = clazz; } - public InstantiationException(String s, Class clazz) { - super(s); - this.clazz = clazz; - } - - public InstantiationException(String s, Class clazz, Exception e) { - super(s, e); + /** + * Constructs a InstantiationException. + * + * @param message A message explaining the exception condition + * @param clazz The Class we are attempting to instantiate + */ + public InstantiationException(String message, Class clazz) { + this( message, clazz, null ); + } + + /** + * Constructs a InstantiationException. + * + * @param message A message explaining the exception condition + * @param clazz The Class we are attempting to instantiate + * @param cause The underlying exception + */ + public InstantiationException(String message, Class clazz, Exception cause) { + super( message, cause ); this.clazz = clazz; } + /** + * @deprecated Use {@link #getUninstantiatableClass} instead + */ + @Deprecated public Class getPersistentClass() { return clazz; } + /** + * Returns the Class we were attempting to instantiate. + * + * @return The class we are unable to instantiate + */ + public Class getUninstantiatableClass() { + return clazz; + } + + @Override public String getMessage() { - return super.getMessage() + clazz.getName(); + return super.getMessage() + " : " + clazz.getName(); } } - - - - - - diff --git a/hibernate-core/src/main/java/org/hibernate/Interceptor.java b/hibernate-core/src/main/java/org/hibernate/Interceptor.java index 7664c36eb6..29b5108387 100644 --- a/hibernate-core/src/main/java/org/hibernate/Interceptor.java +++ b/hibernate-core/src/main/java/org/hibernate/Interceptor.java @@ -30,18 +30,18 @@ /** * Allows user code to inspect and/or change property values. - *

+ * * Inspection occurs before property values are written and after they are read - * from the database.
- *
+ * from the database. + * * There might be a single instance of Interceptor for a SessionFactory, or a new instance * might be specified for each Session. Whichever approach is used, the interceptor must be * serializable if the Session is to be serializable. This means that SessionFactory-scoped - * interceptors should implement readResolve().
- *
+ * interceptors should implement readResolve(). + * * The Session may not be invoked from a callback (nor may a callback cause a collection or proxy to - * be lazily initialized).
- *
+ * be lazily initialized). + * * Instead of implementing this interface directly, it is usually better to extend EmptyInterceptor * and override only the callback methods of interest. * @@ -155,9 +155,9 @@ public interface Interceptor { public void onCollectionUpdate(Object collection, Serializable key) throws CallbackException; /** - * Called before a flush + * Called before a flush. * - * @param entities The entities to be flushed + * @param entities The entities to be flushed. * * @throws CallbackException Thrown if the interceptor encounters any problems handling the callback. */ @@ -215,6 +215,7 @@ public interface Interceptor { * @param entityName the name of the entity * @param entityMode The type of entity instance to be returned. * @param id the identifier of the new instance + * * @return an instance of the class, or null to choose default behaviour * * @throws CallbackException Thrown if the interceptor encounters any problems handling the callback. @@ -222,8 +223,10 @@ public interface Interceptor { public Object instantiate(String entityName, EntityMode entityMode, Serializable id) throws CallbackException; /** - * Get the entity name for a persistent or transient instance + * Get the entity name for a persistent or transient instance. + * * @param object an entity instance + * * @return the name of the entity * * @throws CallbackException Thrown if the interceptor encounters any problems handling the callback. @@ -231,9 +234,11 @@ public interface Interceptor { public String getEntityName(Object object) throws CallbackException; /** - * Get a fully loaded entity instance that is cached externally + * Get a fully loaded entity instance that is cached externally. + * * @param entityName the name of the entity * @param id the instance identifier + * * @return a fully initialized entity * * @throws CallbackException Thrown if the interceptor encounters any problems handling the callback. diff --git a/hibernate-core/src/main/java/org/hibernate/InvalidMappingException.java b/hibernate-core/src/main/java/org/hibernate/InvalidMappingException.java index 3635b328f1..474f295882 100644 --- a/hibernate-core/src/main/java/org/hibernate/InvalidMappingException.java +++ b/hibernate-core/src/main/java/org/hibernate/InvalidMappingException.java @@ -28,7 +28,9 @@ /** * Thrown when a mapping is found to be invalid. - * Similar to MappingException, but this contains more info about the path and type of mapping (e.g. file, resource or url) + * + * Similar to MappingException, but this contains more info about the path and type of + * mapping (e.g. file, resource or url) * * @author Max Rydahl Andersen * @author Steve Ebersole @@ -37,44 +39,104 @@ public class InvalidMappingException extends MappingException { private final String path; private final String type; + /** + * Constructs an InvalidMappingException using the given information. + * + * @param customMessage The custom message explaining the exception condition + * @param type The type of invalid mapping document + * @param path The path (type specific) of the invalid mapping document + * @param cause The underlying cause + */ public InvalidMappingException(String customMessage, String type, String path, Throwable cause) { - super(customMessage, cause); - this.type=type; - this.path=path; + super( customMessage, cause ); + this.type = type; + this.path = path; } + /** + * Constructs an InvalidMappingException using the given information. + * + * @param customMessage The custom message explaining the exception condition + * @param type The type of invalid mapping document + * @param path The path (type specific) of the invalid mapping document + */ public InvalidMappingException(String customMessage, String type, String path) { super(customMessage); this.type=type; this.path=path; } + /** + * Constructs an InvalidMappingException using the given information. + * + * @param customMessage The custom message explaining the exception condition + * @param xmlDocument The document that was invalid + * @param cause The underlying cause + */ public InvalidMappingException(String customMessage, XmlDocument xmlDocument, Throwable cause) { this( customMessage, xmlDocument.getOrigin().getType(), xmlDocument.getOrigin().getName(), cause ); } + /** + * Constructs an InvalidMappingException using the given information. + * + * @param customMessage The custom message explaining the exception condition + * @param xmlDocument The document that was invalid + */ public InvalidMappingException(String customMessage, XmlDocument xmlDocument) { this( customMessage, xmlDocument.getOrigin().getType(), xmlDocument.getOrigin().getName() ); } + /** + * Constructs an InvalidMappingException using the given information. + * + * @param customMessage The custom message explaining the exception condition + * @param origin The origin of the invalid mapping document + */ public InvalidMappingException(String customMessage, Origin origin) { this( customMessage, origin.getType().toString(), origin.getName() ); } + /** + * Constructs an InvalidMappingException using the given information and a standard message. + * + * @param type The type of invalid mapping document + * @param path The path (type specific) of the invalid mapping document + */ public InvalidMappingException(String type, String path) { this("Could not parse mapping document from " + type + (path==null?"":" " + path), type, path); } + /** + * Constructs an InvalidMappingException using the given information and a standard message. + * + * @param type The type of invalid mapping document + * @param path The path (type specific) of the invalid mapping document + * @param cause The underlying cause + */ public InvalidMappingException(String type, String path, Throwable cause) { this("Could not parse mapping document from " + type + (path==null?"":" " + path), type, path, cause); } - public InvalidMappingException(String message, org.hibernate.internal.util.xml.Origin origin, Exception cause) { - this( message, origin.getType(), origin.getName(), cause ); + /** + * Constructs an InvalidMappingException using the given information. + * + * @param customMessage The custom message explaining the exception condition + * @param origin The origin of the invalid mapping document + * @param cause The underlying cause + */ + public InvalidMappingException(String customMessage, org.hibernate.internal.util.xml.Origin origin, Exception cause) { + this( customMessage, origin.getType(), origin.getName(), cause ); } - public InvalidMappingException(String message, org.hibernate.internal.util.xml.Origin origin) { - this( message, origin, null ); + /** + * Constructs an InvalidMappingException using the given information. + * + * @param customMessage The custom message explaining the exception condition + * @param origin The origin of the invalid mapping document + */ + public InvalidMappingException(String customMessage, org.hibernate.internal.util.xml.Origin origin) { + this( customMessage, origin, null ); } public String getType() { diff --git a/hibernate-core/src/main/java/org/hibernate/JDBCException.java b/hibernate-core/src/main/java/org/hibernate/JDBCException.java index c02305e29e..12de808328 100644 --- a/hibernate-core/src/main/java/org/hibernate/JDBCException.java +++ b/hibernate-core/src/main/java/org/hibernate/JDBCException.java @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2008, 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,31 +20,35 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate; + import java.sql.SQLException; - /** - * Wraps an SQLException. Indicates that an exception - * occurred during a JDBC call. + * Wraps a {@link SQLException}. Indicates that an exception occurred during a JDBC call. + * + * @author Gavin King * * @see java.sql.SQLException - * @author Gavin King */ public class JDBCException extends HibernateException { + private final SQLException sqlException; + private final String sql; - private SQLException sqle; - private String sql; - - public JDBCException(String string, SQLException root) { - super(string, root); - sqle=root; + /** + * Constructs a JDBCException using the given information + * + * @param message The message explaining the exception condition + * @param cause The underlying cause + */ + public JDBCException(String message, SQLException cause) { + this( message, cause, null ); } - public JDBCException(String string, SQLException root, String sql) { - this(string, root); + public JDBCException(String string, SQLException cause, String sql) { + super( string, cause ); + this.sqlException = cause; this.sql = sql; } @@ -54,7 +58,7 @@ public JDBCException(String string, SQLException root, String sql) { * @return String */ public String getSQLState() { - return sqle.getSQLState(); + return sqlException.getSQLState(); } /** @@ -63,7 +67,7 @@ public String getSQLState() { * @return int the error code */ public int getErrorCode() { - return sqle.getErrorCode(); + return sqlException.getErrorCode(); } /** @@ -71,7 +75,7 @@ public int getErrorCode() { * @return SQLException */ public SQLException getSQLException() { - return sqle; + return sqlException; } /** diff --git a/hibernate-core/src/main/java/org/hibernate/LazyInitializationException.java b/hibernate-core/src/main/java/org/hibernate/LazyInitializationException.java index 87b948ac73..5fc07fa4b8 100644 --- a/hibernate-core/src/main/java/org/hibernate/LazyInitializationException.java +++ b/hibernate-core/src/main/java/org/hibernate/LazyInitializationException.java @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2008, 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,17 +20,17 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate; + import org.jboss.logging.Logger; import org.hibernate.internal.CoreMessageLogger; /** - * Indicates access to unfetched data outside of a session context. - * For example, when an uninitialized proxy or collection is accessed - * after the session was closed. + * Indicates an attempt to access not-yet-fetched data outside of a session context. + * + * For example, when an uninitialized proxy or collection is accessed after the session was closed. * * @see Hibernate#initialize(java.lang.Object) * @see Hibernate#isInitialized(java.lang.Object) @@ -38,11 +38,19 @@ */ public class LazyInitializationException extends HibernateException { - private static final CoreMessageLogger LOG = Logger.getMessageLogger( CoreMessageLogger.class, LazyInitializationException.class.getName() ); + private static final CoreMessageLogger LOG = Logger.getMessageLogger( + CoreMessageLogger.class, + LazyInitializationException.class.getName() + ); - public LazyInitializationException(String msg) { - super( msg ); - LOG.trace( msg, this ); + /** + * Constructs a LazyInitializationException using the given message + * + * @param message A message explaining the exception condition + */ + public LazyInitializationException(String message) { + super( message ); + LOG.trace( message, this ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/LobHelper.java b/hibernate-core/src/main/java/org/hibernate/LobHelper.java index f22566fed2..f2c7849289 100644 --- a/hibernate-core/src/main/java/org/hibernate/LobHelper.java +++ b/hibernate-core/src/main/java/org/hibernate/LobHelper.java @@ -30,7 +30,7 @@ import java.sql.NClob; /** - * A {@link Session session's} helper for creating LOB data + * A {@link Session session's} helper for creating LOB data. * * @author Steve Ebersole */ @@ -56,7 +56,7 @@ public interface LobHelper { public Blob createBlob(InputStream stream, long length); /** - * Create a new {@link java.sql.Clob} from content + * Create a new {@link java.sql.Clob} from content. * * @param string The string data * diff --git a/hibernate-core/src/main/java/org/hibernate/LockOptions.java b/hibernate-core/src/main/java/org/hibernate/LockOptions.java index 6de28a4a9a..849e72657a 100644 --- a/hibernate-core/src/main/java/org/hibernate/LockOptions.java +++ b/hibernate-core/src/main/java/org/hibernate/LockOptions.java @@ -36,18 +36,17 @@ */ public class LockOptions implements Serializable { /** - * NONE represents LockMode.NONE (timeout + scope do not apply) + * Represents LockMode.NONE (timeout + scope do not apply). */ public static final LockOptions NONE = new LockOptions(LockMode.NONE); /** - * READ represents LockMode.READ (timeout + scope do not apply) + * Represents LockMode.READ (timeout + scope do not apply). */ public static final LockOptions READ = new LockOptions(LockMode.READ); /** - * UPGRADE represents LockMode.UPGRADE (will wait forever for lock and - * scope of false meaning only entity is locked) + * Represents LockMode.UPGRADE (will wait forever for lock and scope of false meaning only entity is locked). */ @SuppressWarnings("deprecation") public static final LockOptions UPGRADE = new LockOptions(LockMode.UPGRADE); @@ -73,12 +72,19 @@ public class LockOptions implements Serializable { private LockMode lockMode = LockMode.NONE; private int timeout = WAIT_FOREVER; - //initialize lazily as LockOptions is frequently created without needing this - private Map aliasSpecificLockModes = null; + private Map aliasSpecificLockModes; + /** + * Constructs a LockOptions with all default options + */ public LockOptions() { } + /** + * Constructs a LockOptions with the given lock mode + * + * @param lockMode The lock mode to use + */ public LockOptions( LockMode lockMode) { this.lockMode = lockMode; } @@ -109,7 +115,6 @@ public LockOptions setLockMode(LockMode lockMode) { return this; } - /** * Specify the {@link LockMode} to be used for a specific query alias. * @@ -186,7 +191,7 @@ public int getAliasLockCount() { } /** - * Iterator for accessing Alias (key) and LockMode (value) as Map.Entry + * Iterator for accessing Alias (key) and LockMode (value) as Map.Entry. * * @return Iterator for accessing the Map.Entry's */ @@ -265,7 +270,7 @@ public boolean getScope() { } /** - * Set the cope. + * Set the scope. * * @param scope The new scope setting * @@ -276,6 +281,11 @@ public LockOptions setScope(boolean scope) { return this; } + /** + * Make a copy. + * + * @return The copy + */ public LockOptions makeCopy() { final LockOptions copy = new LockOptions(); copy( this, copy ); diff --git a/hibernate-core/src/main/java/org/hibernate/MappingException.java b/hibernate-core/src/main/java/org/hibernate/MappingException.java index ae24dc2ef4..fc818a55a4 100644 --- a/hibernate-core/src/main/java/org/hibernate/MappingException.java +++ b/hibernate-core/src/main/java/org/hibernate/MappingException.java @@ -1,7 +1,7 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008-2011, Red Hat Inc. or third-party contributors as + * Copyright (c) 2008, 2011, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are * distributed under license by Red Hat Inc. @@ -24,23 +24,38 @@ package org.hibernate; /** - * An exception that usually occurs at configuration time, rather - * than runtime, as a result of something screwy in the O-R mappings. + * An exception that occurs while reading mapping sources (xml/annotations),usually as a result of something + * screwy in the O-R mappings. * * @author Gavin King */ public class MappingException extends HibernateException { - - public MappingException(String msg, Throwable root) { - super( msg, root ); + /** + * Constructs a MappingException using the given information + * + * @param message A message explaining the exception condition + * @param cause The underlying cause + */ + public MappingException(String message, Throwable cause) { + super( message, cause ); } - public MappingException(Throwable root) { - super(root); + /** + * Constructs a MappingException using the given information + * + * @param cause The underlying cause + */ + public MappingException(Throwable cause) { + super(cause); } - public MappingException(String s) { - super(s); + /** + * Constructs a MappingException using the given information + * + * @param message A message explaining the exception condition + */ + public MappingException(String message) { + super(message); } } diff --git a/hibernate-core/src/main/java/org/hibernate/MappingNotFoundException.java b/hibernate-core/src/main/java/org/hibernate/MappingNotFoundException.java index 30c17fc54e..73680e32eb 100644 --- a/hibernate-core/src/main/java/org/hibernate/MappingNotFoundException.java +++ b/hibernate-core/src/main/java/org/hibernate/MappingNotFoundException.java @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2008, 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,10 +20,8 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ -package org.hibernate; - +package org.hibernate; /** * Thrown when a resource for a mapping could not be found. @@ -31,26 +29,53 @@ * @author Max Rydahl Andersen */ public class MappingNotFoundException extends MappingException { - private final String path; private final String type; + /** + * Constructs a MappingNotFoundException using the given information. + * + * @param customMessage A message explaining the exception condition + * @param type The type of mapping that could not be found + * @param path The path (type specific) of the mapping that could not be found + * @param cause The underlying cause + */ public MappingNotFoundException(String customMessage, String type, String path, Throwable cause) { super(customMessage, cause); this.type=type; this.path=path; } - + + /** + * Constructs a MappingNotFoundException using the given information. + * + * @param customMessage A message explaining the exception condition + * @param type The type of mapping that could not be found + * @param path The path (type specific) of the mapping that could not be found + */ public MappingNotFoundException(String customMessage, String type, String path) { super(customMessage); this.type=type; this.path=path; } - + + /** + * Constructs a MappingNotFoundException using the given information, using a standard message. + * + * @param type The type of mapping that could not be found + * @param path The path (type specific) of the mapping that could not be found + */ public MappingNotFoundException(String type, String path) { this(type + ": " + path + " not found", type, path); } + /** + * Constructs a MappingNotFoundException using the given information, using a standard message. + * + * @param type The type of mapping that could not be found + * @param path The path (type specific) of the mapping that could not be found + * @param cause The underlying cause + */ public MappingNotFoundException(String type, String path, Throwable cause) { this(type + ": " + path + " not found", type, path, cause); } diff --git a/hibernate-core/src/main/java/org/hibernate/MultiTenancyStrategy.java b/hibernate-core/src/main/java/org/hibernate/MultiTenancyStrategy.java index fff40398ad..16d0f9c220 100644 --- a/hibernate-core/src/main/java/org/hibernate/MultiTenancyStrategy.java +++ b/hibernate-core/src/main/java/org/hibernate/MultiTenancyStrategy.java @@ -49,7 +49,7 @@ public enum MultiTenancyStrategy { */ DATABASE, /** - * No multi-tenancy + * No multi-tenancy. */ NONE; @@ -58,10 +58,24 @@ public enum MultiTenancyStrategy { MultiTenancyStrategy.class.getName() ); + /** + * Does this strategy indicate a requirement for the specialized + * {@link org.hibernate.engine.jdbc.connections.spi.MultiTenantConnectionProvider}, rather than the + * traditional {@link org.hibernate.engine.jdbc.connections.spi.ConnectionProvider} + * + * @return {@code true} indicates a MultiTenantConnectionProvider is required; {@code false} indicates it is not. + */ public boolean requiresMultiTenantConnectionProvider() { return this == DATABASE || this == SCHEMA; } + /** + * Extract the MultiTenancyStrategy from the setting map. + * + * @param properties The map of settings. + * + * @return The selected strategy. {@link #NONE} is always the default. + */ public static MultiTenancyStrategy determineMultiTenancyStrategy(Map properties) { final Object strategy = properties.get( Environment.MULTI_TENANT ); if ( strategy == null ) { diff --git a/hibernate-core/src/main/java/org/hibernate/NaturalIdLoadAccess.java b/hibernate-core/src/main/java/org/hibernate/NaturalIdLoadAccess.java index 89effd90b6..e5c1e62356 100644 --- a/hibernate-core/src/main/java/org/hibernate/NaturalIdLoadAccess.java +++ b/hibernate-core/src/main/java/org/hibernate/NaturalIdLoadAccess.java @@ -24,7 +24,7 @@ package org.hibernate; /** - * Loads an entity by its natural identifier + * Loads an entity by its natural identifier. * * @author Eric Dalquist * @author Steve Ebersole diff --git a/hibernate-core/src/main/java/org/hibernate/NonUniqueObjectException.java b/hibernate-core/src/main/java/org/hibernate/NonUniqueObjectException.java index 6664316d8c..b852f706bd 100644 --- a/hibernate-core/src/main/java/org/hibernate/NonUniqueObjectException.java +++ b/hibernate-core/src/main/java/org/hibernate/NonUniqueObjectException.java @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2008, 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,19 +20,17 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate; + import java.io.Serializable; import org.hibernate.pretty.MessageHelper; /** - * This exception is thrown when an operation would - * break session-scoped identity. This occurs if the - * user tries to associate two different instances of - * the same Java class with a particular identifier, - * in the scope of a single Session. + * This exception is thrown when an operation would break session-scoped identity. This occurs if the + * user tries to associate two different instances of the same Java class with a particular identifier, + * in the scope of a single Session. * * @author Gavin King */ @@ -40,27 +38,43 @@ public class NonUniqueObjectException extends HibernateException { private final Serializable identifier; private final String entityName; - public NonUniqueObjectException(String message, Serializable id, String clazz) { - super(message); - this.entityName = clazz; - this.identifier = id; + /** + * Constructs a NonUniqueObjectException using the given information. + * + * @param message A message explaining the exception condition + * @param entityId The identifier of the entity + * @param entityName The name of the entity + */ + public NonUniqueObjectException(String message, Serializable entityId, String entityName) { + super( message ); + this.entityName = entityName; + this.identifier = entityId; } - public NonUniqueObjectException(Serializable id, String clazz) { - this("a different object with the same identifier value was already associated with the session", id, clazz); - } - - public Serializable getIdentifier() { - return identifier; - } - - public String getMessage() { - return super.getMessage() + ": " + - MessageHelper.infoString(entityName, identifier); + /** + * Constructs a NonUniqueObjectException using the given information, using a standard message + * + * @param entityId The identifier of the entity + * @param entityName The name of the entity + */ + public NonUniqueObjectException(Serializable entityId, String entityName) { + this( + "A different object with the same identifier value was already associated with the session", + entityId, + entityName + ); } public String getEntityName() { return entityName; } + public Serializable getIdentifier() { + return identifier; + } + + @Override + public String getMessage() { + return super.getMessage() + " : " + MessageHelper.infoString( entityName, identifier ); + } } diff --git a/hibernate-core/src/main/java/org/hibernate/NonUniqueResultException.java b/hibernate-core/src/main/java/org/hibernate/NonUniqueResultException.java index 12630e2c42..5e7145115e 100644 --- a/hibernate-core/src/main/java/org/hibernate/NonUniqueResultException.java +++ b/hibernate-core/src/main/java/org/hibernate/NonUniqueResultException.java @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2008, 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,20 +20,22 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate; - /** * Thrown when the application calls Query.uniqueResult() and - * the query returned more than one result. Unlike all other Hibernate + * the query returned more than one result. Unlike all other Hibernate * exceptions, this one is recoverable! * * @author Gavin King */ public class NonUniqueResultException extends HibernateException { - + /** + * Constructs a NonUniqueResultException + * + * @param resultCount The number of actual results. + */ public NonUniqueResultException(int resultCount) { super( "query did not return a unique result: " + resultCount ); } diff --git a/hibernate-core/src/main/java/org/hibernate/NullPrecedence.java b/hibernate-core/src/main/java/org/hibernate/NullPrecedence.java index f4b9dab727..c2e59bd1ea 100644 --- a/hibernate-core/src/main/java/org/hibernate/NullPrecedence.java +++ b/hibernate-core/src/main/java/org/hibernate/NullPrecedence.java @@ -1,3 +1,26 @@ +/* + * 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; /** @@ -21,21 +44,37 @@ public enum NullPrecedence { */ LAST; - public static NullPrecedence parse(String type) { - if ( "none".equalsIgnoreCase( type ) ) { + /** + * Interprets a string representation of a NullPrecedence, returning {@code null} by default. For + * alternative default handling, see {@link #parse(String, NullPrecedence)} + * + * @param name The String representation to interpret + * + * @return The recognized NullPrecedence, or {@code null} + */ + public static NullPrecedence parse(String name) { + if ( "none".equalsIgnoreCase( name ) ) { return NullPrecedence.NONE; } - else if ( "first".equalsIgnoreCase( type ) ) { + else if ( "first".equalsIgnoreCase( name ) ) { return NullPrecedence.FIRST; } - else if ( "last".equalsIgnoreCase( type ) ) { + else if ( "last".equalsIgnoreCase( name ) ) { return NullPrecedence.LAST; } return null; } - public static NullPrecedence parse(String type, NullPrecedence defaultValue) { - final NullPrecedence value = parse( type ); + /** + * Interprets a string representation of a NullPrecedence, returning the specified default if not recognized. + * + * @param name The String representation to interpret + * @param defaultValue The default value to use + * + * @return The recognized NullPrecedence, or {@code defaultValue}. + */ + public static NullPrecedence parse(String name, NullPrecedence defaultValue) { + final NullPrecedence value = parse( name ); return value != null ? value : defaultValue; } } diff --git a/hibernate-core/src/main/java/org/hibernate/ObjectDeletedException.java b/hibernate-core/src/main/java/org/hibernate/ObjectDeletedException.java index 766fb4e86e..3a41929d95 100644 --- a/hibernate-core/src/main/java/org/hibernate/ObjectDeletedException.java +++ b/hibernate-core/src/main/java/org/hibernate/ObjectDeletedException.java @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2008, 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,21 +20,26 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate; + import java.io.Serializable; /** - * Thrown when the user tries to do something illegal with a deleted - * object. + * Thrown when the user tries to do something illegal with a deleted object. * * @author Gavin King */ public class ObjectDeletedException extends UnresolvableObjectException { - - public ObjectDeletedException(String message, Serializable identifier, String clazz) { - super(message, identifier, clazz); + /** + * Constructs an ObjectDeletedException using the given information + * + * @param message A message explaining the exception condition + * @param identifier The identifier of the entity + * @param entityName The name of the entity + */ + public ObjectDeletedException(String message, Serializable identifier, String entityName) { + super( message, identifier, entityName ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/ObjectNotFoundException.java b/hibernate-core/src/main/java/org/hibernate/ObjectNotFoundException.java index 06a945cda0..a69dd6e551 100644 --- a/hibernate-core/src/main/java/org/hibernate/ObjectNotFoundException.java +++ b/hibernate-core/src/main/java/org/hibernate/ObjectNotFoundException.java @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2008, 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,9 +20,9 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate; + import java.io.Serializable; /** @@ -39,8 +39,13 @@ * @author Gavin King */ public class ObjectNotFoundException extends UnresolvableObjectException { - - public ObjectNotFoundException(Serializable identifier, String clazz) { - super(identifier, clazz); + /** + * Constructs a ObjectNotFoundException using the given information. + * + * @param identifier The identifier of the entity + * @param entityName The name of the entity + */ + public ObjectNotFoundException(Serializable identifier, String entityName) { + super(identifier, entityName); } } diff --git a/hibernate-core/src/main/java/org/hibernate/OptimisticLockException.java b/hibernate-core/src/main/java/org/hibernate/OptimisticLockException.java index 87ad02b1ef..396807f657 100644 --- a/hibernate-core/src/main/java/org/hibernate/OptimisticLockException.java +++ b/hibernate-core/src/main/java/org/hibernate/OptimisticLockException.java @@ -1,7 +1,7 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2009-2011, Red Hat Inc. or third-party contributors as + * Copyright (c) 2009, 2011, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are * distributed under license by Red Hat Inc. @@ -32,8 +32,15 @@ * * @deprecated Use {@link org.hibernate.dialect.lock.OptimisticEntityLockException} instead */ +@Deprecated public class OptimisticLockException extends OptimisticEntityLockException { + /** + * Constructs a OptimisticLockException using the specified information + * + * @param entity The entity instance that could not be locked + * @param message A message explaining the exception condition + */ public OptimisticLockException(Object entity, String message) { super( entity, message ); } -} \ No newline at end of file +} diff --git a/hibernate-core/src/main/java/org/hibernate/PersistentObjectException.java b/hibernate-core/src/main/java/org/hibernate/PersistentObjectException.java index 3d0f4b0142..7841bcf7a3 100644 --- a/hibernate-core/src/main/java/org/hibernate/PersistentObjectException.java +++ b/hibernate-core/src/main/java/org/hibernate/PersistentObjectException.java @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2008, 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,11 +20,9 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate; - /** * Thrown when the user passes a persistent instance to a Session * method that expects a transient instance. @@ -32,8 +30,12 @@ * @author Gavin King */ public class PersistentObjectException extends HibernateException { - - public PersistentObjectException(String s) { - super(s); + /** + * Constructs a PersistentObjectException using the given message. + * + * @param message A message explaining the exception condition + */ + public PersistentObjectException(String message) { + super( message ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/PessimisticLockException.java b/hibernate-core/src/main/java/org/hibernate/PessimisticLockException.java index c89660ad5d..260fb790ef 100644 --- a/hibernate-core/src/main/java/org/hibernate/PessimisticLockException.java +++ b/hibernate-core/src/main/java/org/hibernate/PessimisticLockException.java @@ -31,7 +31,14 @@ * @author Scott Marlow */ public class PessimisticLockException extends JDBCException { - public PessimisticLockException(String s, SQLException se, String sql) { - super( s, se, sql ); + /** + * Constructs a PessimisticLockException using the specified information + * + * @param message A message explaining the exception condition + * @param sqlException The underlying SQL exception + * @param sql The sql that led to the exception (may be null, though usually should not be) + */ + public PessimisticLockException(String message, SQLException sqlException, String sql) { + super( message, sqlException, sql ); } -} \ No newline at end of file +} diff --git a/hibernate-core/src/main/java/org/hibernate/PropertyAccessException.java b/hibernate-core/src/main/java/org/hibernate/PropertyAccessException.java index 829ee685d6..2c0620e7a9 100644 --- a/hibernate-core/src/main/java/org/hibernate/PropertyAccessException.java +++ b/hibernate-core/src/main/java/org/hibernate/PropertyAccessException.java @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2008, 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; @@ -39,13 +38,26 @@ * @author Gavin King */ public class PropertyAccessException extends HibernateException { - private final Class persistentClass; private final String propertyName; private final boolean wasSetter; - public PropertyAccessException(Throwable root, String s, boolean wasSetter, Class persistentClass, String propertyName) { - super(s, root); + /** + * Constructs a PropertyAccessException using the specified information. + * + * @param cause The underlying cause + * @param message A message explaining the exception condition + * @param wasSetter Was the attempting to access the setter the cause of the exception? + * @param persistentClass The class which is supposed to contain the property in question + * @param propertyName The name of the property. + */ + public PropertyAccessException( + Throwable cause, + String message, + boolean wasSetter, + Class persistentClass, + String propertyName) { + super(message, cause); this.persistentClass = persistentClass; this.wasSetter = wasSetter; this.propertyName = propertyName; diff --git a/hibernate-core/src/main/java/org/hibernate/PropertyNotFoundException.java b/hibernate-core/src/main/java/org/hibernate/PropertyNotFoundException.java index 1ac945f77f..b2498525fa 100644 --- a/hibernate-core/src/main/java/org/hibernate/PropertyNotFoundException.java +++ b/hibernate-core/src/main/java/org/hibernate/PropertyNotFoundException.java @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2008, 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,11 +20,9 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate; - /** * Indicates that an expected getter or setter method could not be * found on a class. @@ -32,9 +30,12 @@ * @author Gavin King */ public class PropertyNotFoundException extends MappingException { - - public PropertyNotFoundException(String s) { - super(s); + /** + * Constructs a PropertyNotFoundException given the specified message. + * + * @param message A message explaining the exception condition + */ + public PropertyNotFoundException(String message) { + super(message); } - } diff --git a/hibernate-core/src/main/java/org/hibernate/PropertyValueException.java b/hibernate-core/src/main/java/org/hibernate/PropertyValueException.java index 241cd49063..9634fd5c0c 100644 --- a/hibernate-core/src/main/java/org/hibernate/PropertyValueException.java +++ b/hibernate-core/src/main/java/org/hibernate/PropertyValueException.java @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2008, 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; @@ -36,12 +35,18 @@ * @author Gavin King */ public class PropertyValueException extends HibernateException { - private final String entityName; private final String propertyName; - public PropertyValueException(String s, String entityName, String propertyName) { - super(s); + /** + * Constructs a PropertyValueException using the specified information. + * + * @param message A message explaining the exception condition + * @param entityName The name of the entity, containing the property + * @param propertyName The name of the property being accessed. + */ + public PropertyValueException(String message, String entityName, String propertyName) { + super(message); this.entityName = entityName; this.propertyName = propertyName; } @@ -56,25 +61,6 @@ public String getPropertyName() { @Override public String getMessage() { - return super.getMessage() + ": " + - StringHelper.qualify(entityName, propertyName); - } - - /** - * Return a well formed property path. - * Basicaly, it will return parent.child - * - * @param parent parent in path - * @param child child in path - * @return parent-child path - */ - public static String buildPropertyPath(String parent, String child) { - return new StringBuilder(parent).append('.').append(child).toString(); + return super.getMessage() + " : " + StringHelper.qualify( entityName, propertyName ); } } - - - - - - diff --git a/hibernate-core/src/main/java/org/hibernate/Query.java b/hibernate-core/src/main/java/org/hibernate/Query.java index c8f202b4f7..8f2a1f7d4f 100644 --- a/hibernate-core/src/main/java/org/hibernate/Query.java +++ b/hibernate-core/src/main/java/org/hibernate/Query.java @@ -99,6 +99,8 @@ public interface Query extends BasicQueryContract { * * @param maxResults the maximum number of rows * + * @return {@code this}, for method chaining + * * @see #getMaxResults() */ public Query setMaxResults(int maxResults); @@ -117,6 +119,8 @@ public interface Query extends BasicQueryContract { * * @param firstResult a row number, numbered from 0 * + * @return {@code this}, for method chaining + * * @see #getFirstResult() */ public Query setFirstResult(int firstResult); @@ -159,6 +163,8 @@ public interface Query extends BasicQueryContract { * * For alias-specific locking, use {@link #setLockMode(String, LockMode)}. * + * @return {@code this}, for method chaining + * * @see #getLockOptions() */ public Query setLockOptions(LockOptions lockOptions); @@ -175,6 +181,8 @@ public interface Query extends BasicQueryContract { * * @param alias a query alias, or this for a collection filter * + * @return {@code this}, for method chaining + * * @see #getLockOptions() */ public Query setLockMode(String alias, LockMode lockMode); @@ -194,21 +202,25 @@ public interface Query extends BasicQueryContract { * * @param comment The human-readable comment * + * @return {@code this}, for method chaining + * * @see #getComment() */ public Query setComment(String comment); /** * Return the HQL select clause aliases (if any) + * * @return an array of aliases as strings */ - public String[] getReturnAliases() throws HibernateException; + public String[] getReturnAliases(); /** * Return the names of all named parameters of the query. + * * @return the parameter names, in no particular order */ - public String[] getNamedParameters() throws HibernateException; + public String[] getNamedParameters(); /** * Return the query results as an Iterator. If the query @@ -219,9 +231,8 @@ public interface Query extends BasicQueryContract { * SQL query returns identifiers only.
* * @return the result iterator - * @throws HibernateException */ - public Iterator iterate() throws HibernateException; + public Iterator iterate(); /** * Return the query results as ScrollableResults. The @@ -229,10 +240,10 @@ public interface Query extends BasicQueryContract { * support for scrollable ResultSets.
* * @see ScrollableResults + * * @return the result iterator - * @throws HibernateException */ - public ScrollableResults scroll() throws HibernateException; + public ScrollableResults scroll(); /** * Return the query results as ScrollableResults. The @@ -241,10 +252,10 @@ public interface Query extends BasicQueryContract { * * @see ScrollableResults * @see ScrollMode + * * @return the result iterator - * @throws HibernateException */ - public ScrollableResults scroll(ScrollMode scrollMode) throws HibernateException; + public ScrollableResults scroll(ScrollMode scrollMode); /** * Return the query results as a List. If the query contains @@ -252,18 +263,18 @@ public interface Query extends BasicQueryContract { * of Object[]. * * @return the result list - * @throws HibernateException */ - public List list() throws HibernateException; + public List list(); /** * Convenience method to return a single instance that matches * the query, or null if the query returns no results. * * @return the single result or null + * * @throws NonUniqueResultException if there is more than one matching result */ - public Object uniqueResult() throws HibernateException; + public Object uniqueResult(); /** * Execute the update or delete statement. @@ -272,24 +283,29 @@ public interface Query extends BasicQueryContract { * method. * * @return The number of entities updated or deleted. - * @throws HibernateException */ - public int executeUpdate() throws HibernateException; + public int executeUpdate(); /** * Bind a value to a JDBC-style query parameter. + * * @param position the position of the parameter in the query * string, numbered from 0. * @param val the possibly-null parameter value * @param type the Hibernate type + * + * @return {@code this}, for method chaining */ public Query setParameter(int position, Object val, Type type); /** * Bind a value to a named query parameter. + * * @param name the name of the parameter * @param val the possibly-null parameter value * @param type the Hibernate type + * + * @return {@code this}, for method chaining */ public Query setParameter(String name, Object val, Type type); @@ -297,79 +313,110 @@ public interface Query extends BasicQueryContract { * Bind a value to a JDBC-style query parameter. The Hibernate type of the parameter is * first detected via the usage/position in the query and if not sufficient secondly * guessed from the class of the given object. + * * @param position the position of the parameter in the query * string, numbered from 0. * @param val the non-null parameter value - * @throws org.hibernate.HibernateException if no type could be determined + * + * @return {@code this}, for method chaining */ - public Query setParameter(int position, Object val) throws HibernateException; + public Query setParameter(int position, Object val); /** * Bind a value to a named query parameter. The Hibernate type of the parameter is * first detected via the usage/position in the query and if not sufficient secondly * guessed from the class of the given object. + * * @param name the name of the parameter * @param val the non-null parameter value - * @throws org.hibernate.HibernateException if no type could be determined + * + * @return {@code this}, for method chaining */ - public Query setParameter(String name, Object val) throws HibernateException; + public Query setParameter(String name, Object val); /** - * Bind values and types to positional parameters. + * Bind values and types to positional parameters. Allows binding more than one at a time; no real performance + * impact. + * + * The number of elements in each array should match. That is, element number-0 in types array corresponds to + * element-0 in the values array, etc, + * + * @param types The types + * @param values The values + * + * @return {@code this}, for method chaining */ - public Query setParameters(Object[] values, Type[] types) throws HibernateException; + public Query setParameters(Object[] values, Type[] types); /** * Bind multiple values to a named query parameter. This is useful for binding * a list of values to an expression such as foo.bar in (:value_list). + * * @param name the name of the parameter - * @param vals a collection of values to list + * @param values a collection of values to list * @param type the Hibernate type of the values + * + * @return {@code this}, for method chaining */ - public Query setParameterList(String name, Collection vals, Type type) throws HibernateException; + public Query setParameterList(String name, Collection values, Type type); /** * Bind multiple values to a named query parameter. The Hibernate type of the parameter is * first detected via the usage/position in the query and if not sufficient secondly * guessed from the class of the first object in the collection. This is useful for binding a list of values * to an expression such as foo.bar in (:value_list). + * * @param name the name of the parameter - * @param vals a collection of values to list + * @param values a collection of values to list + * + * @return {@code this}, for method chaining */ - public Query setParameterList(String name, Collection vals) throws HibernateException; + public Query setParameterList(String name, Collection values); /** * Bind multiple values to a named query parameter. This is useful for binding * a list of values to an expression such as foo.bar in (:value_list). + * * @param name the name of the parameter - * @param vals a collection of values to list + * @param values a collection of values to list * @param type the Hibernate type of the values + * + * @return {@code this}, for method chaining */ - public Query setParameterList(String name, Object[] vals, Type type) throws HibernateException; + public Query setParameterList(String name, Object[] values, Type type); /** * Bind multiple values to a named query parameter. The Hibernate type of the parameter is * first detected via the usage/position in the query and if not sufficient secondly * guessed from the class of the first object in the array. This is useful for binding a list of values * to an expression such as foo.bar in (:value_list). + * * @param name the name of the parameter - * @param vals a collection of values to list + * @param values a collection of values to list + * + * @return {@code this}, for method chaining */ - public Query setParameterList(String name, Object[] vals) throws HibernateException; + public Query setParameterList(String name, Object[] values); /** * Bind the property values of the given bean to named parameters of the query, * matching property names with parameter names and mapping property types to - * Hibernate types using hueristics. + * Hibernate types using heuristics. + * * @param bean any JavaBean or POJO + * + * @return {@code this}, for method chaining */ public Query setProperties(Object bean) throws HibernateException; /** * Bind the values of the given Map for each named parameters of the query, * matching key names with parameter names and mapping value types to - * Hibernate types using hueristics. + * Hibernate types using heuristics. + * * @param bean a java.util.Map + * + * @return {@code this}, for method chaining */ public Query setProperties(Map bean) throws HibernateException; @@ -412,28 +459,34 @@ public interface Query extends BasicQueryContract { public Query setBigDecimal(String name, BigDecimal number); public Query setBigInteger(String name, BigInteger number); - /** - * Bind the date (time is truncated) of a given Date object to a named query parameter. - * + /** + * Bind the date (time is truncated) of a given Date object to a named query parameter. + * * @param name The name of the parameter * @param date The date object - */ + * + * @return {@code this}, for method chaining + */ public Query setDate(String name, Date date); - /** - * Bind the time (date is truncated) of a given Date object to a named query parameter. - * + /** + * Bind the time (date is truncated) of a given Date object to a named query parameter. + * * @param name The name of the parameter * @param date The date object - */ + * + * @return {@code this}, for method chaining + */ public Query setTime(String name, Date date); - /** - * Bind the date and the time of a given Date object to a named query parameter. - * + /** + * Bind the date and the time of a given Date object to a named query parameter. + * * @param name The name of the parameter * @param date The date object - */ + * + * @return {@code this}, for method chaining + */ public Query setTimestamp(String name, Date date); public Query setCalendar(String name, Calendar calendar); @@ -441,16 +494,22 @@ public interface Query extends BasicQueryContract { /** * Bind an instance of a mapped persistent class to a JDBC-style query parameter. + * * @param position the position of the parameter in the query * string, numbered from 0. * @param val a non-null instance of a persistent class + * + * @return {@code this}, for method chaining */ public Query setEntity(int position, Object val); // use setParameter for null values /** * Bind an instance of a mapped persistent class to a named query parameter. + * * @param name the name of the parameter * @param val a non-null instance of a persistent class + * + * @return {@code this}, for method chaining */ public Query setEntity(String name, Object val); // use setParameter for null values @@ -460,7 +519,7 @@ public interface Query extends BasicQueryContract { * "shape" of the query result. * * @param transformer The transformer to apply - * @return this (for method chaining) + * @return this (for method chaining) */ public Query setResultTransformer(ResultTransformer transformer); diff --git a/hibernate-core/src/main/java/org/hibernate/QueryException.java b/hibernate-core/src/main/java/org/hibernate/QueryException.java index c6658b81fd..79cc8cab62 100644 --- a/hibernate-core/src/main/java/org/hibernate/QueryException.java +++ b/hibernate-core/src/main/java/org/hibernate/QueryException.java @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2008, 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,45 +20,90 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate; +import org.jboss.logging.Logger; /** - * A problem occurred translating a Hibernate query to SQL - * due to invalid query syntax, etc. + * A problem occurred translating a Hibernate query to SQL due to invalid query syntax, etc. */ public class QueryException extends HibernateException { + private static final Logger log = Logger.getLogger( QueryException.class ); private String queryString; + /** + * Constructs a QueryException using the specified exception message + * + * @param message A message explaining the exception condition + */ public QueryException(String message) { super(message); } - public QueryException(String message, Throwable e) { - super(message, e); + + /** + * Constructs a QueryException using the specified exception message and cause + * + * @param message A message explaining the exception condition + * @param cause The underlying cause + */ + public QueryException(String message, Throwable cause) { + super(message, cause); } + /** + * Constructs a QueryException using the specified exception message and query-string + * + * @param message A message explaining the exception condition + * @param queryString The query being evaluated when the exception occurred + */ public QueryException(String message, String queryString) { super(message); this.queryString = queryString; } - public QueryException(Exception e) { - super(e); + /** + * Constructs a QueryException using the specified cause + * + * @param cause The underlying cause + */ + public QueryException(Exception cause) { + super(cause); } + + /** + * Retrieve the query being evaluated when the exception occurred. May be null, but generally should not. + * + * @return The query string + */ public String getQueryString() { return queryString; } + /** + * Set the query string. EVen an option, since often the part of the code generating the exception does not + * have access to the query overall. + * + * @param queryString The query string. + */ public void setQueryString(String queryString) { + if ( this.queryString != null ) { + log.debugf( + "queryString overriding non-null previous value [%s] : %s", + this.queryString, + queryString + ); + } this.queryString = queryString; } + @Override public String getMessage() { String msg = super.getMessage(); - if ( queryString!=null ) msg += " [" + queryString + ']'; + if ( queryString!=null ) { + msg += " [" + queryString + ']'; + } return msg; } diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/Ejb3JoinColumn.java b/hibernate-core/src/main/java/org/hibernate/cfg/Ejb3JoinColumn.java index 270ed3192a..bcc79fd21f 100644 --- a/hibernate-core/src/main/java/org/hibernate/cfg/Ejb3JoinColumn.java +++ b/hibernate-core/src/main/java/org/hibernate/cfg/Ejb3JoinColumn.java @@ -556,7 +556,7 @@ public static int checkReferencedColumnsType( ); } catch (MappingException e) { - throw new RecoverableException(e); + throw new RecoverableException( e.getMessage(), e ); } } Table matchingTable = columnOwner instanceof PersistentClass ? diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/RecoverableException.java b/hibernate-core/src/main/java/org/hibernate/cfg/RecoverableException.java index 3b320f1041..daa351da5b 100644 --- a/hibernate-core/src/main/java/org/hibernate/cfg/RecoverableException.java +++ b/hibernate-core/src/main/java/org/hibernate/cfg/RecoverableException.java @@ -22,25 +22,35 @@ * Boston, MA 02110-1301 USA */ package org.hibernate.cfg; + import org.hibernate.AnnotationException; /** - * Should neven be exposed to the client - * An exception that wrap an underlying exception whith the hope - * subsequent processing will recover from it. + * An exception that indicates a condition where the hope is that subsequent processing will be able to + * recover from it. + * + * @deprecated Was only ever referenced in a single place, in an extremely dubious way. * * @author Emmanuel Bernard */ +@Deprecated public class RecoverableException extends AnnotationException { - public RecoverableException(String msg, Throwable root) { - super( msg, root ); + /** + * Constructs a RecoverableException using the given message and underlying cause. + * + * @param msg The message explaining the condition that caused the exception + * @param cause The underlying exception + */ + public RecoverableException(String msg, Throwable cause) { + super( msg, cause ); } - public RecoverableException(Throwable root) { - super( root ); - } - - public RecoverableException(String s) { - super( s ); + /** + * Constructs a RecoverableException using the given message and underlying cause. + * + * @param msg + */ + public RecoverableException(String msg) { + super( msg ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/internal/AbstractQueryImpl.java b/hibernate-core/src/main/java/org/hibernate/internal/AbstractQueryImpl.java index 3aa6b0d166..5dfaaeb249 100644 --- a/hibernate-core/src/main/java/org/hibernate/internal/AbstractQueryImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/internal/AbstractQueryImpl.java @@ -887,8 +887,8 @@ public Query setParameterList(String name, Object[] vals, Type type) throws Hibe return setParameterList( name, Arrays.asList(vals), type ); } - public Query setParameterList(String name, Object[] vals) throws HibernateException { - return setParameterList( name, Arrays.asList(vals) ); + public Query setParameterList(String name, Object[] values) throws HibernateException { + return setParameterList( name, Arrays.asList( values ) ); } public Query setProperties(Map map) throws HibernateException { diff --git a/shared/config/checkstyle/checkstyle.xml b/shared/config/checkstyle/checkstyle.xml index 7e74a79d35..9c2e410d7f 100644 --- a/shared/config/checkstyle/checkstyle.xml +++ b/shared/config/checkstyle/checkstyle.xml @@ -25,6 +25,14 @@ + + @@ -88,9 +96,6 @@ - - - diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ANSICaseFragment.java b/hibernate-core/src/main/java/org/hibernate/sql/ANSICaseFragment.java index c76a8beca2..21556b80bd 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/ANSICaseFragment.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/ANSICaseFragment.java @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2008, 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,33 +20,31 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.sql; -import java.util.Iterator; + import java.util.Map; /** - An ANSI SQL CASE expression. -
- case when ... then ... end as ... -
- @author Gavin King, Simon Harris + * An ANSI SQL CASE expression : {@code case when ... then ... end as ..} + * + * @author Gavin King + * @author Simon Harris */ public class ANSICaseFragment extends CaseFragment { + @Override public String toFragmentString() { - StringBuilder buf = new StringBuilder( cases.size() * 15 + 10 ) + final StringBuilder buf = new StringBuilder( cases.size() * 15 + 10 ) .append("case"); - Iterator iter = cases.entrySet().iterator(); - while ( iter.hasNext() ) { - Map.Entry me = (Map.Entry) iter.next(); - buf.append(" when ") - .append( me.getKey() ) - .append(" is not null then ") - .append( me.getValue() ); + for ( Object o : cases.entrySet() ) { + Map.Entry me = (Map.Entry) o; + buf.append( " when " ) + .append( me.getKey() ) + .append( " is not null then " ) + .append( me.getValue() ); } buf.append(" end"); @@ -59,4 +57,4 @@ public String toFragmentString() { return buf.toString(); } -} \ No newline at end of file +} diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ANSIJoinFragment.java b/hibernate-core/src/main/java/org/hibernate/sql/ANSIJoinFragment.java index 905f73a964..baf2bb7315 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/ANSIJoinFragment.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/ANSIJoinFragment.java @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2008, 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,27 +20,45 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.sql; + import org.hibernate.AssertionFailure; /** - * An ANSI-style join + * An ANSI-style join. * * @author Gavin King */ public class ANSIJoinFragment extends JoinFragment { - private StringBuilder buffer = new StringBuilder(); private StringBuilder conditions = new StringBuilder(); + /** + * Adds a join, represented by the given information, to the fragment. + * + * @param tableName The name of the table being joined. + * @param alias The alias applied to the table being joined. + * @param fkColumns The columns (from the table being joined) used to define the join-restriction (the ON) + * @param pkColumns The columns (from the table being joined to) used to define the join-restriction (the ON) + * @param joinType The type of join to produce (INNER, etc). + */ public void addJoin(String tableName, String alias, String[] fkColumns, String[] pkColumns, JoinType joinType) { - addJoin(tableName, alias, fkColumns, pkColumns, joinType, null); + addJoin( tableName, alias, fkColumns, pkColumns, joinType, null ); } + /** + * Adds a join, represented by the given information, to the fragment. + * + * @param tableName The name of the table being joined. + * @param alias The alias applied to the table being joined. + * @param fkColumns The columns (from the table being joined) used to define the join-restriction (the ON) + * @param pkColumns The columns (from the table being joined to) used to define the join-restriction (the ON) + * @param joinType The type of join to produce (INNER, etc). + * @param on Any extra join restrictions + */ public void addJoin(String tableName, String alias, String[] fkColumns, String[] pkColumns, JoinType joinType, String on) { - String joinString; + final String joinString; switch (joinType) { case INNER_JOIN: joinString = " inner join "; @@ -58,7 +76,7 @@ public void addJoin(String tableName, String alias, String[] fkColumns, String[] throw new AssertionFailure("undefined join type"); } - buffer.append(joinString) + this.buffer.append(joinString) .append(tableName) .append(' ') .append(alias) @@ -66,74 +84,87 @@ public void addJoin(String tableName, String alias, String[] fkColumns, String[] for ( int j=0; j @@ -65,9 +65,6 @@ - @@ -76,6 +73,9 @@ + + + @@ -90,6 +90,7 @@ + @@ -99,10 +100,19 @@ + + + + - From ea9f478e0f30d3625b7611431415f535fdae5bb4 Mon Sep 17 00:00:00 2001 From: Steve Ebersole Date: Tue, 9 Apr 2013 12:58:18 -0500 Subject: [PATCH 16/54] HHH-8159 - Apply fixups indicated by analysis tools --- shared/config/checkstyle/checkstyle.xml | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/shared/config/checkstyle/checkstyle.xml b/shared/config/checkstyle/checkstyle.xml index 6eed3ff844..930d7cbfbd 100644 --- a/shared/config/checkstyle/checkstyle.xml +++ b/shared/config/checkstyle/checkstyle.xml @@ -73,9 +73,6 @@ - - - @@ -138,6 +135,12 @@ + + + + + + From 9ace3a6a082cb0784f7146530b94081f52303685 Mon Sep 17 00:00:00 2001 From: Brett Meyer Date: Tue, 9 Apr 2013 13:39:09 -0400 Subject: [PATCH 17/54] HHH-7617 Gradle eclipse task missing src paths and test source generation --- build.gradle | 2 ++ 1 file changed, 2 insertions(+) diff --git a/build.gradle b/build.gradle index 83764a2d3f..2ea0319202 100644 --- a/build.gradle +++ b/build.gradle @@ -305,6 +305,8 @@ subprojects { subProject -> plusConfigurations.add( configurations.provided ) } } + // eclipseClasspath will not add sources to classpath unless the dirs actually exist. + eclipseClasspath.dependsOn("generateSources") // Report configs ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ checkstyle { From 34e7512c76b4634fbb264df5e71fcf5fa12d447f Mon Sep 17 00:00:00 2001 From: Steve Ebersole Date: Tue, 9 Apr 2013 19:38:12 -0500 Subject: [PATCH 18/54] HHH-8159 - Apply fixups indicated by analysis tools --- build.gradle | 18 +++ .../main/java/org/hibernate/ScrollMode.java | 4 +- .../hibernate/StaleObjectStateException.java | 2 +- .../org/hibernate/action/spi/Executable.java | 7 +- .../hibernate/action/spi/package-info.java | 5 + .../org/hibernate/annotations/AccessType.java | 9 +- .../org/hibernate/annotations/AnyMetaDef.java | 5 +- .../hibernate/annotations/AnyMetaDefs.java | 3 + .../annotations/AttributeAccessor.java | 2 +- .../org/hibernate/annotations/BatchSize.java | 2 +- .../java/org/hibernate/annotations/Cache.java | 20 ++- .../annotations/CacheConcurrencyStrategy.java | 58 ++++++- .../hibernate/annotations/CacheModeType.java | 87 ++++++++++- .../org/hibernate/annotations/Cascade.java | 3 + .../hibernate/annotations/CascadeType.java | 45 +++++- .../java/org/hibernate/annotations/Check.java | 6 +- .../hibernate/annotations/CollectionId.java | 17 +- .../hibernate/annotations/CollectionType.java | 12 +- .../annotations/ColumnTransformer.java | 8 +- .../annotations/ColumnTransformers.java | 4 + .../org/hibernate/annotations/Columns.java | 4 + .../annotations/DiscriminatorFormula.java | 4 + .../annotations/DiscriminatorOptions.java | 13 +- .../hibernate/annotations/DynamicInsert.java | 4 + .../hibernate/annotations/DynamicUpdate.java | 5 + .../org/hibernate/annotations/Entity.java | 23 ++- .../java/org/hibernate/annotations/Fetch.java | 8 +- .../org/hibernate/annotations/FetchMode.java | 12 +- .../hibernate/annotations/FetchProfile.java | 26 +++- .../hibernate/annotations/FetchProfiles.java | 13 +- .../org/hibernate/annotations/Filter.java | 19 ++- .../org/hibernate/annotations/FilterDef.java | 11 +- .../org/hibernate/annotations/FilterDefs.java | 5 +- .../annotations/FilterJoinTable.java | 21 ++- .../annotations/FilterJoinTables.java | 8 +- .../org/hibernate/annotations/Filters.java | 5 +- .../hibernate/annotations/FlushModeType.java | 19 ++- .../org/hibernate/annotations/ForeignKey.java | 12 +- .../org/hibernate/annotations/Formula.java | 4 + .../org/hibernate/annotations/Generated.java | 8 +- .../hibernate/annotations/GenerationTime.java | 14 +- .../annotations/GenericGenerator.java | 10 +- .../annotations/GenericGenerators.java | 6 +- .../java/org/hibernate/annotations/Index.java | 9 +- .../hibernate/annotations/IndexColumn.java | 26 +++- .../annotations/JoinColumnOrFormula.java | 13 +- .../annotations/JoinColumnsOrFormulas.java | 5 + .../hibernate/annotations/JoinFormula.java | 13 +- .../hibernate/annotations/LazyCollection.java | 8 +- .../annotations/LazyCollectionOption.java | 17 +- .../org/hibernate/annotations/LazyToOne.java | 9 +- .../annotations/LazyToOneOption.java | 24 +-- .../org/hibernate/annotations/Loader.java | 6 +- .../org/hibernate/annotations/MapKeyType.java | 4 + .../org/hibernate/annotations/MetaValue.java | 4 +- .../annotations/NamedNativeQueries.java | 9 +- .../annotations/NamedNativeQuery.java | 61 ++++++-- .../hibernate/annotations/NamedQueries.java | 9 +- .../org/hibernate/annotations/NamedQuery.java | 24 +-- .../org/hibernate/annotations/NaturalId.java | 6 +- .../org/hibernate/annotations/NotFound.java | 3 + .../hibernate/annotations/NotFoundAction.java | 7 +- .../org/hibernate/annotations/OnDelete.java | 7 +- .../hibernate/annotations/OnDeleteAction.java | 7 +- .../hibernate/annotations/OptimisticLock.java | 3 +- .../annotations/OptimisticLockType.java | 16 +- .../annotations/OptimisticLocking.java | 3 + .../org/hibernate/annotations/OrderBy.java | 9 +- .../org/hibernate/annotations/ParamDef.java | 11 +- .../org/hibernate/annotations/Parameter.java | 8 +- .../org/hibernate/annotations/Parent.java | 2 +- .../org/hibernate/annotations/Persister.java | 2 +- .../hibernate/annotations/Polymorphism.java | 3 + .../annotations/PolymorphismType.java | 7 +- .../java/org/hibernate/annotations/Proxy.java | 7 +- .../org/hibernate/annotations/QueryHints.java | 75 ++++++++- .../annotations/ResultCheckStyle.java | 11 +- .../java/org/hibernate/annotations/RowId.java | 6 +- .../org/hibernate/annotations/SQLDelete.java | 7 +- .../hibernate/annotations/SQLDeleteAll.java | 7 +- .../org/hibernate/annotations/SQLInsert.java | 7 +- .../org/hibernate/annotations/SQLUpdate.java | 8 +- .../annotations/SelectBeforeUpdate.java | 5 + .../java/org/hibernate/annotations/Sort.java | 17 +- .../org/hibernate/annotations/SortType.java | 12 +- .../org/hibernate/annotations/Source.java | 9 +- .../org/hibernate/annotations/SourceType.java | 13 +- .../annotations/SqlFragmentAlias.java | 14 +- .../org/hibernate/annotations/Subselect.java | 10 +- .../hibernate/annotations/Synchronize.java | 7 +- .../java/org/hibernate/annotations/Table.java | 18 +-- .../org/hibernate/annotations/Tables.java | 7 +- .../org/hibernate/annotations/Target.java | 8 +- .../org/hibernate/annotations/Tuplizer.java | 17 +- .../org/hibernate/annotations/Tuplizers.java | 9 +- .../java/org/hibernate/annotations/Type.java | 21 ++- .../org/hibernate/annotations/TypeDef.java | 28 +++- .../org/hibernate/annotations/TypeDefs.java | 6 +- .../java/org/hibernate/annotations/Where.java | 8 +- .../hibernate/annotations/WhereJoinTable.java | 10 +- .../hibernate/annotations/package-info.java | 4 + shared/config/checkstyle/public_checks.xml | 145 ++++++++++++++++++ 102 files changed, 1103 insertions(+), 299 deletions(-) create mode 100644 hibernate-core/src/main/java/org/hibernate/action/spi/package-info.java create mode 100644 hibernate-core/src/main/java/org/hibernate/annotations/package-info.java create mode 100644 shared/config/checkstyle/public_checks.xml diff --git a/build.gradle b/build.gradle index 2ea0319202..ea9f8b682e 100644 --- a/build.gradle +++ b/build.gradle @@ -308,6 +308,24 @@ subprojects { subProject -> // eclipseClasspath will not add sources to classpath unless the dirs actually exist. eclipseClasspath.dependsOn("generateSources") + // specialized API/SPI checkstyle tasks ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + task checkstylePublicSources(type: Checkstyle) { + checkstyleClasspath = checkstyleMain.checkstyleClasspath + classpath = checkstyleMain.classpath + configFile = rootProject.file( 'shared/config/checkstyle/public_checks.xml' ) + source subProject.sourceSets.main.originalJavaSrcDirs + exclude '**/internal/**' + exclude '**/internal/*' + ignoreFailures = false + showViolations = true + reports { + xml { + destination "$buildDir/reports/checkstyle/public.xml" + } + } + } + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // Report configs ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ checkstyle { configFile = rootProject.file( 'shared/config/checkstyle/checkstyle.xml' ) diff --git a/hibernate-core/src/main/java/org/hibernate/ScrollMode.java b/hibernate-core/src/main/java/org/hibernate/ScrollMode.java index 223f6018da..17d227748f 100755 --- a/hibernate-core/src/main/java/org/hibernate/ScrollMode.java +++ b/hibernate-core/src/main/java/org/hibernate/ScrollMode.java @@ -40,14 +40,14 @@ public enum ScrollMode { FORWARD_ONLY( ResultSet.TYPE_FORWARD_ONLY ), /** - * Requests a scrollable result which is sensitive to changes in the underlying data + * Requests a scrollable result which is sensitive to changes in the underlying data. * * @see java.sql.ResultSet#TYPE_SCROLL_SENSITIVE */ SCROLL_SENSITIVE( ResultSet.TYPE_SCROLL_SENSITIVE ), /** - * Requests a scrollable result which is insensitive to changes in the underlying data + * Requests a scrollable result which is insensitive to changes in the underlying data. * * Note that since the Hibernate session acts as a cache, you * might need to explicitly evict objects, if you need to see diff --git a/hibernate-core/src/main/java/org/hibernate/StaleObjectStateException.java b/hibernate-core/src/main/java/org/hibernate/StaleObjectStateException.java index 49f59c8ab1..e10ccd6cb2 100644 --- a/hibernate-core/src/main/java/org/hibernate/StaleObjectStateException.java +++ b/hibernate-core/src/main/java/org/hibernate/StaleObjectStateException.java @@ -38,7 +38,7 @@ public class StaleObjectStateException extends StaleStateException { private final Serializable identifier; /** - * Constructs a StaleObjectStateException using the supplied information + * Constructs a StaleObjectStateException using the supplied information. * * @param entityName The name of the entity * @param identifier The identifier of the entity diff --git a/hibernate-core/src/main/java/org/hibernate/action/spi/Executable.java b/hibernate-core/src/main/java/org/hibernate/action/spi/Executable.java index d44c3b4f96..737544c69f 100644 --- a/hibernate-core/src/main/java/org/hibernate/action/spi/Executable.java +++ b/hibernate-core/src/main/java/org/hibernate/action/spi/Executable.java @@ -28,9 +28,8 @@ import org.hibernate.HibernateException; /** - * An operation which may be scheduled for later execution. - * Usually, the operation is a database insert/update/delete, - * together with required second-level cache management. + * An operation which may be scheduled for later execution. Usually, the operation is a database + * insert/update/delete, together with required second-level cache management. * * @author Gavin King * @author Steve Ebersole @@ -51,7 +50,7 @@ public interface Executable { public void beforeExecutions() throws HibernateException; /** - * Execute this action + * Execute this action. * * @throws HibernateException Indicates a problem during execution. */ diff --git a/hibernate-core/src/main/java/org/hibernate/action/spi/package-info.java b/hibernate-core/src/main/java/org/hibernate/action/spi/package-info.java new file mode 100644 index 0000000000..b364028e4c --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/action/spi/package-info.java @@ -0,0 +1,5 @@ +/** + * Defines SPI hooks into the {@link org.hibernate.engine.spi.ActionQueue}. Mainly for registering custom + * {@link AfterTransactionCompletionProcess} and {@link BeforeTransactionCompletionProcess} hooks. + */ +package org.hibernate.action.spi; diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/AccessType.java b/hibernate-core/src/main/java/org/hibernate/annotations/AccessType.java index af2e72b8ca..94c5eb0329 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/AccessType.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/AccessType.java @@ -22,6 +22,7 @@ * Boston, MA 02110-1301 USA */ package org.hibernate.annotations; + import java.lang.annotation.Retention; import java.lang.annotation.Target; @@ -31,9 +32,8 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME; /** - * Property Access type - * - * Prefer the standard {@link javax.persistence.Access} annotation + * Property Access type. Prefer the standard {@link javax.persistence.Access} annotation; however, + * {@code @Access} is limited to field/property access definitions. * * @author Emmanuel Bernard * @@ -44,5 +44,8 @@ @Retention(RUNTIME) @Deprecated public @interface AccessType { + /** + * The access strategy name. + */ String value(); } diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/AnyMetaDef.java b/hibernate-core/src/main/java/org/hibernate/annotations/AnyMetaDef.java index e7cac8a031..6df8303ec1 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/AnyMetaDef.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/AnyMetaDef.java @@ -22,6 +22,7 @@ * Boston, MA 02110-1301 USA */ package org.hibernate.annotations; + import java.lang.annotation.Retention; import static java.lang.annotation.ElementType.FIELD; @@ -42,8 +43,8 @@ @Retention( RUNTIME ) public @interface AnyMetaDef { /** - * If defined, assign a global meta definition name to be used in an @Any or @ManyToAny annotation - * If not defined, the metadata applies to the current property or field + * If defined, assign a global meta definition name to be used in an @Any or @ManyToAny annotation. If + * not defined, the metadata applies to the current property or field. */ String name() default ""; diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/AnyMetaDefs.java b/hibernate-core/src/main/java/org/hibernate/annotations/AnyMetaDefs.java index 0de690efa7..6db78268da 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/AnyMetaDefs.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/AnyMetaDefs.java @@ -38,5 +38,8 @@ @java.lang.annotation.Target( { PACKAGE, TYPE } ) @Retention( RUNTIME ) public @interface AnyMetaDefs { + /** + * The collective set of any meta-defs. + */ AnyMetaDef[] value(); } diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/AttributeAccessor.java b/hibernate-core/src/main/java/org/hibernate/annotations/AttributeAccessor.java index 32991f4865..0b33363101 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/AttributeAccessor.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/AttributeAccessor.java @@ -55,7 +55,7 @@ @Retention(RUNTIME) public @interface AttributeAccessor { /** - * Names the {@link org.hibernate.property.PropertyAccessor} strategy + * Names the {@link org.hibernate.property.PropertyAccessor} strategy. */ String value(); } diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/BatchSize.java b/hibernate-core/src/main/java/org/hibernate/annotations/BatchSize.java index 414af5199c..49c3e625ef 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/BatchSize.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/BatchSize.java @@ -56,7 +56,7 @@ @Retention(RUNTIME) public @interface BatchSize { /** - * Strictly positive integer + * Strictly positive integer. */ int size(); } diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/Cache.java b/hibernate-core/src/main/java/org/hibernate/annotations/Cache.java index 8fd717be64..77f943c2bd 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/Cache.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/Cache.java @@ -31,20 +31,26 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME; /** - * Add caching strategy to a root entity or a collection + * Add caching strategy to a root entity or a collection. * * @author Emmanuel Bernard */ @Target({TYPE, METHOD, FIELD}) @Retention(RUNTIME) public @interface Cache { - /** concurrency strategy chosen */ - CacheConcurrencyStrategy usage(); - /** cache region name */ - String region() default ""; /** - * whether or not lazy-properties are included in the second level cache - * default all, other value: non-lazy + * The concurrency strategy chosen. + */ + CacheConcurrencyStrategy usage(); + + /** + * The cache region name. + */ + String region() default ""; + + /** + * How lazy properties are included in the second level cache. Default value is "all"; other allowable + * value: "non-lazy" */ String include() default "all"; } diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/CacheConcurrencyStrategy.java b/hibernate-core/src/main/java/org/hibernate/annotations/CacheConcurrencyStrategy.java index 10d15d2384..ab2c26aaa6 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/CacheConcurrencyStrategy.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/CacheConcurrencyStrategy.java @@ -26,15 +26,38 @@ import org.hibernate.cache.spi.access.AccessType; /** - * Cache concurrency strategy + * Cache concurrency strategy. * * @author Emmanuel Bernard */ public enum CacheConcurrencyStrategy { + /** + * Indicates no concurrency strategy should be applied. + */ NONE( null ), + /** + * Indicates that read-only strategy should be applied. + * + * @see AccessType#READ_ONLY + */ READ_ONLY( AccessType.READ_ONLY ), + /** + * Indicates that the non-strict read-write strategy should be applied. + * + * @see AccessType#NONSTRICT_READ_WRITE + */ NONSTRICT_READ_WRITE( AccessType.NONSTRICT_READ_WRITE ), + /** + * Indicates that the read-write strategy should be applied. + * + * @see AccessType#READ_WRITE + */ READ_WRITE( AccessType.READ_WRITE ), + /** + * Indicates that the transaction strategy should be applied. + * + * @see AccessType#TRANSACTIONAL + */ TRANSACTIONAL( AccessType.TRANSACTIONAL ); private final AccessType accessType; @@ -43,13 +66,26 @@ private CacheConcurrencyStrategy(AccessType accessType) { this.accessType = accessType; } - private boolean isMatch(String name) { - return ( accessType != null && accessType.getExternalName().equalsIgnoreCase( name ) ) - || name().equalsIgnoreCase( name ); + /** + * Get the AccessType corresponding to this concurrency strategy. + * + * @return The corresponding concurrency strategy. Note that this will return {@code null} for + * {@link #NONE} + */ + public AccessType toAccessType() { + return accessType; } + /** + * Conversion from {@link AccessType} to {@link CacheConcurrencyStrategy}. + * + * @param accessType The access type to convert + * + * @return The corresponding enum value. {@link #NONE} is returned by default if unable to + * recognize {@code accessType} or if {@code accessType} is {@code null}. + */ public static CacheConcurrencyStrategy fromAccessType(AccessType accessType) { - if (null == accessType) { + if ( null == accessType ) { return NONE; } @@ -72,6 +108,13 @@ public static CacheConcurrencyStrategy fromAccessType(AccessType accessType) { } } + /** + * Parse an external representation of a CacheConcurrencyStrategy value. + * + * @param name The external representation + * + * @return The corresponding enum value, or {@code null} if not match was found. + */ public static CacheConcurrencyStrategy parse(String name) { if ( READ_ONLY.isMatch( name ) ) { return READ_ONLY; @@ -93,7 +136,8 @@ else if ( NONE.isMatch( name ) ) { } } - public AccessType toAccessType() { - return accessType; + private boolean isMatch(String name) { + return ( accessType != null && accessType.getExternalName().equalsIgnoreCase( name ) ) + || name().equalsIgnoreCase( name ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/CacheModeType.java b/hibernate-core/src/main/java/org/hibernate/annotations/CacheModeType.java index bd35ba9dec..d9fa888121 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/CacheModeType.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/CacheModeType.java @@ -23,6 +23,7 @@ */ package org.hibernate.annotations; +import org.hibernate.CacheMode; /** * Enumeration for the different interaction modes between the session and @@ -31,11 +32,83 @@ * @author Emmanuel Bernard * @author Carlos Gonzalez-Cadenas */ - public enum CacheModeType { - GET, - IGNORE, - NORMAL, - PUT, - REFRESH -} \ No newline at end of file + /** + * Corresponds to {@link CacheMode#GET}. + * + * @see CacheMode#GET + */ + GET( CacheMode.GET ), + + /** + * Corresponds to {@link CacheMode#IGNORE}. + * + * @see CacheMode#IGNORE + */ + IGNORE( CacheMode.IGNORE ), + + /** + * Corresponds to {@link CacheMode#NORMAL}. + * + * @see CacheMode#NORMAL + */ + NORMAL( CacheMode.NORMAL ), + + /** + * Corresponds to {@link CacheMode#PUT}. + * + * @see CacheMode#PUT + */ + PUT( CacheMode.PUT ), + + /** + * Corresponds to {@link CacheMode#REFRESH}. + * + * @see CacheMode#REFRESH + */ + REFRESH( CacheMode.REFRESH ); + + private final CacheMode cacheMode; + + private CacheModeType(CacheMode cacheMode) { + this.cacheMode = cacheMode; + } + + public CacheMode getCacheMode() { + return cacheMode; + } + + /** + * Conversion from {@link CacheMode} to {@link CacheModeType}. + * + * @param cacheMode The cache mode to convert + * + * @return The corresponding enum value. Will be {@code null} if the given {@code accessType} is {@code null}. + */ + public static CacheModeType fromCacheMode(CacheMode cacheMode) { + if ( null == cacheMode ) { + return null; + } + + switch ( cacheMode ) { + case NORMAL: { + return NORMAL; + } + case GET: { + return GET; + } + case PUT: { + return PUT; + } + case REFRESH: { + return REFRESH; + } + case IGNORE: { + return IGNORE; + } + default: { + throw new IllegalArgumentException( "Unrecognized CacheMode : " + cacheMode ); + } + } + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/Cascade.java b/hibernate-core/src/main/java/org/hibernate/annotations/Cascade.java index 406adb7948..1c5f35d895 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/Cascade.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/Cascade.java @@ -40,5 +40,8 @@ @Target({METHOD, FIELD}) @Retention(RUNTIME) public @interface Cascade { + /** + * The cascade value. + */ CascadeType[] value(); } diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/CascadeType.java b/hibernate-core/src/main/java/org/hibernate/annotations/CascadeType.java index 2767b824c2..96ad7ec1f7 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/CascadeType.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/CascadeType.java @@ -23,25 +23,62 @@ */ package org.hibernate.annotations; - /** - * Cascade types (can override default JPA cascades + * Cascade types (can override default JPA cascades). */ public enum CascadeType { + /** + * Includes all types listed here. + */ ALL, + /** + * Corresponds to {@link javax.persistence.CascadeType#PERSIST}. + */ PERSIST, + /** + * Corresponds to {@link javax.persistence.CascadeType#MERGE}. + */ MERGE, + /** + * Corresponds to {@link javax.persistence.CascadeType#REMOVE}. + */ REMOVE, + /** + * Corresponds to {@link javax.persistence.CascadeType#REFRESH}. + */ REFRESH, + /** + * Corresponds to the Hibernate native DELETE action. + */ DELETE, + /** + * Corresponds to the Hibernate native SAVE_UPDATE (direct reattachment) action. + */ SAVE_UPDATE, + /** + * Corresponds to the Hibernate native REPLICATE action. + */ REPLICATE, - /** @deprecated use @OneToOne(orphanRemoval=true) or @OneToMany(orphanRemoval=true) */ + /** + * Hibernate originally handled orphan removal as a specialized cascade. + * + * @deprecated use @OneToOne(orphanRemoval=true) or @OneToMany(orphanRemoval=true) + */ @Deprecated DELETE_ORPHAN, + /** + * Corresponds to the Hibernate native LOCK action. + */ LOCK, - /** @deprecated use javax.persistence.CascadeType.DETACH */ + /** + * JPA originally planned on calling DETACH EVICT. + * + * @deprecated use javax.persistence.CascadeType.DETACH + */ @Deprecated EVICT, + /** + * Corresponds to {@link javax.persistence.CascadeType#REFRESH}. + */ DETACH } diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/Check.java b/hibernate-core/src/main/java/org/hibernate/annotations/Check.java index 4929f71fbd..fd3ceb761d 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/Check.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/Check.java @@ -22,6 +22,7 @@ * Boston, MA 02110-1301 USA */ package org.hibernate.annotations; + import java.lang.annotation.Retention; import java.lang.annotation.Target; @@ -31,12 +32,15 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME; /** - * Arbitrary SQL CHECK constraints which can be defined at the class, property or collection level + * Arbitrary SQL CHECK constraints which can be defined at the class, property or collection level. * * @author Emmanuel Bernard */ @Target({TYPE, METHOD, FIELD}) @Retention(RUNTIME) public @interface Check { + /** + * The check constraints string. + */ String constraints(); } diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/CollectionId.java b/hibernate-core/src/main/java/org/hibernate/annotations/CollectionId.java index 54aee08fa8..a6d7e57fe5 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/CollectionId.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/CollectionId.java @@ -31,7 +31,8 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME; /** - * Describe an identifier column for a bag (ie an idbag) + * Describe an identifier column for a bag (ie an idbag). + * * EXPERIMENTAL: the structure of this annotation might slightly change (generator() mix strategy and generator * * @author Emmanuel Bernard @@ -39,10 +40,18 @@ @Target({METHOD, FIELD}) @Retention(RUNTIME) public @interface CollectionId { - /** Collection id column(s) */ + /** + * Collection id column(s). + */ Column[] columns(); - /** id type, type.type() must be set */ + + /** + * id type, type.type() must be set. + */ Type type(); - /** generator name: 'identity' or a defined generator name */ + + /** + * The generator name. For example 'identity' or a defined generator name + */ String generator(); } diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/CollectionType.java b/hibernate-core/src/main/java/org/hibernate/annotations/CollectionType.java index 5bbe42d538..31c5c759f4 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/CollectionType.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/CollectionType.java @@ -42,11 +42,11 @@ @Retention(RUNTIME) public @interface CollectionType { /** - * Names the type (either {@link org.hibernate.type.CollectionType} or - * {@link org.hibernate.usertype.UserCollectionType} implementation class. Could also name a - * custom type defined via a {@link TypeDef @TypeDef} - * - * @return The implementation class to use. + * Names the type. + * + * Could name the implementation class (an implementation of {@link org.hibernate.type.CollectionType} or + * {@link org.hibernate.usertype.UserCollectionType}). Could also name a custom type defined via a + * {@link TypeDef @TypeDef} */ String type(); @@ -54,8 +54,6 @@ * Specifies configuration information for the type. Note that if the named type is a * {@link org.hibernate.usertype.UserCollectionType}, it must also implement * {@link org.hibernate.usertype.ParameterizedType} in order to receive these values. - * - * @return The configuration parameters. */ Parameter[] parameters() default {}; } diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/ColumnTransformer.java b/hibernate-core/src/main/java/org/hibernate/annotations/ColumnTransformer.java index 0d9c1c4486..870215a734 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/ColumnTransformer.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/ColumnTransformer.java @@ -43,20 +43,20 @@ @Retention(RUNTIME) public @interface ColumnTransformer { /** - * (Logical) column name for which the expression is used + * (Logical) column name for which the expression is used. * * This can be left out if the property is bound to a single column */ String forColumn() default ""; /** - * Custom SQL expression used to read from the column + * Custom SQL expression used to read from the column. */ String read() default ""; /** - * Custom SQL expression used to write to the column. - * The write expression must contain exactly one '?' placeholder for the value. + * Custom SQL expression used to write to the column. The write expression must contain exactly + * one '?' placeholder for the value. */ String write() default ""; } diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/ColumnTransformers.java b/hibernate-core/src/main/java/org/hibernate/annotations/ColumnTransformers.java index 6bd9681fe5..1d86d24b50 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/ColumnTransformers.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/ColumnTransformers.java @@ -22,6 +22,7 @@ * Boston, MA 02110-1301 USA */ package org.hibernate.annotations; + import java.lang.annotation.Retention; import static java.lang.annotation.ElementType.FIELD; @@ -37,5 +38,8 @@ @java.lang.annotation.Target({FIELD,METHOD}) @Retention(RUNTIME) public @interface ColumnTransformers { + /** + * The aggregated transformers. + */ ColumnTransformer[] value(); } diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/Columns.java b/hibernate-core/src/main/java/org/hibernate/annotations/Columns.java index 2e597074a5..28c70acdd4 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/Columns.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/Columns.java @@ -22,6 +22,7 @@ * Boston, MA 02110-1301 USA */ package org.hibernate.annotations; + import java.lang.annotation.Retention; import java.lang.annotation.Target; import javax.persistence.Column; @@ -38,5 +39,8 @@ @Target({METHOD, FIELD}) @Retention(RUNTIME) public @interface Columns { + /** + * The aggregated columns. + */ Column[] columns(); } diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/DiscriminatorFormula.java b/hibernate-core/src/main/java/org/hibernate/annotations/DiscriminatorFormula.java index c272298480..7020c4df8d 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/DiscriminatorFormula.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/DiscriminatorFormula.java @@ -22,6 +22,7 @@ * Boston, MA 02110-1301 USA */ package org.hibernate.annotations; + import java.lang.annotation.Retention; import java.lang.annotation.Target; @@ -42,5 +43,8 @@ @Target({TYPE}) @Retention(RUNTIME) public @interface DiscriminatorFormula { + /** + * The formula string. + */ String value(); } diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/DiscriminatorOptions.java b/hibernate-core/src/main/java/org/hibernate/annotations/DiscriminatorOptions.java index 3a1c2da57d..8d9888cc26 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/DiscriminatorOptions.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/DiscriminatorOptions.java @@ -38,18 +38,15 @@ @Retention(RUNTIME) public @interface DiscriminatorOptions { /** - * "Forces" Hibernate to specify the allowed discriminator values, even when retrieving all instances of the root class. - * - * @return {@code true} in case the discriminator value should be forces, {@code false} otherwise. Default is {@code false}. + * "Forces" Hibernate to specify the allowed discriminator values, even when retrieving all instances of + * the root class. {@code true} indicates that the discriminator value should be forced; Default is + * {@code false}. */ boolean force() default false; /** - * Set this to {@code false}, if your discriminator column is also part of a mapped composite identifier. - * It tells Hibernate not to include the column in SQL INSERTs. - * - * @return {@code true} in case the discriminator value should be included in inserts, {@code false} otherwise. - * Default is {@code true}. + * Set this to {@code false} if your discriminator column is also part of a mapped composite identifier. + * It tells Hibernate not to include the column in SQL INSERTs. Default is {@code true}. */ boolean insert() default true; } diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/DynamicInsert.java b/hibernate-core/src/main/java/org/hibernate/annotations/DynamicInsert.java index 11446e8725..730a98844c 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/DynamicInsert.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/DynamicInsert.java @@ -38,5 +38,9 @@ @Target( TYPE ) @Retention( RUNTIME ) public @interface DynamicInsert { + /** + * Should dynamic insertion be used for this entity? {@code true} says dynamic insertion will be used. + * Default is {@code true} (since generally this annotation is not used unless the user wants dynamic insertion). + */ boolean value() default true; } diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/DynamicUpdate.java b/hibernate-core/src/main/java/org/hibernate/annotations/DynamicUpdate.java index b873ce9974..66297af5e9 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/DynamicUpdate.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/DynamicUpdate.java @@ -42,5 +42,10 @@ @Target( TYPE ) @Retention( RUNTIME ) public @interface DynamicUpdate { + /** + * Should dynamic update generation be used for this entity? {@code true} says the update sql will be dynamic + * generated. Default is {@code true} (since generally this annotation is not used unless the user wants dynamic + * generation). + */ boolean value() default true; } diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/Entity.java b/hibernate-core/src/main/java/org/hibernate/annotations/Entity.java index 11758e6750..00527d5092 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/Entity.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/Entity.java @@ -30,7 +30,7 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME; /** - * Extends {@link javax.persistence.Entity} with Hibernate features + * Extends {@link javax.persistence.Entity} with Hibernate features. * * @author Emmanuel Bernard * @@ -41,39 +41,46 @@ @Deprecated public @interface Entity { /** - * Is this entity mutable (read only) or not + * Is this entity mutable (read only) or not. * * @deprecated use {@link org.hibernate.annotations.Immutable} */ + @Deprecated boolean mutable() default true; /** - * Needed column only in SQL on insert + * Needed column only in SQL on insert. * @deprecated use {@link DynamicInsert} instead */ + @Deprecated boolean dynamicInsert() default false; /** - * Needed column only in SQL on update + * Needed column only in SQL on update. * @deprecated Use {@link DynamicUpdate} instead */ + @Deprecated boolean dynamicUpdate() default false; /** - * Do a select to retrieve the entity before any potential update + * Do a select to retrieve the entity before any potential update. * @deprecated Use {@link SelectBeforeUpdate} instead */ + @Deprecated boolean selectBeforeUpdate() default false; /** - * polymorphism strategy for this entity + * polymorphism strategy for this entity. * @deprecated use {@link Polymorphism} instead */ + @Deprecated PolymorphismType polymorphism() default PolymorphismType.IMPLICIT; /** - * optimistic locking strategy + * optimistic locking strategy. * @deprecated use {@link OptimisticLocking} instead. */ + @Deprecated OptimisticLockType optimisticLock() default OptimisticLockType.VERSION; /** - * persister of this entity, default is hibernate internal one + * persister of this entity, default is hibernate internal one. * @deprecated use {@link Persister} instead */ + @Deprecated String persister() default ""; } diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/Fetch.java b/hibernate-core/src/main/java/org/hibernate/annotations/Fetch.java index afbeaa5ec6..598033e26e 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/Fetch.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/Fetch.java @@ -21,19 +21,23 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.annotations; +package org.hibernate.annotations; + import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** - * Define the fetching strategy used for the given association + * Define the fetching strategy used for the given association. * * @author Emmanuel Bernard */ @Target({ElementType.METHOD, ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) public @interface Fetch { + /** + * The style of fetch to use. + */ FetchMode value(); } diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/FetchMode.java b/hibernate-core/src/main/java/org/hibernate/annotations/FetchMode.java index 703e8ecdc0..84e25db1f4 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/FetchMode.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/FetchMode.java @@ -21,25 +21,25 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.annotations; - +package org.hibernate.annotations; /** - * Fetch options on associations + * Fetch options on associations. Defines more of the "how" of fetching, whereas JPA {@link javax.persistence.FetchType} + * focuses on the "when". * * @author Emmanuel Bernard */ public enum FetchMode { /** - * use a select for each individual entity, collection, or join load + * use a select for each individual entity, collection, or join load. */ SELECT, /** - * use an outer join to load the related entities, collections or joins + * use an outer join to load the related entities, collections or joins. */ JOIN, /** - * use a subselect query to load the additional collections + * use a subselect query to load the additional collections. */ SUBSELECT } diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/FetchProfile.java b/hibernate-core/src/main/java/org/hibernate/annotations/FetchProfile.java index 6dd1e086b2..9a91467be1 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/FetchProfile.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/FetchProfile.java @@ -21,10 +21,8 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ - -// $Id$ - package org.hibernate.annotations; + import java.lang.annotation.Retention; import java.lang.annotation.Target; @@ -40,17 +38,35 @@ @Target({ TYPE, PACKAGE }) @Retention(RUNTIME) public @interface FetchProfile { + /** + * The name of the fetch profile. + */ String name(); + /** + * The association fetch overrides. + */ FetchOverride[] fetchOverrides(); + /** + * Descriptor for a particular association override. + */ @Target({ TYPE, PACKAGE }) @Retention(RUNTIME) - @interface FetchOverride { + @interface FetchOverride { + /** + * The entity containing the association whose fetch is being overridden. + */ Class entity(); + /** + * The association whose fetch is being overridden. + */ String association(); + /** + * The fetch mode to apply to the association. + */ FetchMode mode(); } -} \ No newline at end of file +} diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/FetchProfiles.java b/hibernate-core/src/main/java/org/hibernate/annotations/FetchProfiles.java index a52c290343..0b093c6742 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/FetchProfiles.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/FetchProfiles.java @@ -21,10 +21,8 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ - -// $Id$ - package org.hibernate.annotations; + import java.lang.annotation.Retention; import java.lang.annotation.Target; @@ -33,10 +31,15 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME; /** + * Collects together multiple fetch profiles. + * * @author Hardy Ferentschik */ @Target({ TYPE, PACKAGE }) @Retention(RUNTIME) public @interface FetchProfiles { - public abstract FetchProfile[] value(); -} \ No newline at end of file + /** + * The aggregated fetch profiles. + */ + public FetchProfile[] value(); +} diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/Filter.java b/hibernate-core/src/main/java/org/hibernate/annotations/Filter.java index 997baccfc5..eea2379bac 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/Filter.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/Filter.java @@ -22,6 +22,7 @@ * Boston, MA 02110-1301 USA */ package org.hibernate.annotations; + import java.lang.annotation.Retention; import java.lang.annotation.Target; @@ -31,7 +32,7 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME; /** - * Add filters to an entity or a target entity of a collection + * Add filters to an entity or a target entity of a collection. * * @author Emmanuel Bernard * @author Matthew Inger @@ -41,8 +42,24 @@ @Target({TYPE, METHOD, FIELD}) @Retention(RUNTIME) public @interface Filter { + /** + * The filter name. + */ String name(); + + /** + * The filter condition. If empty, the default condition from the correspondingly named {@link FilterDef} is used. + */ String condition() default ""; + + /** + * Do we need to determine all points within the condition fragment that are alias injection points? Or + * are injection points already marked? + */ boolean deduceAliasInjectionPoints() default true; + + /** + * The alias descriptors for injection. + */ SqlFragmentAlias[] aliases() default {}; } diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/FilterDef.java b/hibernate-core/src/main/java/org/hibernate/annotations/FilterDef.java index 252a4a6a21..df5e311664 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/FilterDef.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/FilterDef.java @@ -30,7 +30,7 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME; /** - * Filter definition + * Filter definition. Defines a name, default condition and parameter types (if any). * * @author Matthew Inger * @author Emmanuel Bernard @@ -38,9 +38,18 @@ @Target({TYPE, PACKAGE}) @Retention(RUNTIME) public @interface FilterDef { + /** + * The filter name. + */ String name(); + /** + * The default filter condition. + */ String defaultCondition() default ""; + /** + * The filter parameter definitions. + */ ParamDef[] parameters() default {}; } diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/FilterDefs.java b/hibernate-core/src/main/java/org/hibernate/annotations/FilterDefs.java index a407e1c721..7dc2032c5d 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/FilterDefs.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/FilterDefs.java @@ -30,7 +30,7 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME; /** - * Array of filter definitions + * Array of filter definitions. * * @author Matthew Inger * @author Emmanuel Bernard @@ -38,5 +38,8 @@ @Target({PACKAGE, TYPE}) @Retention(RUNTIME) public @interface FilterDefs { + /** + * The aggregated filter definitions. + */ FilterDef[] value(); } diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/FilterJoinTable.java b/hibernate-core/src/main/java/org/hibernate/annotations/FilterJoinTable.java index 10f730b8e8..a8f4d1f3bc 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/FilterJoinTable.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/FilterJoinTable.java @@ -21,16 +21,15 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ +package org.hibernate.annotations; -//$Id$ -package org.hibernate.annotations; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** - * Add filters to a join table collection + * Add filters to a join table collection. * * @author Emmanuel Bernard * @author Rob Worsnop @@ -38,8 +37,24 @@ @Target({ElementType.TYPE, ElementType.METHOD, ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) public @interface FilterJoinTable { + /** + * The filter name. + */ String name(); + + /** + * The filter condition. If empty, the default condition from the correspondingly named {@link FilterDef} is used. + */ String condition() default ""; + + /** + * Do we need to determine all points within the condition fragment that are alias injection points? Or + * are injection points already marked? + */ boolean deduceAliasInjectionPoints() default true; + + /** + * The alias descriptors for injection. + */ SqlFragmentAlias[] aliases() default {}; } diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/FilterJoinTables.java b/hibernate-core/src/main/java/org/hibernate/annotations/FilterJoinTables.java index 568a37783e..741b551843 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/FilterJoinTables.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/FilterJoinTables.java @@ -21,19 +21,23 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.annotations; +package org.hibernate.annotations; + import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** - * Add multiple @FilterJoinTable to a collection + * Add multiple {@code @FilterJoinTable} to a collection. * * @author Emmanuel Bernard */ @Target({ElementType.TYPE, ElementType.METHOD, ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) public @interface FilterJoinTables { + /** + * The aggregated filters. + */ FilterJoinTable[] value(); } diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/Filters.java b/hibernate-core/src/main/java/org/hibernate/annotations/Filters.java index 89432ad680..9777a3bec5 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/Filters.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/Filters.java @@ -31,7 +31,7 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME; /** - * Add multiple @Filters + * Add multiple {@code @Filters}. * * @author Emmanuel Bernard * @author Matthew Inger @@ -40,5 +40,8 @@ @Target({TYPE, METHOD, FIELD}) @Retention(RUNTIME) public @interface Filters { + /** + * The aggregated filters. + */ Filter[] value(); } diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/FlushModeType.java b/hibernate-core/src/main/java/org/hibernate/annotations/FlushModeType.java index c50190b8b9..69bc487d83 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/FlushModeType.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/FlushModeType.java @@ -23,38 +23,37 @@ */ package org.hibernate.annotations; - /** * Enumeration extending javax.persistence flush modes. * * @author Carlos Gonz�lez-Cadenas */ - public enum FlushModeType { /** - * see {@link org.hibernate.FlushMode#ALWAYS} + * Corresponds to {@link org.hibernate.FlushMode#ALWAYS}. */ ALWAYS, /** - * see {@link org.hibernate.FlushMode#AUTO} + * Corresponds to {@link org.hibernate.FlushMode#AUTO}. */ AUTO, /** - * see {@link org.hibernate.FlushMode#COMMIT} + * Corresponds to {@link org.hibernate.FlushMode#COMMIT}. */ COMMIT, /** - * see {@link org.hibernate.FlushMode#NEVER} + * Corresponds to {@link org.hibernate.FlushMode#NEVER}. + * * @deprecated use MANUAL, will be removed in a subsequent release */ + @Deprecated NEVER, /** - * see {@link org.hibernate.FlushMode#MANUAL} + * Corresponds to {@link org.hibernate.FlushMode#MANUAL}. */ MANUAL, - /** - * Current flush mode of the persistence context at the time the query is executed + * Current flush mode of the persistence context at the time the query is executed. */ PERSISTENCE_CONTEXT -} \ No newline at end of file +} diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/ForeignKey.java b/hibernate-core/src/main/java/org/hibernate/annotations/ForeignKey.java index c1a77410d8..61b4f5b3f0 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/ForeignKey.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/ForeignKey.java @@ -22,6 +22,7 @@ * Boston, MA 02110-1301 USA */ package org.hibernate.annotations; + import java.lang.annotation.Retention; import java.lang.annotation.Target; @@ -30,12 +31,13 @@ import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; +/** + * Define the foreign key name. + * + * Prefer the JPA 2.1 introduced {@link javax.persistence.ForeignKey} instead. + */ @Target({FIELD, METHOD, TYPE}) @Retention(RUNTIME) - -/** - * Define the foreign key name - */ public @interface ForeignKey { /** * Name of the foreign key. Used in OneToMany, ManyToOne, and OneToOne @@ -48,4 +50,4 @@ * in other relationships */ String inverseName() default ""; -} \ No newline at end of file +} diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/Formula.java b/hibernate-core/src/main/java/org/hibernate/annotations/Formula.java index 813d8fd94b..9639d00619 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/Formula.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/Formula.java @@ -22,6 +22,7 @@ * Boston, MA 02110-1301 USA */ package org.hibernate.annotations; + import java.lang.annotation.Retention; import java.lang.annotation.Target; @@ -62,5 +63,8 @@ @Target({METHOD, FIELD}) @Retention(RUNTIME) public @interface Formula { + /** + * The formula string. + */ String value(); } diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/Generated.java b/hibernate-core/src/main/java/org/hibernate/annotations/Generated.java index 0899c5f059..3885c78ef5 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/Generated.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/Generated.java @@ -21,19 +21,23 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.annotations; +package org.hibernate.annotations; + import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** - * The annotated property is generated by the database + * The annotated property is generated by the database. * * @author Emmanuel Bernard */ @Target({ElementType.FIELD, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) public @interface Generated { + /** + * The enum value representing when the value is generated. + */ GenerationTime value(); } diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/GenerationTime.java b/hibernate-core/src/main/java/org/hibernate/annotations/GenerationTime.java index bf54b0ba6e..ecc98c53df 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/GenerationTime.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/GenerationTime.java @@ -21,16 +21,24 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.annotations; - +package org.hibernate.annotations; /** - * When should the generation occurs + * At what time(s) will the generation occur? * * @author Emmanuel Bernard */ public enum GenerationTime { + /** + * Indicates the value is never generated. + */ NEVER, + /** + * Indicates the value is generated on insert. + */ INSERT, + /** + * Indicates the value is generated on insert and on update. + */ ALWAYS } diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/GenericGenerator.java b/hibernate-core/src/main/java/org/hibernate/annotations/GenericGenerator.java index bbe0967916..64e66a53ac 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/GenericGenerator.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/GenericGenerator.java @@ -32,8 +32,7 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME; /** - * Generator annotation describing any kind of Hibernate - * generator in a detyped manner + * Generator annotation describing any kind of Hibernate generator in a generic (de-typed) manner. * * @author Emmanuel Bernard */ @@ -41,16 +40,15 @@ @Retention(RUNTIME) public @interface GenericGenerator { /** - * unique generator name + * unique generator name. */ String name(); /** - * Generator strategy either a predefined Hibernate - * strategy or a fully qualified class name. + * Generator strategy either a predefined Hibernate strategy or a fully qualified class name. */ String strategy(); /** - * Optional generator parameters + * Optional generator parameters. */ Parameter[] parameters() default {}; } diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/GenericGenerators.java b/hibernate-core/src/main/java/org/hibernate/annotations/GenericGenerators.java index 7ed4cc2249..28e8fa82cc 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/GenericGenerators.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/GenericGenerators.java @@ -22,6 +22,7 @@ * Boston, MA 02110-1301 USA */ package org.hibernate.annotations; + import java.lang.annotation.Retention; import java.lang.annotation.Target; @@ -30,13 +31,16 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME; /** - * Array of generic generator definitions + * Array of generic generator definitions. * * @author Paul Cowan */ @Target({PACKAGE, TYPE}) @Retention(RUNTIME) public @interface GenericGenerators { + /** + * The aggregated generators. + */ GenericGenerator[] value(); } diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/Index.java b/hibernate-core/src/main/java/org/hibernate/annotations/Index.java index 6779606255..5b6a9ea0db 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/Index.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/Index.java @@ -30,16 +30,23 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME; /** - * Define a DB index + * Define a DB index. * * @author Emmanuel Bernard + * * @deprecated Using {@link javax.persistence.Index} instead. */ @Target({FIELD, METHOD}) @Retention(RUNTIME) @Deprecated public @interface Index { + /** + * The index name. + */ String name(); + /** + * The column(s) that are indexed. + */ String[] columnNames() default {}; } diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/IndexColumn.java b/hibernate-core/src/main/java/org/hibernate/annotations/IndexColumn.java index 5c1689452e..f26076e6a8 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/IndexColumn.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/IndexColumn.java @@ -22,6 +22,7 @@ * Boston, MA 02110-1301 USA */ package org.hibernate.annotations; + import java.lang.annotation.Retention; import java.lang.annotation.Target; @@ -30,20 +31,33 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME; /** - * Describe an index column of a List - * Prefer the standard {@link javax.persistence.OrderColumn} annotation + * Describe an index column of a List. + * + * Prefer the standard {@link javax.persistence.OrderColumn} annotation. Currently the only time to use + * this annotation is to specify {@link #base()}. * * @author Matthew Inger */ @Target({METHOD, FIELD}) @Retention(RUNTIME) public @interface IndexColumn { - /** column name */ + /** + * The column name. + */ String name(); - /** index in DB start from base */ + + /** + * The starting index value. Zero (0) by default, since Lists indexes start at zero (0). + */ int base() default 0; - /** is the index nullable */ + + /** + * Is the column nullable? + */ boolean nullable() default true; - /** column definition, default to an appropriate integer */ + + /** + * An explicit column definition. + */ String columnDefinition() default ""; } diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/JoinColumnOrFormula.java b/hibernate-core/src/main/java/org/hibernate/annotations/JoinColumnOrFormula.java index cf77887675..c34438393e 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/JoinColumnOrFormula.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/JoinColumnOrFormula.java @@ -21,9 +21,8 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ - - package org.hibernate.annotations; + import java.lang.annotation.Retention; import java.lang.annotation.Target; import javax.persistence.JoinColumn; @@ -33,11 +32,21 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME; /** + * Allows joins based on column or a formula. One of {@link #formula()} or {@link #column()} should be + * specified, but not both. + * * @author Sharath Reddy */ @Target({METHOD, FIELD}) @Retention(RUNTIME) public @interface JoinColumnOrFormula { + /** + * The formula to use in joining. + */ JoinFormula formula() default @JoinFormula(value="", referencedColumnName=""); + + /** + * The column to use in joining. + */ JoinColumn column() default @JoinColumn(); } diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/JoinColumnsOrFormulas.java b/hibernate-core/src/main/java/org/hibernate/annotations/JoinColumnsOrFormulas.java index d73fe41420..c69bb4a1c0 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/JoinColumnsOrFormulas.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/JoinColumnsOrFormulas.java @@ -31,10 +31,15 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME; /** + * Collection of {@code @JoinColumnOrFormula} definitions. + * * @author Sharath Reddy */ @Target({METHOD, FIELD}) @Retention(RUNTIME) public @interface JoinColumnsOrFormulas { + /** + * The aggregated values. + */ JoinColumnOrFormula [] value(); } diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/JoinFormula.java b/hibernate-core/src/main/java/org/hibernate/annotations/JoinFormula.java index 07a7b122cb..1dc87debdd 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/JoinFormula.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/JoinFormula.java @@ -21,8 +21,8 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ - package org.hibernate.annotations; + import java.lang.annotation.Retention; import java.lang.annotation.Target; @@ -31,14 +31,21 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME; /** - * JoinFormula. To be used as a replacement for @JoinColumn in most places - * The formula has to be a valid SQL fragment + * To be used as a replacement for {@code @JoinColumn} in most places. The formula has to be a valid + * SQL fragment * * @author Sharath Reddy */ @Target({METHOD, FIELD}) @Retention(RUNTIME) public @interface JoinFormula { + /** + * The formula. + */ String value(); + + /** + * The column this formula references. + */ String referencedColumnName() default ""; } diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/LazyCollection.java b/hibernate-core/src/main/java/org/hibernate/annotations/LazyCollection.java index 685edced72..fd1676b0fa 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/LazyCollection.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/LazyCollection.java @@ -21,19 +21,23 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.annotations; +package org.hibernate.annotations; + import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** - * Define the lazy status of a collection + * Define the lazy status of a collection. * * @author Emmanuel Bernard */ @Target({ElementType.METHOD, ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) public @interface LazyCollection { + /** + * The laziness option for the collection. + */ LazyCollectionOption value(); } diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/LazyCollectionOption.java b/hibernate-core/src/main/java/org/hibernate/annotations/LazyCollectionOption.java index da06858880..86661c6dd6 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/LazyCollectionOption.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/LazyCollectionOption.java @@ -21,19 +21,24 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.annotations; - +package org.hibernate.annotations; /** - * Lazy options available for a collection + * Lazy options available for a collection. * * @author Emmanuel Bernard */ public enum LazyCollectionOption { - /** eagerly load it */ + /** + * Eagerly load it. + */ FALSE, - /** load it when the state is requested */ + /** + * Load it when the state is requested. + */ TRUE, - /** prefer extra queries over fill collection loading */ + /** + * Prefer extra queries over full collection loading. + */ EXTRA } diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/LazyToOne.java b/hibernate-core/src/main/java/org/hibernate/annotations/LazyToOne.java index a41e2ac4c4..92dbbbfc9b 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/LazyToOne.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/LazyToOne.java @@ -21,20 +21,23 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.annotations; +package org.hibernate.annotations; + import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** - * Define the lazy status of a ToOne association - * (ie OneToOne or ManyToOne) + * Define the laziness options available for a ToOne (ie OneToOne or ManyToOne) association. * * @author Emmanuel Bernard */ @Target({ElementType.METHOD, ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) public @interface LazyToOne { + /** + * Specify the laziness option. + */ LazyToOneOption value(); } diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/LazyToOneOption.java b/hibernate-core/src/main/java/org/hibernate/annotations/LazyToOneOption.java index b7b8df229b..eaaeccdef6 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/LazyToOneOption.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/LazyToOneOption.java @@ -21,26 +21,30 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.annotations; - +package org.hibernate.annotations; /** - * Lazy options available for a ToOne association + * Lazy options available for a ToOne association. * * @author Emmanuel Bernard */ public enum LazyToOneOption { - /** eagerly load the association */ + /** + * Eagerly load the association. + */ FALSE, /** - * Lazy, give back a proxy which will be loaded when the state is requested - * This should be the prefered option + * Lazy, give back a proxy which will be loaded when the state is requested. + * + * This should be the preferred option. */ PROXY, - /** Lazy, give back the real object loaded when a reference is requested - * (Bytecode enhancement is mandatory for this option, fall back to PROXY - * if the class is not enhanced) - * This option should be avoided unless you can't afford the use of proxies + /** + * Lazy, give back the real object loaded when a reference is requested. + * + * Bytecode enhancement is mandatory for this option. Falls back to {@link #PROXY} + * if the class is not enhanced. This option should be avoided unless you can't afford + * the use of proxies */ NO_PROXY } diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/Loader.java b/hibernate-core/src/main/java/org/hibernate/annotations/Loader.java index 57c74fa282..8e2e3b2619 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/Loader.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/Loader.java @@ -22,6 +22,7 @@ * Boston, MA 02110-1301 USA */ package org.hibernate.annotations; + import java.lang.annotation.Retention; import java.lang.annotation.Target; @@ -31,7 +32,8 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME; /** - * Loader Annotation for overwriting Hibernate default FIND method + * Used to override how Hibernate performs load operations. naming a named query to use instead of + * its generated SELECT SQL. * * @author L�szl� Benke */ @@ -39,7 +41,7 @@ @Retention( RUNTIME ) public @interface Loader { /** - * namedQuery to use for loading + * THe namedQuery to use for loading. */ String namedQuery() default ""; } diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/MapKeyType.java b/hibernate-core/src/main/java/org/hibernate/annotations/MapKeyType.java index 4d07fd7805..d3392e2e98 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/MapKeyType.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/MapKeyType.java @@ -22,6 +22,7 @@ * Boston, MA 02110-1301 USA */ package org.hibernate.annotations; + import java.lang.annotation.Retention; import static java.lang.annotation.ElementType.FIELD; @@ -36,5 +37,8 @@ @java.lang.annotation.Target({METHOD, FIELD}) @Retention(RUNTIME) public @interface MapKeyType { + /** + * The map key type definition. + */ Type value(); } diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/MetaValue.java b/hibernate-core/src/main/java/org/hibernate/annotations/MetaValue.java index e9428b019d..ec435e66c9 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/MetaValue.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/MetaValue.java @@ -33,12 +33,12 @@ */ public @interface MetaValue { /** - * entity type + * The entity type. */ Class targetEntity(); /** - * discriminator value stored in database + * The corresponding discriminator value stored in database. */ String value(); } diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/NamedNativeQueries.java b/hibernate-core/src/main/java/org/hibernate/annotations/NamedNativeQueries.java index f9a2ce6c12..7df7eb4e68 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/NamedNativeQueries.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/NamedNativeQueries.java @@ -30,13 +30,16 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME; /** - * Extends {@link javax.persistence.NamedNativeQueries} to hold hibernate NamedNativeQuery - * objects + * A grouping of Hibernate-specific {@link NamedNativeQuery} definitions. Effectively extends the named native + * query definitions made available through {@link javax.persistence.NamedNativeQueries}. * * @author Emmanuel Bernard */ @Target({TYPE, PACKAGE}) @Retention(RUNTIME) public @interface NamedNativeQueries { + /** + * The grouping of Hibernate named native SQL queries. + */ NamedNativeQuery[] value(); -} \ No newline at end of file +} diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/NamedNativeQuery.java b/hibernate-core/src/main/java/org/hibernate/annotations/NamedNativeQuery.java index 8c90153d52..fdf4beba2a 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/NamedNativeQuery.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/NamedNativeQuery.java @@ -30,36 +30,77 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME; /** - * Extends {@link javax.persistence.NamedNativeQuery} with Hibernate features + * Extends {@link javax.persistence.NamedNativeQuery} with Hibernate features. * * @author Emmanuel Bernard + * + * @see org.hibernate.SQLQuery */ @Target({TYPE, PACKAGE}) @Retention(RUNTIME) public @interface NamedNativeQuery { + /** + * The name. It is a named query after all :) + */ String name(); + /** + * The SQL query string. + */ String query(); + /** + * The result Class. Should not be used in conjunction with {@link #resultSetMapping()} + */ Class resultClass() default void.class; - String resultSetMapping() default ""; // name of SQLResultSetMapping - /** the flush mode for the query */ + /** + * The name of a SQLResultSetMapping to use. Should not be used in conjunction with {@link #resultClass()}. + */ + String resultSetMapping() default ""; + + /** + * The flush mode for the query. + */ FlushModeType flushMode() default FlushModeType.PERSISTENCE_CONTEXT; - /** mark the query as cacheable or not */ + + /** + * Whether the query (results) is cacheable or not. Default is {@code false}, that is not cacheable. + */ boolean cacheable() default false; - /** the cache region to use */ + + /** + * If the query results are cacheable, name the query cache region to use. + */ String cacheRegion() default ""; - /** the number of rows fetched by the JDBC Driver per roundtrip */ + + /** + * The number of rows fetched by the JDBC Driver per trip. + */ int fetchSize() default -1; - /**the query timeout in seconds*/ + + /** + * The query timeout (in seconds). Default is no timeout. + */ int timeout() default -1; + /** + * Does the SQL ({@link #query()}) represent a call to a procedure/function? + */ boolean callable() default false; - /**comment added to the SQL query, useful for the DBA */ + + /** + * A comment added to the SQL query. Useful when engaging with DBA. + */ String comment() default ""; - /**the cache mode used for this query*/ + + /** + * The cache mode used for this query. This refers to entities/collections returned from the query. + */ CacheModeType cacheMode() default CacheModeType.NORMAL; - /**marks whether the results are fetched in read-only mode or not*/ + + /** + * Whether the results should be read-only. Default is {@code false}. + */ boolean readOnly() default false; } diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/NamedQueries.java b/hibernate-core/src/main/java/org/hibernate/annotations/NamedQueries.java index caee4694e0..f5f90130e0 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/NamedQueries.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/NamedQueries.java @@ -30,8 +30,8 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME; /** - * Extends {@link javax.persistence.NamedQueries} to hold hibernate NamedQuery - * objects + * A grouping of Hibernate-specific {@link NamedQuery} definitions. Effectively extends the named query + * definitions made available through {@link javax.persistence.NamedQueries}. * * @author Emmanuel Bernard * @author Carlos Gonz�lez-Cadenas @@ -39,5 +39,8 @@ @Target({TYPE, PACKAGE}) @Retention(RUNTIME) public @interface NamedQueries { + /** + * The grouping of named queries. + */ NamedQuery[] value(); -} \ No newline at end of file +} diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/NamedQuery.java b/hibernate-core/src/main/java/org/hibernate/annotations/NamedQuery.java index cf8abdc83f..8a73574c38 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/NamedQuery.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/NamedQuery.java @@ -31,61 +31,63 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME; /** - * Extends {@link javax.persistence.NamedQuery} with Hibernate features + * Extends {@link javax.persistence.NamedQuery} with Hibernate features. * * @author Carlos Gonzalez-Cadenas + * + * @see org.hibernate.Query */ @Target( { TYPE, PACKAGE }) @Retention(RUNTIME) public @interface NamedQuery { /** - * @return returns the name of this {@code NamedQuery} + * The name of this {@code NamedQuery}. */ String name(); /** - * @return returns the query string for this {@code NamedQuery} + * The query string for this {@code NamedQuery}. */ String query(); /** - * @return returns the flush mode for this query + * The flush mode for this query. */ FlushModeType flushMode() default FlushModeType.PERSISTENCE_CONTEXT; /** - * @return returns whether this query is cacheable or not + * Whether the query (results) is cacheable or not. Default is {@code false}, that is not cacheable. */ boolean cacheable() default false; /** - * @return returns the the cache region to use + * If the query results are cacheable, name the query cache region to use. */ String cacheRegion() default ""; /** - * @return returns the number of rows fetched by the JDBC Driver per database round-trip + * The number of rows fetched by the JDBC Driver per trip. */ int fetchSize() default -1; /** - * @return return the query timeout in seconds + * The query timeout (in seconds). Default is no timeout. */ int timeout() default -1; /** - * @return returns the comment added to the SQL query (useful for the DBA) + * A comment added to the generated SQL query. Useful when engaging with DBA. */ String comment() default ""; /** - * @return returns the cache mode used for this query + * The cache mode used for this query. This refers to entities/collections returned from the query. */ CacheModeType cacheMode() default CacheModeType.NORMAL; /** - * @return returns whether the results are fetched in read-only mode or not. Default is {@code false} + * Whether the results should be read-only. Default is {@code false}. */ boolean readOnly() default false; } diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/NaturalId.java b/hibernate-core/src/main/java/org/hibernate/annotations/NaturalId.java index 84cf003f0f..b5e35d77d0 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/NaturalId.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/NaturalId.java @@ -34,15 +34,15 @@ * This specifies that a property is part of the natural id of the entity. * * @author Nicol�s Lichtmaier + * * @see NaturalIdCache */ @Target( { METHOD, FIELD } ) @Retention( RUNTIME ) public @interface NaturalId { /** - * Is this natural id mutable (or immutable)? - * - * @return {@code true} indicates the natural id is mutable; {@code false} (the default) that it is immutable. + * Whether the natural id is mutable (or immutable)? {@code false} (the default) indicates it is immutable; + * {@code true} indicates it is mutable. */ boolean mutable() default false; } diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/NotFound.java b/hibernate-core/src/main/java/org/hibernate/annotations/NotFound.java index 18e7484e77..8f795911b6 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/NotFound.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/NotFound.java @@ -38,5 +38,8 @@ @Target( { METHOD, FIELD }) @Retention(RUNTIME) public @interface NotFound { + /** + * The action to perform when an associated entity is not found. By default an exception is thrown. + */ NotFoundAction action() default NotFoundAction.EXCEPTION; } diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/NotFoundAction.java b/hibernate-core/src/main/java/org/hibernate/annotations/NotFoundAction.java index c2fbb985f5..7460471e7b 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/NotFoundAction.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/NotFoundAction.java @@ -25,17 +25,18 @@ /** - * Actoin to use when an element is not found in DB while beeing expected + * Possible actions when an associated entity is not found in the database. Often seen with "legacy" foreign-key + * schemes which do not use {@code NULL} to indicate a missing reference, instead using a "magic value". * * @author Emmanuel Bernard */ public enum NotFoundAction { /** - * raise an exception when an element is not found (default and recommended) + * Raise an exception when an element is not found (default and recommended). */ EXCEPTION, /** - * ignore the element when not found in DB + * Ignore the element when not found in database. */ IGNORE } diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/OnDelete.java b/hibernate-core/src/main/java/org/hibernate/annotations/OnDelete.java index 12d2bf414a..2278bed2fb 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/OnDelete.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/OnDelete.java @@ -22,6 +22,7 @@ * Boston, MA 02110-1301 USA */ package org.hibernate.annotations; + import java.lang.annotation.Retention; import java.lang.annotation.Target; @@ -32,7 +33,8 @@ /** - * Strategy to use on collections, arrays and on joined subclasses delete + * Strategy to use on collections, arrays and on joined subclasses delete. + * * OnDelete of secondary tables currently not supported. * * @author Emmanuel Bernard @@ -40,5 +42,8 @@ @Target({METHOD, FIELD, TYPE}) @Retention(RUNTIME) public @interface OnDelete { + /** + * The on-delete action. + */ OnDeleteAction action(); } diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/OnDeleteAction.java b/hibernate-core/src/main/java/org/hibernate/annotations/OnDeleteAction.java index af53d0077d..3b839878c3 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/OnDeleteAction.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/OnDeleteAction.java @@ -23,19 +23,18 @@ */ package org.hibernate.annotations; - /** - * Possible actions on deletes + * Possible actions for on-delete. * * @author Emmanuel Bernard */ public enum OnDeleteAction { /** - * the default + * Take no action. The default. */ NO_ACTION, /** - * use cascade delete capabilities of the DD + * Use cascade delete capabilities of the database foreign-key. */ CASCADE } diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/OptimisticLock.java b/hibernate-core/src/main/java/org/hibernate/annotations/OptimisticLock.java index 876efa84c6..ce3492d044 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/OptimisticLock.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/OptimisticLock.java @@ -30,6 +30,7 @@ /** * Whether or not a change of the annotated property will trigger a entity version increment. + * * If the annotation is not present, the property is involved in the optimistic lock strategy (default). * * @author Logi Ragnarsson @@ -38,7 +39,7 @@ @Retention(RetentionPolicy.RUNTIME) public @interface OptimisticLock { /** - * @return If {@code true}, the annotated property change will not trigger a version increment. + * Whether the annotated property should be included in optimistic locking determinations for the owner. */ boolean excluded(); } diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/OptimisticLockType.java b/hibernate-core/src/main/java/org/hibernate/annotations/OptimisticLockType.java index a6df6dd3a0..ce2ca87306 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/OptimisticLockType.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/OptimisticLockType.java @@ -23,28 +23,30 @@ */ package org.hibernate.annotations; - /** - * Optimistic locking strategy - * VERSION is the default and recommended one + * Possible optimistic locking strategies. * * @author Emmanuel Bernard */ public enum OptimisticLockType { /** - * no optimistic locking + * Perform no optimistic locking. */ NONE, /** - * use a column version + * Perform optimistic locking using a dedicated version column. + * + * @see javax.persistence.Version */ VERSION, /** - * dirty columns are compared + * Perform optimistic locking based on *dirty* fields as part of an expanded WHERE clause restriction for the + * UPDATE/DELETE SQL statement. */ DIRTY, /** - * all columns are compared + * Perform optimistic locking based on *all* fields as part of an expanded WHERE clause restriction for the + * UPDATE/DELETE SQL statement. */ ALL } diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/OptimisticLocking.java b/hibernate-core/src/main/java/org/hibernate/annotations/OptimisticLocking.java index 49278d2aca..564c6faba2 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/OptimisticLocking.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/OptimisticLocking.java @@ -38,5 +38,8 @@ @Target( TYPE ) @Retention( RUNTIME ) public @interface OptimisticLocking { + /** + * Defines the style of optimistic locking for the entity. + */ OptimisticLockType type() default OptimisticLockType.VERSION; } diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/OrderBy.java b/hibernate-core/src/main/java/org/hibernate/annotations/OrderBy.java index 70f4595f8b..4143b3b74c 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/OrderBy.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/OrderBy.java @@ -30,13 +30,18 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME; /** - * Order a collection using SQL ordering (not HQL ordering) + * Order a collection using SQL ordering (not HQL ordering). * * @author Emmanuel Bernard + * + * @see javax.persistence.OrderBy + * @see Sort */ @Target({METHOD, FIELD}) @Retention(RUNTIME) public @interface OrderBy { - /** SQL orderby clause */ + /** + * SQL ordering clause. + */ String clause(); } diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/ParamDef.java b/hibernate-core/src/main/java/org/hibernate/annotations/ParamDef.java index 57e457b098..d3bd662511 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/ParamDef.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/ParamDef.java @@ -22,20 +22,29 @@ * Boston, MA 02110-1301 USA */ package org.hibernate.annotations; + import java.lang.annotation.Retention; import java.lang.annotation.Target; import static java.lang.annotation.RetentionPolicy.RUNTIME; /** - * A parameter definition + * A parameter definition. * * @author Emmanuel Bernard */ @Target({}) @Retention(RUNTIME) public @interface ParamDef { + /** + * The name of the parameter definition. + */ String name(); + /** + * The type being defined, Typically this is the fully-qualified name of the {@link org.hibernate.type.Type}, + * {@link org.hibernate.usertype.UserType} or {@link org.hibernate.usertype.CompositeUserType} implementation + * class. + */ String type(); } diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/Parameter.java b/hibernate-core/src/main/java/org/hibernate/annotations/Parameter.java index 596292f020..9141a74af3 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/Parameter.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/Parameter.java @@ -28,14 +28,20 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME; /** - * Parameter (basically key/value pattern) + * Generic parameter (basically a key/value combination) used to parametrize other annotations. * * @author Emmanuel Bernard */ @Target({}) @Retention(RUNTIME) public @interface Parameter { + /** + * The parameter name. + */ String name(); + /** + * The parameter value. + */ String value(); } diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/Parent.java b/hibernate-core/src/main/java/org/hibernate/annotations/Parent.java index 7407a50268..3f8d398666 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/Parent.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/Parent.java @@ -30,7 +30,7 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME; /** - * Reference the property as a pointer back to the owner (generally the owning entity) + * Reference the property as a pointer back to the owner (generally the owning entity). * * @author Emmanuel Bernard */ diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/Persister.java b/hibernate-core/src/main/java/org/hibernate/annotations/Persister.java index 73897a5246..749978a37c 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/Persister.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/Persister.java @@ -36,7 +36,7 @@ @Retention(RetentionPolicy.RUNTIME) public @interface Persister { /** - * @return The custom persister class + * The custom persister class. */ Class impl(); } diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/Polymorphism.java b/hibernate-core/src/main/java/org/hibernate/annotations/Polymorphism.java index 1be03925e5..08790562ab 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/Polymorphism.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/Polymorphism.java @@ -37,5 +37,8 @@ @Target( TYPE ) @Retention( RUNTIME ) public @interface Polymorphism { + /** + * Specifies the polymorphism type. + */ PolymorphismType type() default PolymorphismType.IMPLICIT; } diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/PolymorphismType.java b/hibernate-core/src/main/java/org/hibernate/annotations/PolymorphismType.java index 3b59889690..0d8558584c 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/PolymorphismType.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/PolymorphismType.java @@ -23,19 +23,18 @@ */ package org.hibernate.annotations; - /** - * Type of available polymorphism for a particular entity + * Type of available polymorphism for a particular entity. * * @author Emmanuel Bernard */ public enum PolymorphismType { /** - * default, this entity is retrieved if any of its super entity is asked + * This entity is retrieved if any of its super entity are retrieved. The default, */ IMPLICIT, /** - * this entity is retrieved only if explicitly asked + * This entity is retrieved only if explicitly asked. */ EXPLICIT } diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/Proxy.java b/hibernate-core/src/main/java/org/hibernate/annotations/Proxy.java index 7e11c5637f..380f832a7d 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/Proxy.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/Proxy.java @@ -22,6 +22,7 @@ * Boston, MA 02110-1301 USA */ package org.hibernate.annotations; + import java.lang.annotation.Retention; import java.lang.annotation.Target; @@ -29,7 +30,7 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME; /** - * Lazy and proxy configuration of a particular class + * Lazy and proxy configuration of a particular class. * * @author Emmanuel Bernard */ @@ -37,12 +38,12 @@ @Retention(RUNTIME) public @interface Proxy { /** - * Whether this class is lazy or not (default to true) + * Whether this class is lazy or not. Default to true. */ boolean lazy() default true; /** - * Proxy class or interface used. Default entity class name. + * Proxy class or interface used. Default is to use the entity class name. */ Class proxyClass() default void.class; } diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/QueryHints.java b/hibernate-core/src/main/java/org/hibernate/annotations/QueryHints.java index 19635cd12c..d16e8015a5 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/QueryHints.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/QueryHints.java @@ -24,21 +24,90 @@ package org.hibernate.annotations; /** - * + * Consolidation of hints available to Hibernate JPA queries. Mainly used to define features available on + * Hibernate queries that have no corollary in JPA queries. */ public class QueryHints { + /** + * Disallow instantiation. + */ + private QueryHints() { + } + /** + * The cache mode to use. + * + * @see org.hibernate.Query#setCacheMode + * @see org.hibernate.SQLQuery#setCacheMode + */ public static final String CACHE_MODE = "org.hibernate.cacheMode"; + + /** + * The cache region to use. + * + * @see org.hibernate.Query#setCacheRegion + * @see org.hibernate.SQLQuery#setCacheRegion + */ public static final String CACHE_REGION = "org.hibernate.cacheRegion"; + + /** + * Are the query results cacheable? + * + * @see org.hibernate.Query#setCacheable + * @see org.hibernate.SQLQuery#setCacheable + */ public static final String CACHEABLE = "org.hibernate.cacheable"; + + /** + * Is the query callable? Note: only valid for named native sql queries. + */ public static final String CALLABLE = "org.hibernate.callable"; + + /** + * Defines a comment to be applied to the SQL sent to the database. + * + * @see org.hibernate.Query#setComment + * @see org.hibernate.SQLQuery#setComment + */ public static final String COMMENT = "org.hibernate.comment"; + + /** + * Defines the JDBC fetch size to use. + * + * @see org.hibernate.Query#setFetchSize + * @see org.hibernate.SQLQuery#setFetchSize + */ public static final String FETCH_SIZE = "org.hibernate.fetchSize"; + + /** + * The flush mode to associate with the execution of the query. + * + * @see org.hibernate.Query#setFlushMode + * @see org.hibernate.SQLQuery#setFlushMode + * @see org.hibernate.Session#setFlushMode + */ public static final String FLUSH_MODE = "org.hibernate.flushMode"; + + /** + * Should entities returned from the query be set in read only mode? + * + * @see org.hibernate.Query#setReadOnly + * @see org.hibernate.SQLQuery#setReadOnly + * @see org.hibernate.Session#setReadOnly + */ public static final String READ_ONLY = "org.hibernate.readOnly"; + + /** + * Apply a Hibernate query timeout, which is defined in seconds. + * + * @see org.hibernate.Query#setTimeout + * @see org.hibernate.SQLQuery#setTimeout + */ public static final String TIMEOUT_HIBERNATE = "org.hibernate.timeout"; + + /** + * Apply a JPA query timeout, which is defined in milliseconds. + */ public static final String TIMEOUT_JPA = "javax.persistence.query.timeout"; - private QueryHints() { - } } diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/ResultCheckStyle.java b/hibernate-core/src/main/java/org/hibernate/annotations/ResultCheckStyle.java index f0667636a2..8904909ecd 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/ResultCheckStyle.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/ResultCheckStyle.java @@ -23,18 +23,17 @@ */ package org.hibernate.annotations; - /** - * Possible checks on Sql Insert, Delete, Update + * Possible styles of checking return codes on SQL INSERT, UPDATE and DELETE queries. * * @author L�szl� Benke */ public enum ResultCheckStyle { /** - * Do not perform checking. Either user simply does not want checking, or is - * indicating a {@link java.sql.CallableStatement} execution in which the - * checks are being performed explicitly and failures are handled through - * propogation of {@link java.sql.SQLException}s. + * Do not perform checking. Might mean that the user really just does not want any checking. Might + * also mean that the user is expecting a failure to be indicated by a {@link java.sql.SQLException} being + * thrown (presumably from a {@link java.sql.CallableStatement} which is performing explicit checks and + * propagating failures back through the driver). */ NONE, /** diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/RowId.java b/hibernate-core/src/main/java/org/hibernate/annotations/RowId.java index 5405f20689..2556e30707 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/RowId.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/RowId.java @@ -29,7 +29,7 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME; /** - * Support for {@literal ROWID} mapping feature of Hibernate. + * Support for {@code ROWID} mapping feature of Hibernate. * * @author Steve Ebersole */ @@ -37,9 +37,7 @@ @Retention(RUNTIME) public @interface RowId { /** - * Names the {@literal ROWID} identifier - * - * @return The {@literal ROWID} identifier + * Names the {@code ROWID} identifier. */ String value(); } diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/SQLDelete.java b/hibernate-core/src/main/java/org/hibernate/annotations/SQLDelete.java index db50b21540..8066b07ed0 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/SQLDelete.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/SQLDelete.java @@ -22,6 +22,7 @@ * Boston, MA 02110-1301 USA */ package org.hibernate.annotations; + import java.lang.annotation.Retention; import java.lang.annotation.Target; @@ -31,7 +32,7 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME; /** - * SqlDelete Annotation for overwriting Hibernate default DELETE method + * Custom SQL statement for delete of an entity/collection. * * @author L�szl� Benke */ @@ -39,12 +40,12 @@ @Retention( RUNTIME ) public @interface SQLDelete { /** - * Procedure name or DELETE STATEMENT + * Procedure name or SQL DELETE statement. */ String sql(); /** - * Is the statement using stored procedure or not + * Is the statement callable (aka a {@link java.sql.CallableStatement})? */ boolean callable() default false; diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/SQLDeleteAll.java b/hibernate-core/src/main/java/org/hibernate/annotations/SQLDeleteAll.java index 96ed9b9d8c..236024ada8 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/SQLDeleteAll.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/SQLDeleteAll.java @@ -22,6 +22,7 @@ * Boston, MA 02110-1301 USA */ package org.hibernate.annotations; + import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @@ -31,7 +32,7 @@ import static java.lang.annotation.ElementType.TYPE; /** - * SqlDelete Annotation for overwriting Hibernate default DELETE ALL method + * Custom SQL statement for delete of all of a collection's elements. * * @author L�szl� Benke */ @@ -39,12 +40,12 @@ @Retention( RetentionPolicy.RUNTIME ) public @interface SQLDeleteAll { /** - * Procedure name or DELETE STATEMENT + * Procedure name or SQL DELETE statement. */ String sql(); /** - * Is the statement using stored procedure or not + * Is the statement callable (aka a {@link java.sql.CallableStatement})? */ boolean callable() default false; diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/SQLInsert.java b/hibernate-core/src/main/java/org/hibernate/annotations/SQLInsert.java index ea668043e1..ce2553c212 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/SQLInsert.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/SQLInsert.java @@ -22,6 +22,7 @@ * Boston, MA 02110-1301 USA */ package org.hibernate.annotations; + import java.lang.annotation.Retention; import java.lang.annotation.Target; @@ -31,7 +32,7 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME; /** - * SqlInsert Annotation for overwriting Hibernate default INSERT INTO method + * Custom SQL statement for insertion of an entity/collection. * * @author L�szl� Benke */ @@ -39,12 +40,12 @@ @Retention( RUNTIME ) public @interface SQLInsert { /** - * Procedure name or INSERT STATEMENT + * Procedure name or SQL INSERT statement. */ String sql(); /** - * Is the statement using stored procedure or not + * Is the statement callable (aka a {@link java.sql.CallableStatement})? */ boolean callable() default false; diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/SQLUpdate.java b/hibernate-core/src/main/java/org/hibernate/annotations/SQLUpdate.java index ea5e2ba260..9a10f42c0d 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/SQLUpdate.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/SQLUpdate.java @@ -22,6 +22,7 @@ * Boston, MA 02110-1301 USA */ package org.hibernate.annotations; + import java.lang.annotation.Retention; import java.lang.annotation.Target; @@ -31,21 +32,20 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME; /** - * SqlUpdate Annotation for overwriting Hibernate default UPDATE method + * Custom SQL statement for update of an entity/collection. * * @author L�szl� Benke */ @Target( {TYPE, FIELD, METHOD} ) @Retention( RUNTIME ) public @interface SQLUpdate { - /** - * Procedure name or UPDATE STATEMENT + * Procedure name or SQL UPDATE statement. */ String sql(); /** - * Is the statement using stored procedure or not + * Is the statement callable (aka a {@link java.sql.CallableStatement})? */ boolean callable() default false; diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/SelectBeforeUpdate.java b/hibernate-core/src/main/java/org/hibernate/annotations/SelectBeforeUpdate.java index 5e4464ed17..9c4fe2c9fa 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/SelectBeforeUpdate.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/SelectBeforeUpdate.java @@ -38,5 +38,10 @@ @Target( TYPE ) @Retention( RUNTIME ) public @interface SelectBeforeUpdate { + /** + * {@code true} (which is the default when this annotation is present) indicates that + * {@code select-before-update} processing should occur. {@code false} indicates + * {@code select-before-update} processing should not occur. + */ boolean value() default true; } diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/Sort.java b/hibernate-core/src/main/java/org/hibernate/annotations/Sort.java index 0070dcb9a2..0fe5faa70e 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/Sort.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/Sort.java @@ -22,6 +22,7 @@ * Boston, MA 02110-1301 USA */ package org.hibernate.annotations; + import java.lang.annotation.Retention; import java.lang.annotation.Target; @@ -30,22 +31,24 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME; /** - * Collection sort - * (Java level sorting) + * Collection sort (in-memory sorting). Different that ordering, which is applied during the SQL select. * * @author Emmanuel Bernard + * + * @see OrderBy */ @Target({METHOD, FIELD}) @Retention(RUNTIME) public @interface Sort { /** - * sort type + * The type of sorting to use. The default is to not use sorting. */ SortType type() default SortType.UNSORTED; - /** - * Sort comparator implementation - */ - //TODO find a way to use Class + /** + * Specifies the comparator to use. Only valid when {@link #type} specifies {@link SortType#COMPARATOR}. + * + * TODO find a way to use Class -> see HHH-8164 + */ Class comparator() default void.class; } diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/SortType.java b/hibernate-core/src/main/java/org/hibernate/annotations/SortType.java index b33c772189..18f7aa8727 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/SortType.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/SortType.java @@ -23,14 +23,22 @@ */ package org.hibernate.annotations; - /** - * Sort strategies + * Possible collection sorting strategies. * * @author Emmanuel Bernard */ public enum SortType { + /** + * The collection is unsorted. + */ UNSORTED, + /** + * The collection is sorted using its natural sorting. + */ NATURAL, + /** + * The collection is sorted using a supplied comparator. + */ COMPARATOR } diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/Source.java b/hibernate-core/src/main/java/org/hibernate/annotations/Source.java index 5152d04198..30d575beef 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/Source.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/Source.java @@ -21,8 +21,8 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ - package org.hibernate.annotations; + import java.lang.annotation.Retention; import java.lang.annotation.Target; @@ -31,13 +31,16 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME; /** - * Optional annotation in conjunction with {@link javax.persistence.Version} and timestamp version properties. - * The annotation value decides where the timestamp is generated. + * Optional annotation in conjunction with {@link javax.persistence.Version} and timestamp version properties + * indicating the source of the timestamp value. * * @author Hardy Ferentschik */ @Target({ METHOD, FIELD }) @Retention(RUNTIME) public @interface Source { + /** + * How is the timestamp generated? Default is a JVM generated value. + */ SourceType value() default SourceType.VM; } diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/SourceType.java b/hibernate-core/src/main/java/org/hibernate/annotations/SourceType.java index 907d1722f2..f9468923a8 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/SourceType.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/SourceType.java @@ -21,10 +21,8 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ - package org.hibernate.annotations; - /** * Where should Hibernate retrieve the value from? From the database, or from the current JVM? * @@ -34,19 +32,24 @@ public enum SourceType { /** * Get the timestamp from the current VM. */ - VM("timestamp"), + VM( "timestamp" ), /** * Get the timestamp from the database. */ - DB("dbtimestamp"); + DB( "dbtimestamp" ); private final String typeName; - SourceType(String typeName ) { + private SourceType(String typeName ) { this.typeName = typeName; } + /** + * Get the corresponding Hibernate {@link org.hibernate.type.VersionType} name. + * + * @return The corresponding type name. + */ public String typeName() { return typeName; } diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/SqlFragmentAlias.java b/hibernate-core/src/main/java/org/hibernate/annotations/SqlFragmentAlias.java index 031ff6417d..b850a5559b 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/SqlFragmentAlias.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/SqlFragmentAlias.java @@ -29,15 +29,27 @@ import java.lang.annotation.Retention; import java.lang.annotation.Target; + /** - * Describe aliases for filters + * Describe aliases for filters. * * @author Rob Worsnop */ @Target({METHOD, FIELD}) @Retention(RUNTIME) public @interface SqlFragmentAlias { + /** + * The alias within the fragment. + */ String alias(); + + /** + * The table corresponding to the alias. + */ String table() default ""; + + /** + * The entity class associated with the alias. + */ Class entity() default void.class; } diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/Subselect.java b/hibernate-core/src/main/java/org/hibernate/annotations/Subselect.java index 28cd043006..8ed3cd758d 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/Subselect.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/Subselect.java @@ -22,6 +22,7 @@ * Boston, MA 02110-1301 USA */ package org.hibernate.annotations; + import java.lang.annotation.Retention; import java.lang.annotation.Target; @@ -29,12 +30,17 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME; /** - * Map an immutable and read-only entity to a given SQL subselect expression: - * @author Sharath Reddy + * Map an immutable and read-only entity to a given SQL select expression. * + * @see Synchronize + * + * @author Sharath Reddy */ @Target(TYPE) @Retention(RUNTIME) public @interface Subselect { + /** + * The query. + */ String value(); } diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/Synchronize.java b/hibernate-core/src/main/java/org/hibernate/annotations/Synchronize.java index 25e99e0958..fcdb41bedc 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/Synchronize.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/Synchronize.java @@ -22,6 +22,7 @@ * Boston, MA 02110-1301 USA */ package org.hibernate.annotations; + import java.lang.annotation.Retention; import java.lang.annotation.Target; @@ -32,7 +33,7 @@ * Ensures that auto-flush happens correctly and that queries against the derived * entity do not return stale data. * - * Mostly used with Subselect. + * Mostly used with {@link Subselect}. * * @author Sharath Reddy */ @@ -40,7 +41,7 @@ @Retention(RUNTIME) public @interface Synchronize { /** - * Table names + * Table names. */ - String [] value(); + String[] value(); } diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/Table.java b/hibernate-core/src/main/java/org/hibernate/annotations/Table.java index f4c1119b6a..43338e0dc1 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/Table.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/Table.java @@ -22,6 +22,7 @@ * Boston, MA 02110-1301 USA */ package org.hibernate.annotations; + import java.lang.annotation.Retention; import java.lang.annotation.Target; @@ -29,7 +30,7 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME; /** - * Complementary information to a table either primary or secondary + * Complementary information to a table either primary or secondary. * * @author Emmanuel Bernard */ @@ -37,23 +38,22 @@ @Retention(RUNTIME) public @interface Table { /** - * name of the targeted table + * name of the targeted table. */ String appliesTo(); /** - * Indexes + * Indexes. */ Index[] indexes() default {}; /** - * define a table comment + * define a table comment. */ String comment() default ""; /** - * Defines the Foreign Key name of a secondary table - * pointing back to the primary table + * Defines the Foreign Key name of a secondary table pointing back to the primary table. */ ForeignKey foreignKey() default @ForeignKey( name="" ); @@ -86,21 +86,21 @@ boolean optional() default true; /** - * Defines a custom SQL insert statement + * Defines a custom SQL insert statement. * * Only applies to secondary tables */ SQLInsert sqlInsert() default @SQLInsert(sql=""); /** - * Defines a custom SQL update statement + * Defines a custom SQL update statement. * * Only applies to secondary tables */ SQLUpdate sqlUpdate() default @SQLUpdate(sql=""); /** - * Defines a custom SQL delete statement + * Defines a custom SQL delete statement. * * Only applies to secondary tables */ diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/Tables.java b/hibernate-core/src/main/java/org/hibernate/annotations/Tables.java index 2df5b35e47..6159ec2ceb 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/Tables.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/Tables.java @@ -22,6 +22,7 @@ * Boston, MA 02110-1301 USA */ package org.hibernate.annotations; + import java.lang.annotation.Retention; import java.lang.annotation.Target; @@ -29,13 +30,15 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME; /** - * Plural of Table + * A grouping of tables. * * @author Emmanuel Bernard - * @see Table */ @Target({TYPE}) @Retention(RUNTIME) public @interface Tables { + /** + * The table grouping. + */ Table[] value(); } diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/Target.java b/hibernate-core/src/main/java/org/hibernate/annotations/Target.java index 480b273161..72dab62eb6 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/Target.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/Target.java @@ -21,18 +21,22 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.annotations; +package org.hibernate.annotations; + import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; /** - * Define an explicit target,a voiding reflection and generics resolving + * Define an explicit target, avoiding reflection and generics resolving. * * @author Emmanuel Bernard */ @java.lang.annotation.Target({ElementType.FIELD, ElementType.METHOD}) @Retention( RetentionPolicy.RUNTIME ) public @interface Target { + /** + * The target entity type. + */ Class value(); } diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/Tuplizer.java b/hibernate-core/src/main/java/org/hibernate/annotations/Tuplizer.java index 1f8037cf33..c692a36455 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/Tuplizer.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/Tuplizer.java @@ -22,6 +22,7 @@ * Boston, MA 02110-1301 USA */ package org.hibernate.annotations; + import java.lang.annotation.Retention; import org.hibernate.EntityMode; @@ -32,19 +33,27 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME; /** - * Define a tuplizer for an entity or a component + * Define a tuplizer for an entity or a component. + * * @author Emmanuel Bernard */ @java.lang.annotation.Target( {TYPE, FIELD, METHOD} ) @Retention( RUNTIME ) public @interface Tuplizer { - /** tuplizer implementation */ - Class impl(); /** - * either pojo, dynamic-map or dom4j + * Tuplizer implementation. + */ + Class impl(); + + /** + * either pojo, dynamic-map or dom4j. * @deprecated should use #entityModeType instead */ @Deprecated String entityMode() default "pojo"; + + /** + * The entity mode. + */ EntityMode entityModeType() default EntityMode.POJO; } diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/Tuplizers.java b/hibernate-core/src/main/java/org/hibernate/annotations/Tuplizers.java index 78924b842d..6a14061d01 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/Tuplizers.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/Tuplizers.java @@ -21,17 +21,22 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.annotations; +package org.hibernate.annotations; + import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; /** - * Define a set of tuplizer for an entity or a component + * Grouping of tuplizers. + * * @author Emmanuel Bernard */ @java.lang.annotation.Target( {ElementType.TYPE, ElementType.FIELD, ElementType.METHOD} ) @Retention( RetentionPolicy.RUNTIME ) public @interface Tuplizers { + /** + * The grouping of tuplizers. + */ Tuplizer[] value(); } diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/Type.java b/hibernate-core/src/main/java/org/hibernate/annotations/Type.java index 3ca6583dc0..a3fc6d3ea7 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/Type.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/Type.java @@ -22,6 +22,7 @@ * Boston, MA 02110-1301 USA */ package org.hibernate.annotations; + import java.lang.annotation.Retention; import java.lang.annotation.Target; @@ -30,14 +31,30 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME; /** - * hibernate type + * Defines a Hibernate type mapping. + * + * @see org.hibernate.type.Type + * @see org.hibernate.usertype.UserType + * @see org.hibernate.usertype.CompositeUserType + * + * @see TypeDef * * @author Emmanuel Bernard + * @author Steve Ebersole */ @Target({FIELD, METHOD}) @Retention(RUNTIME) public @interface Type { + /** + * The Hibernate type name. Usually the fully qualified name of an implementation class for + * {@link org.hibernate.type.Type}, {@link org.hibernate.usertype.UserType} or + * {@link org.hibernate.usertype.CompositeUserType}. May also refer to a type definition by name + * {@link TypeDef#name()} + */ String type(); + /** + * Any configuration parameters for the named type. + */ Parameter[] parameters() default {}; -} \ No newline at end of file +} diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/TypeDef.java b/hibernate-core/src/main/java/org/hibernate/annotations/TypeDef.java index 8b2d355266..f25825fec9 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/TypeDef.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/TypeDef.java @@ -22,6 +22,7 @@ * Boston, MA 02110-1301 USA */ package org.hibernate.annotations; + import java.lang.annotation.Retention; import java.lang.annotation.Target; @@ -30,15 +31,38 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME; /** - * Type definition + * A type definition. Much like {@link Type}, but here we can centralize the definition under a name and + * refer to that name elsewhere. + * + * @see org.hibernate.type.Type + * @see org.hibernate.usertype.UserType + * @see org.hibernate.usertype.CompositeUserType + * + * @see Type * * @author Emmanuel Bernard + * @author Steve Ebersole */ @Target({TYPE, PACKAGE}) @Retention(RUNTIME) public @interface TypeDef { + /** + * The type name. This is the name that would be used in other locations. + */ String name() default ""; - Class defaultForType() default void.class; + + /** + * The type implementation class. + */ Class typeClass(); + + /** + * Name a java type for which this defined type should be the default mapping. + */ + Class defaultForType() default void.class; + + /** + * Any configuration parameters for this type definition. + */ Parameter[] parameters() default {}; } diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/TypeDefs.java b/hibernate-core/src/main/java/org/hibernate/annotations/TypeDefs.java index 9e562b4246..55542ad01b 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/TypeDefs.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/TypeDefs.java @@ -22,6 +22,7 @@ * Boston, MA 02110-1301 USA */ package org.hibernate.annotations; + import java.lang.annotation.Retention; import java.lang.annotation.Target; @@ -30,12 +31,15 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME; /** - * Type definition array + * Grouping of type definitions. * * @author Emmanuel Bernard */ @Target({TYPE, PACKAGE}) @Retention(RUNTIME) public @interface TypeDefs { + /** + * The grouping of type defs. + */ TypeDef[] value(); } diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/Where.java b/hibernate-core/src/main/java/org/hibernate/annotations/Where.java index 3d60347b43..bd3e032d57 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/Where.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/Where.java @@ -22,6 +22,7 @@ * Boston, MA 02110-1301 USA */ package org.hibernate.annotations; + import java.lang.annotation.Retention; import java.lang.annotation.Target; @@ -31,13 +32,16 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME; /** - * Where clause to add to the element Entity or target entity of a collection - * The clause is written in SQL + * Where clause to add to the element Entity or target entity of a collection. The clause is written in SQL. + * A common use case here is for soft-deletes. * * @author Emmanuel Bernard */ @Target({TYPE, METHOD, FIELD}) @Retention(RUNTIME) public @interface Where { + /** + * The where-clause predicate. + */ String clause(); } diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/WhereJoinTable.java b/hibernate-core/src/main/java/org/hibernate/annotations/WhereJoinTable.java index 9b9adf3d7d..f6f8357da9 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/WhereJoinTable.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/WhereJoinTable.java @@ -21,20 +21,24 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.annotations; +package org.hibernate.annotations; + import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** - * Where clause to add to the colleciton join table - * The clause is written in SQL + * Where clause to add to the collection join table. The clause is written in SQL. Just as with + * {@link Where}, a common use case is for implementing soft-deletes. * * @author Emmanuel Bernard */ @Target({ElementType.TYPE, ElementType.METHOD, ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) public @interface WhereJoinTable { + /** + * The where-clause predicate. + */ String clause(); } diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/package-info.java b/hibernate-core/src/main/java/org/hibernate/annotations/package-info.java new file mode 100644 index 0000000000..a01041a44b --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/annotations/package-info.java @@ -0,0 +1,4 @@ +/** + * Package containing all the Hibernate specific annotations. + */ +package org.hibernate.annotations; diff --git a/shared/config/checkstyle/public_checks.xml b/shared/config/checkstyle/public_checks.xml new file mode 100644 index 0000000000..8cdad56c57 --- /dev/null +++ b/shared/config/checkstyle/public_checks.xml @@ -0,0 +1,145 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From b8ebe0ef4da28329e0ca9141b74cea9437359ba9 Mon Sep 17 00:00:00 2001 From: Steve Ebersole Date: Tue, 9 Apr 2013 19:40:58 -0500 Subject: [PATCH 19/54] HHH-8159 - Apply fixups indicated by analysis tools --- build.gradle | 5 +++-- .../main/java/org/hibernate/annotations/CollectionId.java | 1 + 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index ea9f8b682e..901df8e687 100644 --- a/build.gradle +++ b/build.gradle @@ -305,8 +305,9 @@ subprojects { subProject -> plusConfigurations.add( configurations.provided ) } } - // 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") // specialized API/SPI checkstyle tasks ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ task checkstylePublicSources(type: Checkstyle) { diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/CollectionId.java b/hibernate-core/src/main/java/org/hibernate/annotations/CollectionId.java index a6d7e57fe5..37b2fdd0fc 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/CollectionId.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/CollectionId.java @@ -22,6 +22,7 @@ * Boston, MA 02110-1301 USA */ package org.hibernate.annotations; + import java.lang.annotation.Retention; import java.lang.annotation.Target; import javax.persistence.Column; From bb5e07dce95a488e6cf62ea2983f6a17c6b7d762 Mon Sep 17 00:00:00 2001 From: Steve Ebersole Date: Tue, 9 Apr 2013 20:40:36 -0500 Subject: [PATCH 20/54] HHH-8159 - Apply fixups indicated by analysis tools --- .../registry/BootstrapServiceRegistry.java | 7 ++- .../BootstrapServiceRegistryBuilder.java | 38 +++++++++------- .../registry/StandardServiceInitiator.java | 4 +- .../StandardServiceRegistryBuilder.java | 43 +++++++++++++------ .../classloading/spi/ClassLoaderService.java | 11 ++--- .../spi/ClassLoadingException.java | 21 ++++++--- .../classloading/spi/package-info.java | 4 ++ .../hibernate/boot/registry/package-info.java | 7 +++ .../boot/registry/selector/Availability.java | 30 +++++++++++-- .../selector/AvailabilityAnnouncer.java | 7 ++- .../selector/SimpleAvailabilityImpl.java | 36 ++++++++++++---- .../internal/StrategySelectorBuilder.java | 36 +++++++++++++--- .../internal/StrategySelectorImpl.java | 13 ++++-- .../boot/registry/selector/package-info.java | 6 ++- .../spi/StrategySelectionException.java | 17 +++++++- .../selector/spi/StrategySelector.java | 10 +++++ .../registry/selector/spi/package-info.java | 4 ++ 17 files changed, 229 insertions(+), 65 deletions(-) create mode 100644 hibernate-core/src/main/java/org/hibernate/boot/registry/classloading/spi/package-info.java create mode 100644 hibernate-core/src/main/java/org/hibernate/boot/registry/package-info.java create mode 100644 hibernate-core/src/main/java/org/hibernate/boot/registry/selector/spi/package-info.java diff --git a/hibernate-core/src/main/java/org/hibernate/boot/registry/BootstrapServiceRegistry.java b/hibernate-core/src/main/java/org/hibernate/boot/registry/BootstrapServiceRegistry.java index d7d9387225..1fd7854b2a 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/registry/BootstrapServiceRegistry.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/registry/BootstrapServiceRegistry.java @@ -26,8 +26,11 @@ import org.hibernate.service.ServiceRegistry; /** - * Specialization of the {@link org.hibernate.service.ServiceRegistry} contract mainly to make the - * {@link StandardServiceRegistryBuilder#StandardServiceRegistryBuilder(BootstrapServiceRegistry)} signature type-safe + * Provides the most basic services needed. Class loading, etc. + * + * Specialized mainly for type safety. + * + * @see BootstrapServiceRegistryBuilder * * @author Steve Ebersole */ diff --git a/hibernate-core/src/main/java/org/hibernate/boot/registry/BootstrapServiceRegistryBuilder.java b/hibernate-core/src/main/java/org/hibernate/boot/registry/BootstrapServiceRegistryBuilder.java index 0108042470..ec3da4699c 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/registry/BootstrapServiceRegistryBuilder.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/registry/BootstrapServiceRegistryBuilder.java @@ -39,13 +39,15 @@ import org.hibernate.integrator.spi.Integrator; /** - * Builder for bootstrap {@link org.hibernate.service.ServiceRegistry} instances. + * Builder for {@link BootstrapServiceRegistry} instances. Provides registry for services needed for + * most operations. This includes {@link Integrator} handling and ClassLoader handling. + * + * Additionally responsible for building and managing the {@link org.hibernate.boot.registry.selector.spi.StrategySelector} * * @author Steve Ebersole * @author Brett Meyer * - * @see BootstrapServiceRegistryImpl - * @see StandardServiceRegistryBuilder#StandardServiceRegistryBuilder(org.hibernate.boot.registry.BootstrapServiceRegistry) + * @see StandardServiceRegistryBuilder */ public class BootstrapServiceRegistryBuilder { private final LinkedHashSet providedIntegrators = new LinkedHashSet(); @@ -53,12 +55,11 @@ public class BootstrapServiceRegistryBuilder { private ClassLoaderService providedClassLoaderService; private StrategySelectorBuilder strategySelectorBuilder = new StrategySelectorBuilder(); - - /** * Add an {@link Integrator} to be applied to the bootstrap registry. * * @param integrator The integrator to add. + * * @return {@code this}, for method chaining */ public BootstrapServiceRegistryBuilder with(Integrator integrator) { @@ -67,7 +68,7 @@ public BootstrapServiceRegistryBuilder with(Integrator integrator) { } /** - * Adds a provided {@link ClassLoader} for use in class-loading and resource-lookup + * Adds a provided {@link ClassLoader} for use in class-loading and resource-lookup. * * @param classLoader The class loader to use * @@ -82,9 +83,9 @@ public BootstrapServiceRegistryBuilder with(ClassLoader classLoader) { } /** - * Adds a provided {@link ClassLoaderService} for use in class-loading and resource-lookup + * Adds a provided {@link ClassLoaderService} for use in class-loading and resource-lookup. * - * @param classLoader The class loader to use + * @param classLoaderService The class loader service to use * * @return {@code this}, for method chaining */ @@ -94,9 +95,10 @@ public BootstrapServiceRegistryBuilder with(ClassLoaderService classLoaderServic } /** - * Applies the specified {@link ClassLoader} as the application class loader for the bootstrap registry + * Applies the specified {@link ClassLoader} as the application class loader for the bootstrap registry. * * @param classLoader The class loader to use + * * @return {@code this}, for method chaining * * @deprecated Use {@link #with(ClassLoader)} instead @@ -108,9 +110,10 @@ public BootstrapServiceRegistryBuilder withApplicationClassLoader(ClassLoader cl } /** - * Applies the specified {@link ClassLoader} as the resource class loader for the bootstrap registry + * Applies the specified {@link ClassLoader} as the resource class loader for the bootstrap registry. * * @param classLoader The class loader to use + * * @return {@code this}, for method chaining * * @deprecated Use {@link #with(ClassLoader)} instead @@ -122,9 +125,10 @@ public BootstrapServiceRegistryBuilder withResourceClassLoader(ClassLoader class } /** - * Applies the specified {@link ClassLoader} as the Hibernate class loader for the bootstrap registry + * Applies the specified {@link ClassLoader} as the Hibernate class loader for the bootstrap registry. * * @param classLoader The class loader to use + * * @return {@code this}, for method chaining * * @deprecated Use {@link #with(ClassLoader)} instead @@ -136,9 +140,10 @@ public BootstrapServiceRegistryBuilder withHibernateClassLoader(ClassLoader clas } /** - * Applies the specified {@link ClassLoader} as the environment (or system) class loader for the bootstrap registry + * Applies the specified {@link ClassLoader} as the environment (or system) class loader for the bootstrap registry. * * @param classLoader The class loader to use + * * @return {@code this}, for method chaining * * @deprecated Use {@link #with(ClassLoader)} instead @@ -150,11 +155,13 @@ public BootstrapServiceRegistryBuilder withEnvironmentClassLoader(ClassLoader cl } /** - * Applies a named strategy implementation to the bootstrap registry + * Applies a named strategy implementation to the bootstrap registry. * * @param strategy The strategy * @param name The registered name * @param implementation The strategy implementation Class + * @param Defines the strategy type and makes sure that the strategy and implementation are of + * compatible types. * * @return {@code this}, for method chaining * @@ -176,7 +183,7 @@ public BootstrapServiceRegistryBuilder withStrategySelector(Class strateg * @see org.hibernate.boot.registry.selector.spi.StrategySelector#registerStrategyImplementor(Class, String, Class) */ @SuppressWarnings( {"UnusedDeclaration"}) - public BootstrapServiceRegistryBuilder withStrategySelectors(AvailabilityAnnouncer availabilityAnnouncer) { + public BootstrapServiceRegistryBuilder withStrategySelectors(AvailabilityAnnouncer availabilityAnnouncer) { for ( Availability availability : availabilityAnnouncer.getAvailabilities() ) { this.strategySelectorBuilder.addExplicitAvailability( availability ); } @@ -200,7 +207,8 @@ public BootstrapServiceRegistry build() { } classLoaderService = new ClassLoaderServiceImpl( classLoaders ); - } else { + } + else { classLoaderService = providedClassLoaderService; } diff --git a/hibernate-core/src/main/java/org/hibernate/boot/registry/StandardServiceInitiator.java b/hibernate-core/src/main/java/org/hibernate/boot/registry/StandardServiceInitiator.java index ceeb6cb1e6..0f663102a6 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/registry/StandardServiceInitiator.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/registry/StandardServiceInitiator.java @@ -30,7 +30,9 @@ import org.hibernate.service.spi.ServiceRegistryImplementor; /** - * Contract for an initiator of services that target the standard {@link org.hibernate.service.ServiceRegistry} + * Contract for an initiator of services that target the standard {@link org.hibernate.service.ServiceRegistry}. + * + * @param The type of the service initiated. * * @author Steve Ebersole */ diff --git a/hibernate-core/src/main/java/org/hibernate/boot/registry/StandardServiceRegistryBuilder.java b/hibernate-core/src/main/java/org/hibernate/boot/registry/StandardServiceRegistryBuilder.java index 869455622f..949be8967b 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/registry/StandardServiceRegistryBuilder.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/registry/StandardServiceRegistryBuilder.java @@ -28,7 +28,6 @@ import java.util.LinkedHashSet; import java.util.List; import java.util.Map; -import java.util.Properties; import org.hibernate.boot.registry.classloading.spi.ClassLoaderService; import org.hibernate.boot.registry.internal.StandardServiceRegistryImpl; @@ -53,6 +52,9 @@ * @see org.hibernate.boot.registry.BootstrapServiceRegistryBuilder */ public class StandardServiceRegistryBuilder { + /** + * The default resource name for a hibernate configuration xml file. + */ public static final String DEFAULT_CFG_RESOURCE_NAME = "hibernate.cfg.xml"; private final Map settings; @@ -63,7 +65,7 @@ public class StandardServiceRegistryBuilder { private final ConfigLoader configLoader; /** - * Create a default builder + * Create a default builder. */ public StandardServiceRegistryBuilder() { this( new BootstrapServiceRegistryBuilder().build() ); @@ -96,8 +98,10 @@ public BootstrapServiceRegistry getBootstrapServiceRegistry() { } /** - * Read settings from a {@link Properties} file. Differs from {@link #configure()} and {@link #configure(String)} - * in that here we read a {@link Properties} file while for {@link #configure} we read the XML variant. + * Read settings from a {@link java.util.Properties} file by resource name. + * + * Differs from {@link #configure()} and {@link #configure(String)} in that here we expect to read a + * {@link java.util.Properties} file while for {@link #configure} we read the XML variant. * * @param resourceName The name by which to perform a resource look up for the properties file. * @@ -113,7 +117,7 @@ public StandardServiceRegistryBuilder loadProperties(String resourceName) { } /** - * Read setting information from an XML file using the standard resource location + * Read setting information from an XML file using the standard resource location. * * @return this, for method chaining * @@ -126,7 +130,7 @@ public StandardServiceRegistryBuilder configure() { } /** - * Read setting information from an XML file using the named resource location + * Read setting information from an XML file using the named resource location. * * @param resourceName The named resource * @@ -136,7 +140,7 @@ public StandardServiceRegistryBuilder configure() { */ @SuppressWarnings( {"unchecked"}) public StandardServiceRegistryBuilder configure(String resourceName) { - JaxbHibernateConfiguration configurationElement = configLoader.loadConfigXmlResource( resourceName ); + final JaxbHibernateConfiguration configurationElement = configLoader.loadConfigXmlResource( resourceName ); for ( JaxbHibernateConfiguration.JaxbSessionFactory.JaxbProperty xmlProperty : configurationElement.getSessionFactory().getProperty() ) { settings.put( xmlProperty.getName(), xmlProperty.getValue() ); } @@ -145,7 +149,7 @@ public StandardServiceRegistryBuilder configure(String resourceName) { } /** - * Apply a setting value + * Apply a setting value. * * @param settingName The name of the setting * @param value The value to use. @@ -159,7 +163,7 @@ public StandardServiceRegistryBuilder applySetting(String settingName, Object va } /** - * Apply a groups of setting values + * Apply a groups of setting values. * * @param settings The incoming settings to apply * @@ -185,7 +189,7 @@ public StandardServiceRegistryBuilder addInitiator(StandardServiceInitiator init } /** - * Adds a user-provided service + * Adds a user-provided service. * * @param serviceRole The role of the service being added * @param service The service implementation @@ -198,8 +202,14 @@ public StandardServiceRegistryBuilder addService(final Class serviceRole, final return this; } + /** + * Build the StandardServiceRegistry. + * + * @return The StandardServiceRegistry. + */ + @SuppressWarnings("unchecked") public StandardServiceRegistry build() { - Map settingsCopy = new HashMap(); + final Map settingsCopy = new HashMap(); settingsCopy.putAll( settings ); Environment.verifyProperties( settingsCopy ); ConfigurationHelper.resolvePlaceHolders( settingsCopy ); @@ -220,8 +230,10 @@ private void applyServiceContributingIntegrators() { } private void applyServiceContributors() { - LinkedHashSet serviceContributors = - bootstrapServiceRegistry.getService( ClassLoaderService.class ).loadJavaServices( ServiceContributor.class ); + final LinkedHashSet serviceContributors = + bootstrapServiceRegistry.getService( ClassLoaderService.class ) + .loadJavaServices( ServiceContributor.class ); + for ( ServiceContributor serviceContributor : serviceContributors ) { serviceContributor.contribute( this ); } @@ -230,6 +242,11 @@ private void applyServiceContributors() { /** * Temporarily exposed since Configuration is still around and much code still uses Configuration. This allows * code to configure the builder and access that to configure Configuration object (used from HEM atm). + * + * @return The settings map. + * + * @deprecated Temporarily exposed since Configuration is still around and much code still uses Configuration. + * This allows code to configure the builder and access that to configure Configuration object (used from HEM atm). */ @Deprecated public Map getSettings() { diff --git a/hibernate-core/src/main/java/org/hibernate/boot/registry/classloading/spi/ClassLoaderService.java b/hibernate-core/src/main/java/org/hibernate/boot/registry/classloading/spi/ClassLoaderService.java index cc4cbe4d02..25b94c726b 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/registry/classloading/spi/ClassLoaderService.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/registry/classloading/spi/ClassLoaderService.java @@ -31,15 +31,16 @@ import org.hibernate.service.Service; /** - * A service for interacting with class loaders + * A service for interacting with class loaders. * * @author Steve Ebersole */ public interface ClassLoaderService extends Service { /** - * Locate a class by name + * Locate a class by name. * * @param className The name of the class to locate + * @param The returned class type. * * @return The class reference * @@ -48,7 +49,7 @@ public interface ClassLoaderService extends Service { public Class classForName(String className); /** - * Locate a resource by name (classpath lookup) + * Locate a resource by name (classpath lookup). * * @param name The resource name. * @@ -57,7 +58,7 @@ public interface ClassLoaderService extends Service { public URL locateResource(String name); /** - * Locate a resource by name (classpath lookup) and gets its stream + * Locate a resource by name (classpath lookup) and gets its stream. * * @param name The resource name. * @@ -66,7 +67,7 @@ public interface ClassLoaderService extends Service { public InputStream locateResourceStream(String name); /** - * Locate a series of resource by name (classpath lookup) + * Locate a series of resource by name (classpath lookup). * * @param name The resource name. * diff --git a/hibernate-core/src/main/java/org/hibernate/boot/registry/classloading/spi/ClassLoadingException.java b/hibernate-core/src/main/java/org/hibernate/boot/registry/classloading/spi/ClassLoadingException.java index ce02f02f99..c34d16e874 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/registry/classloading/spi/ClassLoadingException.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/registry/classloading/spi/ClassLoadingException.java @@ -25,16 +25,27 @@ import org.hibernate.HibernateException; /** - * Indicates a problem performing class loading + * Indicates a problem performing class loading. * * @author Steve Ebersole */ public class ClassLoadingException extends HibernateException { - public ClassLoadingException(String string, Throwable root) { - super( string, root ); + /** + * Constructs a ClassLoadingException using the specified message and cause. + * + * @param message A message explaining the exception condition. + * @param cause The underlying cause + */ + public ClassLoadingException(String message, Throwable cause) { + super( message, cause ); } - public ClassLoadingException(String s) { - super( s ); + /** + * Constructs a ClassLoadingException using the specified message. + * + * @param message A message explaining the exception condition. + */ + public ClassLoadingException(String message) { + super( message ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/boot/registry/classloading/spi/package-info.java b/hibernate-core/src/main/java/org/hibernate/boot/registry/classloading/spi/package-info.java new file mode 100644 index 0000000000..14ba6b53aa --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/boot/registry/classloading/spi/package-info.java @@ -0,0 +1,4 @@ +/** + * The class loading service SPI. + */ +package org.hibernate.boot.registry.classloading.spi; diff --git a/hibernate-core/src/main/java/org/hibernate/boot/registry/package-info.java b/hibernate-core/src/main/java/org/hibernate/boot/registry/package-info.java new file mode 100644 index 0000000000..88b77afdc4 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/boot/registry/package-info.java @@ -0,0 +1,7 @@ +/** + * Defines service registry contracts application are likely to want to utilize for + * configuring Hibernate behavior. + * + * {@link BootstrapServiceRegistry} is the + */ +package org.hibernate.boot.registry; diff --git a/hibernate-core/src/main/java/org/hibernate/boot/registry/selector/Availability.java b/hibernate-core/src/main/java/org/hibernate/boot/registry/selector/Availability.java index 658bbb7bed..20de189f6f 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/registry/selector/Availability.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/registry/selector/Availability.java @@ -24,10 +24,34 @@ package org.hibernate.boot.registry.selector; /** + * Describes the availability of a named strategy implementation. A strategy + selector name should resolve + * to a single implementation. + * + * todo : better name? + * + * @param The type of the strategy described by this implementation availability. + * * @author Steve Ebersole */ -public interface Availability { - public Class getStrategyRole(); +public interface Availability { + /** + * The strategy role. Best practice says this should be an interface. + * + * @return The strategy contract/role. + */ + public Class getStrategyRole(); + + /** + * Any registered names for this strategy availability. + * + * @return The registered selection names. + */ public Iterable getSelectorNames(); - public Class getStrategyImplementation(); + + /** + * The strategy implementation class. + * + * @return The strategy implementation. + */ + public Class getStrategyImplementation(); } diff --git a/hibernate-core/src/main/java/org/hibernate/boot/registry/selector/AvailabilityAnnouncer.java b/hibernate-core/src/main/java/org/hibernate/boot/registry/selector/AvailabilityAnnouncer.java index eddc5b3e7e..bcc365a887 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/registry/selector/AvailabilityAnnouncer.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/registry/selector/AvailabilityAnnouncer.java @@ -25,12 +25,17 @@ /** * Responsible for announcing the availability of strategy selector(s). Can be registered directly with the - * {@link org.hibernate.boot.registry.BootstrapServiceRegistry} or located via discovery + * {@link org.hibernate.boot.registry.BootstrapServiceRegistry} or located via discovery. * * todo : better name? * * @author Steve Ebersole */ public interface AvailabilityAnnouncer { + /** + * Get all availabilities announced by this announcer. + * + * @return All announced availabilities + */ public Iterable getAvailabilities(); } diff --git a/hibernate-core/src/main/java/org/hibernate/boot/registry/selector/SimpleAvailabilityImpl.java b/hibernate-core/src/main/java/org/hibernate/boot/registry/selector/SimpleAvailabilityImpl.java index ad515ce1ab..ff536956ab 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/registry/selector/SimpleAvailabilityImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/registry/selector/SimpleAvailabilityImpl.java @@ -26,31 +26,49 @@ import java.util.Arrays; /** + * A simple implementation of Availability. + * + * @param The strategy type. + * * @author Steve Ebersole */ -public class SimpleAvailabilityImpl implements Availability { - private final Class strategyRole; - private final Class strategyImplementation; +public class SimpleAvailabilityImpl implements Availability { + private final Class strategyRole; + private final Class strategyImplementation; private final Iterable selectorNames; + /** + * Constructs a SimpleAvailabilityImpl. + * + * @param strategyRole The strategy contract + * @param strategyImplementation The strategy implementation class + * @param selectorNames The selection/registration names for this implementation + */ public SimpleAvailabilityImpl( - Class strategyRole, - Class strategyImplementation, + Class strategyRole, + Class strategyImplementation, Iterable selectorNames) { this.strategyRole = strategyRole; this.strategyImplementation = strategyImplementation; this.selectorNames = selectorNames; } + /** + * Constructs a SimpleAvailabilityImpl. + * + * @param strategyRole The strategy contract + * @param strategyImplementation The strategy implementation class + * @param selectorNames The selection/registration names for this implementation + */ public SimpleAvailabilityImpl( - Class strategyRole, - Class strategyImplementation, + Class strategyRole, + Class strategyImplementation, String... selectorNames) { this( strategyRole, strategyImplementation, Arrays.asList( selectorNames ) ); } @Override - public Class getStrategyRole() { + public Class getStrategyRole() { return strategyRole; } @@ -60,7 +78,7 @@ public Iterable getSelectorNames() { } @Override - public Class getStrategyImplementation() { + public Class getStrategyImplementation() { return strategyImplementation; } } diff --git a/hibernate-core/src/main/java/org/hibernate/boot/registry/selector/internal/StrategySelectorBuilder.java b/hibernate-core/src/main/java/org/hibernate/boot/registry/selector/internal/StrategySelectorBuilder.java index b248afba3b..47d0962f87 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/registry/selector/internal/StrategySelectorBuilder.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/registry/selector/internal/StrategySelectorBuilder.java @@ -98,6 +98,8 @@ import org.jboss.logging.Logger; /** + * Builder for StrategySelector instances. + * * @author Steve Ebersole */ public class StrategySelectorBuilder { @@ -105,15 +107,31 @@ public class StrategySelectorBuilder { private final List explicitAvailabilities = new ArrayList(); + /** + * Adds an explicit (as opposed to discovered) strategy availability. + * + * @param strategy The strategy + * @param implementation The strategy implementation + * @param name The registered name + * @param The type of the strategy. Used to make sure that the strategy and implementation are type + * compatible. + */ @SuppressWarnings("unchecked") public void addExplicitAvailability(Class strategy, Class implementation, String name) { - addExplicitAvailability( new SimpleAvailabilityImpl( strategy, implementation, name ) ); + addExplicitAvailability( new SimpleAvailabilityImpl( strategy, implementation, name ) ); } - public void addExplicitAvailability(Availability availability) { + /** + * Adds an explicit (as opposed to discovered) strategy availability. + * + * @param availability The strategy implementation availability. + * @param The type of the strategy. Used to make sure that the strategy and implementation are type + * compatible. + */ + public void addExplicitAvailability(Availability availability) { if ( !availability.getStrategyRole().isInterface() ) { // not good form... - log.debug( "Registering non-interface strategy implementation : " + availability.getStrategyRole().getName() ); + log.debug( "Registering non-interface strategy : " + availability.getStrategyRole().getName() ); } if ( ! availability.getStrategyRole().isAssignableFrom( availability.getStrategyImplementation() ) ) { @@ -126,8 +144,16 @@ public void addExplicitAvailability(Availability availability) { explicitAvailabilities.add( availability ); } + /** + * Builds the selector. + * + * @param classLoaderService The class loading service used to (attempt to) resolve any un-registered + * strategy implementations. + * + * @return The selector. + */ public StrategySelector buildSelector(ClassLoaderService classLoaderService) { - StrategySelectorImpl strategySelector = new StrategySelectorImpl( classLoaderService ); + final StrategySelectorImpl strategySelector = new StrategySelectorImpl( classLoaderService ); // build the baseline... addDialects( strategySelector ); @@ -151,7 +177,7 @@ public StrategySelector buildSelector(ClassLoaderService classLoaderService) { } @SuppressWarnings("unchecked") - private void applyFromAvailability(StrategySelectorImpl strategySelector, Availability availability) { + private void applyFromAvailability(StrategySelectorImpl strategySelector, Availability availability) { for ( String name : availability.getSelectorNames() ) { strategySelector.registerStrategyImplementor( availability.getStrategyRole(), diff --git a/hibernate-core/src/main/java/org/hibernate/boot/registry/selector/internal/StrategySelectorImpl.java b/hibernate-core/src/main/java/org/hibernate/boot/registry/selector/internal/StrategySelectorImpl.java index 9d7c6b98e4..69d3e003b8 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/registry/selector/internal/StrategySelectorImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/registry/selector/internal/StrategySelectorImpl.java @@ -35,6 +35,8 @@ import org.hibernate.boot.registry.selector.spi.StrategySelector; /** + * Standard implementation of the StrategySelector contract. + * * @author Steve Ebersole */ public class StrategySelectorImpl implements StrategySelector { @@ -45,6 +47,11 @@ public class StrategySelectorImpl implements StrategySelector { private final ClassLoaderService classLoaderService; + /** + * Constructs a StrategySelectorImpl using the given class loader service. + * + * @param classLoaderService The class loader service usable by this StrategySelectorImpl instance. + */ public StrategySelectorImpl(ClassLoaderService classLoaderService) { this.classLoaderService = classLoaderService; } @@ -57,7 +64,7 @@ public void registerStrategyImplementor(Class strategy, String name, Clas namedStrategyImplementorByStrategyMap.put( strategy, namedStrategyImplementorMap ); } - Class old = namedStrategyImplementorMap.put( name, implementation ); + final Class old = namedStrategyImplementorMap.put( name, implementation ); if ( old == null ) { log.trace( String.format( @@ -83,7 +90,7 @@ public void registerStrategyImplementor(Class strategy, String name, Clas @Override public void unRegisterStrategyImplementor(Class strategy, Class implementation) { - Map namedStrategyImplementorMap = namedStrategyImplementorByStrategyMap.get( strategy ); + final Map namedStrategyImplementorMap = namedStrategyImplementorByStrategyMap.get( strategy ); if ( namedStrategyImplementorMap == null ) { log.debug( "Named strategy map did not exist on call to un-register" ); return; @@ -106,7 +113,7 @@ public void unRegisterStrategyImplementor(Class strategy, Class Class selectStrategyImplementor(Class strategy, String name) { - Map namedStrategyImplementorMap = namedStrategyImplementorByStrategyMap.get( strategy ); + final Map namedStrategyImplementorMap = namedStrategyImplementorByStrategyMap.get( strategy ); if ( namedStrategyImplementorMap != null ) { final Class registered = namedStrategyImplementorMap.get( name ); if ( registered != null ) { diff --git a/hibernate-core/src/main/java/org/hibernate/boot/registry/selector/package-info.java b/hibernate-core/src/main/java/org/hibernate/boot/registry/selector/package-info.java index 095e5ca34b..be46a2f644 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/registry/selector/package-info.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/registry/selector/package-info.java @@ -1 +1,5 @@ -package org.hibernate.boot.registry.selector; \ No newline at end of file +/** + * Defines a feature-set around named registration of implementations of various contracts and the ability + * to select those implementations. + */ +package org.hibernate.boot.registry.selector; diff --git a/hibernate-core/src/main/java/org/hibernate/boot/registry/selector/spi/StrategySelectionException.java b/hibernate-core/src/main/java/org/hibernate/boot/registry/selector/spi/StrategySelectionException.java index 01b63580be..118bda69a0 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/registry/selector/spi/StrategySelectionException.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/registry/selector/spi/StrategySelectionException.java @@ -26,14 +26,27 @@ import org.hibernate.HibernateException; /** + * Indicates a problem performing the selection/resolution. + * * @author Steve Ebersole */ public class StrategySelectionException extends HibernateException { + /** + * Constructs a StrategySelectionException using the specified message. + * + * @param message A message explaining the exception condition. + */ public StrategySelectionException(String message) { super( message ); } - public StrategySelectionException(String message, Throwable root) { - super( message, root ); + /** + * Constructs a StrategySelectionException using the specified message and cause. + * + * @param message A message explaining the exception condition. + * @param cause The underlying cause. + */ + public StrategySelectionException(String message, Throwable cause) { + super( message, cause ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/boot/registry/selector/spi/StrategySelector.java b/hibernate-core/src/main/java/org/hibernate/boot/registry/selector/spi/StrategySelector.java index 21012a25fb..5438f940ca 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/registry/selector/spi/StrategySelector.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/registry/selector/spi/StrategySelector.java @@ -37,6 +37,8 @@ public interface StrategySelector extends Service { * @param strategy The strategy contract. * @param name The registration name * @param implementation The implementation Class + * @param The type of the strategy. Used to make sure that the strategy and implementation are type + * compatible. */ public void registerStrategyImplementor(Class strategy, String name, Class implementation); @@ -46,6 +48,8 @@ public interface StrategySelector extends Service { * * @param strategy The strategy contract. * @param implementation The implementation Class + * @param The type of the strategy. Used to make sure that the strategy and implementation are type + * compatible. */ public void unRegisterStrategyImplementor(Class strategy, Class implementation); @@ -54,6 +58,8 @@ public interface StrategySelector extends Service { * * @param strategy The type of strategy to be resolved. * @param name The name of the strategy to locate; might be either a registered name or the implementation FQN. + * @param The type of the strategy. Used to make sure that the strategy and implementation are type + * compatible. * * @return The named strategy implementation class. */ @@ -65,6 +71,8 @@ public interface StrategySelector extends Service { * * @param strategy The type (interface) of the strategy to be resolved. * @param strategyReference The reference to the strategy for which we need to resolve an instance. + * @param The type of the strategy. Used to make sure that the strategy and implementation are type + * compatible. * * @return The strategy instance */ @@ -91,6 +99,8 @@ public interface StrategySelector extends Service { * @param strategy The type (interface) of the strategy to be resolved. * @param strategyReference The reference to the strategy for which we need to resolve an instance. * @param defaultValue THe default value to use if strategyReference is null + * @param The type of the strategy. Used to make sure that the strategy and implementation are type + * compatible. * * @return The strategy instance */ diff --git a/hibernate-core/src/main/java/org/hibernate/boot/registry/selector/spi/package-info.java b/hibernate-core/src/main/java/org/hibernate/boot/registry/selector/spi/package-info.java new file mode 100644 index 0000000000..ccad0b4e71 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/boot/registry/selector/spi/package-info.java @@ -0,0 +1,4 @@ +/** + * Defines actual contract used for strategy selection : {@link StrategySelector}. + */ +package org.hibernate.boot.registry.selector.spi; From 48063242912356065ced416ca1bfdbe415ca5124 Mon Sep 17 00:00:00 2001 From: Steve Ebersole Date: Wed, 10 Apr 2013 11:48:24 -0500 Subject: [PATCH 21/54] HHH-8163 - Deprecate @IndexColumn and add @ListIndexBase --- .../hibernate/annotations/IndexColumn.java | 7 +-- .../hibernate/annotations/ListIndexBase.java | 44 +++++++++++++++++++ 2 files changed, 48 insertions(+), 3 deletions(-) create mode 100644 hibernate-core/src/main/java/org/hibernate/annotations/ListIndexBase.java diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/IndexColumn.java b/hibernate-core/src/main/java/org/hibernate/annotations/IndexColumn.java index f26076e6a8..88c228ccc2 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/IndexColumn.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/IndexColumn.java @@ -33,13 +33,14 @@ /** * Describe an index column of a List. * - * Prefer the standard {@link javax.persistence.OrderColumn} annotation. Currently the only time to use - * this annotation is to specify {@link #base()}. - * * @author Matthew Inger + * + * @deprecated Prefer the standard JPA {@link javax.persistence.OrderColumn} annotation and the Hibernate specific + * {@link ListIndexBase} (for replacing {@link #base()}). */ @Target({METHOD, FIELD}) @Retention(RUNTIME) +@Deprecated public @interface IndexColumn { /** * The column name. diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/ListIndexBase.java b/hibernate-core/src/main/java/org/hibernate/annotations/ListIndexBase.java new file mode 100644 index 0000000000..db3e8cf17d --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/annotations/ListIndexBase.java @@ -0,0 +1,44 @@ +/* + * 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.annotations; + +/** + * Defines the start index value for a list index as stored on the database. This base is subtracted from the + * incoming database value on reads to determine the List position; it is added to the List position index when + * writing to the database. + * + * By default list indexes are stored starting at zero. + * + * Generally used in conjunction with {@link javax.persistence.OrderColumn}. + * + * @see javax.persistence.OrderColumn + * + * @author Steve Ebersole + */ +public @interface ListIndexBase { + /** + * The list index base. Default is 0. + */ + int value() default 0; +} From 54bc9fbf9db36e55a869a5a7bacbc6897ae2f18e Mon Sep 17 00:00:00 2001 From: Steve Ebersole Date: Wed, 10 Apr 2013 12:26:33 -0500 Subject: [PATCH 22/54] HHH-8163 - Deprecate @IndexColumn and add @ListIndexBase --- .../en-US/content/collection_mapping.xml | 17 +++++---- .../org/hibernate/cfg/AnnotationBinder.java | 4 +++ .../java/org/hibernate/cfg/IndexColumn.java | 35 ++++++++++++++----- .../test/annotations/array/Contest.java | 6 ++-- .../test/annotations/indexcoll/Wardrobe.java | 8 +++-- .../test/propertyref/DoesNotWork.java | 5 ++- 6 files changed, 54 insertions(+), 21 deletions(-) diff --git a/documentation/src/main/docbook/manual/en-US/content/collection_mapping.xml b/documentation/src/main/docbook/manual/en-US/content/collection_mapping.xml index 3fe09b797d..26b6c0f166 100644 --- a/documentation/src/main/docbook/manual/en-US/content/collection_mapping.xml +++ b/documentation/src/main/docbook/manual/en-US/content/collection_mapping.xml @@ -584,13 +584,16 @@ public class Order { - We recommend you to convert the legacy - @org.hibernate.annotations.IndexColumn usages to - @OrderColumn unless you are making use of the - base property. The base property lets you define - the index value of the first element (aka as base index). The usual - value is 0 or 1. The default - is 0 like in Java. + + We recommend you to convert the legacy @org.hibernate.annotations.IndexColumn + usages to the JPA standard @javax.persistence.OrderColumn. + + + If you are leveraging a custom list index base (maybe currently using the + org.hibernate.annotations.IndexColumn.literal attribute), you can + specify this using the @org.hibernate.annotations.ListIndexBase in conjunction + with @javax.persistence.OrderColumn. The default base is 0 like in Java. + Looking again at the Hibernate mapping file equivalent, the diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/AnnotationBinder.java b/hibernate-core/src/main/java/org/hibernate/cfg/AnnotationBinder.java index d5d370c164..bf7293310e 100644 --- a/hibernate-core/src/main/java/org/hibernate/cfg/AnnotationBinder.java +++ b/hibernate-core/src/main/java/org/hibernate/cfg/AnnotationBinder.java @@ -111,6 +111,7 @@ import org.hibernate.annotations.Index; import org.hibernate.annotations.LazyToOne; import org.hibernate.annotations.LazyToOneOption; +import org.hibernate.annotations.ListIndexBase; import org.hibernate.annotations.ManyToAny; import org.hibernate.annotations.MapKeyType; import org.hibernate.annotations.NaturalId; @@ -1708,6 +1709,9 @@ else if ( property.isAnnotationPresent( OneToMany.class ) entityBinder.getSecondaryTables(), mappings ); + if ( property.isAnnotationPresent( ListIndexBase.class ) ) { + indexColumn.setBase( ( property.getAnnotation( ListIndexBase.class ) ).value() ); + } } else { //if @IndexColumn is not there, the generated IndexColumn is an implicit column and not used. diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/IndexColumn.java b/hibernate-core/src/main/java/org/hibernate/cfg/IndexColumn.java index 36a4898346..893850342f 100644 --- a/hibernate-core/src/main/java/org/hibernate/cfg/IndexColumn.java +++ b/hibernate-core/src/main/java/org/hibernate/cfg/IndexColumn.java @@ -77,17 +77,27 @@ public void setBase(int base) { this.base = base; } - //JPA 2 @OrderColumn processing + /** + * JPA 2 {@link OrderColumn @OrderColumn} processing. + * + * @param ann The OrderColumn annotation instance + * @param propertyHolder Information about the property + * @param inferredData Yeah, right. Uh... + * @param secondaryTables Any secondary tables available. + * @param mappings The mappings being built. + * + * @return The index column + */ public static IndexColumn buildColumnFromAnnotation( OrderColumn ann, PropertyHolder propertyHolder, PropertyData inferredData, Map secondaryTables, Mappings mappings) { - IndexColumn column; + final IndexColumn column; if ( ann != null ) { - String sqlType = BinderHelper.isEmptyAnnotationValue( ann.columnDefinition() ) ? null : ann.columnDefinition(); - String name = BinderHelper.isEmptyAnnotationValue( ann.name() ) ? inferredData.getPropertyName() + "_ORDER" : ann.name(); + final String sqlType = BinderHelper.isEmptyAnnotationValue( ann.columnDefinition() ) ? null : ann.columnDefinition(); + final String name = BinderHelper.isEmptyAnnotationValue( ann.name() ) ? inferredData.getPropertyName() + "_ORDER" : ann.name(); //TODO move it to a getter based system and remove the constructor // The JPA OrderColumn annotation defines no table element... // column = new IndexColumn( @@ -110,16 +120,25 @@ public static IndexColumn buildColumnFromAnnotation( return column; } - //legacy @IndexColumn processing + /** + * Legacy {@link IndexColumn @IndexColumn} processing. + * + * @param ann The IndexColumn annotation instance + * @param propertyHolder Information about the property + * @param inferredData Yeah, right. Uh... + * @param mappings The mappings being built. + * + * @return The index column + */ public static IndexColumn buildColumnFromAnnotation( org.hibernate.annotations.IndexColumn ann, PropertyHolder propertyHolder, PropertyData inferredData, Mappings mappings) { - IndexColumn column; + final IndexColumn column; if ( ann != null ) { - String sqlType = BinderHelper.isEmptyAnnotationValue( ann.columnDefinition() ) ? null : ann.columnDefinition(); - String name = BinderHelper.isEmptyAnnotationValue( ann.name() ) ? inferredData.getPropertyName() : ann.name(); + final String sqlType = BinderHelper.isEmptyAnnotationValue( ann.columnDefinition() ) ? null : ann.columnDefinition(); + final String name = BinderHelper.isEmptyAnnotationValue( ann.name() ) ? inferredData.getPropertyName() : ann.name(); //TODO move it to a getter based system and remove the constructor column = new IndexColumn( false, sqlType, 0, 0, 0, name, ann.nullable(), diff --git a/hibernate-core/src/test/java/org/hibernate/test/annotations/array/Contest.java b/hibernate-core/src/test/java/org/hibernate/test/annotations/array/Contest.java index 8db7c0b122..19c6e6328e 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/annotations/array/Contest.java +++ b/hibernate-core/src/test/java/org/hibernate/test/annotations/array/Contest.java @@ -1,5 +1,6 @@ //$Id$ package org.hibernate.test.annotations.array; + import javax.persistence.CascadeType; import javax.persistence.ElementCollection; import javax.persistence.Entity; @@ -8,7 +9,7 @@ import javax.persistence.OneToMany; import javax.persistence.OrderColumn; -import org.hibernate.annotations.IndexColumn; +import org.hibernate.annotations.ListIndexBase; /** * @author Emmanuel Bernard @@ -40,7 +41,8 @@ public void setResults(Competitor[] results) { } @ElementCollection - @IndexColumn(name = "pos", base=1) //legacy + base + @OrderColumn + @ListIndexBase( 1 ) public Month[] getHeldIn() { return heldIn; } diff --git a/hibernate-core/src/test/java/org/hibernate/test/annotations/indexcoll/Wardrobe.java b/hibernate-core/src/test/java/org/hibernate/test/annotations/indexcoll/Wardrobe.java index 35caf58329..68349d6838 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/annotations/indexcoll/Wardrobe.java +++ b/hibernate-core/src/test/java/org/hibernate/test/annotations/indexcoll/Wardrobe.java @@ -1,5 +1,5 @@ -//$Id$ package org.hibernate.test.annotations.indexcoll; + import java.util.List; import javax.persistence.CascadeType; import javax.persistence.Entity; @@ -7,8 +7,9 @@ import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.OneToMany; +import javax.persistence.OrderColumn; -import org.hibernate.annotations.IndexColumn; +import org.hibernate.annotations.ListIndexBase; /** * @author Emmanuel Bernard @@ -34,8 +35,9 @@ public void setId(Long id) { * not recommended). */ @OneToMany(cascade = CascadeType.ALL) - @IndexColumn(name = "drawer_position", base = 1) @JoinColumn(name = "wardrobe_id", nullable = false) + @OrderColumn( name = "drawer_position" ) + @ListIndexBase( 1 ) public List getDrawers() { return drawers; } diff --git a/hibernate-core/src/test/java/org/hibernate/test/propertyref/DoesNotWork.java b/hibernate-core/src/test/java/org/hibernate/test/propertyref/DoesNotWork.java index 1cb7292cc6..60aa29b906 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/propertyref/DoesNotWork.java +++ b/hibernate-core/src/test/java/org/hibernate/test/propertyref/DoesNotWork.java @@ -30,12 +30,14 @@ import javax.persistence.Entity; import javax.persistence.JoinColumn; import javax.persistence.JoinTable; +import javax.persistence.OrderColumn; import javax.persistence.Table; import java.io.Serializable; import java.util.ArrayList; import java.util.List; import org.hibernate.annotations.IndexColumn; +import org.hibernate.annotations.ListIndexBase; /** * @author Steve Ebersole @@ -58,7 +60,8 @@ public class DoesNotWork implements Serializable { joinColumns = @JoinColumn(name = "text_id", referencedColumnName = "production_credits_tid") ) @Column(name = "text_part", insertable = false, updatable = false) - @IndexColumn(name = "seq_no", base = 1) + @OrderColumn( name = "seq_no" ) + @ListIndexBase(1) private List globalNotes = new ArrayList(); public DoesNotWork() { From 6386ba4d887e4ee83fec6d08d5700802f9caa235 Mon Sep 17 00:00:00 2001 From: Brett Meyer Date: Wed, 10 Apr 2013 14:46:08 -0400 Subject: [PATCH 23/54] HHH-7944 Corrected envers JPA imports in manifest --- hibernate-envers/hibernate-envers.gradle | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/hibernate-envers/hibernate-envers.gradle b/hibernate-envers/hibernate-envers.gradle index c3f9a6ec7e..1d406053b5 100644 --- a/hibernate-envers/hibernate-envers.gradle +++ b/hibernate-envers/hibernate-envers.gradle @@ -52,5 +52,14 @@ generateSources.dependsOn generateJpaMetamodelClasses jar { manifest { instruction 'Bundle-Description', 'Hibernate ORM Envers' + + instruction 'Import-Package', + // TODO: Shouldn't have to explicitly list the JPA packages, but + // the plugin generates them with [1.0,2) versions. + 'javax.persistence;version="2.1.0"', + 'javax.persistence.criteria;version="2.1.0"', + 'javax.persistence.metamodel;version="2.1.0"', + 'javax.persistence.spi;version="2.1.0"', + '*' } } \ No newline at end of file From 9c3bad3b2dd443b71d8b323918c4396e46d37126 Mon Sep 17 00:00:00 2001 From: Brett Meyer Date: Wed, 10 Apr 2013 15:12:32 -0400 Subject: [PATCH 24/54] HHH-8084 LobMergeTest fails on oracle --- .../src/main/java/org/hibernate/internal/SessionImpl.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/hibernate-core/src/main/java/org/hibernate/internal/SessionImpl.java b/hibernate-core/src/main/java/org/hibernate/internal/SessionImpl.java index b994ed92c7..59e9dba423 100644 --- a/hibernate-core/src/main/java/org/hibernate/internal/SessionImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/internal/SessionImpl.java @@ -85,6 +85,7 @@ import org.hibernate.criterion.NaturalIdentifier; import org.hibernate.engine.internal.StatefulPersistenceContext; import org.hibernate.engine.jdbc.LobCreator; +import org.hibernate.engine.jdbc.NonContextualLobCreator; import org.hibernate.engine.query.spi.FilterQueryPlan; import org.hibernate.engine.query.spi.HQLQueryPlan; import org.hibernate.engine.query.spi.NativeSQLQueryPlan; @@ -2244,7 +2245,9 @@ public Blob createBlob(byte[] bytes) { } private LobCreator lobCreator() { - return session.getFactory().getJdbcServices().getLobCreator( session ); + // Always use NonContextualLobCreator. If ContextualLobCreator is + // used both here and in WrapperOptions, + return NonContextualLobCreator.INSTANCE; } @Override From 33640ae2bdd37a0102e21f5a3ff8a47f0d6361b5 Mon Sep 17 00:00:00 2001 From: Steve Ebersole Date: Wed, 10 Apr 2013 15:09:45 -0500 Subject: [PATCH 25/54] HHH-8164 - Deprecate @Sort in favor of @SortNatural and @SortComparator --- .../org/hibernate/annotations/OrderBy.java | 7 +- .../java/org/hibernate/annotations/Sort.java | 3 + .../hibernate/annotations/SortComparator.java | 46 ++++ .../hibernate/annotations/SortNatural.java | 40 +++ .../org/hibernate/annotations/SortType.java | 3 + .../org/hibernate/cfg/AnnotationBinder.java | 20 +- .../hibernate/cfg/annotations/BagBinder.java | 2 +- .../cfg/annotations/CollectionBinder.java | 227 ++++++++++++------ .../hibernate/cfg/annotations/ListBinder.java | 1 + .../hibernate/cfg/annotations/MapBinder.java | 4 - .../hibernate/cfg/annotations/SetBinder.java | 4 - 11 files changed, 266 insertions(+), 91 deletions(-) create mode 100644 hibernate-core/src/main/java/org/hibernate/annotations/SortComparator.java create mode 100644 hibernate-core/src/main/java/org/hibernate/annotations/SortNatural.java diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/OrderBy.java b/hibernate-core/src/main/java/org/hibernate/annotations/OrderBy.java index 4143b3b74c..38a5f3acf2 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/OrderBy.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/OrderBy.java @@ -32,10 +32,15 @@ /** * Order a collection using SQL ordering (not HQL ordering). * + * Different from {@link javax.persistence.OrderBy} in that this expects SQL fragment, JPA OrderBy expects a + * valid JPQL order-by fragment. + * * @author Emmanuel Bernard + * @author Steve Ebersole * * @see javax.persistence.OrderBy - * @see Sort + * @see SortComparator + * @see SortNatural */ @Target({METHOD, FIELD}) @Retention(RUNTIME) diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/Sort.java b/hibernate-core/src/main/java/org/hibernate/annotations/Sort.java index 0fe5faa70e..3dd90115e6 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/Sort.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/Sort.java @@ -36,9 +36,12 @@ * @author Emmanuel Bernard * * @see OrderBy + * + * @deprecated Use {@link SortComparator} or {@link SortNatural} instead depending on need. */ @Target({METHOD, FIELD}) @Retention(RUNTIME) +@Deprecated public @interface Sort { /** * The type of sorting to use. The default is to not use sorting. diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/SortComparator.java b/hibernate-core/src/main/java/org/hibernate/annotations/SortComparator.java new file mode 100644 index 0000000000..6ed0c2710a --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/annotations/SortComparator.java @@ -0,0 +1,46 @@ +/* + * 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.annotations; + +import java.util.Comparator; + +/** + * Specifies in-memory Set/Map sorting using a specified {@link Comparator} for sorting. + * + * NOTE : Sorting is different than ordering (see {@link OrderBy}) which is applied during the SQL SELECT. + * + * For sorting based on natural sort order, use {@link SortNatural} instead. It is illegal to combine + * {@link SortComparator} and {@link SortNatural}. + * + * @see OrderBy + * @see SortComparator + * + * @author Steve Ebersole + */ +public @interface SortComparator { + /** + * Specifies the comparator class to use. + */ + Class> value(); +} diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/SortNatural.java b/hibernate-core/src/main/java/org/hibernate/annotations/SortNatural.java new file mode 100644 index 0000000000..9fc285dedc --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/annotations/SortNatural.java @@ -0,0 +1,40 @@ +/* + * 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.annotations; + +/** + * Specifies in-memory Set/Map sorting using natural sorting. + * + * NOTE : Sorting is different than ordering (see {@link OrderBy}) which is applied during the SQL SELECT. + * + * For sorting based on a comparator, use {@link SortComparator} instead. It is illegal to combine + *{@link SortComparator} and SortNatural. + * + * @see OrderBy + * @see SortComparator + * + * @author Steve Ebersole + */ +public @interface SortNatural { +} diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/SortType.java b/hibernate-core/src/main/java/org/hibernate/annotations/SortType.java index 18f7aa8727..b8f0ea4baa 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/SortType.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/SortType.java @@ -27,7 +27,10 @@ * Possible collection sorting strategies. * * @author Emmanuel Bernard + * + * @deprecated Since {@link Sort} is deprecated. */ +@Deprecated public enum SortType { /** * The collection is unsorted. diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/AnnotationBinder.java b/hibernate-core/src/main/java/org/hibernate/cfg/AnnotationBinder.java index bf7293310e..03751aa81b 100644 --- a/hibernate-core/src/main/java/org/hibernate/cfg/AnnotationBinder.java +++ b/hibernate-core/src/main/java/org/hibernate/cfg/AnnotationBinder.java @@ -126,6 +126,8 @@ import org.hibernate.annotations.Parent; import org.hibernate.annotations.Proxy; import org.hibernate.annotations.Sort; +import org.hibernate.annotations.SortComparator; +import org.hibernate.annotations.SortNatural; import org.hibernate.annotations.Source; import org.hibernate.annotations.Tuplizer; import org.hibernate.annotations.Tuplizers; @@ -1733,14 +1735,16 @@ else if ( property.isAnnotationPresent( OneToMany.class ) collectionBinder.setIndexColumn( indexColumn ); collectionBinder.setMapKey( property.getAnnotation( MapKey.class ) ); collectionBinder.setPropertyName( inferredData.getPropertyName() ); - BatchSize batchAnn = property.getAnnotation( BatchSize.class ); - collectionBinder.setBatchSize( batchAnn ); - javax.persistence.OrderBy ejb3OrderByAnn = property.getAnnotation( javax.persistence.OrderBy.class ); - OrderBy orderByAnn = property.getAnnotation( OrderBy.class ); - collectionBinder.setEjb3OrderBy( ejb3OrderByAnn ); - collectionBinder.setSqlOrderBy( orderByAnn ); - Sort sortAnn = property.getAnnotation( Sort.class ); - collectionBinder.setSort( sortAnn ); + + collectionBinder.setBatchSize( property.getAnnotation( BatchSize.class ) ); + + collectionBinder.setJpaOrderBy( property.getAnnotation( javax.persistence.OrderBy.class ) ); + collectionBinder.setSqlOrderBy( property.getAnnotation( OrderBy.class ) ); + + collectionBinder.setSort( property.getAnnotation( Sort.class ) ); + collectionBinder.setNaturalSort( property.getAnnotation( SortNatural.class ) ); + collectionBinder.setComparatorSort( property.getAnnotation( SortComparator.class ) ); + Cache cachAnn = property.getAnnotation( Cache.class ); collectionBinder.setCache( cachAnn ); collectionBinder.setPropertyHolder( propertyHolder ); diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/annotations/BagBinder.java b/hibernate-core/src/main/java/org/hibernate/cfg/annotations/BagBinder.java index c0490c57e2..a38756c9fe 100644 --- a/hibernate-core/src/main/java/org/hibernate/cfg/annotations/BagBinder.java +++ b/hibernate-core/src/main/java/org/hibernate/cfg/annotations/BagBinder.java @@ -31,8 +31,8 @@ * @author Matthew Inger */ public class BagBinder extends CollectionBinder { - public BagBinder() { + super( false ); } protected Collection createCollection(PersistentClass persistentClass) { diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/annotations/CollectionBinder.java b/hibernate-core/src/main/java/org/hibernate/cfg/annotations/CollectionBinder.java index b33812e644..8d5d5be9f2 100644 --- a/hibernate-core/src/main/java/org/hibernate/cfg/annotations/CollectionBinder.java +++ b/hibernate-core/src/main/java/org/hibernate/cfg/annotations/CollectionBinder.java @@ -72,6 +72,8 @@ import org.hibernate.annotations.SQLInsert; import org.hibernate.annotations.SQLUpdate; import org.hibernate.annotations.Sort; +import org.hibernate.annotations.SortComparator; +import org.hibernate.annotations.SortNatural; import org.hibernate.annotations.SortType; import org.hibernate.annotations.Where; import org.hibernate.annotations.WhereJoinTable; @@ -138,11 +140,6 @@ public abstract class CollectionBinder { String cacheRegionName; private boolean oneToMany; protected IndexColumn indexColumn; - private String orderBy; - protected String hqlOrderBy; - private boolean isSorted; - private Class comparator; - private boolean hasToBeSorted; protected boolean cascadeDeleteEnabled; protected String mapKeyPropertyName; private boolean insertable = true; @@ -163,6 +160,13 @@ public abstract class CollectionBinder { private AccessType accessType; private boolean hibernateExtensionMapping; + private boolean isSortedCollection; + private javax.persistence.OrderBy jpaOrderBy; + private OrderBy sqlOrderBy; + private Sort deprecatedSort; + private SortNatural naturalSort; + private SortComparator comparatorSort; + private String explicitType; private Properties explicitTypeParameters = new Properties(); @@ -220,27 +224,24 @@ public void setBatchSize(BatchSize batchSize) { this.batchSize = batchSize == null ? -1 : batchSize.size(); } - public void setEjb3OrderBy(javax.persistence.OrderBy orderByAnn) { - if ( orderByAnn != null ) { - hqlOrderBy = orderByAnn.value(); - } + public void setJpaOrderBy(javax.persistence.OrderBy jpaOrderBy) { + this.jpaOrderBy = jpaOrderBy; } - public void setSqlOrderBy(OrderBy orderByAnn) { - if ( orderByAnn != null ) { - if ( !BinderHelper.isEmptyAnnotationValue( orderByAnn.clause() ) ) { - orderBy = orderByAnn.clause(); - } - } + public void setSqlOrderBy(OrderBy sqlOrderBy) { + this.sqlOrderBy = sqlOrderBy; } - public void setSort(Sort sortAnn) { - if ( sortAnn != null ) { - isSorted = !SortType.UNSORTED.equals( sortAnn.type() ); - if ( isSorted && SortType.COMPARATOR.equals( sortAnn.type() ) ) { - comparator = sortAnn.comparator(); - } - } + public void setSort(Sort deprecatedSort) { + this.deprecatedSort = deprecatedSort; + } + + public void setNaturalSort(SortNatural naturalSort) { + this.naturalSort = naturalSort; + } + + public void setComparatorSort(SortComparator comparatorSort) { + this.comparatorSort = comparatorSort; } /** @@ -252,7 +253,7 @@ public static CollectionBinder getCollectionBinder( boolean isIndexed, boolean isHibernateExtensionMapping, Mappings mappings) { - CollectionBinder result; + final CollectionBinder result; if ( property.isArray() ) { if ( property.getElementClass().isPrimitive() ) { result = new PrimitiveArrayBinder(); @@ -269,7 +270,7 @@ else if ( property.isCollection() ) { throw new AnnotationException( "Set do not support @CollectionId: " + StringHelper.qualify( entityName, property.getName() ) ); } - result = new SetBinder(); + result = new SetBinder( false ); } else if ( java.util.SortedSet.class.equals( returnedClass ) ) { if ( property.isAnnotationPresent( CollectionId.class ) ) { @@ -283,7 +284,7 @@ else if ( java.util.Map.class.equals( returnedClass ) ) { throw new AnnotationException( "Map do not support @CollectionId: " + StringHelper.qualify( entityName, property.getName() ) ); } - result = new MapBinder(); + result = new MapBinder( false ); } else if ( java.util.SortedMap.class.equals( returnedClass ) ) { if ( property.isAnnotationPresent( CollectionId.class ) ) { @@ -351,11 +352,8 @@ else if ( property.isAnnotationPresent( CollectionId.class ) ) { return result; } - protected CollectionBinder() { - } - - protected CollectionBinder(boolean sorted) { - this.hasToBeSorted = sorted; + protected CollectionBinder(boolean isSortedCollection) { + this.isSortedCollection = isSortedCollection; } public void setMappedBy(String mappedBy) { @@ -427,11 +425,6 @@ public void bind() { //set laziness defineFetchingStrategy(); collection.setBatchSize( batchSize ); - if ( orderBy != null && hqlOrderBy != null ) { - throw new AnnotationException( - "Cannot use sql order by clause in conjunction of EJB3 order by clause: " + safeCollectionRole() - ); - } collection.setMutable( !property.isAnnotationPresent( Immutable.class ) ); @@ -449,36 +442,7 @@ public void bind() { collection.setCollectionPersisterClass( persisterAnn.impl() ); } - // set ordering - if ( orderBy != null ) collection.setOrderBy( orderBy ); - if ( isSorted ) { - collection.setSorted( true ); - if ( comparator != null ) { - try { - collection.setComparator( (Comparator) comparator.newInstance() ); - } - catch (ClassCastException e) { - throw new AnnotationException( - "Comparator not implementing java.util.Comparator class: " - + comparator.getName() + "(" + safeCollectionRole() + ")" - ); - } - catch (Exception e) { - throw new AnnotationException( - "Could not instantiate comparator class: " - + comparator.getName() + "(" + safeCollectionRole() + ")" - ); - } - } - } - else { - if ( hasToBeSorted ) { - throw new AnnotationException( - "A sorted collection has to define @Sort: " - + safeCollectionRole() - ); - } - } + applySortingAndOrdering( collection ); //set cache if ( StringHelper.isNotEmpty( cacheConcurrencyStrategy ) ) { @@ -577,6 +541,99 @@ public void bind() { propertyHolder.addProperty( prop, declaringClass ); } + private void applySortingAndOrdering(Collection collection) { + boolean isSorted = isSortedCollection; + + boolean hadOrderBy = false; + boolean hadExplicitSort = false; + + Class comparatorClass = null; + + if ( jpaOrderBy == null && sqlOrderBy == null ) { + if ( deprecatedSort != null ) { + LOG.debug( "Encountered deprecated @Sort annotation; use @SortNatural or @SortComparator instead." ); + if ( naturalSort != null || comparatorSort != null ) { + throw buildIllegalSortCombination(); + } + hadExplicitSort = deprecatedSort.type() != SortType.UNSORTED; + if ( deprecatedSort.type() == SortType.NATURAL ) { + isSorted = true; + } + else if ( deprecatedSort.type() == SortType.COMPARATOR ) { + isSorted = true; + comparatorClass = deprecatedSort.comparator(); + } + } + else if ( naturalSort != null ) { + if ( comparatorSort != null ) { + throw buildIllegalSortCombination(); + } + hadExplicitSort = true; + } + else if ( comparatorSort != null ) { + hadExplicitSort = true; + comparatorClass = comparatorSort.value(); + } + } + else { + if ( jpaOrderBy != null && sqlOrderBy != null ) { + throw new AnnotationException( + String.format( + "Illegal combination of @%s and @%s on %s", + javax.persistence.OrderBy.class.getName(), + OrderBy.class.getName(), + safeCollectionRole() + ) + ); + } + + hadOrderBy = true; + hadExplicitSort = false; + + // we can only apply the sql-based order by up front. The jpa order by has to wait for second pass + if ( sqlOrderBy != null ) { + collection.setOrderBy( sqlOrderBy.clause() ); + } + } + + if ( isSortedCollection ) { + if ( ! hadExplicitSort && !hadOrderBy ) { + throw new AnnotationException( + "A sorted collection must define and ordering or sorting : " + safeCollectionRole() + ); + } + } + + collection.setSorted( isSortedCollection || hadExplicitSort ); + + if ( comparatorClass != null ) { + try { + collection.setComparator( comparatorClass.newInstance() ); + } + catch (Exception e) { + throw new AnnotationException( + String.format( + "Could not instantiate comparator class [%s] for %s", + comparatorClass.getName(), + safeCollectionRole() + ) + ); + } + } + } + + private AnnotationException buildIllegalSortCombination() { + return new AnnotationException( + String.format( + "Illegal combination of annotations on %s. Only one of @%s, @%s and @%s can be used", + safeCollectionRole(), + Sort.class.getName(), + SortNatural.class.getName(), + SortComparator.class.getName() + ) + ); + } + private void defineFetchingStrategy() { LazyCollection lazy = property.getAnnotation( LazyCollection.class ); Fetch fetch = property.getAnnotation( Fetch.class ); @@ -722,7 +779,7 @@ protected boolean bindStarToManySecondPass( fkJoinColumns, collType, cascadeDeleteEnabled, - ignoreNotFound, hqlOrderBy, + ignoreNotFound, mappings, inheritanceStatePerClass ); @@ -739,7 +796,10 @@ protected boolean bindStarToManySecondPass( isEmbedded, collType, ignoreNotFound, unique, cascadeDeleteEnabled, - associationTableBinder, property, propertyHolder, hqlOrderBy, mappings + associationTableBinder, + property, + propertyHolder, + mappings ); return false; } @@ -752,7 +812,6 @@ protected void bindOneToManySecondPass( XClass collectionType, boolean cascadeDeleteEnabled, boolean ignoreNotFound, - String hqlOrderBy, Mappings mappings, Map inheritanceStatePerClass) { if ( LOG.isDebugEnabled() ) { @@ -765,8 +824,20 @@ protected void bindOneToManySecondPass( String assocClass = oneToMany.getReferencedEntityName(); PersistentClass associatedClass = (PersistentClass) persistentClasses.get( assocClass ); - String orderBy = buildOrderByClauseFromHql( hqlOrderBy, associatedClass, collection.getRole() ); - if ( orderBy != null ) collection.setOrderBy( orderBy ); + if ( jpaOrderBy != null ) { + final String jpaOrderByFragment = jpaOrderBy.value(); + if ( StringHelper.isNotEmpty( jpaOrderByFragment ) ) { + final String orderByFragment = buildOrderByClauseFromHql( + jpaOrderBy.value(), + associatedClass, + collection.getRole() + ); + if ( StringHelper.isNotEmpty( orderByFragment ) ) { + collection.setOrderBy( orderByFragment ); + } + } + } + if ( mappings == null ) { throw new AssertionFailure( "CollectionSecondPass for oneToMany should not be called with null mappings" @@ -1037,10 +1108,10 @@ protected void bindManyToManySecondPass( TableBinder associationTableBinder, XProperty property, PropertyHolder parentPropertyHolder, - String hqlOrderBy, Mappings mappings) throws MappingException { - PersistentClass collectionEntity = (PersistentClass) persistentClasses.get( collType.getName() ); + final String hqlOrderBy = extractHqlOrderBy( jpaOrderBy ); + boolean isCollectionOfEntities = collectionEntity != null; ManyToAny anyAnn = property.getAnnotation( ManyToAny.class ); if (LOG.isDebugEnabled()) { @@ -1162,7 +1233,7 @@ else if ( anyAnn != null ) { element.setFetchMode( FetchMode.JOIN ); element.setLazy( false ); element.setIgnoreNotFound( ignoreNotFound ); - // as per 11.1.38 of JPA-2 spec, default to primary key if no column is specified by @OrderBy. + // as per 11.1.38 of JPA 2.0 spec, default to primary key if no column is specified by @OrderBy. if ( hqlOrderBy != null ) { collValue.setManyToManyOrdering( buildOrderByClauseFromHql( hqlOrderBy, collectionEntity, collValue.getRole() ) @@ -1308,6 +1379,16 @@ else if ( owner.getIdentifierMapper() != null && owner.getIdentifierMapper().get } + private String extractHqlOrderBy(javax.persistence.OrderBy jpaOrderBy) { + if ( jpaOrderBy != null ) { + final String jpaOrderByFragment = jpaOrderBy.value(); + return StringHelper.isNotEmpty( jpaOrderByFragment ) + ? jpaOrderByFragment + : null; + } + return null; + } + private static void checkFilterConditions(Collection collValue) { //for now it can't happen, but sometime soon... if ( ( collValue.getFilters().size() != 0 || StringHelper.isNotEmpty( collValue.getWhere() ) ) && diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/annotations/ListBinder.java b/hibernate-core/src/main/java/org/hibernate/cfg/annotations/ListBinder.java index 4ee8d3d3a5..9ee882c558 100644 --- a/hibernate-core/src/main/java/org/hibernate/cfg/annotations/ListBinder.java +++ b/hibernate-core/src/main/java/org/hibernate/cfg/annotations/ListBinder.java @@ -60,6 +60,7 @@ public class ListBinder extends CollectionBinder { private static final CoreMessageLogger LOG = Logger.getMessageLogger( CoreMessageLogger.class, ListBinder.class.getName() ); public ListBinder() { + super( false ); } @Override diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/annotations/MapBinder.java b/hibernate-core/src/main/java/org/hibernate/cfg/annotations/MapBinder.java index 4883499bf5..1e5e7d8150 100644 --- a/hibernate-core/src/main/java/org/hibernate/cfg/annotations/MapBinder.java +++ b/hibernate-core/src/main/java/org/hibernate/cfg/annotations/MapBinder.java @@ -77,10 +77,6 @@ public MapBinder(boolean sorted) { super( sorted ); } - public MapBinder() { - super(); - } - public boolean isMap() { return true; } diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/annotations/SetBinder.java b/hibernate-core/src/main/java/org/hibernate/cfg/annotations/SetBinder.java index 4df97b1a01..4618f92671 100644 --- a/hibernate-core/src/main/java/org/hibernate/cfg/annotations/SetBinder.java +++ b/hibernate-core/src/main/java/org/hibernate/cfg/annotations/SetBinder.java @@ -33,10 +33,6 @@ * @author Matthew Inger */ public class SetBinder extends CollectionBinder { - - public SetBinder() { - } - public SetBinder(boolean sorted) { super( sorted ); } From 692959a48e8f6f03ecdbade60a99d9879a61bdfb Mon Sep 17 00:00:00 2001 From: Steve Ebersole Date: Wed, 10 Apr 2013 16:24:43 -0500 Subject: [PATCH 26/54] HHH-8170 - Deprecate Hibernate @ForeignKey in favor of JPA 2.1 introduced @ForeignKey annotation --- .../src/main/java/org/hibernate/annotations/ForeignKey.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/ForeignKey.java b/hibernate-core/src/main/java/org/hibernate/annotations/ForeignKey.java index 61b4f5b3f0..c1963ec162 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/ForeignKey.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/ForeignKey.java @@ -34,10 +34,11 @@ /** * Define the foreign key name. * - * Prefer the JPA 2.1 introduced {@link javax.persistence.ForeignKey} instead. + * @deprecated Prefer the JPA 2.1 introduced {@link javax.persistence.ForeignKey} instead. */ @Target({FIELD, METHOD, TYPE}) @Retention(RUNTIME) +@Deprecated public @interface ForeignKey { /** * Name of the foreign key. Used in OneToMany, ManyToOne, and OneToOne From 35bd192556ba9318a96f9374a2dfb1557e5a1fb2 Mon Sep 17 00:00:00 2001 From: Lukasz Antoniak Date: Thu, 11 Apr 2013 09:12:23 +0200 Subject: [PATCH 27/54] HHH-2403 - Test cleanup --- .../fileimport/MultiLineImportFileTest.java | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/hibernate-core/src/test/java/org/hibernate/test/fileimport/MultiLineImportFileTest.java b/hibernate-core/src/test/java/org/hibernate/test/fileimport/MultiLineImportFileTest.java index 9907a864b0..bac8e4081f 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/fileimport/MultiLineImportFileTest.java +++ b/hibernate-core/src/test/java/org/hibernate/test/fileimport/MultiLineImportFileTest.java @@ -24,6 +24,9 @@ package org.hibernate.test.fileimport; import java.math.BigInteger; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.SQLException; import org.junit.Test; @@ -32,6 +35,8 @@ import org.hibernate.cfg.Configuration; import org.hibernate.cfg.Environment; import org.hibernate.dialect.H2Dialect; +import org.hibernate.jdbc.Work; +import org.hibernate.testing.AfterClassOnce; import org.hibernate.testing.RequiresDialect; import org.hibernate.testing.TestForIssue; import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; @@ -83,4 +88,27 @@ public void testImportFile() throws Exception { tx.commit(); s.close(); } + + @AfterClassOnce + public void tearDown() { + final Session session = openSession(); + session.getTransaction().begin(); + session.doWork( new Work() { + @Override + public void execute(Connection connection) throws SQLException { + PreparedStatement statement = null; + try { + statement = connection.prepareStatement( "DROP TABLE test_data" ); + statement.execute(); + } + finally { + if ( statement != null ) { + statement.close(); + } + } + } + } ); + session.getTransaction().commit(); + session.close(); + } } From d39272a28052dc48fb1a53acb8361aa82b259088 Mon Sep 17 00:00:00 2001 From: Brett Meyer Date: Thu, 11 Apr 2013 12:40:14 -0400 Subject: [PATCH 28/54] HHH-8175 Test fixes for postgresplus92 --- .../test/annotations/manytoone/Frame.java | 4 ++++ .../test/hql/FunctionNameAsColumnTest.java | 18 +++++++++++------- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/hibernate-core/src/test/java/org/hibernate/test/annotations/manytoone/Frame.java b/hibernate-core/src/test/java/org/hibernate/test/annotations/manytoone/Frame.java index 262e91d01f..8e80927555 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/annotations/manytoone/Frame.java +++ b/hibernate-core/src/test/java/org/hibernate/test/annotations/manytoone/Frame.java @@ -2,10 +2,12 @@ package org.hibernate.test.annotations.manytoone; import java.io.Serializable; import java.util.Set; + import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.OneToMany; +import javax.persistence.Table; import org.hibernate.annotations.Formula; @@ -13,6 +15,8 @@ * @author Emmanuel Bernard */ @Entity +// "frame" is reserved in postgresplus +@Table(name = "FrameTable") public class Frame implements Serializable { @Id @GeneratedValue diff --git a/hibernate-core/src/test/java/org/hibernate/test/hql/FunctionNameAsColumnTest.java b/hibernate-core/src/test/java/org/hibernate/test/hql/FunctionNameAsColumnTest.java index 8796f55525..c299ac78de 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/hql/FunctionNameAsColumnTest.java +++ b/hibernate-core/src/test/java/org/hibernate/test/hql/FunctionNameAsColumnTest.java @@ -23,9 +23,11 @@ */ package org.hibernate.test.hql; -import java.util.List; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; -import org.junit.Test; +import java.util.List; import org.hibernate.FetchMode; import org.hibernate.Hibernate; @@ -34,22 +36,24 @@ import org.hibernate.cfg.Configuration; import org.hibernate.cfg.Environment; import org.hibernate.criterion.Restrictions; +import org.hibernate.dialect.PostgresPlusDialect; import org.hibernate.dialect.SybaseASE15Dialect; import org.hibernate.dialect.function.SQLFunction; import org.hibernate.testing.SkipForDialect; +import org.hibernate.testing.SkipForDialects; import org.hibernate.testing.SkipLog; import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; +import org.junit.Test; /** * Tests HQL and Criteria queries using DB columns having the same name as registered functions. * * @author Gail Badner */ -@SkipForDialect( value = SybaseASE15Dialect.class, jiraKey = "HHH-6426") +@SkipForDialects({ + @SkipForDialect( value = SybaseASE15Dialect.class, jiraKey = "HHH-6426"), + @SkipForDialect( value = PostgresPlusDialect.class, comment = "Almost all of the tests result in 'ambiguous column' errors.") +}) public class FunctionNameAsColumnTest extends BaseCoreFunctionalTestCase { @Override public String[] getMappings() { From 53f7b73adb88f19bd4e48667688b4298d96e2b9a Mon Sep 17 00:00:00 2001 From: Brett Meyer Date: Thu, 11 Apr 2013 14:18:58 -0400 Subject: [PATCH 29/54] HHH-8178 Natural IDs generate one UniqueKey for all columns --- .../java/org/hibernate/cfg/AnnotationBinder.java | 4 ++-- .../src/main/java/org/hibernate/mapping/Table.java | 13 +++++++++++++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/AnnotationBinder.java b/hibernate-core/src/main/java/org/hibernate/cfg/AnnotationBinder.java index 03751aa81b..3e11ef67bf 100644 --- a/hibernate-core/src/main/java/org/hibernate/cfg/AnnotationBinder.java +++ b/hibernate-core/src/main/java/org/hibernate/cfg/AnnotationBinder.java @@ -2106,12 +2106,12 @@ else if ( !isId || !entityBinder.isIgnoreIdAnnotations() ) { if ( naturalIdAnn != null ) { if ( joinColumns != null ) { for ( Ejb3Column column : joinColumns ) { - column.addUniqueKey( StringHelper.randomFixedLengthHex("UK_"), inSecondPass ); + column.addUniqueKey( column.getTable().getNaturalIdUniqueKeyName(), inSecondPass ); } } else { for ( Ejb3Column column : columns ) { - column.addUniqueKey( StringHelper.randomFixedLengthHex("UK_"), inSecondPass ); + column.addUniqueKey( column.getTable().getNaturalIdUniqueKeyName(), inSecondPass ); } } } diff --git a/hibernate-core/src/main/java/org/hibernate/mapping/Table.java b/hibernate-core/src/main/java/org/hibernate/mapping/Table.java index 05fbdd10aa..15aeee8f87 100644 --- a/hibernate-core/src/main/java/org/hibernate/mapping/Table.java +++ b/hibernate-core/src/main/java/org/hibernate/mapping/Table.java @@ -68,6 +68,15 @@ public class Table implements RelationalModel, Serializable { private boolean isAbstract; 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; @@ -818,6 +827,10 @@ public void setComment(String comment) { public Iterator getCheckConstraintsIterator() { return checkConstraints.iterator(); } + + public String getNaturalIdUniqueKeyName() { + return naturalIdUniqueKeyName; + } public Iterator sqlCommentStrings(Dialect dialect, String defaultCatalog, String defaultSchema) { List comments = new ArrayList(); From c259e157b0286b7c36859710215eca2e0da4fd4a Mon Sep 17 00:00:00 2001 From: Steve Ebersole Date: Thu, 11 Apr 2013 14:28:22 -0500 Subject: [PATCH 30/54] HHH-8167 - Adding @NotNull to a @ManyToOne association with @JoinColumnsOrFormulas logs a ClassCastException --- changelog.txt | 2 +- .../CopyIdentifierComponentSecondPass.java | 14 ++++- .../cfg/beanvalidation/TypeSafeActivator.java | 30 ++++++--- .../util/collections/JoinedIterator.java | 62 ++++++++----------- .../org/hibernate/mapping/Collection.java | 5 +- .../java/org/hibernate/mapping/Component.java | 2 +- .../java/org/hibernate/mapping/OneToMany.java | 2 +- .../org/hibernate/mapping/Selectable.java | 4 ++ .../org/hibernate/mapping/SimpleValue.java | 5 +- .../java/org/hibernate/mapping/Value.java | 2 +- .../test/formulajoin/AnnotatedDetail.java | 42 +++++++++++++ ...atedFormWithBeanValidationNotNullTest.java | 44 +++++++++++++ .../test/formulajoin/AnnotatedMaster.java | 55 ++++++++++++++++ .../test/formulajoin/FormulaJoinTest.java | 3 +- 14 files changed, 216 insertions(+), 56 deletions(-) create mode 100644 hibernate-core/src/test/java/org/hibernate/test/formulajoin/AnnotatedDetail.java create mode 100644 hibernate-core/src/test/java/org/hibernate/test/formulajoin/AnnotatedFormWithBeanValidationNotNullTest.java create mode 100644 hibernate-core/src/test/java/org/hibernate/test/formulajoin/AnnotatedMaster.java diff --git a/changelog.txt b/changelog.txt index a2fc570847..e679bf4880 100644 --- a/changelog.txt +++ b/changelog.txt @@ -4890,7 +4890,7 @@ Changes in version 0.9.5 (8.2.2002) * fixed potential bug related to cacheing of compiled queries * major rewrite of code relating to O-R mappings * Session.copy() and Session.equals() as convenience for users -* fixed repeated invocations of hasNext() on iterator + iterators now always work with distinct SQL resultsets +* fixed repeated invocations of hasNext() on iterator + wrappedIterators now always work with distinct SQL resultsets * McKoi dialect was contributed by Gabe Hicks Changes in version 0.9.4 (29.1.2002) diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/CopyIdentifierComponentSecondPass.java b/hibernate-core/src/main/java/org/hibernate/cfg/CopyIdentifierComponentSecondPass.java index 0e63016139..9dad56567f 100644 --- a/hibernate-core/src/main/java/org/hibernate/cfg/CopyIdentifierComponentSecondPass.java +++ b/hibernate-core/src/main/java/org/hibernate/cfg/CopyIdentifierComponentSecondPass.java @@ -26,6 +26,8 @@ import java.util.Iterator; import java.util.Map; +import org.jboss.logging.Logger; + import org.hibernate.AnnotationException; import org.hibernate.AssertionFailure; import org.hibernate.MappingException; @@ -33,12 +35,15 @@ import org.hibernate.mapping.Component; import org.hibernate.mapping.PersistentClass; import org.hibernate.mapping.Property; +import org.hibernate.mapping.Selectable; import org.hibernate.mapping.SimpleValue; /** * @author Emmanuel Bernard */ public class CopyIdentifierComponentSecondPass implements SecondPass { + private static final Logger log = Logger.getLogger( CopyIdentifierComponentSecondPass.class ); + private final String referencedEntityName; private final Component component; private final Mappings mappings; @@ -113,7 +118,7 @@ public void doSecondPass(Map persistentClasses) throws MappingException { final SimpleValue referencedValue = (SimpleValue) referencedProperty.getValue(); value.setTypeName( referencedValue.getTypeName() ); value.setTypeParameters( referencedValue.getTypeParameters() ); - final Iterator columns = referencedValue.getColumnIterator(); + final Iterator columns = referencedValue.getColumnIterator(); if ( joinColumns[0].isNameDeferred() ) { joinColumns[0].copyReferencedStructureAndCreateDefaultJoinColumns( @@ -124,7 +129,12 @@ public void doSecondPass(Map persistentClasses) throws MappingException { else { //FIXME take care of Formula while ( columns.hasNext() ) { - Column column = columns.next(); + final Selectable selectable = columns.next(); + if ( ! Column.class.isInstance( selectable ) ) { + log.debug( "Encountered formula definition; skipping" ); + continue; + } + final Column column = (Column) selectable; final Ejb3JoinColumn joinColumn; String logicalColumnName = null; if ( isExplicitReference ) { diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/beanvalidation/TypeSafeActivator.java b/hibernate-core/src/main/java/org/hibernate/cfg/beanvalidation/TypeSafeActivator.java index fb5733adc8..07c808e746 100644 --- a/hibernate-core/src/main/java/org/hibernate/cfg/beanvalidation/TypeSafeActivator.java +++ b/hibernate-core/src/main/java/org/hibernate/cfg/beanvalidation/TypeSafeActivator.java @@ -60,6 +60,7 @@ import org.hibernate.mapping.Component; import org.hibernate.mapping.PersistentClass; import org.hibernate.mapping.Property; +import org.hibernate.mapping.Selectable; import org.hibernate.mapping.SingleTableSubclass; /** @@ -156,6 +157,7 @@ private static void applyRelationalConstraints(ValidatorFactory factory, Activat } applyRelationalConstraints( + factory, activationContext.getConfiguration().createMappings().getClasses().values(), properties, activationContext.getServiceRegistry().getService( JdbcServices.class ).getDialect() @@ -163,8 +165,11 @@ private static void applyRelationalConstraints(ValidatorFactory factory, Activat } @SuppressWarnings( {"UnusedDeclaration"}) - public static void applyRelationalConstraints(Collection persistentClasses, Properties properties, Dialect dialect) { - ValidatorFactory factory = getValidatorFactory( properties ); + public static void applyRelationalConstraints( + ValidatorFactory factory, + Collection persistentClasses, + Properties properties, + Dialect dialect) { Class[] groupsArray = new GroupsPerOperation( properties ).get( GroupsPerOperation.Operation.DDL ); Set> groups = new HashSet>( Arrays.asList( groupsArray ) ); @@ -305,14 +310,23 @@ private static void applySQLCheck(Column col, String checkConstraint) { private static boolean applyNotNull(Property property, ConstraintDescriptor descriptor) { boolean hasNotNull = false; if ( NotNull.class.equals( descriptor.getAnnotation().annotationType() ) ) { + // single table inheritance should not be forced to null due to shared state if ( !( property.getPersistentClass() instanceof SingleTableSubclass ) ) { - //single table should not be forced to null - if ( !property.isComposite() ) { //composite should not add not-null on all columns - @SuppressWarnings( "unchecked" ) - Iterator iter = property.getColumnIterator(); + //composite should not add not-null on all columns + if ( !property.isComposite() ) { + final Iterator iter = property.getColumnIterator(); while ( iter.hasNext() ) { - iter.next().setNullable( false ); - hasNotNull = true; + final Selectable selectable = iter.next(); + if ( Column.class.isInstance( selectable ) ) { + Column.class.cast( selectable ).setNullable( false ); + } + else { + LOG.debugf( + "@NotNull was applied to attribute [%s] which is defined (at least partially) " + + "by formula(s); formula portions will be skipped", + property.getName() + ); + } } } } diff --git a/hibernate-core/src/main/java/org/hibernate/internal/util/collections/JoinedIterator.java b/hibernate-core/src/main/java/org/hibernate/internal/util/collections/JoinedIterator.java index b7a3e02085..28a910d9b7 100644 --- a/hibernate-core/src/main/java/org/hibernate/internal/util/collections/JoinedIterator.java +++ b/hibernate-core/src/main/java/org/hibernate/internal/util/collections/JoinedIterator.java @@ -24,46 +24,35 @@ */ package org.hibernate.internal.util.collections; +import java.util.Collections; import java.util.Iterator; import java.util.List; /** - * An JoinedIterator is an Iterator that wraps a number of Iterators. - * - * This class makes multiple iterators look like one to the caller. - * When any method from the Iterator interface is called, the JoinedIterator - * will delegate to a single underlying Iterator. The JoinedIterator will - * invoke the Iterators in sequence until all Iterators are exhausted. + * An Iterator implementation that wraps other Iterators, and presents them all as one + * continuous Iterator. When any method from Iterator is called, we delegate to each + * wrapped Iterator in turn until all wrapped Iterators are exhausted. * + * @author Gavine King + * @author Steve Ebersole */ -public class JoinedIterator implements Iterator { +public class JoinedIterator implements Iterator { + private Iterator[] wrappedIterators; - private static final Iterator[] ITERATORS = {}; - - // wrapped iterators - private Iterator[] iterators; - - // index of current iterator in the wrapped iterators array private int currentIteratorIndex; + private Iterator currentIterator; + private Iterator lastUsedIterator; - // the current iterator - private Iterator currentIterator; - - // the last used iterator - private Iterator lastUsedIterator; - - public JoinedIterator(List iterators) { - this( (Iterator[]) iterators.toArray(ITERATORS) ); + @SuppressWarnings("unchecked") + public JoinedIterator(List> wrappedIterators) { + this( wrappedIterators.toArray( new Iterator[ wrappedIterators.size() ]) ); } - public JoinedIterator(Iterator[] iterators) { - if( iterators==null ) - throw new NullPointerException("Unexpected NULL iterators argument"); - this.iterators = iterators; - } - - public JoinedIterator(Iterator first, Iterator second) { - this( new Iterator[] { first, second } ); + public JoinedIterator(Iterator... iteratorsToWrap) { + if( iteratorsToWrap == null ) { + throw new NullPointerException( "Iterators to join were null" ); + } + this.wrappedIterators = iteratorsToWrap; } public boolean hasNext() { @@ -71,7 +60,7 @@ public boolean hasNext() { return currentIterator.hasNext(); } - public Object next() { + public T next() { updateCurrentIterator(); return currentIterator.next(); } @@ -85,22 +74,21 @@ public void remove() { // call this before any Iterator method to make sure that the current Iterator // is not exhausted protected void updateCurrentIterator() { - - if (currentIterator == null) { - if( iterators.length==0 ) { - currentIterator = EmptyIterator.INSTANCE; + if ( currentIterator == null ) { + if( wrappedIterators.length == 0 ) { + currentIterator = Collections.emptyIterator(); } else { - currentIterator = iterators[0]; + currentIterator = wrappedIterators[0]; } // set last used iterator here, in case the user calls remove // before calling hasNext() or next() (although they shouldn't) lastUsedIterator = currentIterator; } - while (! currentIterator.hasNext() && currentIteratorIndex < iterators.length - 1) { + while (! currentIterator.hasNext() && currentIteratorIndex < wrappedIterators.length - 1) { currentIteratorIndex++; - currentIterator = iterators[currentIteratorIndex]; + currentIterator = wrappedIterators[currentIteratorIndex]; } } diff --git a/hibernate-core/src/main/java/org/hibernate/mapping/Collection.java b/hibernate-core/src/main/java/org/hibernate/mapping/Collection.java index 49dd3a0bc4..ba1ec4e63d 100644 --- a/hibernate-core/src/main/java/org/hibernate/mapping/Collection.java +++ b/hibernate-core/src/main/java/org/hibernate/mapping/Collection.java @@ -23,6 +23,7 @@ */ package org.hibernate.mapping; import java.util.ArrayList; +import java.util.Collections; import java.util.Comparator; import java.util.HashSet; import java.util.Iterator; @@ -365,8 +366,8 @@ private void checkColumnDuplication() throws MappingException { } } - public Iterator getColumnIterator() { - return EmptyIterator.INSTANCE; + public Iterator getColumnIterator() { + return Collections.emptyIterator(); } public int getColumnSpan() { diff --git a/hibernate-core/src/main/java/org/hibernate/mapping/Component.java b/hibernate-core/src/main/java/org/hibernate/mapping/Component.java index fd48b6156c..7a2bfe4ee6 100644 --- a/hibernate-core/src/main/java/org/hibernate/mapping/Component.java +++ b/hibernate-core/src/main/java/org/hibernate/mapping/Component.java @@ -106,7 +106,7 @@ public int getColumnSpan() { } return n; } - public Iterator getColumnIterator() { + public Iterator getColumnIterator() { Iterator[] iters = new Iterator[ getPropertySpan() ]; Iterator iter = getPropertyIterator(); int i=0; diff --git a/hibernate-core/src/main/java/org/hibernate/mapping/OneToMany.java b/hibernate-core/src/main/java/org/hibernate/mapping/OneToMany.java index 5abfefd081..18b45cded1 100644 --- a/hibernate-core/src/main/java/org/hibernate/mapping/OneToMany.java +++ b/hibernate-core/src/main/java/org/hibernate/mapping/OneToMany.java @@ -76,7 +76,7 @@ public void createForeignKey() { // no foreign key element of for a one-to-many } - public Iterator getColumnIterator() { + public Iterator getColumnIterator() { return associatedClass.getKey().getColumnIterator(); } diff --git a/hibernate-core/src/main/java/org/hibernate/mapping/Selectable.java b/hibernate-core/src/main/java/org/hibernate/mapping/Selectable.java index 92a370e8f3..b79b1b89ea 100755 --- a/hibernate-core/src/main/java/org/hibernate/mapping/Selectable.java +++ b/hibernate-core/src/main/java/org/hibernate/mapping/Selectable.java @@ -22,9 +22,13 @@ * Boston, MA 02110-1301 USA */ package org.hibernate.mapping; + import org.hibernate.dialect.Dialect; import org.hibernate.dialect.function.SQLFunctionRegistry; +/** + * Models the commonality between a column and a formula (computed value). + */ public interface Selectable { public String getAlias(Dialect dialect); public String getAlias(Dialect dialect, Table table); diff --git a/hibernate-core/src/main/java/org/hibernate/mapping/SimpleValue.java b/hibernate-core/src/main/java/org/hibernate/mapping/SimpleValue.java index f5fb84a81b..a9bbdb3619 100644 --- a/hibernate-core/src/main/java/org/hibernate/mapping/SimpleValue.java +++ b/hibernate-core/src/main/java/org/hibernate/mapping/SimpleValue.java @@ -75,7 +75,8 @@ public class SimpleValue implements KeyValue { private final Mappings mappings; - private final List columns = new ArrayList(); + private final List columns = new ArrayList(); + private String typeName; private Properties identifierGeneratorProperties; private String identifierGeneratorStrategy = DEFAULT_ID_GEN_STRATEGY; @@ -132,7 +133,7 @@ public boolean hasFormula() { public int getColumnSpan() { return columns.size(); } - public Iterator getColumnIterator() { + public Iterator getColumnIterator() { return columns.iterator(); } public List getConstraintColumns() { diff --git a/hibernate-core/src/main/java/org/hibernate/mapping/Value.java b/hibernate-core/src/main/java/org/hibernate/mapping/Value.java index eaa460e64a..731216baf1 100644 --- a/hibernate-core/src/main/java/org/hibernate/mapping/Value.java +++ b/hibernate-core/src/main/java/org/hibernate/mapping/Value.java @@ -41,7 +41,7 @@ */ public interface Value extends Serializable { public int getColumnSpan(); - public Iterator getColumnIterator(); + public Iterator getColumnIterator(); public Type getType() throws MappingException; public FetchMode getFetchMode(); public Table getTable(); diff --git a/hibernate-core/src/test/java/org/hibernate/test/formulajoin/AnnotatedDetail.java b/hibernate-core/src/test/java/org/hibernate/test/formulajoin/AnnotatedDetail.java new file mode 100644 index 0000000000..b2d090cc3d --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/test/formulajoin/AnnotatedDetail.java @@ -0,0 +1,42 @@ +/* + * 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.formulajoin; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; + +/** + * @author Steve Ebersole + */ +@Entity +public class AnnotatedDetail { + @Id + private Integer id; + private String name; + + // because otherwise schema export would not know about it... + @Column( name = "detail_domain" ) + private String domain; +} diff --git a/hibernate-core/src/test/java/org/hibernate/test/formulajoin/AnnotatedFormWithBeanValidationNotNullTest.java b/hibernate-core/src/test/java/org/hibernate/test/formulajoin/AnnotatedFormWithBeanValidationNotNullTest.java new file mode 100644 index 0000000000..2bb218be18 --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/test/formulajoin/AnnotatedFormWithBeanValidationNotNullTest.java @@ -0,0 +1,44 @@ +/* + * 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.formulajoin; + +import org.hibernate.cfg.Configuration; + +import org.junit.Test; + +import org.hibernate.testing.TestForIssue; +import org.hibernate.testing.junit4.BaseUnitTestCase; + +/** + * @author Steve Ebersole + */ +public class AnnotatedFormWithBeanValidationNotNullTest extends BaseUnitTestCase { + @Test + @TestForIssue( jiraKey = "HHH-8167" ) + public void testAnnotatedFormWithBeanValidationNotNull() { + Configuration cfg = new Configuration(); + cfg.addAnnotatedClass( AnnotatedMaster.class ).addAnnotatedClass( AnnotatedDetail.class ); + cfg.buildSessionFactory(); + } +} diff --git a/hibernate-core/src/test/java/org/hibernate/test/formulajoin/AnnotatedMaster.java b/hibernate-core/src/test/java/org/hibernate/test/formulajoin/AnnotatedMaster.java new file mode 100644 index 0000000000..17779287f9 --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/test/formulajoin/AnnotatedMaster.java @@ -0,0 +1,55 @@ +/* + * 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.formulajoin; + +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.validation.constraints.NotNull; + +import org.hibernate.annotations.Fetch; +import org.hibernate.annotations.FetchMode; +import org.hibernate.annotations.JoinColumnOrFormula; +import org.hibernate.annotations.JoinColumnsOrFormulas; +import org.hibernate.annotations.JoinFormula; + +/** + * @author Steve Ebersole + */ +@Entity +public class AnnotatedMaster { + @Id + private Integer id; + private String name; + @ManyToOne(fetch= FetchType.EAGER, optional=false) + @JoinColumnsOrFormulas({ + @JoinColumnOrFormula(formula=@JoinFormula(value="my_domain_key'", referencedColumnName="detail_domain")), + @JoinColumnOrFormula(column=@JoinColumn(name="detail", referencedColumnName="id")) + }) + @Fetch(FetchMode.JOIN) + @NotNull + private AnnotatedDetail detail; +} diff --git a/hibernate-core/src/test/java/org/hibernate/test/formulajoin/FormulaJoinTest.java b/hibernate-core/src/test/java/org/hibernate/test/formulajoin/FormulaJoinTest.java index 6f95c2eb91..de3f0728ea 100755 --- a/hibernate-core/src/test/java/org/hibernate/test/formulajoin/FormulaJoinTest.java +++ b/hibernate-core/src/test/java/org/hibernate/test/formulajoin/FormulaJoinTest.java @@ -30,6 +30,8 @@ import org.hibernate.Transaction; import org.hibernate.dialect.PostgreSQL81Dialect; import org.hibernate.dialect.PostgreSQLDialect; + +import org.hibernate.testing.TestForIssue; import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; import static org.junit.Assert.assertEquals; @@ -111,6 +113,5 @@ public void testFormulaJoin() { s.close(); } - } From a102bf2c31d931044504ad460bee0435695042be Mon Sep 17 00:00:00 2001 From: Steve Ebersole Date: Mon, 4 Mar 2013 15:58:16 -0600 Subject: [PATCH 31/54] HHH-7841 - Redesign Loader --- .../org/hibernate/engine/FetchStrategy.java | 50 ++++ .../CascadeLoadPlanBuilderStrategy.java | 60 ++++ .../loader/plan/internal/LoadPlanImpl.java | 59 ++++ ...ngleRootReturnLoadPlanBuilderStrategy.java | 268 ++++++++++++++++++ .../loader/plan/spi/AbstractFetch.java | 88 ++++++ .../loader/plan/spi/AbstractFetchOwner.java | 75 +++++ .../spi/AbstractLoadPlanBuilderStrategy.java | 212 ++++++++++++++ .../loader/plan/spi/AbstractPlanNode.java | 43 +++ .../loader/plan/spi/CollectionFetch.java | 80 ++++++ .../loader/plan/spi/CollectionReference.java | 73 +++++ .../loader/plan/spi/CollectionReturn.java | 113 ++++++++ .../loader/plan/spi/CompositeFetch.java | 51 ++++ .../loader/plan/spi/EntityFetch.java | 78 +++++ .../loader/plan/spi/EntityReference.java | 73 +++++ .../loader/plan/spi/EntityReturn.java | 96 +++++++ .../org/hibernate/loader/plan/spi/Fetch.java | 59 ++++ .../hibernate/loader/plan/spi/FetchOwner.java | 68 +++++ .../hibernate/loader/plan/spi/LoadPlan.java | 61 ++++ .../loader/plan/spi/LoadPlanBuilder.java | 64 +++++ .../plan/spi/LoadPlanBuilderStrategy.java | 40 +++ .../org/hibernate/loader/plan/spi/Return.java | 40 +++ .../plan/spi/ReturnVisitationStrategy.java | 138 +++++++++ .../loader/plan/spi/ReturnVisitor.java | 116 ++++++++ .../loader/plan/spi/ScalarReturn.java | 52 ++++ .../AbstractCollectionPersister.java | 81 ++++++ .../collection/CollectionPersister.java | 3 +- .../entity/AbstractEntityPersister.java | 116 +++++++- .../persister/entity/EntityPersister.java | 15 +- .../persister/walking/internal/Helper.java | 160 +++++++++++ .../spi/AssociationAttributeDefinition.java | 46 +++ .../persister/walking/spi/AssociationKey.java | 53 ++++ .../spi/AssociationVisitationStrategy.java | 51 ++++ .../walking/spi/AttributeDefinition.java | 35 +++ .../walking/spi/AttributeSource.java | 31 ++ .../walking/spi/CollectionDefinition.java | 38 +++ .../spi/CollectionElementDefinition.java | 39 +++ .../spi/CollectionIndexDefinition.java | 39 +++ .../walking/spi/CompositeDefinition.java | 30 ++ .../walking/spi/EntityDefinition.java | 36 +++ .../spi/MetadataDrivenModelGraphVisitor.java | 208 ++++++++++++++ .../persister/walking/spi/package-info.java | 6 + .../hibernate/tuple/AbstractAttribute.java | 55 ++++ .../tuple/AbstractNonIdentifierAttribute.java | 133 +++++++++ .../java/org/hibernate/tuple/Attribute.java | 37 +++ .../tuple/BaselineAttributeInformation.java | 166 +++++++++++ .../hibernate/tuple/IdentifierAttribute.java | 21 ++ .../hibernate/tuple/IdentifierProperty.java | 23 +- .../tuple/NonIdentifierAttribute.java | 55 ++++ .../java/org/hibernate/tuple/Property.java | 48 +--- .../org/hibernate/tuple/PropertyFactory.java | 249 +++++++++++----- .../org/hibernate/tuple/StandardProperty.java | 159 ++++------- .../org/hibernate/tuple/VersionProperty.java | 81 ------ .../AbstractCompositeBasedAttribute.java | 61 ++++ .../AbstractCompositeDefinition.java | 202 +++++++++++++ .../tuple/component/ComponentMetamodel.java | 2 +- .../CompositeBasedAssociationAttribute.java | 157 ++++++++++ .../CompositeBasedBasicAttribute.java | 45 +++ .../CompositeBasedCompositeAttribute.java | 46 +++ .../entity/AbstractEntityBasedAttribute.java | 50 ++++ .../tuple/entity/AbstractEntityTuplizer.java | 5 +- .../EntityBasedAssociationAttribute.java | 132 +++++++++ .../entity/EntityBasedBasicAttribute.java | 44 +++ .../entity/EntityBasedCompositeAttribute.java | 49 ++++ .../tuple/entity/EntityMetamodel.java | 64 +++-- .../tuple/entity/VersionProperty.java | 70 +++++ .../java/org/hibernate/type/TypeHelper.java | 6 +- .../loader/plan/spi/LoadPlanBuilderTest.java | 149 ++++++++++ .../persister/walking/BasicWalkingTest.java | 177 ++++++++++++ .../GoofyPersisterClassProvider.java | 36 ++- .../test/legacy/CustomPersister.java | 17 ++ 70 files changed, 5048 insertions(+), 335 deletions(-) create mode 100644 hibernate-core/src/main/java/org/hibernate/engine/FetchStrategy.java create mode 100644 hibernate-core/src/main/java/org/hibernate/loader/plan/internal/CascadeLoadPlanBuilderStrategy.java create mode 100644 hibernate-core/src/main/java/org/hibernate/loader/plan/internal/LoadPlanImpl.java create mode 100644 hibernate-core/src/main/java/org/hibernate/loader/plan/internal/SingleRootReturnLoadPlanBuilderStrategy.java create mode 100644 hibernate-core/src/main/java/org/hibernate/loader/plan/spi/AbstractFetch.java create mode 100644 hibernate-core/src/main/java/org/hibernate/loader/plan/spi/AbstractFetchOwner.java create mode 100644 hibernate-core/src/main/java/org/hibernate/loader/plan/spi/AbstractLoadPlanBuilderStrategy.java create mode 100644 hibernate-core/src/main/java/org/hibernate/loader/plan/spi/AbstractPlanNode.java create mode 100644 hibernate-core/src/main/java/org/hibernate/loader/plan/spi/CollectionFetch.java create mode 100644 hibernate-core/src/main/java/org/hibernate/loader/plan/spi/CollectionReference.java create mode 100644 hibernate-core/src/main/java/org/hibernate/loader/plan/spi/CollectionReturn.java create mode 100644 hibernate-core/src/main/java/org/hibernate/loader/plan/spi/CompositeFetch.java create mode 100644 hibernate-core/src/main/java/org/hibernate/loader/plan/spi/EntityFetch.java create mode 100644 hibernate-core/src/main/java/org/hibernate/loader/plan/spi/EntityReference.java create mode 100644 hibernate-core/src/main/java/org/hibernate/loader/plan/spi/EntityReturn.java create mode 100644 hibernate-core/src/main/java/org/hibernate/loader/plan/spi/Fetch.java create mode 100644 hibernate-core/src/main/java/org/hibernate/loader/plan/spi/FetchOwner.java create mode 100644 hibernate-core/src/main/java/org/hibernate/loader/plan/spi/LoadPlan.java create mode 100644 hibernate-core/src/main/java/org/hibernate/loader/plan/spi/LoadPlanBuilder.java create mode 100644 hibernate-core/src/main/java/org/hibernate/loader/plan/spi/LoadPlanBuilderStrategy.java create mode 100644 hibernate-core/src/main/java/org/hibernate/loader/plan/spi/Return.java create mode 100644 hibernate-core/src/main/java/org/hibernate/loader/plan/spi/ReturnVisitationStrategy.java create mode 100644 hibernate-core/src/main/java/org/hibernate/loader/plan/spi/ReturnVisitor.java create mode 100644 hibernate-core/src/main/java/org/hibernate/loader/plan/spi/ScalarReturn.java create mode 100644 hibernate-core/src/main/java/org/hibernate/persister/walking/internal/Helper.java create mode 100644 hibernate-core/src/main/java/org/hibernate/persister/walking/spi/AssociationAttributeDefinition.java create mode 100644 hibernate-core/src/main/java/org/hibernate/persister/walking/spi/AssociationKey.java create mode 100644 hibernate-core/src/main/java/org/hibernate/persister/walking/spi/AssociationVisitationStrategy.java create mode 100644 hibernate-core/src/main/java/org/hibernate/persister/walking/spi/AttributeDefinition.java create mode 100644 hibernate-core/src/main/java/org/hibernate/persister/walking/spi/AttributeSource.java create mode 100644 hibernate-core/src/main/java/org/hibernate/persister/walking/spi/CollectionDefinition.java create mode 100644 hibernate-core/src/main/java/org/hibernate/persister/walking/spi/CollectionElementDefinition.java create mode 100644 hibernate-core/src/main/java/org/hibernate/persister/walking/spi/CollectionIndexDefinition.java create mode 100644 hibernate-core/src/main/java/org/hibernate/persister/walking/spi/CompositeDefinition.java create mode 100644 hibernate-core/src/main/java/org/hibernate/persister/walking/spi/EntityDefinition.java create mode 100644 hibernate-core/src/main/java/org/hibernate/persister/walking/spi/MetadataDrivenModelGraphVisitor.java create mode 100644 hibernate-core/src/main/java/org/hibernate/persister/walking/spi/package-info.java create mode 100644 hibernate-core/src/main/java/org/hibernate/tuple/AbstractAttribute.java create mode 100644 hibernate-core/src/main/java/org/hibernate/tuple/AbstractNonIdentifierAttribute.java create mode 100644 hibernate-core/src/main/java/org/hibernate/tuple/Attribute.java create mode 100644 hibernate-core/src/main/java/org/hibernate/tuple/BaselineAttributeInformation.java create mode 100644 hibernate-core/src/main/java/org/hibernate/tuple/IdentifierAttribute.java create mode 100644 hibernate-core/src/main/java/org/hibernate/tuple/NonIdentifierAttribute.java delete mode 100644 hibernate-core/src/main/java/org/hibernate/tuple/VersionProperty.java create mode 100644 hibernate-core/src/main/java/org/hibernate/tuple/component/AbstractCompositeBasedAttribute.java create mode 100644 hibernate-core/src/main/java/org/hibernate/tuple/component/AbstractCompositeDefinition.java create mode 100644 hibernate-core/src/main/java/org/hibernate/tuple/component/CompositeBasedAssociationAttribute.java create mode 100644 hibernate-core/src/main/java/org/hibernate/tuple/component/CompositeBasedBasicAttribute.java create mode 100644 hibernate-core/src/main/java/org/hibernate/tuple/component/CompositeBasedCompositeAttribute.java create mode 100644 hibernate-core/src/main/java/org/hibernate/tuple/entity/AbstractEntityBasedAttribute.java create mode 100644 hibernate-core/src/main/java/org/hibernate/tuple/entity/EntityBasedAssociationAttribute.java create mode 100644 hibernate-core/src/main/java/org/hibernate/tuple/entity/EntityBasedBasicAttribute.java create mode 100644 hibernate-core/src/main/java/org/hibernate/tuple/entity/EntityBasedCompositeAttribute.java create mode 100644 hibernate-core/src/main/java/org/hibernate/tuple/entity/VersionProperty.java create mode 100644 hibernate-core/src/test/java/org/hibernate/loader/plan/spi/LoadPlanBuilderTest.java create mode 100644 hibernate-core/src/test/java/org/hibernate/persister/walking/BasicWalkingTest.java diff --git a/hibernate-core/src/main/java/org/hibernate/engine/FetchStrategy.java b/hibernate-core/src/main/java/org/hibernate/engine/FetchStrategy.java new file mode 100644 index 0000000000..8264eee79a --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/engine/FetchStrategy.java @@ -0,0 +1,50 @@ +/* + * jDocBook, processing of DocBook sources + * + * 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.engine; + +/** + * Describes the strategy for fetching an association + *

+ * todo not really a fan of the name. not sure of a better one though. + * I'd almost rather see this be called the style, but then what to call FetchStyle? HowToFetch? + * + * @author Steve Ebersole + */ +public class FetchStrategy { + private final FetchTiming timing; + private final FetchStyle style; + + public FetchStrategy(FetchTiming timing, FetchStyle style) { + this.timing = timing; + this.style = style; + } + + public FetchTiming getTiming() { + return timing; + } + + public FetchStyle getStyle() { + return style; + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/internal/CascadeLoadPlanBuilderStrategy.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/internal/CascadeLoadPlanBuilderStrategy.java new file mode 100644 index 0000000000..ce19b46079 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/internal/CascadeLoadPlanBuilderStrategy.java @@ -0,0 +1,60 @@ +/* + * jDocBook, processing of DocBook sources + * + * 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.loader.plan.internal; + +import org.hibernate.engine.FetchStrategy; +import org.hibernate.engine.FetchStyle; +import org.hibernate.engine.FetchTiming; +import org.hibernate.engine.spi.CascadingAction; +import org.hibernate.engine.spi.LoadQueryInfluencers; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.persister.walking.spi.AssociationAttributeDefinition; + +/** + * A LoadPlan building strategy for cascade processing; meaning, it builds the LoadPlan for loading related to + * cascading a particular action across associations + * + * @author Steve Ebersole + */ +public class CascadeLoadPlanBuilderStrategy extends SingleRootReturnLoadPlanBuilderStrategy { + private static final FetchStrategy EAGER = new FetchStrategy( FetchTiming.IMMEDIATE, FetchStyle.JOIN ); + private static final FetchStrategy DELAYED = new FetchStrategy( FetchTiming.DELAYED, FetchStyle.SELECT ); + + private final CascadingAction cascadeActionToMatch; + + public CascadeLoadPlanBuilderStrategy( + CascadingAction cascadeActionToMatch, + SessionFactoryImplementor sessionFactory, + LoadQueryInfluencers loadQueryInfluencers, + String rootAlias, + int suffixSeed) { + super( sessionFactory, loadQueryInfluencers, rootAlias, suffixSeed ); + this.cascadeActionToMatch = cascadeActionToMatch; + } + + @Override + protected FetchStrategy determineFetchPlan(AssociationAttributeDefinition attributeDefinition) { + return attributeDefinition.determineCascadeStyle().doCascade( cascadeActionToMatch ) ? EAGER : DELAYED; + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/internal/LoadPlanImpl.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/internal/LoadPlanImpl.java new file mode 100644 index 0000000000..47daeb3c13 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/internal/LoadPlanImpl.java @@ -0,0 +1,59 @@ +/* + * jDocBook, processing of DocBook sources + * + * 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.loader.plan.internal; + +import java.util.Collections; +import java.util.List; + +import org.hibernate.loader.plan.spi.LoadPlan; +import org.hibernate.loader.plan.spi.Return; + +/** + * Implementation of LoadPlan. + * + * @author Steve Ebersole + */ +public class LoadPlanImpl implements LoadPlan { + private final boolean hasScalars; + private final List returns; + + public LoadPlanImpl(boolean hasScalars, List returns) { + this.hasScalars = hasScalars; + this.returns = returns; + } + + public LoadPlanImpl(boolean hasScalars, Return rootReturn) { + this( hasScalars, Collections.singletonList( rootReturn ) ); + } + + @Override + public boolean hasAnyScalarReturns() { + return hasScalars; + } + + @Override + public List getReturns() { + return returns; + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/internal/SingleRootReturnLoadPlanBuilderStrategy.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/internal/SingleRootReturnLoadPlanBuilderStrategy.java new file mode 100644 index 0000000000..f329b30e26 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/internal/SingleRootReturnLoadPlanBuilderStrategy.java @@ -0,0 +1,268 @@ +/* + * jDocBook, processing of DocBook sources + * + * 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.loader.plan.internal; + +import org.hibernate.HibernateException; +import org.hibernate.LockMode; +import org.hibernate.engine.FetchStrategy; +import org.hibernate.engine.FetchStyle; +import org.hibernate.engine.FetchTiming; +import org.hibernate.engine.spi.LoadQueryInfluencers; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.internal.util.StringHelper; +import org.hibernate.loader.CollectionAliases; +import org.hibernate.loader.DefaultEntityAliases; +import org.hibernate.loader.EntityAliases; +import org.hibernate.loader.GeneratedCollectionAliases; +import org.hibernate.loader.PropertyPath; +import org.hibernate.loader.plan.spi.AbstractFetchOwner; +import org.hibernate.loader.plan.spi.AbstractLoadPlanBuilderStrategy; +import org.hibernate.loader.plan.spi.CollectionFetch; +import org.hibernate.loader.plan.spi.CollectionReturn; +import org.hibernate.loader.plan.spi.CompositeFetch; +import org.hibernate.loader.plan.spi.EntityFetch; +import org.hibernate.loader.plan.spi.EntityReturn; +import org.hibernate.loader.plan.spi.FetchOwner; +import org.hibernate.loader.plan.spi.LoadPlan; +import org.hibernate.loader.plan.spi.LoadPlanBuilderStrategy; +import org.hibernate.loader.plan.spi.Return; +import org.hibernate.persister.collection.CollectionPersister; +import org.hibernate.persister.entity.Loadable; +import org.hibernate.persister.walking.spi.AssociationAttributeDefinition; +import org.hibernate.persister.walking.spi.CollectionDefinition; +import org.hibernate.persister.walking.spi.CompositeDefinition; +import org.hibernate.persister.walking.spi.EntityDefinition; +import org.hibernate.type.EntityType; +import org.hibernate.type.Type; + +/** + * LoadPlanBuilderStrategy implementation used for building LoadPlans with a single processing RootEntity LoadPlan building. + * + * Really this is a single-root LoadPlan building strategy for building LoadPlans for:

    + *
  • entity load plans
  • + *
  • cascade load plans
  • + *
  • collection initializer plans
  • + *
+ * + * @author Steve Ebersole + */ +public class SingleRootReturnLoadPlanBuilderStrategy + extends AbstractLoadPlanBuilderStrategy + implements LoadPlanBuilderStrategy { + + private final LoadQueryInfluencers loadQueryInfluencers; + + private final String rootAlias; + private int currentSuffixBase; + + private Return rootReturn; + + private PropertyPath propertyPath = new PropertyPath( "" ); + + public SingleRootReturnLoadPlanBuilderStrategy( + SessionFactoryImplementor sessionFactory, + LoadQueryInfluencers loadQueryInfluencers, + String rootAlias, + int suffixSeed) { + super( sessionFactory ); + this.loadQueryInfluencers = loadQueryInfluencers; + this.rootAlias = rootAlias; + this.currentSuffixBase = suffixSeed; + } + + @Override + protected boolean supportsRootEntityReturns() { + return true; + } + + @Override + protected boolean supportsRootCollectionReturns() { + return true; + } + + @Override + protected void addRootReturn(Return rootReturn) { + if ( this.rootReturn != null ) { + throw new HibernateException( "Root return already identified" ); + } + this.rootReturn = rootReturn; + } + + @Override + public LoadPlan buildLoadPlan() { + return new LoadPlanImpl( false, rootReturn ); + } + + @Override + protected FetchStrategy determineFetchPlan(AssociationAttributeDefinition attributeDefinition) { + FetchStrategy fetchStrategy = attributeDefinition.determineFetchPlan( loadQueryInfluencers, propertyPath ); + if ( fetchStrategy.getTiming() == FetchTiming.IMMEDIATE && fetchStrategy.getStyle() == FetchStyle.JOIN ) { + // see if we need to alter the join fetch to another form for any reason + fetchStrategy = adjustJoinFetchIfNeeded( attributeDefinition, fetchStrategy ); + } + return fetchStrategy; + } + + protected FetchStrategy adjustJoinFetchIfNeeded( + AssociationAttributeDefinition attributeDefinition, + FetchStrategy fetchStrategy) { + if ( currentDepth() > sessionFactory().getSettings().getMaximumFetchDepth() ) { + return new FetchStrategy( fetchStrategy.getTiming(), FetchStyle.SELECT ); + } + + if ( attributeDefinition.getType().isCollectionType() && isTooManyCollections() ) { + // todo : have this revert to batch or subselect fetching once "sql gen redesign" is in place + return new FetchStrategy( fetchStrategy.getTiming(), FetchStyle.SELECT ); + } + + return fetchStrategy; + } + + @Override + protected boolean isTooManyCollections() { + return false; + } + + @Override + protected EntityReturn buildRootEntityReturn(EntityDefinition entityDefinition) { + final String entityName = entityDefinition.getEntityPersister().getEntityName(); + return new EntityReturn( + sessionFactory(), + rootAlias, + LockMode.NONE, // todo : for now + entityName, + StringHelper.generateAlias( StringHelper.unqualifyEntityName( entityName ), currentDepth() ), + new DefaultEntityAliases( + (Loadable) entityDefinition.getEntityPersister(), + Integer.toString( currentSuffixBase++ ) + '_' + ) + ); + } + + @Override + protected CollectionReturn buildRootCollectionReturn(CollectionDefinition collectionDefinition) { + final CollectionPersister persister = collectionDefinition.getCollectionPersister(); + final String collectionRole = persister.getRole(); + + final CollectionAliases collectionAliases = new GeneratedCollectionAliases( + collectionDefinition.getCollectionPersister(), + Integer.toString( currentSuffixBase++ ) + '_' + ); + final Type elementType = collectionDefinition.getCollectionPersister().getElementType(); + final EntityAliases elementAliases; + if ( elementType.isEntityType() ) { + final EntityType entityElementType = (EntityType) elementType; + elementAliases = new DefaultEntityAliases( + (Loadable) entityElementType.getAssociatedJoinable( sessionFactory() ), + Integer.toString( currentSuffixBase++ ) + '_' + ); + } + else { + elementAliases = null; + } + + return new CollectionReturn( + sessionFactory(), + rootAlias, + LockMode.NONE, // todo : for now + persister.getOwnerEntityPersister().getEntityName(), + StringHelper.unqualify( collectionRole ), + collectionAliases, + elementAliases + ); + } + + @Override + protected CollectionFetch buildCollectionFetch( + FetchOwner fetchOwner, + AssociationAttributeDefinition attributeDefinition, + FetchStrategy fetchStrategy) { + final CollectionDefinition collectionDefinition = attributeDefinition.toCollectionDefinition(); + final CollectionAliases collectionAliases = new GeneratedCollectionAliases( + collectionDefinition.getCollectionPersister(), + Integer.toString( currentSuffixBase++ ) + '_' + ); + final Type elementType = collectionDefinition.getCollectionPersister().getElementType(); + final EntityAliases elementAliases; + if ( elementType.isEntityType() ) { + final EntityType entityElementType = (EntityType) elementType; + elementAliases = new DefaultEntityAliases( + (Loadable) entityElementType.getAssociatedJoinable( sessionFactory() ), + Integer.toString( currentSuffixBase++ ) + '_' + ); + } + else { + elementAliases = null; + } + + return new CollectionFetch( + sessionFactory(), + createImplicitAlias(), + LockMode.NONE, // todo : for now + (AbstractFetchOwner) fetchOwner, + fetchStrategy, + attributeDefinition.getName(), + collectionAliases, + elementAliases + ); + } + + @Override + protected EntityFetch buildEntityFetch( + FetchOwner fetchOwner, + AssociationAttributeDefinition attributeDefinition, + FetchStrategy fetchStrategy) { + final EntityDefinition entityDefinition = attributeDefinition.toEntityDefinition(); + + return new EntityFetch( + sessionFactory(), + createImplicitAlias(), + LockMode.NONE, // todo : for now + (AbstractFetchOwner) fetchOwner, + attributeDefinition.getName(), + fetchStrategy, + StringHelper.generateAlias( entityDefinition.getEntityPersister().getEntityName(), currentDepth() ), + new DefaultEntityAliases( + (Loadable) entityDefinition.getEntityPersister(), + Integer.toString( currentSuffixBase++ ) + '_' + ) + ); + } + + @Override + protected CompositeFetch buildCompositeFetch(FetchOwner fetchOwner, CompositeDefinition attributeDefinition) { + return new CompositeFetch( + sessionFactory(), + createImplicitAlias(), + (AbstractFetchOwner) fetchOwner, + attributeDefinition.getName() + ); + } + + private int implicitAliasUniqueness = 0; + + private String createImplicitAlias() { + return "ia" + implicitAliasUniqueness++; + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/AbstractFetch.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/AbstractFetch.java new file mode 100644 index 0000000000..e7d2751247 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/AbstractFetch.java @@ -0,0 +1,88 @@ +/* + * 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.loader.plan.spi; + +import org.hibernate.HibernateException; +import org.hibernate.LockMode; +import org.hibernate.engine.FetchStrategy; +import org.hibernate.engine.FetchStyle; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.loader.PropertyPath; + +/** + * @author Steve Ebersole + */ +public abstract class AbstractFetch extends AbstractFetchOwner implements Fetch { + private final FetchOwner owner; + private final String ownerProperty; + private final FetchStrategy fetchStrategy; + + private final PropertyPath propertyPath; + + public AbstractFetch( + SessionFactoryImplementor factory, + String alias, + LockMode lockMode, + AbstractFetchOwner owner, + String ownerProperty, + FetchStrategy fetchStrategy) { + super( factory, alias, lockMode ); + this.owner = owner; + this.ownerProperty = ownerProperty; + this.fetchStrategy = fetchStrategy; + + owner.addFetch( this ); + + this.propertyPath = owner.getPropertyPath().append( ownerProperty ); + } + + @Override + public FetchOwner getOwner() { + return owner; + } + + @Override + public String getOwnerPropertyName() { + return ownerProperty; + } + + @Override + public FetchStrategy getFetchStrategy() { + return fetchStrategy; + } + + @Override + public void validateFetchPlan(FetchStrategy fetchStrategy) { + if ( fetchStrategy.getStyle() == FetchStyle.JOIN ) { + if ( this.fetchStrategy.getStyle() != FetchStyle.JOIN ) { + throw new HibernateException( "Cannot specify join fetch from owner that is a non-joined fetch" ); + } + } + } + + @Override + public PropertyPath getPropertyPath() { + return propertyPath; + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/AbstractFetchOwner.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/AbstractFetchOwner.java new file mode 100644 index 0000000000..87063b9278 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/AbstractFetchOwner.java @@ -0,0 +1,75 @@ +/* + * 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.loader.plan.spi; + +import java.util.ArrayList; +import java.util.List; + +import org.hibernate.HibernateException; +import org.hibernate.LockMode; +import org.hibernate.engine.spi.SessionFactoryImplementor; + +/** + * @author Steve Ebersole + */ +public abstract class AbstractFetchOwner extends AbstractPlanNode implements FetchOwner { + private final String alias; + private final LockMode lockMode; + + private List fetches; + + public AbstractFetchOwner(SessionFactoryImplementor factory, String alias, LockMode lockMode) { + super( factory ); + this.alias = alias; + if ( alias == null ) { + throw new HibernateException( "alias must be specified" ); + } + this.lockMode = lockMode; + } + + public String getAlias() { + return alias; + } + + public LockMode getLockMode() { + return lockMode; + } + + void addFetch(Fetch fetch) { + if ( fetch.getOwner() != this ) { + throw new IllegalArgumentException( "Fetch and owner did not match" ); + } + + if ( fetches == null ) { + fetches = new ArrayList(); + } + + fetches.add( fetch ); + } + + @Override + public Fetch[] getFetches() { + return fetches == null ? NO_FETCHES : fetches.toArray( new Fetch[ fetches.size() ] ); + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/AbstractLoadPlanBuilderStrategy.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/AbstractLoadPlanBuilderStrategy.java new file mode 100644 index 0000000000..f9324daa96 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/AbstractLoadPlanBuilderStrategy.java @@ -0,0 +1,212 @@ +/* + * jDocBook, processing of DocBook sources + * + * 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.loader.plan.spi; + +import java.util.ArrayDeque; + +import org.hibernate.HibernateException; +import org.hibernate.engine.FetchStrategy; +import org.hibernate.engine.FetchTiming; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.persister.walking.spi.AssociationAttributeDefinition; +import org.hibernate.persister.walking.spi.AttributeDefinition; +import org.hibernate.persister.walking.spi.CollectionDefinition; +import org.hibernate.persister.walking.spi.CompositeDefinition; +import org.hibernate.persister.walking.spi.EntityDefinition; +import org.hibernate.type.Type; + +/** + * @author Steve Ebersole + */ +public abstract class AbstractLoadPlanBuilderStrategy implements LoadPlanBuilderStrategy { + private final SessionFactoryImplementor sessionFactory; + + private ArrayDeque fetchOwnerStack = new ArrayDeque(); + + protected AbstractLoadPlanBuilderStrategy(SessionFactoryImplementor sessionFactory) { + this.sessionFactory = sessionFactory; + } + + public SessionFactoryImplementor sessionFactory() { + return sessionFactory; + } + + protected FetchOwner currentFetchOwner() { + return fetchOwnerStack.peekLast(); + } + + @Override + public void start() { + // nothing to do + } + + @Override + public void finish() { + // nothing to do + } + + @Override + public void startingEntity(EntityDefinition entityDefinition) { + if ( fetchOwnerStack.isEmpty() ) { + // this is a root... + if ( ! supportsRootEntityReturns() ) { + throw new HibernateException( "This strategy does not support root entity returns" ); + } + final EntityReturn entityReturn = buildRootEntityReturn( entityDefinition ); + addRootReturn( entityReturn ); + fetchOwnerStack.push( entityReturn ); + } + // otherwise this call should represent a fetch which should have been handled in #startingAttribute + } + + protected boolean supportsRootEntityReturns() { + return false; + } + + protected abstract void addRootReturn(Return rootReturn); + + @Override + public void finishingEntity(EntityDefinition entityDefinition) { + // nothing to do + } + + @Override + public void startingCollection(CollectionDefinition collectionDefinition) { + if ( fetchOwnerStack.isEmpty() ) { + // this is a root... + if ( ! supportsRootCollectionReturns() ) { + throw new HibernateException( "This strategy does not support root collection returns" ); + } + final CollectionReturn collectionReturn = buildRootCollectionReturn( collectionDefinition ); + addRootReturn( collectionReturn ); + fetchOwnerStack.push( collectionReturn ); + } + } + + protected boolean supportsRootCollectionReturns() { + return false; + } + + @Override + public void finishingCollection(CollectionDefinition collectionDefinition) { + // nothing to do + } + + @Override + public void startingComposite(CompositeDefinition compositeDefinition) { + if ( fetchOwnerStack.isEmpty() ) { + throw new HibernateException( "A component cannot be the root of a walk nor a graph" ); + } + } + + @Override + public void finishingComposite(CompositeDefinition compositeDefinition) { + // nothing to do + } + + @Override + public boolean startingAttribute(AttributeDefinition attributeDefinition) { + final Type attributeType = attributeDefinition.getType(); + + final boolean isComponentType = attributeType.isComponentType(); + final boolean isBasicType = ! ( isComponentType || attributeType.isAssociationType() ); + + if ( isBasicType ) { + return true; + } + else if ( isComponentType ) { + return handleCompositeAttribute( (CompositeDefinition) attributeDefinition ); + } + else { + return handleAssociationAttribute( (AssociationAttributeDefinition) attributeDefinition ); + } + } + + + @Override + public void finishingAttribute(AttributeDefinition attributeDefinition) { + final Type attributeType = attributeDefinition.getType(); + + final boolean isComponentType = attributeType.isComponentType(); + final boolean isBasicType = ! ( isComponentType || attributeType.isAssociationType() ); + + if ( ! isBasicType ) { + fetchOwnerStack.removeLast(); + } + } + + protected boolean handleCompositeAttribute(CompositeDefinition attributeDefinition) { + final FetchOwner fetchOwner = fetchOwnerStack.peekLast(); + final CompositeFetch fetch = buildCompositeFetch( fetchOwner, attributeDefinition ); + fetchOwnerStack.addLast( fetch ); + return true; + } + + protected boolean handleAssociationAttribute(AssociationAttributeDefinition attributeDefinition) { + final FetchStrategy fetchStrategy = determineFetchPlan( attributeDefinition ); + if ( fetchStrategy.getTiming() != FetchTiming.IMMEDIATE ) { + return false; + } + + final FetchOwner fetchOwner = fetchOwnerStack.peekLast(); + fetchOwner.validateFetchPlan( fetchStrategy ); + + final Fetch associationFetch; + if ( attributeDefinition.isCollection() ) { + associationFetch = buildCollectionFetch( fetchOwner, attributeDefinition, fetchStrategy ); + } + else { + associationFetch = buildEntityFetch( fetchOwner, attributeDefinition, fetchStrategy ); + } + fetchOwnerStack.addLast( associationFetch ); + + return true; + } + + protected abstract FetchStrategy determineFetchPlan(AssociationAttributeDefinition attributeDefinition); + + protected int currentDepth() { + return fetchOwnerStack.size(); + } + + protected boolean isTooManyCollections() { + return false; + } + + protected abstract EntityReturn buildRootEntityReturn(EntityDefinition entityDefinition); + + protected abstract CollectionReturn buildRootCollectionReturn(CollectionDefinition collectionDefinition); + + protected abstract CollectionFetch buildCollectionFetch( + FetchOwner fetchOwner, + AssociationAttributeDefinition attributeDefinition, + FetchStrategy fetchStrategy); + + protected abstract EntityFetch buildEntityFetch( + FetchOwner fetchOwner, + AssociationAttributeDefinition attributeDefinition, + FetchStrategy fetchStrategy); + + protected abstract CompositeFetch buildCompositeFetch(FetchOwner fetchOwner, CompositeDefinition attributeDefinition); +} diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/AbstractPlanNode.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/AbstractPlanNode.java new file mode 100644 index 0000000000..eb789612a2 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/AbstractPlanNode.java @@ -0,0 +1,43 @@ +/* + * 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.loader.plan.spi; + +import org.hibernate.engine.spi.SessionFactoryImplementor; + +/** + * Base class for LoadPlan nodes to hold references to the session factory. + * + * @author Steve Ebersole + */ +public abstract class AbstractPlanNode { + private final SessionFactoryImplementor sessionFactory; + + public AbstractPlanNode(SessionFactoryImplementor sessionFactory) { + this.sessionFactory = sessionFactory; + } + + protected SessionFactoryImplementor sessionFactory() { + return sessionFactory; + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/CollectionFetch.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/CollectionFetch.java new file mode 100644 index 0000000000..973d147795 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/CollectionFetch.java @@ -0,0 +1,80 @@ +/* + * 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.loader.plan.spi; + +import org.hibernate.LockMode; +import org.hibernate.engine.FetchStrategy; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.loader.CollectionAliases; +import org.hibernate.loader.EntityAliases; +import org.hibernate.persister.collection.CollectionPersister; +import org.hibernate.persister.collection.QueryableCollection; +import org.hibernate.persister.entity.EntityPersister; + +/** + * @author Steve Ebersole + */ +public class CollectionFetch extends AbstractFetch implements CollectionReference { + private final CollectionAliases collectionAliases; + private final EntityAliases elementEntityAliases; + + private final CollectionPersister persister; + + public CollectionFetch( + SessionFactoryImplementor sessionFactory, + String alias, + LockMode lockMode, + AbstractFetchOwner owner, + FetchStrategy fetchStrategy, + String ownerProperty, + CollectionAliases collectionAliases, + EntityAliases elementEntityAliases) { + super( sessionFactory, alias, lockMode, owner, ownerProperty, fetchStrategy ); + this.collectionAliases = collectionAliases; + this.elementEntityAliases = elementEntityAliases; + + final String role = owner.retrieveFetchSourcePersister().getEntityName() + '.' + getOwnerPropertyName(); + this.persister = sessionFactory.getCollectionPersister( role ); + } + + @Override + public CollectionAliases getCollectionAliases() { + return collectionAliases; + } + + @Override + public EntityAliases getElementEntityAliases() { + return elementEntityAliases; + } + + @Override + public CollectionPersister getCollectionPersister() { + return persister; + } + + @Override + public EntityPersister retrieveFetchSourcePersister() { + return ( (QueryableCollection) getCollectionPersister() ).getElementPersister(); + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/CollectionReference.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/CollectionReference.java new file mode 100644 index 0000000000..fa0460e922 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/CollectionReference.java @@ -0,0 +1,73 @@ +/* + * 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.loader.plan.spi; + +import org.hibernate.LockMode; +import org.hibernate.loader.CollectionAliases; +import org.hibernate.loader.EntityAliases; +import org.hibernate.persister.collection.CollectionPersister; + +/** + * Represents a reference to an owned collection either as a return or as a fetch + * + * @author Steve Ebersole + */ +public interface CollectionReference { + /** + * Retrieve the alias associated with the persister (entity/collection). + * + * @return The alias + */ + public String getAlias(); + + /** + * Retrieve the lock mode associated with this return. + * + * @return The lock mode. + */ + public LockMode getLockMode(); + + /** + * Retrieves the CollectionPersister describing the collection associated with this Return. + * + * @return The CollectionPersister. + */ + public CollectionPersister getCollectionPersister(); + + /** + * Returns the description of the aliases in the JDBC ResultSet that identify values "belonging" to the + * this collection. + * + * @return The ResultSet alias descriptor for the collection + */ + public CollectionAliases getCollectionAliases(); + + /** + * If the elements of this collection are entities, this methods returns the JDBC ResultSet alias descriptions + * for that entity; {@code null} indicates a non-entity collection. + * + * @return The ResultSet alias descriptor for the collection's entity element, or {@code null} + */ + public EntityAliases getElementEntityAliases(); +} diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/CollectionReturn.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/CollectionReturn.java new file mode 100644 index 0000000000..0dacc39806 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/CollectionReturn.java @@ -0,0 +1,113 @@ +/* + * 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.loader.plan.spi; + +import org.hibernate.LockMode; +import org.hibernate.engine.FetchStrategy; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.loader.CollectionAliases; +import org.hibernate.loader.EntityAliases; +import org.hibernate.loader.PropertyPath; +import org.hibernate.persister.collection.CollectionPersister; +import org.hibernate.persister.collection.QueryableCollection; +import org.hibernate.persister.entity.EntityPersister; + +/** + * @author Steve Ebersole + */ +public class CollectionReturn extends AbstractFetchOwner implements Return, FetchOwner, CollectionReference { + private final String ownerEntityName; + private final String ownerProperty; + private final CollectionAliases collectionAliases; + private final EntityAliases elementEntityAliases; + + private final CollectionPersister persister; + + private final PropertyPath propertyPath = new PropertyPath(); // its a root + + public CollectionReturn( + SessionFactoryImplementor sessionFactory, + String alias, + LockMode lockMode, + String ownerEntityName, + String ownerProperty, + CollectionAliases collectionAliases, + EntityAliases elementEntityAliases) { + super( sessionFactory, alias, lockMode ); + this.ownerEntityName = ownerEntityName; + this.ownerProperty = ownerProperty; + this.collectionAliases = collectionAliases; + this.elementEntityAliases = elementEntityAliases; + + final String role = ownerEntityName + '.' + ownerProperty; + this.persister = sessionFactory.getCollectionPersister( role ); + } + + /** + * Returns the class owning the collection. + * + * @return The class owning the collection. + */ + public String getOwnerEntityName() { + return ownerEntityName; + } + + /** + * Returns the name of the property representing the collection from the {@link #getOwnerEntityName}. + * + * @return The name of the property representing the collection on the owner class. + */ + public String getOwnerProperty() { + return ownerProperty; + } + + @Override + public CollectionAliases getCollectionAliases() { + return collectionAliases; + } + + @Override + public EntityAliases getElementEntityAliases() { + return elementEntityAliases; + } + + @Override + public CollectionPersister getCollectionPersister() { + return persister; + } + + @Override + public void validateFetchPlan(FetchStrategy fetchStrategy) { + } + + @Override + public EntityPersister retrieveFetchSourcePersister() { + return ( (QueryableCollection) persister ).getElementPersister(); + } + + @Override + public PropertyPath getPropertyPath() { + return propertyPath; + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/CompositeFetch.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/CompositeFetch.java new file mode 100644 index 0000000000..48d2f4c415 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/CompositeFetch.java @@ -0,0 +1,51 @@ +/* + * jDocBook, processing of DocBook sources + * + * 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.loader.plan.spi; + +import org.hibernate.LockMode; +import org.hibernate.engine.FetchStrategy; +import org.hibernate.engine.FetchStyle; +import org.hibernate.engine.FetchTiming; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.persister.entity.EntityPersister; + +/** + * @author Steve Ebersole + */ +public class CompositeFetch extends AbstractFetch implements Fetch { + public static final FetchStrategy FETCH_PLAN = new FetchStrategy( FetchTiming.IMMEDIATE, FetchStyle.JOIN ); + + public CompositeFetch( + SessionFactoryImplementor sessionFactory, + String alias, + AbstractFetchOwner owner, + String ownerProperty) { + super( sessionFactory, alias, LockMode.NONE, owner, ownerProperty, FETCH_PLAN ); + } + + @Override + public EntityPersister retrieveFetchSourcePersister() { + return getOwner().retrieveFetchSourcePersister(); + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/EntityFetch.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/EntityFetch.java new file mode 100644 index 0000000000..252e3e0288 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/EntityFetch.java @@ -0,0 +1,78 @@ +/* + * 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.loader.plan.spi; + +import org.hibernate.LockMode; +import org.hibernate.engine.FetchStrategy; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.loader.EntityAliases; +import org.hibernate.persister.entity.EntityPersister; +import org.hibernate.type.EntityType; + +/** + * @author Steve Ebersole + */ +public class EntityFetch extends AbstractFetch implements EntityReference { + private final String sqlTableAlias; + private final EntityAliases entityAliases; + + private final EntityPersister persister; + + public EntityFetch( + SessionFactoryImplementor sessionFactory, + String alias, + LockMode lockMode, + AbstractFetchOwner owner, + String ownerProperty, + FetchStrategy fetchStrategy, + String sqlTableAlias, + EntityAliases entityAliases) { + super( sessionFactory, alias, lockMode, owner, ownerProperty, fetchStrategy ); + this.sqlTableAlias = sqlTableAlias; + this.entityAliases = entityAliases; + + final EntityType type = (EntityType) owner.retrieveFetchSourcePersister().getPropertyType( ownerProperty ); + this.persister = sessionFactory.getEntityPersister( type.getAssociatedEntityName() ); + } + + @Override + public EntityPersister getEntityPersister() { + return persister; + } + + @Override + public EntityAliases getEntityAliases() { + return entityAliases; + } + + @Override + public String getSqlTableAlias() { + return sqlTableAlias; + } + + @Override + public EntityPersister retrieveFetchSourcePersister() { + return persister; + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/EntityReference.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/EntityReference.java new file mode 100644 index 0000000000..d1102acc7b --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/EntityReference.java @@ -0,0 +1,73 @@ +/* + * 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.loader.plan.spi; + +import org.hibernate.LockMode; +import org.hibernate.loader.EntityAliases; +import org.hibernate.persister.entity.EntityPersister; + +/** + * Represents a reference to an entity either as a return or as a fetch + * + * @author Steve Ebersole + */ +public interface EntityReference { + /** + * Retrieve the alias associated with the persister (entity/collection). + * + * @return The alias + */ + public String getAlias(); + + /** + * Retrieve the lock mode associated with this return. + * + * @return The lock mode. + */ + public LockMode getLockMode(); + + /** + * Retrieves the EntityPersister describing the entity associated with this Return. + * + * @return The EntityPersister. + */ + public EntityPersister getEntityPersister(); + + /** + * Returns the description of the aliases in the JDBC ResultSet that identify values "belonging" to the this entity. + * + * @return The ResultSet alias descriptor. + */ + public EntityAliases getEntityAliases(); + + /** + * Obtain the SQL table alias associated with this entity. + * + * TODO : eventually this needs to not be a String, but a representation like I did for the Antlr3 branch + * (AliasRoot, I think it was called) + * + * @return The SQL table alias for this entity + */ + public String getSqlTableAlias(); +} diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/EntityReturn.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/EntityReturn.java new file mode 100644 index 0000000000..eb14ecf297 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/EntityReturn.java @@ -0,0 +1,96 @@ +/* + * 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.loader.plan.spi; + +import org.hibernate.LockMode; +import org.hibernate.engine.FetchStrategy; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.loader.EntityAliases; +import org.hibernate.loader.PropertyPath; +import org.hibernate.persister.entity.EntityPersister; + +/** + * @author Steve Ebersole + */ +public class EntityReturn extends AbstractFetchOwner implements Return, FetchOwner, EntityReference { + private final EntityAliases entityAliases; + private final String sqlTableAlias; + + private final EntityPersister persister; + + private final PropertyPath propertyPath = new PropertyPath(); // its a root + + public EntityReturn( + SessionFactoryImplementor sessionFactory, + String alias, + LockMode lockMode, + String entityName, + String sqlTableAlias, + EntityAliases entityAliases) { + super( sessionFactory, alias, lockMode ); + this.entityAliases = entityAliases; + this.sqlTableAlias = sqlTableAlias; + + this.persister = sessionFactory.getEntityPersister( entityName ); + } + + @Override + public String getAlias() { + return super.getAlias(); + } + + @Override + public LockMode getLockMode() { + return super.getLockMode(); + } + + @Override + public EntityPersister getEntityPersister() { + return persister; + } + + @Override + public EntityAliases getEntityAliases() { + return entityAliases; + } + + @Override + public String getSqlTableAlias() { + return sqlTableAlias; + } + + @Override + public void validateFetchPlan(FetchStrategy fetchStrategy) { + } + + @Override + public EntityPersister retrieveFetchSourcePersister() { + return getEntityPersister(); + } + + @Override + public PropertyPath getPropertyPath() { + return propertyPath; + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/Fetch.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/Fetch.java new file mode 100644 index 0000000000..4be5ca8bbc --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/Fetch.java @@ -0,0 +1,59 @@ +/* + * 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.loader.plan.spi; + +import org.hibernate.engine.FetchStrategy; +import org.hibernate.loader.PropertyPath; + +/** + * Contract for associations that are being fetched. + *

+ * NOTE : can represent components/embeddables + * + * @author Steve Ebersole + */ +public interface Fetch extends FetchOwner { + /** + * Obtain the owner of this fetch. + * + * @return The fetch owner. + */ + public FetchOwner getOwner(); + + /** + * Obtain the name of the property, relative to the owner, being fetched. + * + * @return The fetched property name. + */ + public String getOwnerPropertyName(); + + public FetchStrategy getFetchStrategy(); + + /** + * Get the property path to this fetch + * + * @return The property path + */ + public PropertyPath getPropertyPath(); +} diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/FetchOwner.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/FetchOwner.java new file mode 100644 index 0000000000..e28daf1b24 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/FetchOwner.java @@ -0,0 +1,68 @@ +/* + * 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.loader.plan.spi; + +import org.hibernate.engine.FetchStrategy; +import org.hibernate.loader.PropertyPath; +import org.hibernate.persister.entity.EntityPersister; + +/** + * Contract for owners of fetches. Any non-scalar return could be a fetch owner. + * + * @author Steve Ebersole + */ +public interface FetchOwner { + /** + * Convenient constant for returning no fetches from {@link #getFetches()} + */ + public static final Fetch[] NO_FETCHES = new Fetch[0]; + + /** + * Retrieve the fetches owned by this return. + * + * @return The owned fetches. + */ + public Fetch[] getFetches(); + + /** + * Is the asserted plan valid from this owner to a fetch? + * + * @param fetchStrategy The pla to validate + */ + public void validateFetchPlan(FetchStrategy fetchStrategy); + + /** + * Retrieve the EntityPersister that is the base for any property references in the fetches it owns. + * + * @return The EntityPersister, for property name resolution. + */ + public EntityPersister retrieveFetchSourcePersister(); + + /** + * Get the property path to this fetch owner + * + * @return The property path + */ + public PropertyPath getPropertyPath(); +} diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/LoadPlan.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/LoadPlan.java new file mode 100644 index 0000000000..0173b39714 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/LoadPlan.java @@ -0,0 +1,61 @@ +/* + * 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.loader.plan.spi; + +import java.util.List; + +/** + * Describes a plan for performing a load of results. + * + * Generally speaking there are 3 forms of load plans:

    + *
  • + * An entity load plan for handling get/load handling. This form will typically have a single + * return (of type {@link EntityReturn}) defined by {@link #getReturns()}, possibly defining fetches. + *
  • + *
  • + * A collection initializer, used to load the contents of a collection. This form will typically have a + * single return (of type {@link CollectionReturn} defined by {@link #getReturns()}, possibly defining fetches + *
  • + *
  • + * A query load plan which can contain multiple returns of mixed type (though implementing {@link Return}). + * Again, may possibly define fetches. + *
  • + *
+ * + * @author Steve Ebersole + */ +public interface LoadPlan { + /** + * Convenient form of checking {@link #getReturns()} for scalar root returns. + * + * @return {@code true} if {@link #getReturns()} contained any scalar returns; {@code false} otherwise. + */ + public boolean hasAnyScalarReturns(); + + public List getReturns(); + + // todo : would also like to see "call back" style access for handling "subsequent actions" such as: + // 1) follow-on locking + // 2) join fetch conversions to subselect fetches +} diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/LoadPlanBuilder.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/LoadPlanBuilder.java new file mode 100644 index 0000000000..61b7b41ab1 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/LoadPlanBuilder.java @@ -0,0 +1,64 @@ +/* + * jDocBook, processing of DocBook sources + * + * 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.loader.plan.spi; + +import org.hibernate.persister.collection.CollectionPersister; +import org.hibernate.persister.entity.EntityPersister; +import org.hibernate.persister.walking.spi.MetadataDrivenModelGraphVisitor; + +/** + * Coordinates building of a {@link LoadPlan} between the {@link org.hibernate.persister.walking.spi.MetadataDrivenModelGraphVisitor} and + * {@link LoadPlanBuilderStrategy} + * + * @author Steve Ebersole + */ +public class LoadPlanBuilder { + /** + * Coordinates building a LoadPlan that defines just a single root entity return (may have fetches). + *

+ * Typically this includes building load plans for entity loading or cascade loading. + * + * @param strategy The strategy defining the load plan shaping + * @param persister The persister for the entity forming the root of the load plan. + * + * @return The built load plan. + */ + public static LoadPlan buildRootEntityLoadPlan(LoadPlanBuilderStrategy strategy, EntityPersister persister) { + MetadataDrivenModelGraphVisitor.visitEntity( strategy, persister ); + return strategy.buildLoadPlan(); + } + + /** + * Coordinates building a LoadPlan that defines just a single root collection return (may have fetches). + * + * @param strategy The strategy defining the load plan shaping + * @param persister The persister for the collection forming the root of the load plan. + * + * @return The built load plan. + */ + public static LoadPlan buildRootCollectionLoadPlan(LoadPlanBuilderStrategy strategy, CollectionPersister persister) { + MetadataDrivenModelGraphVisitor.visitCollection( strategy, persister ); + return strategy.buildLoadPlan(); + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/LoadPlanBuilderStrategy.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/LoadPlanBuilderStrategy.java new file mode 100644 index 0000000000..7c40540fbf --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/LoadPlanBuilderStrategy.java @@ -0,0 +1,40 @@ +/* + * jDocBook, processing of DocBook sources + * + * 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.loader.plan.spi; + +import org.hibernate.persister.walking.spi.AssociationVisitationStrategy; + +/** + * Specialized {@link org.hibernate.persister.walking.spi.AssociationVisitationStrategy} implementation for building {@link LoadPlan} instances. + * + * @author Steve Ebersole + */ +public interface LoadPlanBuilderStrategy extends AssociationVisitationStrategy { + /** + * After visitation is done, build the load plan. + * + * @return The load plan + */ + public LoadPlan buildLoadPlan(); +} diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/Return.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/Return.java new file mode 100644 index 0000000000..b94adfae9d --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/Return.java @@ -0,0 +1,40 @@ +/* + * 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.loader.plan.spi; + +/** + * Represents a return value in the query results. Not the same as a result (column) in the JDBC ResultSet! + *

+ * This is merely a unifying contract; it defines no behavior. + *

+ * Return is distinctly different from a {@link Fetch}. + * + * @see ScalarReturn + * @see EntityReturn + * @see CollectionReturn + * + * @author Steve Ebersole + */ +public interface Return { +} diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/ReturnVisitationStrategy.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/ReturnVisitationStrategy.java new file mode 100644 index 0000000000..4140249b3a --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/ReturnVisitationStrategy.java @@ -0,0 +1,138 @@ +/* + * 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.loader.plan.spi; + +/** + * @author Steve Ebersole + */ +public interface ReturnVisitationStrategy { + /** + * Notification we are preparing to start visitation. + */ + public void start(); + + /** + * Notification we are finished visitation. + */ + public void finish(); + + /** + * Notification that a new root return branch is being started. Will be followed by calls to one of the following + * based on the type of return:

    + *
  • {@link #handleScalarReturn}
  • + *
  • {@link #handleEntityReturn}
  • + *
  • {@link #handleCollectionReturn}
  • + *
+ * + * @param rootReturn The root return at the root of the branch. + */ + public void startingRootReturn(Return rootReturn); + + /** + * Notification that we are finishing up processing a root return branch + * + * @param rootReturn The RootReturn we are finishing up processing. + */ + public void finishingRootReturn(Return rootReturn); + + /** + * Notification that a scalar return is being processed. Will be surrounded by calls to {@link #startingRootReturn} + * and {@link #finishingRootReturn} + * + * @param scalarReturn The scalar return + */ + public void handleScalarReturn(ScalarReturn scalarReturn); + + /** + * Notification that a root entity return is being processed. Will be surrounded by calls to + * {@link #startingRootReturn} and {@link #finishingRootReturn} + * + * @param rootEntityReturn The root entity return + */ + public void handleEntityReturn(EntityReturn rootEntityReturn); + + /** + * Notification that a root collection return is being processed. Will be surrounded by calls to + * {@link #startingRootReturn} and {@link #finishingRootReturn} + * + * @param rootCollectionReturn The root collection return + */ + public void handleCollectionReturn(CollectionReturn rootCollectionReturn); + + /** + * Notification that we are about to start processing the fetches for the given fetch owner. + * + * @param fetchOwner The fetch owner. + */ + public void startingFetches(FetchOwner fetchOwner); + + /** + * Notification that we are finishing up processing the fetches for the given fetch owner. + * + * @param fetchOwner The fetch owner. + */ + public void finishingFetches(FetchOwner fetchOwner); + + /** + * Notification we are starting the processing of an entity fetch + * + * @param entityFetch The entity fetch + */ + public void startingEntityFetch(EntityFetch entityFetch); + + /** + * Notification that we are finishing up the processing of an entity fetch + * + * @param entityFetch The entity fetch + */ + public void finishingEntityFetch(EntityFetch entityFetch); + + /** + * Notification we are starting the processing of a collection fetch + * + * @param collectionFetch The collection fetch + */ + public void startingCollectionFetch(CollectionFetch collectionFetch); + + /** + * Notification that we are finishing up the processing of a collection fetch + * + * @param collectionFetch The collection fetch + */ + public void finishingCollectionFetch(CollectionFetch collectionFetch); + + /** + * Notification we are starting the processing of a component fetch + * + * @param fetch The composite fetch + */ + public void startingCompositeFetch(CompositeFetch fetch); + + /** + * Notification that we are finishing up the processing of a composite fetch + * + * @param fetch The composite fetch + */ + public void finishingCompositeFetch(CompositeFetch fetch); +} diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/ReturnVisitor.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/ReturnVisitor.java new file mode 100644 index 0000000000..cf4aaf6ef9 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/ReturnVisitor.java @@ -0,0 +1,116 @@ +/* + * 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.loader.plan.spi; + +/** + * Visitor for processing {@link Return} graphs + * + * @author Steve Ebersole + */ +public class ReturnVisitor { + public static void visit(Return[] rootReturns, ReturnVisitationStrategy strategy) { + new ReturnVisitor( strategy ).visitReturns( rootReturns ); + } + + private final ReturnVisitationStrategy strategy; + + public ReturnVisitor(ReturnVisitationStrategy strategy) { + this.strategy = strategy; + } + + private void visitReturns(Return[] rootReturns) { + strategy.start(); + + for ( Return rootReturn : rootReturns ) { + visitRootReturn( rootReturn ); + } + + strategy.finish(); + } + + private void visitRootReturn(Return rootReturn) { + strategy.startingRootReturn( rootReturn ); + + if ( org.hibernate.loader.plan.spi.ScalarReturn.class.isInstance( rootReturn ) ) { + strategy.handleScalarReturn( (ScalarReturn) rootReturn ); + } + else { + visitNonScalarRootReturn( rootReturn ); + } + + strategy.finishingRootReturn( rootReturn ); + } + + private void visitNonScalarRootReturn(Return rootReturn) { + if ( EntityReturn.class.isInstance( rootReturn ) ) { + strategy.handleEntityReturn( (EntityReturn) rootReturn ); + visitFetches( (EntityReturn) rootReturn ); + } + else if ( CollectionReturn.class.isInstance( rootReturn ) ) { + strategy.handleCollectionReturn( (CollectionReturn) rootReturn ); + visitFetches( (CollectionReturn) rootReturn ); + } + else { + throw new IllegalStateException( + "Unexpected return type encountered; expecting a non-scalar root return, but found " + + rootReturn.getClass().getName() + ); + } + } + + private void visitFetches(FetchOwner fetchOwner) { + strategy.startingFetches( fetchOwner ); + + for ( Fetch fetch : fetchOwner.getFetches() ) { + visitFetch( fetch ); + } + + strategy.finishingFetches( fetchOwner ); + } + + private void visitFetch(Fetch fetch) { + if ( EntityFetch.class.isInstance( fetch ) ) { + strategy.startingEntityFetch( (EntityFetch) fetch ); + visitFetches( fetch ); + strategy.finishingEntityFetch( (EntityFetch) fetch ); + } + else if ( CollectionFetch.class.isInstance( fetch ) ) { + strategy.startingCollectionFetch( (CollectionFetch) fetch ); + visitFetches( fetch ); + strategy.finishingCollectionFetch( (CollectionFetch) fetch ); + } + else if ( CompositeFetch.class.isInstance( fetch ) ) { + strategy.startingCompositeFetch( (CompositeFetch) fetch ); + visitFetches( fetch ); + strategy.finishingCompositeFetch( (CompositeFetch) fetch ); + } + else { + throw new IllegalStateException( + "Unexpected return type encountered; expecting a fetch return, but found " + + fetch.getClass().getName() + ); + } + } + +} diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/ScalarReturn.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/ScalarReturn.java new file mode 100644 index 0000000000..9a3d434bbc --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/ScalarReturn.java @@ -0,0 +1,52 @@ +/* + * 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.loader.plan.spi; + +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.type.Type; + +/** + * Represent a simple scalar return within a query result. Generally this would be values of basic (String, Integer, + * etc) or composite types. + * + * @author Steve Ebersole + */ +public class ScalarReturn extends AbstractPlanNode implements Return { + private final Type type; + private final String columnAlias; + + public ScalarReturn(SessionFactoryImplementor factory, Type type, String columnAlias) { + super( factory ); + this.type = type; + this.columnAlias = columnAlias; + } + + public Type getType() { + return type; + } + + public String getColumnAlias() { + return columnAlias; + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/persister/collection/AbstractCollectionPersister.java b/hibernate-core/src/main/java/org/hibernate/persister/collection/AbstractCollectionPersister.java index 5236a08712..0db82ac72c 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/collection/AbstractCollectionPersister.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/collection/AbstractCollectionPersister.java @@ -79,6 +79,11 @@ import org.hibernate.persister.entity.Loadable; import org.hibernate.persister.entity.PropertyMapping; import org.hibernate.persister.entity.Queryable; +import org.hibernate.persister.walking.spi.CollectionDefinition; +import org.hibernate.persister.walking.spi.CollectionElementDefinition; +import org.hibernate.persister.walking.spi.CollectionIndexDefinition; +import org.hibernate.persister.walking.spi.CompositeDefinition; +import org.hibernate.persister.walking.spi.EntityDefinition; import org.hibernate.pretty.MessageHelper; import org.hibernate.sql.Alias; import org.hibernate.sql.SelectFragment; @@ -90,6 +95,7 @@ import org.hibernate.sql.ordering.antlr.OrderByAliasResolver; import org.hibernate.sql.ordering.antlr.OrderByTranslation; import org.hibernate.sql.ordering.antlr.SqlValueReference; +import org.hibernate.type.AssociationType; import org.hibernate.type.CollectionType; import org.hibernate.type.CompositeType; import org.hibernate.type.EntityType; @@ -1934,4 +1940,79 @@ public String resolveTableAlias(String columnReference) { public abstract FilterAliasGenerator getFilterAliasGenerator(final String rootAlias); + + // ColectionDefinition impl ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + @Override + public CollectionPersister getCollectionPersister() { + return this; + } + + @Override + public CollectionIndexDefinition getIndexDefinition() { + if ( ! hasIndex() ) { + return null; + } + + return new CollectionIndexDefinition() { + @Override + public CollectionDefinition getCollectionDefinition() { + return AbstractCollectionPersister.this; + } + + @Override + public Type getType() { + return getIndexType(); + } + + @Override + public EntityDefinition toEntityDefinition() { + if ( getType().isComponentType() ) { + throw new IllegalStateException( "Cannot treat composite collection index type as entity" ); + } + return (EntityPersister) ( (AssociationType) getIndexType() ).getAssociatedJoinable( getFactory() ); + } + + @Override + public CompositeDefinition toCompositeDefinition() { + if ( ! getType().isComponentType() ) { + throw new IllegalStateException( "Cannot treat entity collection index type as composite" ); + } + // todo : implement + throw new NotYetImplementedException(); + } + }; + } + + @Override + public CollectionElementDefinition getElementDefinition() { + return new CollectionElementDefinition() { + @Override + public CollectionDefinition getCollectionDefinition() { + return AbstractCollectionPersister.this; + } + + @Override + public Type getType() { + return getElementType(); + } + + @Override + public EntityDefinition toEntityDefinition() { + if ( getType().isComponentType() ) { + throw new IllegalStateException( "Cannot treat composite collection element type as entity" ); + } + return getElementPersister(); + } + + @Override + public CompositeDefinition toCompositeDefinition() { + if ( ! getType().isComponentType() ) { + throw new IllegalStateException( "Cannot treat entity collection element type as composite" ); + } + // todo : implement + throw new NotYetImplementedException(); + } + }; + } } diff --git a/hibernate-core/src/main/java/org/hibernate/persister/collection/CollectionPersister.java b/hibernate-core/src/main/java/org/hibernate/persister/collection/CollectionPersister.java index 3b2e3788dd..ecfe83c7d8 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/collection/CollectionPersister.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/collection/CollectionPersister.java @@ -38,6 +38,7 @@ import org.hibernate.id.IdentifierGenerator; import org.hibernate.metadata.CollectionMetadata; import org.hibernate.persister.entity.EntityPersister; +import org.hibernate.persister.walking.spi.CollectionDefinition; import org.hibernate.type.CollectionType; import org.hibernate.type.Type; @@ -60,7 +61,7 @@ * @see org.hibernate.collection.spi.PersistentCollection * @author Gavin King */ -public interface CollectionPersister { +public interface CollectionPersister extends CollectionDefinition { /** * Initialize the given collection with the given key */ diff --git a/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java b/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java index 860f4b74b2..5456404f04 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java @@ -59,6 +59,7 @@ import org.hibernate.cache.spi.entry.StandardCacheEntryImpl; import org.hibernate.cache.spi.entry.StructuredCacheEntry; import org.hibernate.cache.spi.entry.UnstructuredCacheEntry; +import org.hibernate.cfg.NotYetImplementedException; import org.hibernate.dialect.lock.LockingStrategy; import org.hibernate.engine.OptimisticLockStyle; import org.hibernate.engine.internal.StatefulPersistenceContext; @@ -91,7 +92,6 @@ import org.hibernate.jdbc.Expectation; import org.hibernate.jdbc.Expectations; import org.hibernate.jdbc.TooManyRowsAffectedException; -import org.hibernate.loader.entity.BatchingEntityLoader; import org.hibernate.loader.entity.BatchingEntityLoaderBuilder; import org.hibernate.loader.entity.CascadeEntityLoader; import org.hibernate.loader.entity.EntityLoader; @@ -109,6 +109,7 @@ import org.hibernate.metamodel.binding.SingularAttributeBinding; import org.hibernate.metamodel.relational.DerivedValue; import org.hibernate.metamodel.relational.Value; +import org.hibernate.persister.walking.spi.AttributeDefinition; import org.hibernate.pretty.MessageHelper; import org.hibernate.property.BackrefPropertyAccessor; import org.hibernate.sql.Alias; @@ -504,7 +505,7 @@ public AbstractEntityPersister( this.naturalIdRegionAccessStrategy = naturalIdRegionAccessStrategy; isLazyPropertiesCacheable = persistentClass.isLazyPropertiesCacheable(); - this.entityMetamodel = new EntityMetamodel( persistentClass, factory ); + this.entityMetamodel = new EntityMetamodel( persistentClass, this, factory ); this.entityTuplizer = this.entityMetamodel.getTuplizer(); // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -834,7 +835,7 @@ public AbstractEntityPersister( entityBinding.getHierarchyDetails().getCaching() == null ? false : entityBinding.getHierarchyDetails().getCaching().isCacheLazyProperties(); - this.entityMetamodel = new EntityMetamodel( entityBinding, factory ); + this.entityMetamodel = new EntityMetamodel( entityBinding, this, factory ); this.entityTuplizer = this.entityMetamodel.getTuplizer(); int batch = entityBinding.getBatchSize(); if ( batch == -1 ) { @@ -3816,10 +3817,11 @@ protected void postConstruct(Mapping mapping) throws MappingException { } public void postInstantiate() throws MappingException { + generateEntityDefinition(); + createLoaders(); createUniqueKeyLoaders(); createQueryLoader(); - } //needed by subclasses to override the createLoader strategy @@ -5070,4 +5072,110 @@ public CacheEntry buildCacheEntry(Object entity, Object[] state, Object version, throw new HibernateException( "Illegal attempt to build cache entry for non-cached entity" ); } } + + + // EntityDefinition impl ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + private Iterable embeddedCompositeIdentifierAttributes; + private Iterable attributeDefinitions; + + protected void generateEntityDefinition() { + collectEmbeddedCompositeIdentifierAttributeDefinitions(); + collectAttributeDefinitions(); + } + + @Override + public EntityPersister getEntityPersister() { + return this; + } + + @Override + public Iterable getEmbeddedCompositeIdentifierAttributes() { + return embeddedCompositeIdentifierAttributes; + } + + @Override + public Iterable getAttributes() { + return attributeDefinitions; + } + + private synchronized void collectEmbeddedCompositeIdentifierAttributeDefinitions() { + final Type idType = getIdentifierType(); + if ( !idType.isComponentType() ) { + return; + } + + final CompositeType cidType = (CompositeType) idType; + if ( !cidType.isEmbedded() ) { + return; + } + + // we have an embedded composite identifier. Most likely we need to process the composite + // properties separately, although there is an edge case where the identifier is really + // a simple identifier (single value) wrapped in a JPA @IdClass or even in the case of a + // a simple identifier (single value) wrapped in a Hibernate composite type. + // + // We really do not have a built-in method to determine that. However, generally the + // persister would report that there is single, physical identifier property which is + // explicitly at odds with the notion of "embedded composite". So we use that for now + if ( getEntityMetamodel().getIdentifierProperty().isEmbedded() ) { + this.embeddedCompositeIdentifierAttributes = new Iterable() { + @Override + public Iterator iterator() { + return new Iterator() { + private final int numberOfAttributes = countSubclassProperties(); + private int currentAttributeNumber = 0; + + @Override + public boolean hasNext() { + return currentAttributeNumber < numberOfAttributes; + } + + @Override + public AttributeDefinition next() { + // todo : implement + throw new NotYetImplementedException(); + } + + @Override + public void remove() { + throw new UnsupportedOperationException( "Remove operation not supported here" ); + } + }; + } + }; + } + } + + private void collectAttributeDefinitions() { + // todo : leverage the attribute definitions housed on EntityMetamodel + // for that to work, we'd have to be able to walk our super entity persister(s) + attributeDefinitions = new Iterable() { + @Override + public Iterator iterator() { + return new Iterator() { +// private final int numberOfAttributes = countSubclassProperties(); + private final int numberOfAttributes = entityMetamodel.getPropertySpan(); + private int currentAttributeNumber = 0; + + @Override + public boolean hasNext() { + return currentAttributeNumber < numberOfAttributes; + } + + @Override + public AttributeDefinition next() { + final int attributeNumber = currentAttributeNumber; + currentAttributeNumber++; + return entityMetamodel.getProperties()[ attributeNumber ]; + } + + @Override + public void remove() { + throw new UnsupportedOperationException( "Remove operation not supported here" ); + } + }; + } + }; + } } diff --git a/hibernate-core/src/main/java/org/hibernate/persister/entity/EntityPersister.java b/hibernate-core/src/main/java/org/hibernate/persister/entity/EntityPersister.java index f95ea71970..46d3fd8bee 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/entity/EntityPersister.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/entity/EntityPersister.java @@ -44,22 +44,25 @@ import org.hibernate.id.IdentifierGenerator; import org.hibernate.internal.FilterAliasGenerator; import org.hibernate.metadata.ClassMetadata; +import org.hibernate.persister.walking.spi.EntityDefinition; import org.hibernate.tuple.entity.EntityMetamodel; import org.hibernate.tuple.entity.EntityTuplizer; import org.hibernate.type.Type; import org.hibernate.type.VersionType; /** - * Implementors define mapping and persistence logic for a particular - * strategy of entity mapping. An instance of entity persisters corresponds - * to a given mapped entity. + * Contract describing mapping information and persistence logic for a particular strategy of entity mapping. A given + * persister instance corresponds to a given mapped entity class. *

- * Implementors must be threadsafe (preferrably immutable) and must provide a constructor - * matching the signature of: {@link org.hibernate.mapping.PersistentClass}, {@link org.hibernate.engine.spi.SessionFactoryImplementor} + * Implementations must be thread-safe (preferably immutable). * * @author Gavin King + * @author Steve Ebersole + * + * @see org.hibernate.persister.spi.PersisterFactory + * @see org.hibernate.persister.spi.PersisterClassResolver */ -public interface EntityPersister extends OptimisticCacheSource { +public interface EntityPersister extends OptimisticCacheSource, EntityDefinition { /** * The property name of the "special" identifier property in HQL diff --git a/hibernate-core/src/main/java/org/hibernate/persister/walking/internal/Helper.java b/hibernate-core/src/main/java/org/hibernate/persister/walking/internal/Helper.java new file mode 100644 index 0000000000..29eb9f5dbe --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/persister/walking/internal/Helper.java @@ -0,0 +1,160 @@ +/* + * jDocBook, processing of DocBook sources + * + * 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.persister.walking.internal; + +import java.util.Iterator; + +import org.hibernate.FetchMode; +import org.hibernate.engine.FetchStyle; +import org.hibernate.engine.FetchTiming; +import org.hibernate.engine.profile.Fetch; +import org.hibernate.engine.profile.FetchProfile; +import org.hibernate.engine.spi.LoadQueryInfluencers; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.loader.PropertyPath; +import org.hibernate.persister.collection.AbstractCollectionPersister; +import org.hibernate.persister.collection.CollectionPersister; +import org.hibernate.persister.entity.EntityPersister; +import org.hibernate.persister.entity.OuterJoinLoadable; +import org.hibernate.type.AssociationType; + +/** + * @author Steve Ebersole + */ +public class Helper { + /** + * Determine the fetch-style (if one) explicitly set for this association via fetch profiles. + *

+ * Note that currently fetch profiles only allow specifying join fetching, so this method currently + * returns either (a) FetchStyle.JOIN or (b) null + * + * @param loadQueryInfluencers + * @param persister + * @param path + * @param propertyNumber + * + * @return + */ + public static FetchStyle determineFetchStyleByProfile( + LoadQueryInfluencers loadQueryInfluencers, + EntityPersister persister, + PropertyPath path, + int propertyNumber) { + if ( !loadQueryInfluencers.hasEnabledFetchProfiles() ) { + // perf optimization + return null; + } + + // ugh, this stuff has to be made easier... + final String fullPath = path.getFullPath(); + final String rootPropertyName = ( (OuterJoinLoadable) persister ).getSubclassPropertyName( propertyNumber ); + int pos = fullPath.lastIndexOf( rootPropertyName ); + final String relativePropertyPath = pos >= 0 + ? fullPath.substring( pos ) + : rootPropertyName; + final String fetchRole = persister.getEntityName() + "." + relativePropertyPath; + + Iterator profiles = loadQueryInfluencers.getEnabledFetchProfileNames().iterator(); + while ( profiles.hasNext() ) { + final String profileName = ( String ) profiles.next(); + final FetchProfile profile = loadQueryInfluencers.getSessionFactory().getFetchProfile( profileName ); + final Fetch fetch = profile.getFetchByRole( fetchRole ); + if ( fetch != null && Fetch.Style.JOIN == fetch.getStyle() ) { + return FetchStyle.JOIN; + } + } + return null; + } + + /** + * + * @param mappingFetchMode The mapping defined fetch mode + * @param type The association type + * @param sessionFactory The session factory + * + * @return + */ + public static FetchStyle determineFetchStyleByMetadata( + FetchMode mappingFetchMode, + AssociationType type, + SessionFactoryImplementor sessionFactory) { + if ( !type.isEntityType() && !type.isCollectionType() ) { + return FetchStyle.SELECT; + } + + if ( mappingFetchMode == FetchMode.JOIN ) { + return FetchStyle.JOIN; + } + + if ( type.isEntityType() ) { + EntityPersister persister = (EntityPersister) type.getAssociatedJoinable( sessionFactory ); + if ( persister.isBatchLoadable() ) { + return FetchStyle.BATCH; + } + } + else { + CollectionPersister persister = (CollectionPersister) type.getAssociatedJoinable( sessionFactory ); + if ( persister instanceof AbstractCollectionPersister + && ( (AbstractCollectionPersister) persister ).isSubselectLoadable() ) { + return FetchStyle.SUBSELECT; + } + else if ( persister.getBatchSize() > 0 ) { + return FetchStyle.BATCH; + } + } + + return FetchStyle.SELECT; + } + + public static FetchTiming determineFetchTiming( + FetchStyle style, + AssociationType type, + SessionFactoryImplementor sessionFactory) { + switch ( style ) { + case JOIN: { + return FetchTiming.IMMEDIATE; + } + case BATCH: + case SUBSELECT: { + return FetchTiming.DELAYED; + } + default: { + // SELECT case, can be either + return isSubsequentSelectDelayed( type, sessionFactory ) + ? FetchTiming.DELAYED + : FetchTiming.IMMEDIATE; + } + } + } + + private static boolean isSubsequentSelectDelayed(AssociationType type, SessionFactoryImplementor sessionFactory) { + if ( type.isEntityType() ) { + return ( (EntityPersister) type.getAssociatedJoinable( sessionFactory ) ).hasProxy(); + } + else { + final CollectionPersister cp = ( (CollectionPersister) type.getAssociatedJoinable( sessionFactory ) ); + return cp.isLazy() || cp.isExtraLazy(); + } + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/persister/walking/spi/AssociationAttributeDefinition.java b/hibernate-core/src/main/java/org/hibernate/persister/walking/spi/AssociationAttributeDefinition.java new file mode 100644 index 0000000000..383b3d4e38 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/persister/walking/spi/AssociationAttributeDefinition.java @@ -0,0 +1,46 @@ +/* + * 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.persister.walking.spi; + +import org.hibernate.engine.FetchStrategy; +import org.hibernate.engine.spi.CascadeStyle; +import org.hibernate.engine.spi.LoadQueryInfluencers; +import org.hibernate.loader.PropertyPath; + +/** + * @author Steve Ebersole + */ +public interface AssociationAttributeDefinition extends AttributeDefinition { + public AssociationKey getAssociationKey(); + + public boolean isCollection(); + + public EntityDefinition toEntityDefinition(); + + public CollectionDefinition toCollectionDefinition(); + + public FetchStrategy determineFetchPlan(LoadQueryInfluencers loadQueryInfluencers, PropertyPath propertyPath); + + public CascadeStyle determineCascadeStyle(); +} diff --git a/hibernate-core/src/main/java/org/hibernate/persister/walking/spi/AssociationKey.java b/hibernate-core/src/main/java/org/hibernate/persister/walking/spi/AssociationKey.java new file mode 100644 index 0000000000..352c4a548f --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/persister/walking/spi/AssociationKey.java @@ -0,0 +1,53 @@ +/* + * 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.persister.walking.spi; + +import java.util.Arrays; + +/** + * Used to uniquely identify a foreign key, so that we don't join it more than once creating circularities. + *

+ * bit of a misnomer to call this an association attribute. But this follows the legacy use of AssociationKey + * from old JoinWalkers to denote circular join detection + */ +public class AssociationKey { + private final String table; + private final String[] columns; + + public AssociationKey(String table, String[] columns) { + this.table = table; + this.columns = columns; + } + + @Override + public boolean equals(Object other) { + AssociationKey that = (AssociationKey) other; + return that.table.equals(table) && Arrays.equals( columns, that.columns ); + } + + @Override + public int hashCode() { + return table.hashCode(); //TODO: inefficient + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/persister/walking/spi/AssociationVisitationStrategy.java b/hibernate-core/src/main/java/org/hibernate/persister/walking/spi/AssociationVisitationStrategy.java new file mode 100644 index 0000000000..1cb649b0d8 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/persister/walking/spi/AssociationVisitationStrategy.java @@ -0,0 +1,51 @@ +/* + * 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.persister.walking.spi; + +/** + * @author Steve Ebersole + */ +public interface AssociationVisitationStrategy { + /** + * Notification we are preparing to start visitation. + */ + public void start(); + + /** + * Notification we are finished visitation. + */ + public void finish(); + + public void startingEntity(EntityDefinition entityDefinition); + public void finishingEntity(EntityDefinition entityDefinition); + + public void startingCollection(CollectionDefinition collectionDefinition); + public void finishingCollection(CollectionDefinition collectionDefinition); + + public void startingComposite(CompositeDefinition compositeDefinition); + public void finishingComposite(CompositeDefinition compositeDefinition); + + public boolean startingAttribute(AttributeDefinition attributeDefinition); + public void finishingAttribute(AttributeDefinition attributeDefinition); +} diff --git a/hibernate-core/src/main/java/org/hibernate/persister/walking/spi/AttributeDefinition.java b/hibernate-core/src/main/java/org/hibernate/persister/walking/spi/AttributeDefinition.java new file mode 100644 index 0000000000..ed58612671 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/persister/walking/spi/AttributeDefinition.java @@ -0,0 +1,35 @@ +/* + * 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.persister.walking.spi; + +import org.hibernate.type.Type; + +/** + * @author Steve Ebersole + */ +public interface AttributeDefinition { + public String getName(); + public Type getType(); + public AttributeSource getSource(); +} diff --git a/hibernate-core/src/main/java/org/hibernate/persister/walking/spi/AttributeSource.java b/hibernate-core/src/main/java/org/hibernate/persister/walking/spi/AttributeSource.java new file mode 100644 index 0000000000..a94dfb1987 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/persister/walking/spi/AttributeSource.java @@ -0,0 +1,31 @@ +/* + * 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.persister.walking.spi; + +/** +* @author Steve Ebersole +*/ +public interface AttributeSource { + public Iterable getAttributes(); +} diff --git a/hibernate-core/src/main/java/org/hibernate/persister/walking/spi/CollectionDefinition.java b/hibernate-core/src/main/java/org/hibernate/persister/walking/spi/CollectionDefinition.java new file mode 100644 index 0000000000..f7e2fb6ad7 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/persister/walking/spi/CollectionDefinition.java @@ -0,0 +1,38 @@ +/* + * 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.persister.walking.spi; + +import org.hibernate.persister.collection.CollectionPersister; +import org.hibernate.type.CollectionType; + +/** + * @author Steve Ebersole + */ +public interface CollectionDefinition { + public CollectionPersister getCollectionPersister(); + public CollectionType getCollectionType(); + + public CollectionIndexDefinition getIndexDefinition(); + public CollectionElementDefinition getElementDefinition(); +} diff --git a/hibernate-core/src/main/java/org/hibernate/persister/walking/spi/CollectionElementDefinition.java b/hibernate-core/src/main/java/org/hibernate/persister/walking/spi/CollectionElementDefinition.java new file mode 100644 index 0000000000..fd48366c3a --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/persister/walking/spi/CollectionElementDefinition.java @@ -0,0 +1,39 @@ +/* + * jDocBook, processing of DocBook sources + * + * 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.persister.walking.spi; + +import org.hibernate.type.Type; + +/** + * @author Steve Ebersole + */ +public interface CollectionElementDefinition { + public CollectionDefinition getCollectionDefinition(); + + public Type getType(); + + public EntityDefinition toEntityDefinition(); + + public CompositeDefinition toCompositeDefinition(); +} diff --git a/hibernate-core/src/main/java/org/hibernate/persister/walking/spi/CollectionIndexDefinition.java b/hibernate-core/src/main/java/org/hibernate/persister/walking/spi/CollectionIndexDefinition.java new file mode 100644 index 0000000000..700e2b5070 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/persister/walking/spi/CollectionIndexDefinition.java @@ -0,0 +1,39 @@ +/* + * jDocBook, processing of DocBook sources + * + * 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.persister.walking.spi; + +import org.hibernate.type.Type; + +/** + * @author Steve Ebersole + */ +public interface CollectionIndexDefinition { + public CollectionDefinition getCollectionDefinition(); + + public Type getType(); + + public EntityDefinition toEntityDefinition(); + + public CompositeDefinition toCompositeDefinition(); +} diff --git a/hibernate-core/src/main/java/org/hibernate/persister/walking/spi/CompositeDefinition.java b/hibernate-core/src/main/java/org/hibernate/persister/walking/spi/CompositeDefinition.java new file mode 100644 index 0000000000..51c88333f4 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/persister/walking/spi/CompositeDefinition.java @@ -0,0 +1,30 @@ +/* + * 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.persister.walking.spi; + +/** + * @author Steve Ebersole + */ +public interface CompositeDefinition extends AttributeDefinition, AttributeSource { +} diff --git a/hibernate-core/src/main/java/org/hibernate/persister/walking/spi/EntityDefinition.java b/hibernate-core/src/main/java/org/hibernate/persister/walking/spi/EntityDefinition.java new file mode 100644 index 0000000000..1e02b42106 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/persister/walking/spi/EntityDefinition.java @@ -0,0 +1,36 @@ +/* + * 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.persister.walking.spi; + +import org.hibernate.persister.entity.EntityPersister; + +/** + * Defines the contract for walking the attributes defined by an entity + * + * @author Steve Ebersole + */ +public interface EntityDefinition extends AttributeSource { + public EntityPersister getEntityPersister(); + public Iterable getEmbeddedCompositeIdentifierAttributes(); +} diff --git a/hibernate-core/src/main/java/org/hibernate/persister/walking/spi/MetadataDrivenModelGraphVisitor.java b/hibernate-core/src/main/java/org/hibernate/persister/walking/spi/MetadataDrivenModelGraphVisitor.java new file mode 100644 index 0000000000..ccbbceb6bb --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/persister/walking/spi/MetadataDrivenModelGraphVisitor.java @@ -0,0 +1,208 @@ +/* + * 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.persister.walking.spi; + +import java.util.HashSet; +import java.util.Set; + +import org.jboss.logging.Logger; + +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.loader.PropertyPath; +import org.hibernate.persister.collection.CollectionPersister; +import org.hibernate.persister.entity.EntityPersister; +import org.hibernate.type.Type; + +/** + * Provides model graph visitation based on the defined metadata (as opposed to based on the incoming graph + * as we see in cascade processing). In layman terms, we are walking the graph of the users model as defined by + * mapped associations. + *

+ * Re-implementation of the legacy {@link org.hibernate.loader.JoinWalker} contract to leverage load plans. + * + * @author Steve Ebersole + */ +public class MetadataDrivenModelGraphVisitor { + private static final Logger log = Logger.getLogger( MetadataDrivenModelGraphVisitor.class ); + + public static void visitEntity(AssociationVisitationStrategy strategy, EntityPersister persister) { + strategy.start(); + try { + new MetadataDrivenModelGraphVisitor( strategy, persister.getFactory() ) + .visitEntityDefinition( persister ); + } + finally { + strategy.finish(); + } + } + + public static void visitCollection(AssociationVisitationStrategy strategy, CollectionPersister persister) { + strategy.start(); + try { + new MetadataDrivenModelGraphVisitor( strategy, persister.getFactory() ) + .visitCollectionDefinition( persister ); + } + finally { + strategy.finish(); + } + } + + private final AssociationVisitationStrategy strategy; + private final SessionFactoryImplementor factory; + + // todo : add a getDepth() method to PropertyPath + private PropertyPath currentPropertyPath = new PropertyPath(); + + public MetadataDrivenModelGraphVisitor(AssociationVisitationStrategy strategy, SessionFactoryImplementor factory) { + this.strategy = strategy; + this.factory = factory; + } + + private void visitEntityDefinition(EntityDefinition entityDefinition) { + strategy.startingEntity( entityDefinition ); + try { + visitAttributes( entityDefinition ); + optionallyVisitEmbeddedCompositeIdentifier( entityDefinition ); + } + finally { + strategy.finishingEntity( entityDefinition ); + } + } + + private void optionallyVisitEmbeddedCompositeIdentifier(EntityDefinition entityDefinition) { + // if the entity has a composite identifier, see if we need to handle its sub-properties separately + final Iterable embeddedCompositeIdentifierAttributes = + entityDefinition.getEmbeddedCompositeIdentifierAttributes(); + if ( embeddedCompositeIdentifierAttributes == null ) { + return; + } + + for ( AttributeDefinition attributeDefinition : embeddedCompositeIdentifierAttributes ) { + visitAttributeDefinition( attributeDefinition ); + } + } + + private void visitAttributes(AttributeSource attributeSource) { + for ( AttributeDefinition attributeDefinition : attributeSource.getAttributes() ) { + visitAttributeDefinition( attributeDefinition ); + } + } + + private void visitAttributeDefinition(AttributeDefinition attributeDefinition) { + final PropertyPath subPath = currentPropertyPath.append( attributeDefinition.getName() ); + log.debug( "Visiting attribute path : " + subPath.getFullPath() ); + + final boolean continueWalk = strategy.startingAttribute( attributeDefinition ); + if ( continueWalk ) { + final PropertyPath old = currentPropertyPath; + currentPropertyPath = subPath; + try { + if ( attributeDefinition.getType().isAssociationType() ) { + visitAssociation( (AssociationAttributeDefinition) attributeDefinition ); + } + else if ( attributeDefinition.getType().isComponentType() ) { + visitCompositeDefinition( (CompositeDefinition) attributeDefinition ); + } + } + finally { + currentPropertyPath = old; + } + } + strategy.finishingAttribute( attributeDefinition ); + } + + private void visitAssociation(AssociationAttributeDefinition attribute) { + // todo : do "too deep" checks; but see note about adding depth to PropertyPath + + if ( isDuplicateAssociation( attribute.getAssociationKey() ) ) { + log.debug( "Property path deemed to be circular : " + currentPropertyPath.getFullPath() ); + return; + } + + if ( attribute.isCollection() ) { + visitCollectionDefinition( attribute.toCollectionDefinition() ); + } + else { + visitEntityDefinition( attribute.toEntityDefinition() ); + } + } + + private void visitCompositeDefinition(CompositeDefinition compositeDefinition) { + strategy.startingComposite( compositeDefinition ); + try { + visitAttributes( compositeDefinition ); + } + finally { + strategy.finishingComposite( compositeDefinition ); + } + } + + private void visitCollectionDefinition(CollectionDefinition collectionDefinition) { + strategy.startingCollection( collectionDefinition ); + + try { + visitCollectionIndex( collectionDefinition.getIndexDefinition() ); + + final CollectionElementDefinition elementDefinition = collectionDefinition.getElementDefinition(); + if ( elementDefinition.getType().isComponentType() ) { + visitCompositeDefinition( elementDefinition.toCompositeDefinition() ); + } + else { + visitEntityDefinition( elementDefinition.toEntityDefinition() ); + } + } + finally { + strategy.finishingCollection( collectionDefinition ); + } + } + + private void visitCollectionIndex(CollectionIndexDefinition collectionIndexDefinition) { + if ( collectionIndexDefinition == null ) { + return; + } + + log.debug( "Visiting collection index : " + currentPropertyPath.getFullPath() ); + currentPropertyPath = currentPropertyPath.append( "" ); + try { + final Type collectionIndexType = collectionIndexDefinition.getType(); + if ( collectionIndexType.isComponentType() ) { + visitCompositeDefinition( collectionIndexDefinition.toCompositeDefinition() ); + } + else if ( collectionIndexType.isAssociationType() ) { + visitEntityDefinition( collectionIndexDefinition.toEntityDefinition() ); + } + } + finally { + currentPropertyPath = currentPropertyPath.getParent(); + } + } + + + private final Set visitedAssociationKeys = new HashSet(); + + protected boolean isDuplicateAssociation(AssociationKey associationKey) { + return !visitedAssociationKeys.add( associationKey ); + } + +} diff --git a/hibernate-core/src/main/java/org/hibernate/persister/walking/spi/package-info.java b/hibernate-core/src/main/java/org/hibernate/persister/walking/spi/package-info.java new file mode 100644 index 0000000000..90d0cd8faf --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/persister/walking/spi/package-info.java @@ -0,0 +1,6 @@ +package org.hibernate.persister.walking.spi; + +/** + * Package for "walking" associations through metadata definition. Ultimately want {@link org.hibernate.persister.walking.spi.AttributeDefinition} and + * {@link AttributeSource} etc to become part of the persister model. + */ \ No newline at end of file diff --git a/hibernate-core/src/main/java/org/hibernate/tuple/AbstractAttribute.java b/hibernate-core/src/main/java/org/hibernate/tuple/AbstractAttribute.java new file mode 100644 index 0000000000..4818c33c22 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/tuple/AbstractAttribute.java @@ -0,0 +1,55 @@ +/* + * jDocBook, processing of DocBook sources + * + * 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.tuple; + +import org.hibernate.type.Type; + +/** + * @author Steve Ebersole + */ +public abstract class AbstractAttribute implements Attribute, Property { + private final String attributeName; + private final Type attributeType; + + protected AbstractAttribute(String attributeName, Type attributeType) { + this.attributeName = attributeName; + this.attributeType = attributeType; + } + + @Override + @Deprecated + public String getNode() { + return null; + } + + @Override + public String getName() { + return attributeName; + } + + @Override + public Type getType() { + return attributeType; + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/tuple/AbstractNonIdentifierAttribute.java b/hibernate-core/src/main/java/org/hibernate/tuple/AbstractNonIdentifierAttribute.java new file mode 100644 index 0000000000..b01458fe64 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/tuple/AbstractNonIdentifierAttribute.java @@ -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.tuple; + +import org.hibernate.FetchMode; +import org.hibernate.engine.spi.CascadeStyle; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.persister.walking.spi.AttributeSource; +import org.hibernate.type.Type; + +/** + * @author Steve Ebersole + */ +public abstract class AbstractNonIdentifierAttribute extends AbstractAttribute implements NonIdentifierAttribute { + private final AttributeSource source; + private final SessionFactoryImplementor sessionFactory; + + private final int attributeNumber; + + private final BaselineAttributeInformation attributeInformation; + + protected AbstractNonIdentifierAttribute( + AttributeSource source, + SessionFactoryImplementor sessionFactory, + int attributeNumber, + String attributeName, + Type attributeType, + BaselineAttributeInformation attributeInformation) { + super( attributeName, attributeType ); + this.source = source; + this.sessionFactory = sessionFactory; + this.attributeNumber = attributeNumber; + this.attributeInformation = attributeInformation; + } + + @Override + public AttributeSource getSource() { + return source(); + } + + protected AttributeSource source() { + return source; + } + + protected SessionFactoryImplementor sessionFactory() { + return sessionFactory; + } + + protected int attributeNumber() { + return attributeNumber; + } + + @Override + public boolean isLazy() { + return attributeInformation.isLazy(); + } + + @Override + public boolean isInsertable() { + return attributeInformation.isInsertable(); + } + + @Override + public boolean isUpdateable() { + return attributeInformation.isUpdateable(); + } + + @Override + public boolean isInsertGenerated() { + return attributeInformation.isInsertGenerated(); + } + + @Override + public boolean isUpdateGenerated() { + return attributeInformation.isUpdateGenerated(); + } + + @Override + public boolean isNullable() { + return attributeInformation.isNullable(); + } + + @Override + public boolean isDirtyCheckable() { + return attributeInformation.isDirtyCheckable(); + } + + @Override + public boolean isDirtyCheckable(boolean hasUninitializedProperties) { + return isDirtyCheckable() && ( !hasUninitializedProperties || !isLazy() ); + } + + @Override + public boolean isVersionable() { + return attributeInformation.isVersionable(); + } + + @Override + public CascadeStyle getCascadeStyle() { + return attributeInformation.getCascadeStyle(); + } + + @Override + public FetchMode getFetchMode() { + return attributeInformation.getFetchMode(); + } + + @Override + public String toString() { + return "Attribute[non-identifier]( " + getName() + ")"; + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/tuple/Attribute.java b/hibernate-core/src/main/java/org/hibernate/tuple/Attribute.java new file mode 100644 index 0000000000..08e7496204 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/tuple/Attribute.java @@ -0,0 +1,37 @@ +/* + * 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.tuple; + +import org.hibernate.persister.walking.spi.AttributeDefinition; +import org.hibernate.type.Type; + +/** + * Contract for attributes + * + * @author Steve Ebersole + */ +public interface Attribute { + public String getName(); + public Type getType(); +} diff --git a/hibernate-core/src/main/java/org/hibernate/tuple/BaselineAttributeInformation.java b/hibernate-core/src/main/java/org/hibernate/tuple/BaselineAttributeInformation.java new file mode 100644 index 0000000000..920231b0d9 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/tuple/BaselineAttributeInformation.java @@ -0,0 +1,166 @@ +package org.hibernate.tuple; + +import org.hibernate.FetchMode; +import org.hibernate.engine.spi.CascadeStyle; + +/** +* @author Steve Ebersole +*/ +public class BaselineAttributeInformation { + private final boolean lazy; + private final boolean insertable; + private final boolean updateable; + private final boolean insertGenerated; + private final boolean updateGenerated; + private final boolean nullable; + private final boolean dirtyCheckable; + private final boolean versionable; + private final CascadeStyle cascadeStyle; + private final FetchMode fetchMode; + private boolean checkable; + + public BaselineAttributeInformation( + boolean lazy, + boolean insertable, + boolean updateable, + boolean insertGenerated, + boolean updateGenerated, + boolean nullable, + boolean dirtyCheckable, + boolean versionable, + CascadeStyle cascadeStyle, + FetchMode fetchMode) { + this.lazy = lazy; + this.insertable = insertable; + this.updateable = updateable; + this.insertGenerated = insertGenerated; + this.updateGenerated = updateGenerated; + this.nullable = nullable; + this.dirtyCheckable = dirtyCheckable; + this.versionable = versionable; + this.cascadeStyle = cascadeStyle; + this.fetchMode = fetchMode; + } + + public boolean isLazy() { + return lazy; + } + + public boolean isInsertable() { + return insertable; + } + + public boolean isUpdateable() { + return updateable; + } + + public boolean isInsertGenerated() { + return insertGenerated; + } + + public boolean isUpdateGenerated() { + return updateGenerated; + } + + public boolean isNullable() { + return nullable; + } + + public boolean isDirtyCheckable() { + return dirtyCheckable; + } + + public boolean isVersionable() { + return versionable; + } + + public CascadeStyle getCascadeStyle() { + return cascadeStyle; + } + + public FetchMode getFetchMode() { + return fetchMode; + } + + public boolean isCheckable() { + return checkable; + } + + public static class Builder { + private boolean lazy; + private boolean insertable; + private boolean updateable; + private boolean insertGenerated; + private boolean updateGenerated; + private boolean nullable; + private boolean dirtyCheckable; + private boolean versionable; + private CascadeStyle cascadeStyle; + private FetchMode fetchMode; + + public Builder setLazy(boolean lazy) { + this.lazy = lazy; + return this; + } + + public Builder setInsertable(boolean insertable) { + this.insertable = insertable; + return this; + } + + public Builder setUpdateable(boolean updateable) { + this.updateable = updateable; + return this; + } + + public Builder setInsertGenerated(boolean insertGenerated) { + this.insertGenerated = insertGenerated; + return this; + } + + public Builder setUpdateGenerated(boolean updateGenerated) { + this.updateGenerated = updateGenerated; + return this; + } + + public Builder setNullable(boolean nullable) { + this.nullable = nullable; + return this; + } + + public Builder setDirtyCheckable(boolean dirtyCheckable) { + this.dirtyCheckable = dirtyCheckable; + return this; + } + + public Builder setVersionable(boolean versionable) { + this.versionable = versionable; + return this; + } + + public Builder setCascadeStyle(CascadeStyle cascadeStyle) { + this.cascadeStyle = cascadeStyle; + return this; + } + + public Builder setFetchMode(FetchMode fetchMode) { + this.fetchMode = fetchMode; + return this; + } + + public BaselineAttributeInformation createInformation() { + return new BaselineAttributeInformation( + lazy, + insertable, + updateable, + insertGenerated, + updateGenerated, + nullable, + dirtyCheckable, + versionable, + cascadeStyle, + fetchMode + ); + } + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/tuple/IdentifierAttribute.java b/hibernate-core/src/main/java/org/hibernate/tuple/IdentifierAttribute.java new file mode 100644 index 0000000000..345ef8f45c --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/tuple/IdentifierAttribute.java @@ -0,0 +1,21 @@ +package org.hibernate.tuple; + +import org.hibernate.engine.spi.IdentifierValue; +import org.hibernate.id.IdentifierGenerator; + +/** + * @author Steve Ebersole + */ +public interface IdentifierAttribute extends Attribute, Property { + boolean isVirtual(); + + boolean isEmbedded(); + + IdentifierValue getUnsavedValue(); + + IdentifierGenerator getIdentifierGenerator(); + + boolean isIdentifierAssignedByInsert(); + + boolean hasIdentifierMapper(); +} diff --git a/hibernate-core/src/main/java/org/hibernate/tuple/IdentifierProperty.java b/hibernate-core/src/main/java/org/hibernate/tuple/IdentifierProperty.java index ccd05be6ec..54ad0ad32d 100644 --- a/hibernate-core/src/main/java/org/hibernate/tuple/IdentifierProperty.java +++ b/hibernate-core/src/main/java/org/hibernate/tuple/IdentifierProperty.java @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2008, 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,9 +20,9 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.tuple; + import org.hibernate.engine.spi.IdentifierValue; import org.hibernate.id.IdentifierGenerator; import org.hibernate.id.PostInsertIdentifierGenerator; @@ -34,7 +34,7 @@ * * @author Steve Ebersole */ -public class IdentifierProperty extends Property { +public class IdentifierProperty extends AbstractAttribute implements IdentifierAttribute { private boolean virtual; private boolean embedded; @@ -63,7 +63,7 @@ public IdentifierProperty( boolean embedded, IdentifierValue unsavedValue, IdentifierGenerator identifierGenerator) { - super(name, node, type); + super( name, type ); this.virtual = false; this.embedded = embedded; this.hasIdentifierMapper = false; @@ -87,7 +87,7 @@ public IdentifierProperty( boolean hasIdentifierMapper, IdentifierValue unsavedValue, IdentifierGenerator identifierGenerator) { - super(null, null, type); + super( null, type ); this.virtual = true; this.embedded = embedded; this.hasIdentifierMapper = hasIdentifierMapper; @@ -96,27 +96,38 @@ public IdentifierProperty( this.identifierAssignedByInsert = identifierGenerator instanceof PostInsertIdentifierGenerator; } + @Override public boolean isVirtual() { return virtual; } + @Override public boolean isEmbedded() { return embedded; } + @Override public IdentifierValue getUnsavedValue() { return unsavedValue; } + @Override public IdentifierGenerator getIdentifierGenerator() { return identifierGenerator; } + @Override public boolean isIdentifierAssignedByInsert() { return identifierAssignedByInsert; } + @Override public boolean hasIdentifierMapper() { return hasIdentifierMapper; } + + @Override + public String toString() { + return "IdentifierAttribute(" + getName() + ")"; + } } diff --git a/hibernate-core/src/main/java/org/hibernate/tuple/NonIdentifierAttribute.java b/hibernate-core/src/main/java/org/hibernate/tuple/NonIdentifierAttribute.java new file mode 100644 index 0000000000..508572de1d --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/tuple/NonIdentifierAttribute.java @@ -0,0 +1,55 @@ +/* + * 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.tuple; + +import org.hibernate.FetchMode; +import org.hibernate.engine.spi.CascadeStyle; +import org.hibernate.persister.walking.spi.AttributeDefinition; + +/** + * @author Steve Ebersole + */ +public interface NonIdentifierAttribute extends Attribute, AttributeDefinition { + public boolean isLazy(); + + public boolean isInsertable(); + + public boolean isUpdateable(); + + public boolean isInsertGenerated(); + + public boolean isUpdateGenerated(); + + public boolean isNullable(); + + public boolean isDirtyCheckable(boolean hasUninitializedProperties); + + public boolean isDirtyCheckable(); + + public boolean isVersionable(); + + public CascadeStyle getCascadeStyle(); + + public FetchMode getFetchMode(); +} diff --git a/hibernate-core/src/main/java/org/hibernate/tuple/Property.java b/hibernate-core/src/main/java/org/hibernate/tuple/Property.java index b9f04fd924..69ea51cd20 100644 --- a/hibernate-core/src/main/java/org/hibernate/tuple/Property.java +++ b/hibernate-core/src/main/java/org/hibernate/tuple/Property.java @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2008, 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,52 +20,16 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.tuple; -import java.io.Serializable; - -import org.hibernate.type.Type; /** * Defines the basic contract of a Property within the runtime metamodel. * * @author Steve Ebersole */ -public abstract class Property implements Serializable { - private String name; - private String node; - private Type type; - - /** - * Constructor for Property instances. - * - * @param name The name by which the property can be referenced within - * its owner. - * @param node The node name to use for XML-based representation of this - * property. - * @param type The Hibernate Type of this property. - */ - protected Property(String name, String node, Type type) { - this.name = name; - this.node = node; - this.type = type; - } - - public String getName() { - return name; - } - - public String getNode() { - return node; - } - - public Type getType() { - return type; - } - - public String toString() { - return "Property(" + name + ':' + type.getName() + ')'; - } - +@Deprecated +public interface Property extends Attribute { + @Deprecated + public String getNode(); } diff --git a/hibernate-core/src/main/java/org/hibernate/tuple/PropertyFactory.java b/hibernate-core/src/main/java/org/hibernate/tuple/PropertyFactory.java index 8c1a51f931..8db4f2048e 100644 --- a/hibernate-core/src/main/java/org/hibernate/tuple/PropertyFactory.java +++ b/hibernate-core/src/main/java/org/hibernate/tuple/PropertyFactory.java @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2008, 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,17 +20,20 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.tuple; + import java.lang.reflect.Constructor; import org.hibernate.EntityMode; import org.hibernate.FetchMode; +import org.hibernate.HibernateException; +import org.hibernate.cfg.NotYetImplementedException; import org.hibernate.engine.internal.UnsavedValueFactory; import org.hibernate.engine.spi.CascadeStyle; import org.hibernate.engine.spi.CascadeStyles; import org.hibernate.engine.spi.IdentifierValue; +import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.VersionValue; import org.hibernate.id.IdentifierGenerator; import org.hibernate.internal.util.ReflectHelper; @@ -45,10 +48,16 @@ import org.hibernate.metamodel.binding.EntityBinding; import org.hibernate.metamodel.binding.SimpleValueBinding; import org.hibernate.metamodel.binding.SingularAttributeBinding; +import org.hibernate.persister.entity.EntityPersister; import org.hibernate.property.Getter; import org.hibernate.property.PropertyAccessor; import org.hibernate.property.PropertyAccessorFactory; +import org.hibernate.tuple.entity.EntityBasedAssociationAttribute; +import org.hibernate.tuple.entity.EntityBasedBasicAttribute; +import org.hibernate.tuple.entity.EntityBasedCompositeAttribute; +import org.hibernate.tuple.entity.VersionProperty; import org.hibernate.type.AssociationType; +import org.hibernate.type.CompositeType; import org.hibernate.type.Type; import org.hibernate.type.VersionType; @@ -59,16 +68,16 @@ * @author Steve Ebersole */ public class PropertyFactory { - /** - * Generates an IdentifierProperty representation of the for a given entity mapping. + * Generates the attribute representation of the identifier for a given entity mapping. * * @param mappedEntity The mapping definition of the entity. * @param generator The identifier value generator to use for this identifier. * @return The appropriate IdentifierProperty definition. */ - public static IdentifierProperty buildIdentifierProperty(PersistentClass mappedEntity, IdentifierGenerator generator) { - + public static IdentifierProperty buildIdentifierAttribute( + PersistentClass mappedEntity, + IdentifierGenerator generator) { String mappedUnsavedValue = mappedEntity.getIdentifier().getNullValue(); Type type = mappedEntity.getIdentifier().getType(); Property property = mappedEntity.getIdentifierProperty(); @@ -109,7 +118,9 @@ public static IdentifierProperty buildIdentifierProperty(PersistentClass mappedE * @param generator The identifier value generator to use for this identifier. * @return The appropriate IdentifierProperty definition. */ - public static IdentifierProperty buildIdentifierProperty(EntityBinding mappedEntity, IdentifierGenerator generator) { + public static IdentifierProperty buildIdentifierProperty( + EntityBinding mappedEntity, + IdentifierGenerator generator) { final BasicAttributeBinding property = mappedEntity.getHierarchyDetails().getEntityIdentifier().getValueBinding(); @@ -157,7 +168,12 @@ public static IdentifierProperty buildIdentifierProperty(EntityBinding mappedEnt * @param lazyAvailable Is property lazy loading currently available. * @return The appropriate VersionProperty definition. */ - public static VersionProperty buildVersionProperty(Property property, boolean lazyAvailable) { + public static VersionProperty buildVersionProperty( + EntityPersister persister, + SessionFactoryImplementor sessionFactory, + int attributeNumber, + Property property, + boolean lazyAvailable) { String mappedUnsavedValue = ( (KeyValue) property.getValue() ).getNullValue(); VersionValue unsavedValue = UnsavedValueFactory.getUnsavedVersionValue( @@ -165,23 +181,27 @@ public static VersionProperty buildVersionProperty(Property property, boolean la getGetter( property ), (VersionType) property.getType(), getConstructor( property.getPersistentClass() ) - ); + ); boolean lazy = lazyAvailable && property.isLazy(); return new VersionProperty( + persister, + sessionFactory, + attributeNumber, property.getName(), - property.getNodeName(), property.getValue().getType(), - lazy, - property.isInsertable(), - property.isUpdateable(), - property.getGeneration() == PropertyGeneration.INSERT || property.getGeneration() == PropertyGeneration.ALWAYS, - property.getGeneration() == PropertyGeneration.ALWAYS, - property.isOptional(), - property.isUpdateable() && !lazy, - property.isOptimisticLocked(), - property.getCascadeStyle(), + new BaselineAttributeInformation.Builder() + .setLazy( lazy ) + .setInsertable( property.isInsertable() ) + .setUpdateable( property.isUpdateable() ) + .setInsertGenerated( property.getGeneration() == PropertyGeneration.INSERT || property.getGeneration() == PropertyGeneration.ALWAYS ) + .setUpdateGenerated( property.getGeneration() == PropertyGeneration.ALWAYS ) + .setNullable( property.isOptional() ) + .setDirtyCheckable( property.isUpdateable() && !lazy ) + .setVersionable( property.isOptimisticLocked() ) + .setCascadeStyle( property.getCascadeStyle() ) + .createInformation(), unsavedValue ); } @@ -194,52 +214,38 @@ public static VersionProperty buildVersionProperty(Property property, boolean la * @param lazyAvailable Is property lazy loading currently available. * @return The appropriate VersionProperty definition. */ - public static VersionProperty buildVersionProperty(BasicAttributeBinding property, boolean lazyAvailable) { - String mappedUnsavedValue = ( (KeyValue) property.getValue() ).getNullValue(); + public static VersionProperty buildVersionProperty( + EntityPersister persister, + BasicAttributeBinding property, + boolean lazyAvailable) { + throw new NotYetImplementedException(); + } - VersionValue unsavedValue = UnsavedValueFactory.getUnsavedVersionValue( - mappedUnsavedValue, - getGetter( property ), - (VersionType) property.getHibernateTypeDescriptor().getResolvedTypeMapping(), - getConstructor( (EntityBinding) property.getContainer() ) - ); - - boolean lazy = lazyAvailable && property.isLazy(); - - final CascadeStyle cascadeStyle = property.isAssociation() - ? ( (AssociationAttributeBinding) property ).getCascadeStyle() - : CascadeStyles.NONE; - - return new VersionProperty( - property.getAttribute().getName(), - null, - property.getHibernateTypeDescriptor().getResolvedTypeMapping(), - lazy, - true, // insertable - true, // updatable - property.getGeneration() == PropertyGeneration.INSERT - || property.getGeneration() == PropertyGeneration.ALWAYS, - property.getGeneration() == PropertyGeneration.ALWAYS, - property.isNullable(), - !lazy, - property.isIncludedInOptimisticLocking(), - cascadeStyle, - unsavedValue - ); + public static enum NonIdentifierAttributeNature { + BASIC, + COMPOSITE, + ANY, + ENTITY, + COLLECTION } /** - * Generate a "standard" (i.e., non-identifier and non-version) based on the given - * mapped property. + * Generate a non-identifier (and non-version) attribute based on the given mapped property from the given entity * * @param property The mapped property. * @param lazyAvailable Is property lazy loading currently available. - * @return The appropriate StandardProperty definition. + * @return The appropriate NonIdentifierProperty definition. */ - public static StandardProperty buildStandardProperty(Property property, boolean lazyAvailable) { - + public static NonIdentifierAttribute buildEntityBasedAttribute( + EntityPersister persister, + SessionFactoryImplementor sessionFactory, + int attributeNumber, + Property property, + boolean lazyAvailable) { final Type type = property.getValue().getType(); - + + final NonIdentifierAttributeNature nature = decode( type ); + // we need to dirty check collections, since they can cause an owner // version number increment @@ -250,30 +256,147 @@ public static StandardProperty buildStandardProperty(Property property, boolean boolean alwaysDirtyCheck = type.isAssociationType() && ( (AssociationType) type ).isAlwaysDirtyChecked(); + switch ( nature ) { + case BASIC: { + return new EntityBasedBasicAttribute( + persister, + sessionFactory, + attributeNumber, + property.getName(), + type, + new BaselineAttributeInformation.Builder() + .setLazy( lazyAvailable && property.isLazy() ) + .setInsertable( property.isInsertable() ) + .setUpdateable( property.isUpdateable() ) + .setInsertGenerated( + property.getGeneration() == PropertyGeneration.INSERT + || property.getGeneration() == PropertyGeneration.ALWAYS + ) + .setUpdateGenerated( property.getGeneration() == PropertyGeneration.ALWAYS ) + .setNullable( property.isOptional() ) + .setDirtyCheckable( alwaysDirtyCheck || property.isUpdateable() ) + .setVersionable( property.isOptimisticLocked() ) + .setCascadeStyle( property.getCascadeStyle() ) + .setFetchMode( property.getValue().getFetchMode() ) + .createInformation() + ); + } + case COMPOSITE: { + return new EntityBasedCompositeAttribute( + persister, + sessionFactory, + attributeNumber, + property.getName(), + (CompositeType) type, + new BaselineAttributeInformation.Builder() + .setLazy( lazyAvailable && property.isLazy() ) + .setInsertable( property.isInsertable() ) + .setUpdateable( property.isUpdateable() ) + .setInsertGenerated( + property.getGeneration() == PropertyGeneration.INSERT + || property.getGeneration() == PropertyGeneration.ALWAYS + ) + .setUpdateGenerated( property.getGeneration() == PropertyGeneration.ALWAYS ) + .setNullable( property.isOptional() ) + .setDirtyCheckable( alwaysDirtyCheck || property.isUpdateable() ) + .setVersionable( property.isOptimisticLocked() ) + .setCascadeStyle( property.getCascadeStyle() ) + .setFetchMode( property.getValue().getFetchMode() ) + .createInformation() + ); + } + case ENTITY: + case ANY: + case COLLECTION: { + return new EntityBasedAssociationAttribute( + persister, + sessionFactory, + attributeNumber, + property.getName(), + (AssociationType) type, + new BaselineAttributeInformation.Builder() + .setLazy( lazyAvailable && property.isLazy() ) + .setInsertable( property.isInsertable() ) + .setUpdateable( property.isUpdateable() ) + .setInsertGenerated( + property.getGeneration() == PropertyGeneration.INSERT + || property.getGeneration() == PropertyGeneration.ALWAYS + ) + .setUpdateGenerated( property.getGeneration() == PropertyGeneration.ALWAYS ) + .setNullable( property.isOptional() ) + .setDirtyCheckable( alwaysDirtyCheck || property.isUpdateable() ) + .setVersionable( property.isOptimisticLocked() ) + .setCascadeStyle( property.getCascadeStyle() ) + .setFetchMode( property.getValue().getFetchMode() ) + .createInformation() + ); + } + default: { + throw new HibernateException( "Internal error" ); + } + } + } + + private static NonIdentifierAttributeNature decode(Type type) { + if ( type.isAssociationType() ) { + AssociationType associationType = (AssociationType) type; + + if ( type.isComponentType() ) { + // an any type is both an association and a composite... + return NonIdentifierAttributeNature.ANY; + } + + return type.isCollectionType() + ? NonIdentifierAttributeNature.COLLECTION + : NonIdentifierAttributeNature.ENTITY; + } + else { + if ( type.isComponentType() ) { + return NonIdentifierAttributeNature.COMPOSITE; + } + + return NonIdentifierAttributeNature.BASIC; + } + } + + @Deprecated + public static StandardProperty buildStandardProperty(Property property, boolean lazyAvailable) { + final Type type = property.getValue().getType(); + + // we need to dirty check collections, since they can cause an owner + // version number increment + + // we need to dirty check many-to-ones with not-found="ignore" in order + // to update the cache (not the database), since in this case a null + // entity reference can lose information + + boolean alwaysDirtyCheck = type.isAssociationType() && + ( (AssociationType) type ).isAlwaysDirtyChecked(); + return new StandardProperty( property.getName(), - property.getNodeName(), type, lazyAvailable && property.isLazy(), property.isInsertable(), property.isUpdateable(), - property.getGeneration() == PropertyGeneration.INSERT || property.getGeneration() == PropertyGeneration.ALWAYS, + property.getGeneration() == PropertyGeneration.INSERT || property.getGeneration() == PropertyGeneration.ALWAYS, property.getGeneration() == PropertyGeneration.ALWAYS, property.isOptional(), alwaysDirtyCheck || property.isUpdateable(), property.isOptimisticLocked(), property.getCascadeStyle(), - property.getValue().getFetchMode() - ); + property.getValue().getFetchMode() + ); } + /** * Generate a "standard" (i.e., non-identifier and non-version) based on the given * mapped property. * * @param property The mapped property. * @param lazyAvailable Is property lazy loading currently available. - * @return The appropriate StandardProperty definition. + * @return The appropriate NonIdentifierProperty definition. */ public static StandardProperty buildStandardProperty(AttributeBinding property, boolean lazyAvailable) { @@ -299,7 +422,6 @@ public static StandardProperty buildStandardProperty(AttributeBinding property, return new StandardProperty( singularAttributeBinding.getAttribute().getName(), - null, type, lazyAvailable && singularAttributeBinding.isLazy(), true, // insertable @@ -325,7 +447,6 @@ public static StandardProperty buildStandardProperty(AttributeBinding property, return new StandardProperty( pluralAttributeBinding.getAttribute().getName(), - null, type, lazyAvailable && pluralAttributeBinding.isLazy(), // TODO: fix this when HHH-6356 is fixed; for now assume AbstractPluralAttributeBinding is updatable and insertable diff --git a/hibernate-core/src/main/java/org/hibernate/tuple/StandardProperty.java b/hibernate-core/src/main/java/org/hibernate/tuple/StandardProperty.java index 30eb8da053..a4c1adb8c2 100644 --- a/hibernate-core/src/main/java/org/hibernate/tuple/StandardProperty.java +++ b/hibernate-core/src/main/java/org/hibernate/tuple/StandardProperty.java @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2008, 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,118 +20,69 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.tuple; + import org.hibernate.FetchMode; import org.hibernate.engine.spi.CascadeStyle; import org.hibernate.type.Type; /** - * Represents a basic property within the Hibernate runtime-metamodel. + * Represents a non-identifier property within the Hibernate runtime-metamodel. * * @author Steve Ebersole */ -public class StandardProperty extends Property { +@Deprecated +public class StandardProperty extends AbstractNonIdentifierAttribute implements NonIdentifierAttribute { - private final boolean lazy; - private final boolean insertable; - private final boolean updateable; - private final boolean insertGenerated; - private final boolean updateGenerated; - private final boolean nullable; - private final boolean dirtyCheckable; - private final boolean versionable; - private final CascadeStyle cascadeStyle; - private final FetchMode fetchMode; - - /** - * Constructs StandardProperty instances. - * - * @param name The name by which the property can be referenced within - * its owner. - * @param node The node name to use for XML-based representation of this - * property. - * @param type The Hibernate Type of this property. - * @param lazy Should this property be handled lazily? - * @param insertable Is this property an insertable value? - * @param updateable Is this property an updateable value? - * @param insertGenerated Is this property generated in the database on insert? - * @param updateGenerated Is this property generated in the database on update? - * @param nullable Is this property a nullable value? - * @param checkable Is this property a checkable value? - * @param versionable Is this property a versionable value? - * @param cascadeStyle The cascade style for this property's value. - * @param fetchMode Any fetch mode defined for this property - */ - public StandardProperty( - String name, - String node, - Type type, - boolean lazy, - boolean insertable, - boolean updateable, - boolean insertGenerated, - boolean updateGenerated, - boolean nullable, - boolean checkable, - boolean versionable, - CascadeStyle cascadeStyle, - FetchMode fetchMode) { - super(name, node, type); - this.lazy = lazy; - this.insertable = insertable; - this.updateable = updateable; - this.insertGenerated = insertGenerated; - this.updateGenerated = updateGenerated; - this.nullable = nullable; - this.dirtyCheckable = checkable; - this.versionable = versionable; - this.cascadeStyle = cascadeStyle; - this.fetchMode = fetchMode; - } - - public boolean isLazy() { - return lazy; - } - - public boolean isInsertable() { - return insertable; - } - - public boolean isUpdateable() { - return updateable; - } - - public boolean isInsertGenerated() { - return insertGenerated; - } - - public boolean isUpdateGenerated() { - return updateGenerated; - } - - public boolean isNullable() { - return nullable; - } - - public boolean isDirtyCheckable(boolean hasUninitializedProperties) { - return isDirtyCheckable() && ( !hasUninitializedProperties || !isLazy() ); - } - - public boolean isDirtyCheckable() { - return dirtyCheckable; - } - - public boolean isVersionable() { - return versionable; - } - - public CascadeStyle getCascadeStyle() { - return cascadeStyle; - } - - public FetchMode getFetchMode() { - return fetchMode; + /** + * Constructs NonIdentifierProperty instances. + * + * @param name The name by which the property can be referenced within + * its owner. + * @param type The Hibernate Type of this property. + * @param lazy Should this property be handled lazily? + * @param insertable Is this property an insertable value? + * @param updateable Is this property an updateable value? + * @param insertGenerated Is this property generated in the database on insert? + * @param updateGenerated Is this property generated in the database on update? + * @param nullable Is this property a nullable value? + * @param checkable Is this property a checkable value? + * @param versionable Is this property a versionable value? + * @param cascadeStyle The cascade style for this property's value. + * @param fetchMode Any fetch mode defined for this property + */ + public StandardProperty( + String name, + Type type, + boolean lazy, + boolean insertable, + boolean updateable, + boolean insertGenerated, + boolean updateGenerated, + boolean nullable, + boolean checkable, + boolean versionable, + CascadeStyle cascadeStyle, + FetchMode fetchMode) { + super( + null, + null, + -1, + name, + type, + new BaselineAttributeInformation.Builder() + .setLazy( lazy ) + .setInsertable( insertable ) + .setUpdateable( updateable ) + .setInsertGenerated( insertGenerated ) + .setUpdateGenerated( updateGenerated ) + .setNullable( nullable ) + .setDirtyCheckable( checkable ) + .setVersionable( versionable ) + .setCascadeStyle( cascadeStyle ) + .setFetchMode( fetchMode ) + .createInformation() + ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/tuple/VersionProperty.java b/hibernate-core/src/main/java/org/hibernate/tuple/VersionProperty.java deleted file mode 100644 index 639939eb4c..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/tuple/VersionProperty.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Hibernate, Relational Persistence for Idiomatic Java - * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as - * indicated by the @author tags or express copyright attribution - * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. - * - * This copyrighted material is made available to anyone wishing to use, modify, - * copy, or redistribute it subject to the terms and conditions of the GNU - * Lesser General Public License, as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this distribution; if not, write to: - * Free Software Foundation, Inc. - * 51 Franklin Street, Fifth Floor - * Boston, MA 02110-1301 USA - * - */ -package org.hibernate.tuple; -import org.hibernate.engine.spi.CascadeStyle; -import org.hibernate.engine.spi.VersionValue; -import org.hibernate.type.Type; - -/** - * Represents a version property within the Hibernate runtime-metamodel. - * - * @author Steve Ebersole - */ -public class VersionProperty extends StandardProperty { - - private final VersionValue unsavedValue; - - /** - * Constructs VersionProperty instances. - * - * @param name The name by which the property can be referenced within - * its owner. - * @param node The node name to use for XML-based representation of this - * property. - * @param type The Hibernate Type of this property. - * @param lazy Should this property be handled lazily? - * @param insertable Is this property an insertable value? - * @param updateable Is this property an updateable value? - * @param insertGenerated Is this property generated in the database on insert? - * @param updateGenerated Is this property generated in the database on update? - * @param nullable Is this property a nullable value? - * @param checkable Is this property a checkable value? - * @param versionable Is this property a versionable value? - * @param cascadeStyle The cascade style for this property's value. - * @param unsavedValue The value which, if found as the value of - * this (i.e., the version) property, represents new (i.e., un-saved) - * instances of the owning entity. - */ - public VersionProperty( - String name, - String node, - Type type, - boolean lazy, - boolean insertable, - boolean updateable, - boolean insertGenerated, - boolean updateGenerated, - boolean nullable, - boolean checkable, - boolean versionable, - CascadeStyle cascadeStyle, - VersionValue unsavedValue) { - super( name, node, type, lazy, insertable, updateable, insertGenerated, updateGenerated, nullable, checkable, versionable, cascadeStyle, null ); - this.unsavedValue = unsavedValue; - } - - public VersionValue getUnsavedValue() { - return unsavedValue; - } -} diff --git a/hibernate-core/src/main/java/org/hibernate/tuple/component/AbstractCompositeBasedAttribute.java b/hibernate-core/src/main/java/org/hibernate/tuple/component/AbstractCompositeBasedAttribute.java new file mode 100644 index 0000000000..9dd83c8885 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/tuple/component/AbstractCompositeBasedAttribute.java @@ -0,0 +1,61 @@ +/* + * jDocBook, processing of DocBook sources + * + * 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.tuple.component; + +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.tuple.AbstractNonIdentifierAttribute; +import org.hibernate.tuple.BaselineAttributeInformation; +import org.hibernate.tuple.NonIdentifierAttribute; +import org.hibernate.type.Type; + +/** + * @author Steve Ebersole + */ +public abstract class AbstractCompositeBasedAttribute + extends AbstractNonIdentifierAttribute + implements NonIdentifierAttribute { + + private final int ownerAttributeNumber; + + public AbstractCompositeBasedAttribute( + AbstractCompositeDefinition source, + SessionFactoryImplementor sessionFactory, + int attributeNumber, + String attributeName, + Type attributeType, + BaselineAttributeInformation baselineInfo, + int ownerAttributeNumber) { + super( source, sessionFactory, attributeNumber, attributeName, attributeType, baselineInfo ); + this.ownerAttributeNumber = ownerAttributeNumber; + } + + protected int ownerAttributeNumber() { + return ownerAttributeNumber; + } + + @Override + public AbstractCompositeDefinition getSource() { + return (AbstractCompositeDefinition) super.getSource(); + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/tuple/component/AbstractCompositeDefinition.java b/hibernate-core/src/main/java/org/hibernate/tuple/component/AbstractCompositeDefinition.java new file mode 100644 index 0000000000..87ca927f9d --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/tuple/component/AbstractCompositeDefinition.java @@ -0,0 +1,202 @@ +/* + * jDocBook, processing of DocBook sources + * + * 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.tuple.component; + +import java.util.Iterator; + +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.persister.entity.EntityPersister; +import org.hibernate.persister.entity.Joinable; +import org.hibernate.persister.entity.OuterJoinLoadable; +import org.hibernate.persister.walking.spi.AssociationKey; +import org.hibernate.persister.walking.spi.AttributeDefinition; +import org.hibernate.persister.walking.spi.AttributeSource; +import org.hibernate.persister.walking.spi.CompositeDefinition; +import org.hibernate.persister.walking.spi.EntityDefinition; +import org.hibernate.tuple.AbstractNonIdentifierAttribute; +import org.hibernate.tuple.BaselineAttributeInformation; +import org.hibernate.type.AssociationType; +import org.hibernate.type.CompositeType; +import org.hibernate.type.ForeignKeyDirection; +import org.hibernate.type.Type; + +import static org.hibernate.engine.internal.JoinHelper.getLHSColumnNames; +import static org.hibernate.engine.internal.JoinHelper.getLHSTableName; +import static org.hibernate.engine.internal.JoinHelper.getRHSColumnNames; + +/** + * @author Steve Ebersole + */ +public abstract class AbstractCompositeDefinition extends AbstractNonIdentifierAttribute implements CompositeDefinition { + protected AbstractCompositeDefinition( + AttributeSource source, + SessionFactoryImplementor sessionFactory, + int attributeNumber, + String attributeName, + CompositeType attributeType, + BaselineAttributeInformation baselineInfo) { + super( source, sessionFactory, attributeNumber, attributeName, attributeType, baselineInfo ); + } + + @Override + public CompositeType getType() { + return (CompositeType) super.getType(); + } + + @Override + public Iterable getAttributes() { + return new Iterable() { + @Override + public Iterator iterator() { + return new Iterator() { + private final int numberOfAttributes = getType().getSubtypes().length; + private int currentAttributeNumber = 0; + private int currentColumnPosition = 0; + + @Override + public boolean hasNext() { + return currentAttributeNumber < numberOfAttributes; + } + + @Override + public AttributeDefinition next() { + final int attributeNumber = currentAttributeNumber; + currentAttributeNumber++; + + final String name = getType().getPropertyNames()[attributeNumber]; + final Type type = getType().getSubtypes()[attributeNumber]; + + int columnPosition = currentColumnPosition; + currentColumnPosition += type.getColumnSpan( sessionFactory() ); + + if ( type.isAssociationType() ) { + // we build the association-key here because of the "goofiness" with 'currentColumnPosition' + final AssociationKey associationKey; + final AssociationType aType = (AssociationType) type; + final Joinable joinable = aType.getAssociatedJoinable( sessionFactory() ); + if ( aType.getForeignKeyDirection() == ForeignKeyDirection.FOREIGN_KEY_FROM_PARENT ) { + associationKey = new AssociationKey( + getLHSTableName( + aType, + attributeNumber(), + (OuterJoinLoadable) joinable + ), + getLHSColumnNames( + aType, + attributeNumber(), + columnPosition, + (OuterJoinLoadable) joinable, + sessionFactory() + ) + ); + } + else { + associationKey = new AssociationKey( + joinable.getTableName(), + getRHSColumnNames( aType, sessionFactory() ) + ); + } + + return new CompositeBasedAssociationAttribute( + AbstractCompositeDefinition.this, + sessionFactory(), + currentAttributeNumber, + name, + (AssociationType) type, + new BaselineAttributeInformation.Builder() + .setInsertable( AbstractCompositeDefinition.this.isInsertable() ) + .setUpdateable( AbstractCompositeDefinition.this.isUpdateable() ) + .setInsertGenerated( AbstractCompositeDefinition.this.isInsertGenerated() ) + .setUpdateGenerated( AbstractCompositeDefinition.this.isUpdateGenerated() ) + .setNullable( getType().getPropertyNullability()[currentAttributeNumber] ) + .setDirtyCheckable( true ) + .setVersionable( AbstractCompositeDefinition.this.isVersionable() ) + .setCascadeStyle( getType().getCascadeStyle( currentAttributeNumber ) ) + .setFetchMode( getType().getFetchMode( currentAttributeNumber ) ) + .createInformation(), + AbstractCompositeDefinition.this.attributeNumber(), + associationKey + ); + } + else if ( type.isComponentType() ) { + return new CompositeBasedCompositeAttribute( + AbstractCompositeDefinition.this, + sessionFactory(), + currentAttributeNumber, + name, + (CompositeType) type, + new BaselineAttributeInformation.Builder() + .setInsertable( AbstractCompositeDefinition.this.isInsertable() ) + .setUpdateable( AbstractCompositeDefinition.this.isUpdateable() ) + .setInsertGenerated( AbstractCompositeDefinition.this.isInsertGenerated() ) + .setUpdateGenerated( AbstractCompositeDefinition.this.isUpdateGenerated() ) + .setNullable( getType().getPropertyNullability()[currentAttributeNumber] ) + .setDirtyCheckable( true ) + .setVersionable( AbstractCompositeDefinition.this.isVersionable() ) + .setCascadeStyle( getType().getCascadeStyle( currentAttributeNumber ) ) + .setFetchMode( getType().getFetchMode( currentAttributeNumber ) ) + .createInformation() + ); + } + else { + return new CompositeBasedBasicAttribute( + AbstractCompositeDefinition.this, + sessionFactory(), + currentAttributeNumber, + name, + type, + new BaselineAttributeInformation.Builder() + .setInsertable( AbstractCompositeDefinition.this.isInsertable() ) + .setUpdateable( AbstractCompositeDefinition.this.isUpdateable() ) + .setInsertGenerated( AbstractCompositeDefinition.this.isInsertGenerated() ) + .setUpdateGenerated( AbstractCompositeDefinition.this.isUpdateGenerated() ) + .setNullable( getType().getPropertyNullability()[currentAttributeNumber] ) + .setDirtyCheckable( true ) + .setVersionable( AbstractCompositeDefinition.this.isVersionable() ) + .setCascadeStyle( getType().getCascadeStyle( currentAttributeNumber ) ) + .setFetchMode( getType().getFetchMode( currentAttributeNumber ) ) + .createInformation() + ); + } + } + + @Override + public void remove() { + throw new UnsupportedOperationException( "Remove operation not supported here" ); + } + }; + } + }; + } + + public EntityPersister locateOwningPersister() { + if ( EntityDefinition.class.isInstance( getSource() ) ) { + return ( (EntityDefinition) getSource() ).getEntityPersister(); + } + else { + return ( (AbstractCompositeDefinition) getSource() ).locateOwningPersister(); + } + } +} + diff --git a/hibernate-core/src/main/java/org/hibernate/tuple/component/ComponentMetamodel.java b/hibernate-core/src/main/java/org/hibernate/tuple/component/ComponentMetamodel.java index 2de23be05a..2ccd7ffebe 100644 --- a/hibernate-core/src/main/java/org/hibernate/tuple/component/ComponentMetamodel.java +++ b/hibernate-core/src/main/java/org/hibernate/tuple/component/ComponentMetamodel.java @@ -32,8 +32,8 @@ import org.hibernate.HibernateException; import org.hibernate.mapping.Component; import org.hibernate.mapping.Property; -import org.hibernate.tuple.PropertyFactory; import org.hibernate.tuple.StandardProperty; +import org.hibernate.tuple.PropertyFactory; /** * Centralizes metamodel information about a component. diff --git a/hibernate-core/src/main/java/org/hibernate/tuple/component/CompositeBasedAssociationAttribute.java b/hibernate-core/src/main/java/org/hibernate/tuple/component/CompositeBasedAssociationAttribute.java new file mode 100644 index 0000000000..c064c6e457 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/tuple/component/CompositeBasedAssociationAttribute.java @@ -0,0 +1,157 @@ +/* + * jDocBook, processing of DocBook sources + * + * 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.tuple.component; + +import org.hibernate.FetchMode; +import org.hibernate.engine.FetchStrategy; +import org.hibernate.engine.FetchStyle; +import org.hibernate.engine.FetchTiming; +import org.hibernate.engine.spi.CascadeStyle; +import org.hibernate.engine.spi.LoadQueryInfluencers; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.loader.PropertyPath; +import org.hibernate.persister.collection.CollectionPersister; +import org.hibernate.persister.entity.EntityPersister; +import org.hibernate.persister.entity.Joinable; +import org.hibernate.persister.walking.internal.Helper; +import org.hibernate.persister.walking.spi.AssociationAttributeDefinition; +import org.hibernate.persister.walking.spi.AssociationKey; +import org.hibernate.persister.walking.spi.CollectionDefinition; +import org.hibernate.persister.walking.spi.EntityDefinition; +import org.hibernate.tuple.BaselineAttributeInformation; +import org.hibernate.type.AssociationType; +import org.hibernate.type.CompositeType; + +/** + * @author Steve Ebersole + */ +public class CompositeBasedAssociationAttribute + extends AbstractCompositeBasedAttribute + implements AssociationAttributeDefinition { + + private final AssociationKey associationKey; + private Joinable joinable; + + public CompositeBasedAssociationAttribute( + AbstractCompositeDefinition source, + SessionFactoryImplementor factory, + int attributeNumber, + String attributeName, + AssociationType attributeType, + BaselineAttributeInformation baselineInfo, + int ownerAttributeNumber, + AssociationKey associationKey) { + super( source, factory, attributeNumber, attributeName, attributeType, baselineInfo, ownerAttributeNumber ); + this.associationKey = associationKey; + } + + @Override + public AssociationType getType() { + return (AssociationType) super.getType(); + } + + protected Joinable getJoinable() { + if ( joinable == null ) { + joinable = getType().getAssociatedJoinable( sessionFactory() ); + } + return joinable; + } + + @Override + public AssociationKey getAssociationKey() { + return associationKey; + } + + @Override + public boolean isCollection() { + return getJoinable().isCollection(); + } + + @Override + public EntityDefinition toEntityDefinition() { + if ( isCollection() ) { + throw new IllegalStateException( "Cannot treat collection attribute as entity type" ); + } + return (EntityPersister) getJoinable(); + } + + @Override + public CollectionDefinition toCollectionDefinition() { + if ( isCollection() ) { + throw new IllegalStateException( "Cannot treat entity attribute as collection type" ); + } + return (CollectionPersister) getJoinable(); + } + + @Override + public FetchStrategy determineFetchPlan(LoadQueryInfluencers loadQueryInfluencers, PropertyPath propertyPath) { + final EntityPersister owningPersister = locateOwningPersister(); + + FetchStyle style = determineFetchStyleByProfile( + loadQueryInfluencers, + owningPersister, + propertyPath, + ownerAttributeNumber() + ); + if ( style == null ) { + style = determineFetchStyleByMetadata( + getSource().getType().getFetchMode( attributeNumber() ), + getType() + ); + } + + return new FetchStrategy( determineFetchTiming( style ), style ); + } + + protected FetchStyle determineFetchStyleByProfile( + LoadQueryInfluencers loadQueryInfluencers, + EntityPersister owningPersister, + PropertyPath propertyPath, + int ownerAttributeNumber) { + return Helper.determineFetchStyleByProfile( + loadQueryInfluencers, + owningPersister, + propertyPath, + ownerAttributeNumber + ); + } + + protected FetchStyle determineFetchStyleByMetadata(FetchMode fetchMode, AssociationType type) { + return Helper.determineFetchStyleByMetadata( fetchMode, type, sessionFactory() ); + } + + private FetchTiming determineFetchTiming(FetchStyle style) { + return Helper.determineFetchTiming( style, getType(), sessionFactory() ); + } + + private EntityPersister locateOwningPersister() { + return getSource().locateOwningPersister(); + } + + @Override + public CascadeStyle determineCascadeStyle() { + final CompositeType compositeType = (CompositeType) locateOwningPersister().getPropertyType( getName() ); + return compositeType.getCascadeStyle( attributeNumber() ); + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/tuple/component/CompositeBasedBasicAttribute.java b/hibernate-core/src/main/java/org/hibernate/tuple/component/CompositeBasedBasicAttribute.java new file mode 100644 index 0000000000..a975635599 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/tuple/component/CompositeBasedBasicAttribute.java @@ -0,0 +1,45 @@ +/* + * jDocBook, processing of DocBook sources + * + * 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.tuple.component; + +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.persister.walking.spi.AttributeSource; +import org.hibernate.tuple.AbstractNonIdentifierAttribute; +import org.hibernate.tuple.BaselineAttributeInformation; +import org.hibernate.type.Type; + +/** + * @author Steve Ebersole + */ +public class CompositeBasedBasicAttribute extends AbstractNonIdentifierAttribute { + protected CompositeBasedBasicAttribute( + AttributeSource source, + SessionFactoryImplementor sessionFactory, + int attributeNumber, + String attributeName, + Type attributeType, + BaselineAttributeInformation baselineInfo) { + super( source, sessionFactory, attributeNumber, attributeName, attributeType, baselineInfo ); + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/tuple/component/CompositeBasedCompositeAttribute.java b/hibernate-core/src/main/java/org/hibernate/tuple/component/CompositeBasedCompositeAttribute.java new file mode 100644 index 0000000000..1cca99c828 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/tuple/component/CompositeBasedCompositeAttribute.java @@ -0,0 +1,46 @@ +/* + * jDocBook, processing of DocBook sources + * + * 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.tuple.component; + +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.persister.walking.spi.CompositeDefinition; +import org.hibernate.tuple.BaselineAttributeInformation; +import org.hibernate.type.CompositeType; + +/** + * @author Steve Ebersole + */ +public class CompositeBasedCompositeAttribute + extends AbstractCompositeDefinition + implements CompositeDefinition { + public CompositeBasedCompositeAttribute( + CompositeDefinition source, + SessionFactoryImplementor sessionFactory, + int attributeNumber, + String attributeName, + CompositeType attributeType, + BaselineAttributeInformation baselineInfo) { + super( source, sessionFactory, attributeNumber, attributeName, attributeType, baselineInfo ); + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/tuple/entity/AbstractEntityBasedAttribute.java b/hibernate-core/src/main/java/org/hibernate/tuple/entity/AbstractEntityBasedAttribute.java new file mode 100644 index 0000000000..64db5884b3 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/tuple/entity/AbstractEntityBasedAttribute.java @@ -0,0 +1,50 @@ +/* + * jDocBook, processing of DocBook sources + * + * 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.tuple.entity; + +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.persister.entity.EntityPersister; +import org.hibernate.tuple.AbstractNonIdentifierAttribute; +import org.hibernate.tuple.BaselineAttributeInformation; +import org.hibernate.type.Type; + +/** + * @author Steve Ebersole + */ +public abstract class AbstractEntityBasedAttribute extends AbstractNonIdentifierAttribute { + protected AbstractEntityBasedAttribute( + EntityPersister source, + SessionFactoryImplementor sessionFactory, + int attributeNumber, + String attributeName, + Type attributeType, + BaselineAttributeInformation attributeInformation) { + super( source, sessionFactory, attributeNumber, attributeName, attributeType, attributeInformation ); + } + + @Override + public EntityPersister getSource() { + return (EntityPersister) super.getSource(); + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/tuple/entity/AbstractEntityTuplizer.java b/hibernate-core/src/main/java/org/hibernate/tuple/entity/AbstractEntityTuplizer.java index d82567ac21..6c1c08a6f2 100644 --- a/hibernate-core/src/main/java/org/hibernate/tuple/entity/AbstractEntityTuplizer.java +++ b/hibernate-core/src/main/java/org/hibernate/tuple/entity/AbstractEntityTuplizer.java @@ -56,8 +56,9 @@ import org.hibernate.proxy.HibernateProxy; import org.hibernate.proxy.ProxyFactory; import org.hibernate.tuple.Instantiator; +import org.hibernate.tuple.NonIdentifierAttribute; import org.hibernate.tuple.StandardProperty; -import org.hibernate.tuple.VersionProperty; +import org.hibernate.tuple.entity.VersionProperty; import org.hibernate.type.ComponentType; import org.hibernate.type.CompositeType; import org.hibernate.type.EntityType; @@ -604,7 +605,7 @@ public Object[] getPropertyValues(Object entity) throws HibernateException { final Object[] result = new Object[span]; for ( int j = 0; j < span; j++ ) { - StandardProperty property = entityMetamodel.getProperties()[j]; + NonIdentifierAttribute property = entityMetamodel.getProperties()[j]; if ( getAll || !property.isLazy() ) { result[j] = getters[j].get( entity ); } diff --git a/hibernate-core/src/main/java/org/hibernate/tuple/entity/EntityBasedAssociationAttribute.java b/hibernate-core/src/main/java/org/hibernate/tuple/entity/EntityBasedAssociationAttribute.java new file mode 100644 index 0000000000..f19f1d8439 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/tuple/entity/EntityBasedAssociationAttribute.java @@ -0,0 +1,132 @@ +package org.hibernate.tuple.entity; + +import org.hibernate.engine.FetchStrategy; +import org.hibernate.engine.FetchStyle; +import org.hibernate.engine.spi.CascadeStyle; +import org.hibernate.engine.spi.LoadQueryInfluencers; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.loader.PropertyPath; +import org.hibernate.persister.collection.QueryableCollection; +import org.hibernate.persister.entity.EntityPersister; +import org.hibernate.persister.entity.Joinable; +import org.hibernate.persister.entity.OuterJoinLoadable; +import org.hibernate.persister.walking.internal.Helper; +import org.hibernate.persister.walking.spi.AssociationAttributeDefinition; +import org.hibernate.persister.walking.spi.AssociationKey; +import org.hibernate.persister.walking.spi.CollectionDefinition; +import org.hibernate.persister.walking.spi.EntityDefinition; +import org.hibernate.tuple.BaselineAttributeInformation; +import org.hibernate.type.AssociationType; +import org.hibernate.type.ForeignKeyDirection; + +import static org.hibernate.engine.internal.JoinHelper.getLHSColumnNames; +import static org.hibernate.engine.internal.JoinHelper.getLHSTableName; +import static org.hibernate.engine.internal.JoinHelper.getRHSColumnNames; + +/** +* @author Steve Ebersole +*/ +public class EntityBasedAssociationAttribute + extends AbstractEntityBasedAttribute + implements AssociationAttributeDefinition { + + private Joinable joinable; + + public EntityBasedAssociationAttribute( + EntityPersister source, + SessionFactoryImplementor sessionFactory, + int attributeNumber, + String attributeName, + AssociationType attributeType, + BaselineAttributeInformation baselineInfo) { + super( source, sessionFactory, attributeNumber, attributeName, attributeType, baselineInfo ); + } + + @Override + public AssociationType getType() { + return (AssociationType) super.getType(); + } + + protected Joinable getJoinable() { + if ( joinable == null ) { + joinable = getType().getAssociatedJoinable( sessionFactory() ); + } + return joinable; + } + + @Override + public AssociationKey getAssociationKey() { + final AssociationType type = getType(); + final Joinable joinable = type.getAssociatedJoinable( sessionFactory() ); + + if ( type.getForeignKeyDirection() == ForeignKeyDirection.FOREIGN_KEY_FROM_PARENT ) { + final String lhsTableName; + final String[] lhsColumnNames; + + if ( joinable.isCollection() ) { + final QueryableCollection collectionPersister = (QueryableCollection) joinable; + lhsTableName = collectionPersister.getTableName(); + lhsColumnNames = collectionPersister.getElementColumnNames(); + } + else { + final OuterJoinLoadable entityPersister = (OuterJoinLoadable) joinable; + lhsTableName = getLHSTableName( type, attributeNumber(), entityPersister ); + lhsColumnNames = getLHSColumnNames( type, attributeNumber(), entityPersister, sessionFactory() ); + } + return new AssociationKey( lhsTableName, lhsColumnNames ); + } + else { + return new AssociationKey( joinable.getTableName(), getRHSColumnNames( type, sessionFactory() ) ); + } + } + + @Override + public boolean isCollection() { + return getJoinable().isCollection(); + } + + @Override + public EntityDefinition toEntityDefinition() { + if ( isCollection() ) { + throw new IllegalStateException( "Cannot treat collection-valued attribute as entity type" ); + } + return (EntityPersister) getJoinable(); + } + + @Override + public CollectionDefinition toCollectionDefinition() { + if ( ! isCollection() ) { + throw new IllegalStateException( "Cannot treat entity-valued attribute as collection type" ); + } + return (QueryableCollection) getJoinable(); + } + + @Override + public FetchStrategy determineFetchPlan(LoadQueryInfluencers loadQueryInfluencers, PropertyPath propertyPath) { + final EntityPersister owningPersister = getSource().getEntityPersister(); + + FetchStyle style = Helper.determineFetchStyleByProfile( + loadQueryInfluencers, + owningPersister, + propertyPath, + attributeNumber() + ); + if ( style == null ) { + style = Helper.determineFetchStyleByMetadata( + ((OuterJoinLoadable) getSource().getEntityPersister()).getFetchMode( attributeNumber() ), + getType(), + sessionFactory() + ); + } + + return new FetchStrategy( + Helper.determineFetchTiming( style, getType(), sessionFactory() ), + style + ); + } + + @Override + public CascadeStyle determineCascadeStyle() { + return getSource().getEntityPersister().getPropertyCascadeStyles()[attributeNumber()]; + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/tuple/entity/EntityBasedBasicAttribute.java b/hibernate-core/src/main/java/org/hibernate/tuple/entity/EntityBasedBasicAttribute.java new file mode 100644 index 0000000000..ed08bfca29 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/tuple/entity/EntityBasedBasicAttribute.java @@ -0,0 +1,44 @@ +/* + * jDocBook, processing of DocBook sources + * + * 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.tuple.entity; + +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.persister.entity.EntityPersister; +import org.hibernate.tuple.BaselineAttributeInformation; +import org.hibernate.type.Type; + +/** + * @author Steve Ebersole + */ +public class EntityBasedBasicAttribute extends AbstractEntityBasedAttribute { + public EntityBasedBasicAttribute( + EntityPersister source, + SessionFactoryImplementor factory, + int attributeNumber, + String attributeName, + Type attributeType, + BaselineAttributeInformation baselineInfo) { + super( source, factory, attributeNumber, attributeName, attributeType, baselineInfo ); + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/tuple/entity/EntityBasedCompositeAttribute.java b/hibernate-core/src/main/java/org/hibernate/tuple/entity/EntityBasedCompositeAttribute.java new file mode 100644 index 0000000000..514bdd5dd5 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/tuple/entity/EntityBasedCompositeAttribute.java @@ -0,0 +1,49 @@ +/* + * jDocBook, processing of DocBook sources + * + * 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.tuple.entity; + +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.persister.entity.EntityPersister; +import org.hibernate.tuple.component.AbstractCompositeDefinition; +import org.hibernate.persister.walking.spi.CompositeDefinition; +import org.hibernate.tuple.BaselineAttributeInformation; +import org.hibernate.type.CompositeType; + +/** + * @author Steve Ebersole + */ +public class EntityBasedCompositeAttribute + extends AbstractCompositeDefinition + implements CompositeDefinition { + + public EntityBasedCompositeAttribute( + EntityPersister source, + SessionFactoryImplementor factory, + int attributeNumber, + String attributeName, + CompositeType attributeType, + BaselineAttributeInformation baselineInfo) { + super( source, factory, attributeNumber, attributeName, attributeType, baselineInfo ); + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/tuple/entity/EntityMetamodel.java b/hibernate-core/src/main/java/org/hibernate/tuple/entity/EntityMetamodel.java index ac2d02a4d0..7d0b2717fe 100644 --- a/hibernate-core/src/main/java/org/hibernate/tuple/entity/EntityMetamodel.java +++ b/hibernate-core/src/main/java/org/hibernate/tuple/entity/EntityMetamodel.java @@ -57,10 +57,12 @@ import org.hibernate.metamodel.binding.EntityBinding; import org.hibernate.metamodel.domain.Attribute; import org.hibernate.metamodel.domain.SingularAttribute; +import org.hibernate.persister.entity.AbstractEntityPersister; import org.hibernate.tuple.IdentifierProperty; +import org.hibernate.tuple.NonIdentifierAttribute; import org.hibernate.tuple.PropertyFactory; import org.hibernate.tuple.StandardProperty; -import org.hibernate.tuple.VersionProperty; +import org.hibernate.tuple.entity.VersionProperty; import org.hibernate.type.AssociationType; import org.hibernate.type.CompositeType; import org.hibernate.type.EntityType; @@ -78,17 +80,18 @@ public class EntityMetamodel implements Serializable { private static final int NO_VERSION_INDX = -66; private final SessionFactoryImplementor sessionFactory; + private final AbstractEntityPersister persister; private final String name; private final String rootName; private final EntityType entityType; - private final IdentifierProperty identifierProperty; + private final IdentifierProperty identifierAttribute; private final boolean versioned; private final int propertySpan; private final int versionPropertyIndex; - private final StandardProperty[] properties; + private final NonIdentifierAttribute[] properties; // temporary ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ private final String[] propertyNames; private final Type[] propertyTypes; @@ -136,17 +139,21 @@ public class EntityMetamodel implements Serializable { private final EntityTuplizer entityTuplizer; private final EntityInstrumentationMetadata instrumentationMetadata; - public EntityMetamodel(PersistentClass persistentClass, SessionFactoryImplementor sessionFactory) { + public EntityMetamodel( + PersistentClass persistentClass, + AbstractEntityPersister persister, + SessionFactoryImplementor sessionFactory) { this.sessionFactory = sessionFactory; + this.persister = persister; name = persistentClass.getEntityName(); rootName = persistentClass.getRootClass().getEntityName(); entityType = sessionFactory.getTypeResolver().getTypeFactory().manyToOne( name ); - identifierProperty = PropertyFactory.buildIdentifierProperty( - persistentClass, - sessionFactory.getIdentifierGenerator( rootName ) - ); + identifierAttribute = PropertyFactory.buildIdentifierAttribute( + persistentClass, + sessionFactory.getIdentifierGenerator( rootName ) + ); versioned = persistentClass.isVersioned(); @@ -157,7 +164,7 @@ public EntityMetamodel(PersistentClass persistentClass, SessionFactoryImplemento boolean hasLazy = false; propertySpan = persistentClass.getPropertyClosureSpan(); - properties = new StandardProperty[propertySpan]; + properties = new NonIdentifierAttribute[propertySpan]; List naturalIdNumbers = new ArrayList(); // temporary ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ propertyNames = new String[propertySpan]; @@ -191,10 +198,22 @@ public EntityMetamodel(PersistentClass persistentClass, SessionFactoryImplemento if ( prop == persistentClass.getVersion() ) { tempVersionProperty = i; - properties[i] = PropertyFactory.buildVersionProperty( prop, instrumentationMetadata.isInstrumented() ); + properties[i] = PropertyFactory.buildVersionProperty( + persister, + sessionFactory, + i, + prop, + instrumentationMetadata.isInstrumented() + ); } else { - properties[i] = PropertyFactory.buildStandardProperty( prop, instrumentationMetadata.isInstrumented() ); + properties[i] = PropertyFactory.buildEntityBasedAttribute( + persister, + sessionFactory, + i, + prop, + instrumentationMetadata.isInstrumented() + ); } if ( prop.isNaturalIdentifier() ) { @@ -363,15 +382,19 @@ private OptimisticLockStyle interpretOptLockMode(int optimisticLockMode) { } } - public EntityMetamodel(EntityBinding entityBinding, SessionFactoryImplementor sessionFactory) { + public EntityMetamodel( + EntityBinding entityBinding, + AbstractEntityPersister persister, + SessionFactoryImplementor sessionFactory) { this.sessionFactory = sessionFactory; + this.persister = persister; name = entityBinding.getEntity().getName(); rootName = entityBinding.getHierarchyDetails().getRootEntityBinding().getEntity().getName(); entityType = sessionFactory.getTypeResolver().getTypeFactory().manyToOne( name ); - identifierProperty = PropertyFactory.buildIdentifierProperty( + identifierAttribute = PropertyFactory.buildIdentifierProperty( entityBinding, sessionFactory.getIdentifierGenerator( rootName ) ); @@ -398,7 +421,7 @@ public EntityMetamodel(EntityBinding entityBinding, SessionFactoryImplementor se entityBinding.getAttributeBindingClosureSpan() : entityBinding.getAttributeBindingClosureSpan() - 1; - properties = new StandardProperty[propertySpan]; + properties = new NonIdentifierAttribute[propertySpan]; List naturalIdNumbers = new ArrayList(); // temporary ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ propertyNames = new String[propertySpan]; @@ -435,6 +458,7 @@ public EntityMetamodel(EntityBinding entityBinding, SessionFactoryImplementor se if ( attributeBinding == entityBinding.getHierarchyDetails().getVersioningAttributeBinding() ) { tempVersionProperty = i; properties[i] = PropertyFactory.buildVersionProperty( + persister, entityBinding.getHierarchyDetails().getVersioningAttributeBinding(), instrumentationMetadata.isInstrumented() ); @@ -595,7 +619,7 @@ public EntityMetamodel(EntityBinding entityBinding, SessionFactoryImplementor se } } - private ValueInclusion determineInsertValueGenerationType(Property mappingProperty, StandardProperty runtimeProperty) { + private ValueInclusion determineInsertValueGenerationType(Property mappingProperty, NonIdentifierAttribute runtimeProperty) { if ( runtimeProperty.isInsertGenerated() ) { return ValueInclusion.FULL; } @@ -607,7 +631,7 @@ else if ( mappingProperty.getValue() instanceof Component ) { return ValueInclusion.NONE; } - private ValueInclusion determineInsertValueGenerationType(AttributeBinding mappingProperty, StandardProperty runtimeProperty) { + private ValueInclusion determineInsertValueGenerationType(AttributeBinding mappingProperty, NonIdentifierAttribute runtimeProperty) { if ( runtimeProperty.isInsertGenerated() ) { return ValueInclusion.FULL; } @@ -636,7 +660,7 @@ else if ( prop.getValue() instanceof Component ) { return false; } - private ValueInclusion determineUpdateValueGenerationType(Property mappingProperty, StandardProperty runtimeProperty) { + private ValueInclusion determineUpdateValueGenerationType(Property mappingProperty, NonIdentifierAttribute runtimeProperty) { if ( runtimeProperty.isUpdateGenerated() ) { return ValueInclusion.FULL; } @@ -648,7 +672,7 @@ else if ( mappingProperty.getValue() instanceof Component ) { return ValueInclusion.NONE; } - private ValueInclusion determineUpdateValueGenerationType(AttributeBinding mappingProperty, StandardProperty runtimeProperty) { + private ValueInclusion determineUpdateValueGenerationType(AttributeBinding mappingProperty, NonIdentifierAttribute runtimeProperty) { if ( runtimeProperty.isUpdateGenerated() ) { return ValueInclusion.FULL; } @@ -762,7 +786,7 @@ public EntityType getEntityType() { } public IdentifierProperty getIdentifierProperty() { - return identifierProperty; + return identifierAttribute; } public int getPropertySpan() { @@ -782,7 +806,7 @@ public VersionProperty getVersionProperty() { } } - public StandardProperty[] getProperties() { + public NonIdentifierAttribute[] getProperties() { return properties; } diff --git a/hibernate-core/src/main/java/org/hibernate/tuple/entity/VersionProperty.java b/hibernate-core/src/main/java/org/hibernate/tuple/entity/VersionProperty.java new file mode 100644 index 0000000000..51a8e67d4e --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/tuple/entity/VersionProperty.java @@ -0,0 +1,70 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * 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 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.tuple.entity; + +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.engine.spi.VersionValue; +import org.hibernate.persister.entity.EntityPersister; +import org.hibernate.tuple.AbstractNonIdentifierAttribute; +import org.hibernate.tuple.BaselineAttributeInformation; +import org.hibernate.type.Type; + +/** + * Represents a version property within the Hibernate runtime-metamodel. + * + * @author Steve Ebersole + */ +public class VersionProperty extends AbstractNonIdentifierAttribute { + + private final VersionValue unsavedValue; + + /** + * Constructs VersionProperty instances. + * + * @param source Reference back to the source of this attribute (the persister) + * @param sessionFactory The session factory this is part of. + * @param attributeNumber The attribute number within thje + * @param attributeName The name by which the property can be referenced within + * its owner. + * @param attributeType The Hibernate Type of this property. + * @param attributeInformation The basic attribute information. + * @param unsavedValue The value which, if found as the value of + * this (i.e., the version) property, represents new (i.e., un-saved) + * instances of the owning entity. + */ + public VersionProperty( + EntityPersister source, + SessionFactoryImplementor sessionFactory, + int attributeNumber, + String attributeName, + Type attributeType, + BaselineAttributeInformation attributeInformation, VersionValue unsavedValue) { + super( source, sessionFactory, attributeNumber, attributeName, attributeType, attributeInformation ); + this.unsavedValue = unsavedValue; + } + + public VersionValue getUnsavedValue() { + return unsavedValue; + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/type/TypeHelper.java b/hibernate-core/src/main/java/org/hibernate/type/TypeHelper.java index df23ae8603..126e792d2a 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/TypeHelper.java +++ b/hibernate-core/src/main/java/org/hibernate/type/TypeHelper.java @@ -28,7 +28,7 @@ import org.hibernate.bytecode.instrumentation.spi.LazyPropertyInitializer; import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.property.BackrefPropertyAccessor; -import org.hibernate.tuple.StandardProperty; +import org.hibernate.tuple.NonIdentifierAttribute; /** * Collection of convenience methods relating to operations across arrays of types... @@ -280,7 +280,7 @@ else if ( !types[i].isAssociationType() ) { * @return Array containing indices of the dirty properties, or null if no properties considered dirty. */ public static int[] findDirty( - final StandardProperty[] properties, + final NonIdentifierAttribute[] properties, final Object[] currentState, final Object[] previousState, final boolean[][] includeColumns, @@ -328,7 +328,7 @@ public static int[] findDirty( * @return Array containing indices of the modified properties, or null if no properties considered modified. */ public static int[] findModified( - final StandardProperty[] properties, + final NonIdentifierAttribute[] properties, final Object[] currentState, final Object[] previousState, final boolean[][] includeColumns, diff --git a/hibernate-core/src/test/java/org/hibernate/loader/plan/spi/LoadPlanBuilderTest.java b/hibernate-core/src/test/java/org/hibernate/loader/plan/spi/LoadPlanBuilderTest.java new file mode 100644 index 0000000000..597b900344 --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/loader/plan/spi/LoadPlanBuilderTest.java @@ -0,0 +1,149 @@ +/* + * jDocBook, processing of DocBook sources + * + * 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.loader.plan.spi; + +import javax.persistence.CascadeType; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.OneToMany; +import java.util.List; + +import org.hibernate.engine.spi.CascadingActions; +import org.hibernate.engine.spi.LoadQueryInfluencers; +import org.hibernate.loader.plan.internal.CascadeLoadPlanBuilderStrategy; +import org.hibernate.loader.plan.internal.SingleRootReturnLoadPlanBuilderStrategy; +import org.hibernate.persister.collection.CollectionPersister; +import org.hibernate.persister.entity.EntityPersister; + +import org.junit.Test; + +import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; +import org.hibernate.testing.junit4.ExtraAssertions; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; + +/** + * @author Steve Ebersole + */ +public class LoadPlanBuilderTest extends BaseCoreFunctionalTestCase { + @Override + protected Class[] getAnnotatedClasses() { + return new Class[] { Message.class, Poster.class }; + } + + @Test + public void testSimpleBuild() { + EntityPersister ep = (EntityPersister) sessionFactory().getClassMetadata(Message.class); + SingleRootReturnLoadPlanBuilderStrategy strategy = new SingleRootReturnLoadPlanBuilderStrategy( + sessionFactory(), + LoadQueryInfluencers.NONE, + "abc", + 0 + ); + LoadPlan plan = LoadPlanBuilder.buildRootEntityLoadPlan( strategy, ep ); + assertFalse( plan.hasAnyScalarReturns() ); + assertEquals( 1, plan.getReturns().size() ); + Return rtn = plan.getReturns().get( 0 ); + EntityReturn entityReturn = ExtraAssertions.assertTyping( EntityReturn.class, rtn ); + assertEquals( "abc", entityReturn.getAlias() ); + assertNotNull( entityReturn.getFetches() ); + assertEquals( 1, entityReturn.getFetches().length ); + Fetch fetch = entityReturn.getFetches()[0]; + EntityFetch entityFetch = ExtraAssertions.assertTyping( EntityFetch.class, fetch ); + assertNotNull( entityFetch.getFetches() ); + assertEquals( 0, entityFetch.getFetches().length ); + } + + @Test + public void testCascadeBasedBuild() { + EntityPersister ep = (EntityPersister) sessionFactory().getClassMetadata(Message.class); + CascadeLoadPlanBuilderStrategy strategy = new CascadeLoadPlanBuilderStrategy( + CascadingActions.MERGE, + sessionFactory(), + LoadQueryInfluencers.NONE, + "abc", + 0 + ); + LoadPlan plan = LoadPlanBuilder.buildRootEntityLoadPlan( strategy, ep ); + assertFalse( plan.hasAnyScalarReturns() ); + assertEquals( 1, plan.getReturns().size() ); + Return rtn = plan.getReturns().get( 0 ); + EntityReturn entityReturn = ExtraAssertions.assertTyping( EntityReturn.class, rtn ); + assertEquals( "abc", entityReturn.getAlias() ); + assertNotNull( entityReturn.getFetches() ); + assertEquals( 1, entityReturn.getFetches().length ); + Fetch fetch = entityReturn.getFetches()[0]; + EntityFetch entityFetch = ExtraAssertions.assertTyping( EntityFetch.class, fetch ); + assertNotNull( entityFetch.getFetches() ); + assertEquals( 0, entityFetch.getFetches().length ); + } + + @Test + public void testCollectionInitializerCase() { + CollectionPersister cp = sessionFactory().getCollectionPersister( Poster.class.getName() + ".messages" ); + SingleRootReturnLoadPlanBuilderStrategy strategy = new SingleRootReturnLoadPlanBuilderStrategy( + sessionFactory(), + LoadQueryInfluencers.NONE, + "abc", + 0 + ); + LoadPlan plan = LoadPlanBuilder.buildRootCollectionLoadPlan( strategy, cp ); + assertFalse( plan.hasAnyScalarReturns() ); + assertEquals( 1, plan.getReturns().size() ); + Return rtn = plan.getReturns().get( 0 ); + CollectionReturn collectionReturn = ExtraAssertions.assertTyping( CollectionReturn.class, rtn ); + assertEquals( "abc", collectionReturn.getAlias() ); + + assertNotNull( collectionReturn.getFetches() ); + assertEquals( 1, collectionReturn.getFetches().length ); // the collection elements are fetched + Fetch fetch = collectionReturn.getFetches()[0]; + EntityFetch entityFetch = ExtraAssertions.assertTyping( EntityFetch.class, fetch ); + assertNotNull( entityFetch.getFetches() ); + assertEquals( 0, entityFetch.getFetches().length ); + } + + @Entity( name = "Message" ) + public static class Message { + @Id + private Integer id; + private String name; + @ManyToOne( cascade = CascadeType.MERGE ) + @JoinColumn + private Poster poster; + } + + @Entity( name = "Poster" ) + public static class Poster { + @Id + private Integer id; + private String name; + @OneToMany(mappedBy = "poster") + private List messages; + } + +} \ No newline at end of file diff --git a/hibernate-core/src/test/java/org/hibernate/persister/walking/BasicWalkingTest.java b/hibernate-core/src/test/java/org/hibernate/persister/walking/BasicWalkingTest.java new file mode 100644 index 0000000000..07c193bb13 --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/persister/walking/BasicWalkingTest.java @@ -0,0 +1,177 @@ +/* + * jDocBook, processing of DocBook sources + * + * 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.persister.walking; + +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.OneToMany; +import java.util.List; + +import org.hibernate.annotations.common.util.StringHelper; +import org.hibernate.persister.entity.EntityPersister; +import org.hibernate.persister.walking.spi.AssociationVisitationStrategy; +import org.hibernate.persister.walking.spi.AttributeDefinition; +import org.hibernate.persister.walking.spi.CollectionDefinition; +import org.hibernate.persister.walking.spi.CompositeDefinition; +import org.hibernate.persister.walking.spi.EntityDefinition; +import org.hibernate.persister.walking.spi.MetadataDrivenModelGraphVisitor; + +import org.junit.Test; + +import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; + +/** + * @author Steve Ebersole + */ +public class BasicWalkingTest extends BaseCoreFunctionalTestCase { + @Override + protected Class[] getAnnotatedClasses() { + return new Class[] { Message.class, Poster.class }; + } + + @Test + public void testIt() { + EntityPersister ep = (EntityPersister) sessionFactory().getClassMetadata(Message.class); + MetadataDrivenModelGraphVisitor.visitEntity( + new AssociationVisitationStrategy() { + private int depth = 0; + + @Override + public void start() { + System.out.println( ">> Start" ); + } + + @Override + public void finish() { + System.out.println( "<< Finish" ); + } + + @Override + public void startingEntity(EntityDefinition entityDefinition) { + System.out.println( + String.format( + "%s Starting entity (%s)", + StringHelper.repeat( ">>", ++depth ), + entityDefinition.toString() + ) + ); + } + + @Override + public void finishingEntity(EntityDefinition entityDefinition) { + System.out.println( + String.format( + "%s Finishing entity (%s)", + StringHelper.repeat( "<<", depth-- ), + entityDefinition.toString() + ) + ); + } + + @Override + public void startingCollection(CollectionDefinition collectionDefinition) { + System.out.println( + String.format( + "%s Starting collection (%s)", + StringHelper.repeat( ">>", ++depth ), + collectionDefinition.toString() + ) + ); + } + + @Override + public void finishingCollection(CollectionDefinition collectionDefinition) { + System.out.println( + String.format( + "%s Finishing collection (%s)", + StringHelper.repeat( ">>", depth-- ), + collectionDefinition.toString() + ) + ); + } + + @Override + public void startingComposite(CompositeDefinition compositeDefinition) { + System.out.println( + String.format( + "%s Starting composite (%s)", + StringHelper.repeat( ">>", ++depth ), + compositeDefinition.toString() + ) + ); + } + + @Override + public void finishingComposite(CompositeDefinition compositeDefinition) { + System.out.println( + String.format( + "%s Finishing composite (%s)", + StringHelper.repeat( ">>", depth-- ), + compositeDefinition.toString() + ) + ); + } + + @Override + public boolean startingAttribute(AttributeDefinition attributeDefinition) { + System.out.println( + String.format( + "%s Handling attribute (%s)", + StringHelper.repeat( ">>", depth + 1 ), + attributeDefinition.toString() + ) + ); + return true; + } + + @Override + public void finishingAttribute(AttributeDefinition attributeDefinition) { + // nothing to do + } + }, + ep + ); + } + + @Entity( name = "Message" ) + public static class Message { + @Id + private Integer id; + private String name; + @ManyToOne + @JoinColumn + private Poster poster; + } + + @Entity( name = "Poster" ) + public static class Poster { + @Id + private Integer id; + private String name; + @OneToMany(mappedBy = "poster") + private List messages; + } +} diff --git a/hibernate-core/src/test/java/org/hibernate/test/cfg/persister/GoofyPersisterClassProvider.java b/hibernate-core/src/test/java/org/hibernate/test/cfg/persister/GoofyPersisterClassProvider.java index 3e32129981..6af678c8a5 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/cfg/persister/GoofyPersisterClassProvider.java +++ b/hibernate-core/src/test/java/org/hibernate/test/cfg/persister/GoofyPersisterClassProvider.java @@ -37,6 +37,7 @@ import org.hibernate.cache.spi.access.NaturalIdRegionAccessStrategy; import org.hibernate.cache.spi.entry.CacheEntry; import org.hibernate.cache.spi.entry.CacheEntryStructure; +import org.hibernate.cfg.NotYetImplementedException; import org.hibernate.collection.spi.PersistentCollection; import org.hibernate.engine.spi.CascadeStyle; import org.hibernate.engine.spi.Mapping; @@ -54,6 +55,9 @@ import org.hibernate.persister.collection.CollectionPersister; import org.hibernate.persister.entity.EntityPersister; import org.hibernate.persister.spi.PersisterClassResolver; +import org.hibernate.persister.walking.spi.AttributeDefinition; +import org.hibernate.persister.walking.spi.CollectionElementDefinition; +import org.hibernate.persister.walking.spi.CollectionIndexDefinition; import org.hibernate.tuple.entity.EntityMetamodel; import org.hibernate.tuple.entity.EntityTuplizer; import org.hibernate.tuple.entity.NonPojoInstrumentationMetadata; @@ -579,6 +583,21 @@ public FilterAliasGenerator getFilterAliasGenerator(String rootAlias) { // TODO Auto-generated method stub return null; } + + @Override + public EntityPersister getEntityPersister() { + return this; + } + + @Override + public Iterable getEmbeddedCompositeIdentifierAttributes() { + throw new NotYetImplementedException(); + } + + @Override + public Iterable getAttributes() { + throw new NotYetImplementedException(); + } } public static class NoopCollectionPersister implements CollectionPersister { @@ -606,8 +625,23 @@ public CacheEntryStructure getCacheEntryStructure() { return null; //To change body of implemented methods use File | Settings | File Templates. } + @Override + public CollectionPersister getCollectionPersister() { + return this; + } + public CollectionType getCollectionType() { - return null; //To change body of implemented methods use File | Settings | File Templates. + throw new NotYetImplementedException(); + } + + @Override + public CollectionIndexDefinition getIndexDefinition() { + throw new NotYetImplementedException(); + } + + @Override + public CollectionElementDefinition getElementDefinition() { + throw new NotYetImplementedException(); } public Type getKeyType() { diff --git a/hibernate-core/src/test/java/org/hibernate/test/legacy/CustomPersister.java b/hibernate-core/src/test/java/org/hibernate/test/legacy/CustomPersister.java index 62258c377b..55b96323ab 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/legacy/CustomPersister.java +++ b/hibernate-core/src/test/java/org/hibernate/test/legacy/CustomPersister.java @@ -17,6 +17,7 @@ import org.hibernate.cache.spi.entry.CacheEntryStructure; import org.hibernate.cache.spi.entry.StandardCacheEntryImpl; import org.hibernate.cache.spi.entry.UnstructuredCacheEntry; +import org.hibernate.cfg.NotYetImplementedException; import org.hibernate.engine.internal.TwoPhaseLoad; import org.hibernate.engine.spi.CascadeStyle; import org.hibernate.engine.spi.Mapping; @@ -34,6 +35,7 @@ import org.hibernate.mapping.PersistentClass; import org.hibernate.metadata.ClassMetadata; import org.hibernate.persister.entity.EntityPersister; +import org.hibernate.persister.walking.spi.AttributeDefinition; import org.hibernate.tuple.entity.EntityMetamodel; import org.hibernate.tuple.entity.EntityTuplizer; import org.hibernate.tuple.entity.NonPojoInstrumentationMetadata; @@ -671,4 +673,19 @@ public EntityInstrumentationMetadata getInstrumentationMetadata() { public FilterAliasGenerator getFilterAliasGenerator(String rootAlias) { return new StaticFilterAliasGenerator(rootAlias); } + + @Override + public EntityPersister getEntityPersister() { + return this; + } + + @Override + public Iterable getEmbeddedCompositeIdentifierAttributes() { + throw new NotYetImplementedException(); + } + + @Override + public Iterable getAttributes() { + throw new NotYetImplementedException(); + } } From c75dafbeddc12c5d77ed1b893feb1f4163827216 Mon Sep 17 00:00:00 2001 From: Steve Ebersole Date: Tue, 5 Mar 2013 14:12:05 -0600 Subject: [PATCH 32/54] HHH-7841 - Redesign Loader --- .../java/org/hibernate/loader/spi/Loader.java | 65 +++++++++++ .../hibernate/loader/spi/OnDemandLoader.java | 105 ++++++++++++++++++ .../AbstractCompositeBasedAttribute.java | 2 +- .../AbstractCompositeDefinition.java | 2 +- .../CompositeBasedAssociationAttribute.java | 2 +- .../CompositeBasedBasicAttribute.java | 2 +- .../CompositeBasedCompositeAttribute.java | 2 +- .../entity/AbstractEntityBasedAttribute.java | 2 +- .../EntityBasedAssociationAttribute.java | 23 ++++ .../entity/EntityBasedBasicAttribute.java | 2 +- .../entity/EntityBasedCompositeAttribute.java | 2 +- 11 files changed, 201 insertions(+), 8 deletions(-) create mode 100644 hibernate-core/src/main/java/org/hibernate/loader/spi/Loader.java create mode 100644 hibernate-core/src/main/java/org/hibernate/loader/spi/OnDemandLoader.java diff --git a/hibernate-core/src/main/java/org/hibernate/loader/spi/Loader.java b/hibernate-core/src/main/java/org/hibernate/loader/spi/Loader.java new file mode 100644 index 0000000000..28c5cc36be --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/loader/spi/Loader.java @@ -0,0 +1,65 @@ +/* + * 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.loader.spi; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.List; + +import org.hibernate.engine.spi.QueryParameters; +import org.hibernate.engine.spi.SessionImplementor; +import org.hibernate.loader.plan.spi.LoadPlan; +import org.hibernate.transform.ResultTransformer; + +/** + * Definition of the Loader contract. + *

+ * Capabilities I'd like to see added (todo):

    + *
  • + * expose the underlying "query" (although what I see here relies heavily on + * https://github.com/hibernate/hibernate-orm/wiki/Proposal---SQL-generation) + *
  • + *
+ * + * + * @author Gavin King + * @author Steve Ebersole + */ +public interface Loader { + public LoadPlan getLoadPlan(); + + /** + * Obtain the on-demand form of this loader, if possible. + * + * @return The on-demand version of this loader + */ + public OnDemandLoader asOnDemandLoader(); + + public List extractResults( + ResultSet resultSet, + SessionImplementor session, + QueryParameters queryParameters, + boolean returnProxies, + ResultTransformer forcedResultTransformer) throws SQLException; +} diff --git a/hibernate-core/src/main/java/org/hibernate/loader/spi/OnDemandLoader.java b/hibernate-core/src/main/java/org/hibernate/loader/spi/OnDemandLoader.java new file mode 100644 index 0000000000..1a87626f76 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/loader/spi/OnDemandLoader.java @@ -0,0 +1,105 @@ +/* + * 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.loader.spi; + +import java.sql.ResultSet; + +import org.hibernate.HibernateException; +import org.hibernate.engine.spi.QueryParameters; +import org.hibernate.engine.spi.SessionImplementor; + +/** + * Represents an on-demand loading strategy as need for processing single *logical* rows one at a time as required + * for {@link org.hibernate.ScrollableResults} implementations. + * + * @author Steve Ebersole + */ +public interface OnDemandLoader { + + /** + * Given a ResultSet, extract just a single result row. + * + * Copy of {@link org.hibernate.loader.Loader#loadSingleRow(ResultSet, SessionImplementor, QueryParameters, boolean)} + * but dropping the 'returnProxies' (that method has only one use in the entire codebase and it always passes in + * false...) + * + * @param resultSet The result set being processed. + * @param session The originating session + * @param queryParameters The "parameters" used to build the query + * + * @return The extracted result row + * + * @throws HibernateException Indicates a problem extracting values from the result set. + */ + public Object extractSingleRow( + ResultSet resultSet, + SessionImplementor session, + QueryParameters queryParameters) throws HibernateException; + + /** + * Given a ResultSet extract "sequential rows". This is used in cases where we have multi-row fetches that + * are sequential within the ResultSet due to ordering. Multiple ResultSet rows are read into a single query + * result "row". + * + * Copy of {@link org.hibernate.loader.Loader#loadSequentialRowsForward(ResultSet, SessionImplementor, QueryParameters, boolean)} + * but dropping the 'returnProxies' (that method has only one use in the entire codebase and it always passes in + * false...) + * + * @param resultSet The result set being processed. + * @param session The originating session + * @param queryParameters The "parameters" used to build the query + * + * @return The extracted result row + * + * @throws org.hibernate.HibernateException Indicates a problem extracting values from the result set. + */ + public Object extractSequentialRowsForward( + final ResultSet resultSet, + final SessionImplementor session, + final QueryParameters queryParameters) throws HibernateException; + + /** + * Like {@link #extractSequentialRowsForward} but here moving back through the ResultSet. + * + * Copy of {@link org.hibernate.loader.Loader#loadSequentialRowsReverse(ResultSet, SessionImplementor, QueryParameters, boolean, boolean)} + * but dropping the 'returnProxies' (that method has only one use in the entire codebase and it always passes in + * false...). + * + * todo : is 'logicallyAfterLastRow really needed? Can't that be deduced? In fact pretty positive it is not needed. + * + * @param resultSet The result set being processed. + * @param session The originating session + * @param queryParameters The "parameters" used to build the query + * @param isLogicallyAfterLast Is the result set currently positioned after the last row; again, is this really needed? How is it any diff + * + * @return The extracted result row + * + * @throws org.hibernate.HibernateException Indicates a problem extracting values from the result set. + */ + public Object extractSequentialRowsReverse( + ResultSet resultSet, + SessionImplementor session, + QueryParameters queryParameters, + boolean isLogicallyAfterLast) throws HibernateException; +} diff --git a/hibernate-core/src/main/java/org/hibernate/tuple/component/AbstractCompositeBasedAttribute.java b/hibernate-core/src/main/java/org/hibernate/tuple/component/AbstractCompositeBasedAttribute.java index 9dd83c8885..5c62859939 100644 --- a/hibernate-core/src/main/java/org/hibernate/tuple/component/AbstractCompositeBasedAttribute.java +++ b/hibernate-core/src/main/java/org/hibernate/tuple/component/AbstractCompositeBasedAttribute.java @@ -1,5 +1,5 @@ /* - * jDocBook, processing of DocBook sources + * 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 diff --git a/hibernate-core/src/main/java/org/hibernate/tuple/component/AbstractCompositeDefinition.java b/hibernate-core/src/main/java/org/hibernate/tuple/component/AbstractCompositeDefinition.java index 87ca927f9d..17b4b0ccb1 100644 --- a/hibernate-core/src/main/java/org/hibernate/tuple/component/AbstractCompositeDefinition.java +++ b/hibernate-core/src/main/java/org/hibernate/tuple/component/AbstractCompositeDefinition.java @@ -1,5 +1,5 @@ /* - * jDocBook, processing of DocBook sources + * 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 diff --git a/hibernate-core/src/main/java/org/hibernate/tuple/component/CompositeBasedAssociationAttribute.java b/hibernate-core/src/main/java/org/hibernate/tuple/component/CompositeBasedAssociationAttribute.java index c064c6e457..0a8be97a92 100644 --- a/hibernate-core/src/main/java/org/hibernate/tuple/component/CompositeBasedAssociationAttribute.java +++ b/hibernate-core/src/main/java/org/hibernate/tuple/component/CompositeBasedAssociationAttribute.java @@ -1,5 +1,5 @@ /* - * jDocBook, processing of DocBook sources + * 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 diff --git a/hibernate-core/src/main/java/org/hibernate/tuple/component/CompositeBasedBasicAttribute.java b/hibernate-core/src/main/java/org/hibernate/tuple/component/CompositeBasedBasicAttribute.java index a975635599..ba22322640 100644 --- a/hibernate-core/src/main/java/org/hibernate/tuple/component/CompositeBasedBasicAttribute.java +++ b/hibernate-core/src/main/java/org/hibernate/tuple/component/CompositeBasedBasicAttribute.java @@ -1,5 +1,5 @@ /* - * jDocBook, processing of DocBook sources + * 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 diff --git a/hibernate-core/src/main/java/org/hibernate/tuple/component/CompositeBasedCompositeAttribute.java b/hibernate-core/src/main/java/org/hibernate/tuple/component/CompositeBasedCompositeAttribute.java index 1cca99c828..4094ededd1 100644 --- a/hibernate-core/src/main/java/org/hibernate/tuple/component/CompositeBasedCompositeAttribute.java +++ b/hibernate-core/src/main/java/org/hibernate/tuple/component/CompositeBasedCompositeAttribute.java @@ -1,5 +1,5 @@ /* - * jDocBook, processing of DocBook sources + * 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 diff --git a/hibernate-core/src/main/java/org/hibernate/tuple/entity/AbstractEntityBasedAttribute.java b/hibernate-core/src/main/java/org/hibernate/tuple/entity/AbstractEntityBasedAttribute.java index 64db5884b3..ceefd6a8c1 100644 --- a/hibernate-core/src/main/java/org/hibernate/tuple/entity/AbstractEntityBasedAttribute.java +++ b/hibernate-core/src/main/java/org/hibernate/tuple/entity/AbstractEntityBasedAttribute.java @@ -1,5 +1,5 @@ /* - * jDocBook, processing of DocBook sources + * 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 diff --git a/hibernate-core/src/main/java/org/hibernate/tuple/entity/EntityBasedAssociationAttribute.java b/hibernate-core/src/main/java/org/hibernate/tuple/entity/EntityBasedAssociationAttribute.java index f19f1d8439..7177552bbd 100644 --- a/hibernate-core/src/main/java/org/hibernate/tuple/entity/EntityBasedAssociationAttribute.java +++ b/hibernate-core/src/main/java/org/hibernate/tuple/entity/EntityBasedAssociationAttribute.java @@ -1,3 +1,26 @@ +/* + * 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.tuple.entity; import org.hibernate.engine.FetchStrategy; diff --git a/hibernate-core/src/main/java/org/hibernate/tuple/entity/EntityBasedBasicAttribute.java b/hibernate-core/src/main/java/org/hibernate/tuple/entity/EntityBasedBasicAttribute.java index ed08bfca29..1ba07ab2bd 100644 --- a/hibernate-core/src/main/java/org/hibernate/tuple/entity/EntityBasedBasicAttribute.java +++ b/hibernate-core/src/main/java/org/hibernate/tuple/entity/EntityBasedBasicAttribute.java @@ -1,5 +1,5 @@ /* - * jDocBook, processing of DocBook sources + * 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 diff --git a/hibernate-core/src/main/java/org/hibernate/tuple/entity/EntityBasedCompositeAttribute.java b/hibernate-core/src/main/java/org/hibernate/tuple/entity/EntityBasedCompositeAttribute.java index 514bdd5dd5..8f3a9a6e80 100644 --- a/hibernate-core/src/main/java/org/hibernate/tuple/entity/EntityBasedCompositeAttribute.java +++ b/hibernate-core/src/main/java/org/hibernate/tuple/entity/EntityBasedCompositeAttribute.java @@ -1,5 +1,5 @@ /* - * jDocBook, processing of DocBook sources + * 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 From 3d332371bd31841ee065b591b0e4f3e8cff1b3a2 Mon Sep 17 00:00:00 2001 From: Steve Ebersole Date: Mon, 11 Mar 2013 15:55:53 -0500 Subject: [PATCH 33/54] HHH-7841 - Redesign Loader --- .../java/org/hibernate/HibernateError.java | 43 ++ .../internal/classic/QueryTranslatorImpl.java | 1 + .../java/org/hibernate/loader/Loader.java | 9 +- ...cBatchingCollectionInitializerBuilder.java | 1 + .../loader/criteria/CriteriaLoader.java | 1 + .../hibernate/loader/custom/CustomLoader.java | 6 +- .../DynamicBatchingEntityLoaderBuilder.java | 1 + .../org/hibernate/loader/hql/QueryLoader.java | 1 + .../OnDemandResultSetProcessorImpl.java | 58 ++ .../ResultSetProcessingContextImpl.java | 557 ++++++++++++++++ .../internal/ResultSetProcessorHelper.java | 77 +++ .../internal/ResultSetProcessorImpl.java | 207 ++++++ .../plan/internal/LoadPlanBuildingHelper.java | 92 +++ ...ngleRootReturnLoadPlanBuilderStrategy.java | 104 +-- .../plan/spi/AbstractCollectionReference.java | 143 +++++ .../loader/plan/spi/AbstractFetch.java | 7 +- .../loader/plan/spi/AbstractFetchOwner.java | 3 +- .../spi/AbstractLoadPlanBuilderStrategy.java | 595 ++++++++++++++++-- .../loader/plan/spi/CollectionFetch.java | 63 +- .../loader/plan/spi/CollectionReference.java | 6 + .../spi/CollectionReferenceImplementor.java | 30 + .../loader/plan/spi/CollectionReturn.java | 56 +- .../plan/spi/CompositeElementGraph.java | 90 +++ .../loader/plan/spi/CompositeFetch.java | 38 ++ .../loader/plan/spi/CompositeIndexGraph.java | 90 +++ .../loader/plan/spi/EntityElementGraph.java | 133 ++++ .../loader/plan/spi/EntityFetch.java | 192 +++++- .../loader/plan/spi/EntityIndexGraph.java | 150 +++++ .../loader/plan/spi/EntityReference.java | 20 +- .../loader/plan/spi/EntityReturn.java | 103 ++- .../org/hibernate/loader/plan/spi/Fetch.java | 10 +- .../hibernate/loader/plan/spi/FetchOwner.java | 25 + .../plan/spi/IdentifierDescription.java | 41 ++ .../spi/IdentifierDescriptionInjectable.java | 33 + .../hibernate/loader/plan/spi/LoadPlan.java | 1 + .../plan/spi/LoadPlanBuildingContext.java | 48 ++ ...y.java => LoadPlanVisitationStrategy.java} | 6 +- .../LoadPlanVisitationStrategyAdapter.java | 104 +++ ...eturnVisitor.java => LoadPlanVisitor.java} | 29 +- .../org/hibernate/loader/plan/spi/Return.java | 33 +- .../loader/plan/spi/ScalarReturn.java | 26 +- .../hibernate/loader/spi/AfterLoadAction.java | 34 + .../java/org/hibernate/loader/spi/Loader.java | 22 +- .../loader/spi/NamedParameterContext.java | 36 ++ ...r.java => OnDemandResultSetProcessor.java} | 28 +- .../hibernate/loader/spi/ResultBuilder.java | 7 + .../spi/ResultSetProcessingContext.java | 91 +++ .../loader/spi/ResultSetProcessor.java | 70 +++ .../AbstractCollectionPersister.java | 6 +- .../entity/AbstractEntityPersister.java | 111 ++-- .../spi/HydratedCompoundValueHandler.java | 44 ++ .../spi/AssociationAttributeDefinition.java | 3 + .../spi/AssociationVisitationStrategy.java | 13 +- .../spi/CollectionElementDefinition.java | 2 +- .../spi/CollectionIndexDefinition.java | 2 +- ...nition.java => CompositionDefinition.java} | 2 +- ...ncapsulatedEntityIdentifierDefinition.java | 31 + .../walking/spi/EntityDefinition.java | 2 +- .../spi/EntityIdentifierDefinition.java | 43 ++ .../spi/MetadataDrivenModelGraphVisitor.java | 90 +-- ...ncapsulatedEntityIdentifierDefinition.java | 33 + .../walking/spi/WalkingException.java | 41 ++ .../hibernate/result/internal/ResultImpl.java | 1 + .../tuple/AbstractNonIdentifierAttribute.java | 6 +- .../org/hibernate/tuple/PropertyFactory.java | 4 +- .../AbstractCompositeBasedAttribute.java | 6 +- ...ava => AbstractCompositionDefinition.java} | 54 +- .../CompositeBasedAssociationAttribute.java | 30 +- ...CompositionBasedCompositionAttribute.java} | 12 +- .../EntityBasedAssociationAttribute.java | 26 + ...a => EntityBasedCompositionAttribute.java} | 12 +- .../loader/plan/spi/LoadPlanBuilderTest.java | 12 +- .../persister/walking/BasicWalkingTest.java | 43 +- .../GoofyPersisterClassProvider.java | 5 +- .../test/legacy/CustomPersister.java | 3 +- .../src/test/resources/log4j.properties | 2 + 76 files changed, 3729 insertions(+), 431 deletions(-) create mode 100644 hibernate-core/src/main/java/org/hibernate/HibernateError.java create mode 100644 hibernate-core/src/main/java/org/hibernate/loader/internal/OnDemandResultSetProcessorImpl.java create mode 100644 hibernate-core/src/main/java/org/hibernate/loader/internal/ResultSetProcessingContextImpl.java create mode 100644 hibernate-core/src/main/java/org/hibernate/loader/internal/ResultSetProcessorHelper.java create mode 100644 hibernate-core/src/main/java/org/hibernate/loader/internal/ResultSetProcessorImpl.java create mode 100644 hibernate-core/src/main/java/org/hibernate/loader/plan/internal/LoadPlanBuildingHelper.java create mode 100644 hibernate-core/src/main/java/org/hibernate/loader/plan/spi/AbstractCollectionReference.java create mode 100644 hibernate-core/src/main/java/org/hibernate/loader/plan/spi/CollectionReferenceImplementor.java create mode 100644 hibernate-core/src/main/java/org/hibernate/loader/plan/spi/CompositeElementGraph.java create mode 100644 hibernate-core/src/main/java/org/hibernate/loader/plan/spi/CompositeIndexGraph.java create mode 100644 hibernate-core/src/main/java/org/hibernate/loader/plan/spi/EntityElementGraph.java create mode 100644 hibernate-core/src/main/java/org/hibernate/loader/plan/spi/EntityIndexGraph.java create mode 100644 hibernate-core/src/main/java/org/hibernate/loader/plan/spi/IdentifierDescription.java create mode 100644 hibernate-core/src/main/java/org/hibernate/loader/plan/spi/IdentifierDescriptionInjectable.java create mode 100644 hibernate-core/src/main/java/org/hibernate/loader/plan/spi/LoadPlanBuildingContext.java rename hibernate-core/src/main/java/org/hibernate/loader/plan/spi/{ReturnVisitationStrategy.java => LoadPlanVisitationStrategy.java} (97%) create mode 100644 hibernate-core/src/main/java/org/hibernate/loader/plan/spi/LoadPlanVisitationStrategyAdapter.java rename hibernate-core/src/main/java/org/hibernate/loader/plan/spi/{ReturnVisitor.java => LoadPlanVisitor.java} (78%) create mode 100644 hibernate-core/src/main/java/org/hibernate/loader/spi/AfterLoadAction.java create mode 100644 hibernate-core/src/main/java/org/hibernate/loader/spi/NamedParameterContext.java rename hibernate-core/src/main/java/org/hibernate/loader/spi/{OnDemandLoader.java => OnDemandResultSetProcessor.java} (74%) create mode 100644 hibernate-core/src/main/java/org/hibernate/loader/spi/ResultBuilder.java create mode 100644 hibernate-core/src/main/java/org/hibernate/loader/spi/ResultSetProcessingContext.java create mode 100644 hibernate-core/src/main/java/org/hibernate/loader/spi/ResultSetProcessor.java create mode 100644 hibernate-core/src/main/java/org/hibernate/persister/spi/HydratedCompoundValueHandler.java rename hibernate-core/src/main/java/org/hibernate/persister/walking/spi/{CompositeDefinition.java => CompositionDefinition.java} (92%) create mode 100644 hibernate-core/src/main/java/org/hibernate/persister/walking/spi/EncapsulatedEntityIdentifierDefinition.java create mode 100644 hibernate-core/src/main/java/org/hibernate/persister/walking/spi/EntityIdentifierDefinition.java create mode 100644 hibernate-core/src/main/java/org/hibernate/persister/walking/spi/NonEncapsulatedEntityIdentifierDefinition.java create mode 100644 hibernate-core/src/main/java/org/hibernate/persister/walking/spi/WalkingException.java rename hibernate-core/src/main/java/org/hibernate/tuple/component/{AbstractCompositeDefinition.java => AbstractCompositionDefinition.java} (76%) rename hibernate-core/src/main/java/org/hibernate/tuple/component/{CompositeBasedCompositeAttribute.java => CompositionBasedCompositionAttribute.java} (85%) rename hibernate-core/src/main/java/org/hibernate/tuple/entity/{EntityBasedCompositeAttribute.java => EntityBasedCompositionAttribute.java} (84%) diff --git a/hibernate-core/src/main/java/org/hibernate/HibernateError.java b/hibernate-core/src/main/java/org/hibernate/HibernateError.java new file mode 100644 index 0000000000..4376031c02 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/HibernateError.java @@ -0,0 +1,43 @@ +/* + * 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; + +/** + * Marks a group of exceptions that generally indicate an internal Hibernate error or bug. + * + * @author Steve Ebersole + */ +public abstract class HibernateError extends HibernateException { + public HibernateError(String message) { + super( message ); + } + + public HibernateError(Throwable root) { + super( root ); + } + + public HibernateError(String message, Throwable root) { + super( message, root ); + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/hql/internal/classic/QueryTranslatorImpl.java b/hibernate-core/src/main/java/org/hibernate/hql/internal/classic/QueryTranslatorImpl.java index deca43ace7..401b2fe4c6 100644 --- a/hibernate-core/src/main/java/org/hibernate/hql/internal/classic/QueryTranslatorImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/hql/internal/classic/QueryTranslatorImpl.java @@ -63,6 +63,7 @@ import org.hibernate.internal.util.StringHelper; import org.hibernate.internal.util.collections.ArrayHelper; import org.hibernate.loader.BasicLoader; +import org.hibernate.loader.spi.AfterLoadAction; import org.hibernate.persister.collection.CollectionPersister; import org.hibernate.persister.collection.QueryableCollection; import org.hibernate.persister.entity.Loadable; diff --git a/hibernate-core/src/main/java/org/hibernate/loader/Loader.java b/hibernate-core/src/main/java/org/hibernate/loader/Loader.java index 2c80db36c2..2ad4cf8479 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/Loader.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/Loader.java @@ -79,6 +79,7 @@ import org.hibernate.internal.FetchingScrollableResultsImpl; import org.hibernate.internal.ScrollableResultsImpl; import org.hibernate.internal.util.StringHelper; +import org.hibernate.loader.spi.AfterLoadAction; import org.hibernate.persister.collection.CollectionPersister; import org.hibernate.persister.entity.EntityPersister; import org.hibernate.persister.entity.Loadable; @@ -245,10 +246,6 @@ protected String preprocessSQL( : sql; } - protected static interface AfterLoadAction { - public void afterLoad(SessionImplementor session, Object entity, Loadable persister); - } - protected boolean shouldUseFollowOnLocking( QueryParameters parameters, Dialect dialect, @@ -509,7 +506,7 @@ public Object loadSequentialRowsForward( } // We call getKeyFromResultSet() here so that we can know the - // key value upon which to doAfterTransactionCompletion the breaking logic. However, + // key value upon which to perform the breaking logic. However, // it is also then called from getRowFromResultSet() which is certainly // not the most efficient. But the call here is needed, and there // currently is no other way without refactoring of the doQuery()/getRowFromResultSet() @@ -527,7 +524,7 @@ public Object loadSequentialRowsForward( catch ( SQLException sqle ) { throw factory.getSQLExceptionHelper().convert( sqle, - "could not doAfterTransactionCompletion sequential read of results (forward)", + "could not perform sequential read of results (forward)", getSQLString() ); } diff --git a/hibernate-core/src/main/java/org/hibernate/loader/collection/DynamicBatchingCollectionInitializerBuilder.java b/hibernate-core/src/main/java/org/hibernate/loader/collection/DynamicBatchingCollectionInitializerBuilder.java index 62e82e78f6..8f470ca1e1 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/collection/DynamicBatchingCollectionInitializerBuilder.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/collection/DynamicBatchingCollectionInitializerBuilder.java @@ -43,6 +43,7 @@ import org.hibernate.internal.util.collections.ArrayHelper; import org.hibernate.loader.JoinWalker; import org.hibernate.loader.Loader; +import org.hibernate.loader.spi.AfterLoadAction; import org.hibernate.persister.collection.QueryableCollection; import org.hibernate.pretty.MessageHelper; import org.hibernate.type.Type; diff --git a/hibernate-core/src/main/java/org/hibernate/loader/criteria/CriteriaLoader.java b/hibernate-core/src/main/java/org/hibernate/loader/criteria/CriteriaLoader.java index e1caffb218..0b7093bc0e 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/criteria/CriteriaLoader.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/criteria/CriteriaLoader.java @@ -45,6 +45,7 @@ import org.hibernate.internal.CriteriaImpl; import org.hibernate.internal.util.collections.ArrayHelper; import org.hibernate.loader.OuterJoinLoader; +import org.hibernate.loader.spi.AfterLoadAction; import org.hibernate.persister.entity.Loadable; import org.hibernate.persister.entity.Lockable; import org.hibernate.persister.entity.OuterJoinLoadable; diff --git a/hibernate-core/src/main/java/org/hibernate/loader/custom/CustomLoader.java b/hibernate-core/src/main/java/org/hibernate/loader/custom/CustomLoader.java index 239451eea5..b626e375ec 100755 --- a/hibernate-core/src/main/java/org/hibernate/loader/custom/CustomLoader.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/custom/CustomLoader.java @@ -27,7 +27,6 @@ import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.util.ArrayList; -import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; @@ -41,10 +40,7 @@ import org.hibernate.ScrollableResults; import org.hibernate.Session; import org.hibernate.dialect.Dialect; -import org.hibernate.dialect.pagination.LimitHandler; -import org.hibernate.dialect.pagination.LimitHelper; import org.hibernate.engine.spi.QueryParameters; -import org.hibernate.engine.spi.RowSelection; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.hql.internal.HolderInstantiator; @@ -53,10 +49,10 @@ import org.hibernate.loader.CollectionAliases; import org.hibernate.loader.EntityAliases; import org.hibernate.loader.Loader; +import org.hibernate.loader.spi.AfterLoadAction; import org.hibernate.persister.collection.CollectionPersister; import org.hibernate.persister.collection.QueryableCollection; import org.hibernate.persister.entity.Loadable; -import org.hibernate.persister.entity.Lockable; import org.hibernate.persister.entity.Queryable; import org.hibernate.transform.ResultTransformer; import org.hibernate.type.CollectionType; diff --git a/hibernate-core/src/main/java/org/hibernate/loader/entity/DynamicBatchingEntityLoaderBuilder.java b/hibernate-core/src/main/java/org/hibernate/loader/entity/DynamicBatchingEntityLoaderBuilder.java index af1fcc26ea..c1be46e16c 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/entity/DynamicBatchingEntityLoaderBuilder.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/entity/DynamicBatchingEntityLoaderBuilder.java @@ -43,6 +43,7 @@ import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.internal.util.StringHelper; import org.hibernate.internal.util.collections.ArrayHelper; +import org.hibernate.loader.spi.AfterLoadAction; import org.hibernate.persister.entity.OuterJoinLoadable; import org.hibernate.pretty.MessageHelper; diff --git a/hibernate-core/src/main/java/org/hibernate/loader/hql/QueryLoader.java b/hibernate-core/src/main/java/org/hibernate/loader/hql/QueryLoader.java index c50eed3458..3a45e39d53 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/hql/QueryLoader.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/hql/QueryLoader.java @@ -52,6 +52,7 @@ import org.hibernate.internal.IteratorImpl; import org.hibernate.internal.util.collections.ArrayHelper; import org.hibernate.loader.BasicLoader; +import org.hibernate.loader.spi.AfterLoadAction; import org.hibernate.param.ParameterSpecification; import org.hibernate.persister.collection.CollectionPersister; import org.hibernate.persister.collection.QueryableCollection; diff --git a/hibernate-core/src/main/java/org/hibernate/loader/internal/OnDemandResultSetProcessorImpl.java b/hibernate-core/src/main/java/org/hibernate/loader/internal/OnDemandResultSetProcessorImpl.java new file mode 100644 index 0000000000..8fc816c9e6 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/loader/internal/OnDemandResultSetProcessorImpl.java @@ -0,0 +1,58 @@ +/* + * 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.loader.internal; + +import java.sql.ResultSet; + +import org.hibernate.engine.spi.QueryParameters; +import org.hibernate.engine.spi.SessionImplementor; +import org.hibernate.loader.spi.OnDemandResultSetProcessor; + +/** + * @author Steve Ebersole + */ +public class OnDemandResultSetProcessorImpl implements OnDemandResultSetProcessor { + @Override + public Object extractSingleRow( + ResultSet resultSet, + SessionImplementor session, + QueryParameters queryParameters) { + return null; + } + + @Override + public Object extractSequentialRowsForward( + ResultSet resultSet, SessionImplementor session, QueryParameters queryParameters) { + return null; //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + public Object extractSequentialRowsReverse( + ResultSet resultSet, + SessionImplementor session, + QueryParameters queryParameters, + boolean isLogicallyAfterLast) { + return null; //To change body of implemented methods use File | Settings | File Templates. + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/loader/internal/ResultSetProcessingContextImpl.java b/hibernate-core/src/main/java/org/hibernate/loader/internal/ResultSetProcessingContextImpl.java new file mode 100644 index 0000000000..2e390c980b --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/loader/internal/ResultSetProcessingContextImpl.java @@ -0,0 +1,557 @@ +/* + * 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.loader.internal; + +import java.io.Serializable; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.jboss.logging.Logger; + +import org.hibernate.HibernateException; +import org.hibernate.LockMode; +import org.hibernate.StaleObjectStateException; +import org.hibernate.WrongClassException; +import org.hibernate.engine.internal.TwoPhaseLoad; +import org.hibernate.engine.spi.EntityKey; +import org.hibernate.engine.spi.EntityUniqueKey; +import org.hibernate.engine.spi.QueryParameters; +import org.hibernate.engine.spi.SessionImplementor; +import org.hibernate.engine.spi.SubselectFetch; +import org.hibernate.event.spi.EventSource; +import org.hibernate.event.spi.PostLoadEvent; +import org.hibernate.event.spi.PreLoadEvent; +import org.hibernate.loader.EntityAliases; +import org.hibernate.loader.plan.spi.CollectionFetch; +import org.hibernate.loader.plan.spi.CollectionReturn; +import org.hibernate.loader.plan.spi.EntityReference; +import org.hibernate.loader.plan.spi.LoadPlan; +import org.hibernate.loader.plan.spi.LoadPlanVisitationStrategyAdapter; +import org.hibernate.loader.plan.spi.LoadPlanVisitor; +import org.hibernate.loader.spi.AfterLoadAction; +import org.hibernate.loader.spi.NamedParameterContext; +import org.hibernate.loader.spi.ResultSetProcessingContext; +import org.hibernate.persister.collection.CollectionPersister; +import org.hibernate.persister.entity.EntityPersister; +import org.hibernate.persister.entity.Loadable; +import org.hibernate.persister.entity.UniqueKeyLoadable; +import org.hibernate.pretty.MessageHelper; +import org.hibernate.type.EntityType; +import org.hibernate.type.Type; +import org.hibernate.type.VersionType; + +/** + * @author Steve Ebersole + */ +public class ResultSetProcessingContextImpl implements ResultSetProcessingContext { + private static final Logger LOG = Logger.getLogger( ResultSetProcessingContextImpl.class ); + + private final ResultSet resultSet; + private final SessionImplementor session; + private final LoadPlan loadPlan; + private final boolean readOnly; + private final QueryParameters queryParameters; + private final NamedParameterContext namedParameterContext; + private final boolean hadSubselectFetches; + + private final EntityKey dictatedRootEntityKey; + + private List currentRowHydratedEntityRegistrationList; + + private Map> subselectLoadableEntityKeyMap; + private List hydratedEntityRegistrationList; + + public ResultSetProcessingContextImpl( + ResultSet resultSet, + SessionImplementor session, + LoadPlan loadPlan, + boolean readOnly, + boolean useOptionalEntityKey, + QueryParameters queryParameters, + NamedParameterContext namedParameterContext, + boolean hadSubselectFetches) { + this.resultSet = resultSet; + this.session = session; + this.loadPlan = loadPlan; + this.readOnly = readOnly; + this.queryParameters = queryParameters; + this.namedParameterContext = namedParameterContext; + this.hadSubselectFetches = hadSubselectFetches; + + if ( useOptionalEntityKey ) { + this.dictatedRootEntityKey = ResultSetProcessorHelper.getOptionalObjectKey( queryParameters, session ); + if ( this.dictatedRootEntityKey == null ) { + throw new HibernateException( "Unable to resolve optional entity-key" ); + } + } + else { + this.dictatedRootEntityKey = null; + } + } + + @Override + public SessionImplementor getSession() { + return session; + } + + @Override + public QueryParameters getQueryParameters() { + return queryParameters; + } + + @Override + public EntityKey getDictatedRootEntityKey() { + return dictatedRootEntityKey; + } + + private Map identifierResolutionContextMap; + + @Override + public IdentifierResolutionContext getIdentifierResolutionContext(final EntityReference entityReference) { + if ( identifierResolutionContextMap == null ) { + identifierResolutionContextMap = new HashMap(); + } + IdentifierResolutionContext context = identifierResolutionContextMap.get( entityReference ); + if ( context == null ) { + context = new IdentifierResolutionContext() { + private Serializable hydratedForm; + private EntityKey entityKey; + + @Override + public EntityReference getEntityReference() { + return entityReference; + } + + @Override + public void registerHydratedForm(Serializable hydratedForm) { + if ( this.hydratedForm != null ) { + // this could be bad... + } + this.hydratedForm = hydratedForm; + } + + @Override + public Serializable getHydratedForm() { + return hydratedForm; + } + + @Override + public void registerEntityKey(EntityKey entityKey) { + if ( this.entityKey != null ) { + // again, could be trouble... + } + this.entityKey = entityKey; + } + + @Override + public EntityKey getEntityKey() { + return entityKey; + } + }; + identifierResolutionContextMap.put( entityReference, context ); + } + + return context; + } + + @Override + public void checkVersion( + ResultSet resultSet, + EntityPersister persister, + EntityAliases entityAliases, + EntityKey entityKey, + Object entityInstance) throws SQLException { + final Object version = session.getPersistenceContext().getEntry( entityInstance ).getVersion(); + + if ( version != null ) { + //null version means the object is in the process of being loaded somewhere else in the ResultSet + VersionType versionType = persister.getVersionType(); + Object currentVersion = versionType.nullSafeGet( + resultSet, + entityAliases.getSuffixedVersionAliases(), + session, + null + ); + if ( !versionType.isEqual(version, currentVersion) ) { + if ( session.getFactory().getStatistics().isStatisticsEnabled() ) { + session.getFactory().getStatisticsImplementor() + .optimisticFailure( persister.getEntityName() ); + } + throw new StaleObjectStateException( persister.getEntityName(), entityKey.getIdentifier() ); + } + } + } + + @Override + public String getConcreteEntityTypeName( + final ResultSet rs, + final EntityPersister persister, + final EntityAliases entityAliases, + final EntityKey entityKey) throws SQLException { + + final Loadable loadable = (Loadable) persister; + if ( ! loadable.hasSubclasses() ) { + return persister.getEntityName(); + } + + final Object discriminatorValue = loadable.getDiscriminatorType().nullSafeGet( + rs, + entityAliases.getSuffixedDiscriminatorAlias(), + session, + null + ); + + final String result = loadable.getSubclassForDiscriminatorValue( discriminatorValue ); + + if ( result == null ) { + // whoops! we got an instance of another class hierarchy branch + throw new WrongClassException( + "Discriminator: " + discriminatorValue, + entityKey.getIdentifier(), + persister.getEntityName() + ); + } + + return result; + } + + @Override + public void loadFromResultSet( + ResultSet resultSet, + Object entityInstance, + String concreteEntityTypeName, + EntityKey entityKey, + EntityAliases entityAliases, + LockMode acquiredLockMode, + EntityPersister rootPersister, + boolean eagerFetch, + EntityType associationType) throws SQLException { + + final Serializable id = entityKey.getIdentifier(); + + // Get the persister for the _subclass_ + final Loadable persister = (Loadable) getSession().getFactory().getEntityPersister( concreteEntityTypeName ); + + if ( LOG.isTraceEnabled() ) { + LOG.tracev( + "Initializing object from ResultSet: {0}", + MessageHelper.infoString( + persister, + id, + getSession().getFactory() + ) + ); + } + + // add temp entry so that the next step is circular-reference + // safe - only needed because some types don't take proper + // advantage of two-phase-load (esp. components) + TwoPhaseLoad.addUninitializedEntity( + entityKey, + entityInstance, + persister, + acquiredLockMode, + !eagerFetch, + session + ); + + // This is not very nice (and quite slow): + final String[][] cols = persister == rootPersister ? + entityAliases.getSuffixedPropertyAliases() : + entityAliases.getSuffixedPropertyAliases(persister); + + final Object[] values = persister.hydrate( + resultSet, + id, + entityInstance, + (Loadable) rootPersister, + cols, + eagerFetch, + session + ); + + final Object rowId = persister.hasRowId() ? resultSet.getObject( entityAliases.getRowIdAlias() ) : null; + + if ( associationType != null ) { + String ukName = associationType.getRHSUniqueKeyPropertyName(); + if ( ukName != null ) { + final int index = ( (UniqueKeyLoadable) persister ).getPropertyIndex( ukName ); + final Type type = persister.getPropertyTypes()[index]; + + // polymorphism not really handled completely correctly, + // perhaps...well, actually its ok, assuming that the + // entity name used in the lookup is the same as the + // the one used here, which it will be + + EntityUniqueKey euk = new EntityUniqueKey( + rootPersister.getEntityName(), //polymorphism comment above + ukName, + type.semiResolve( values[index], session, entityInstance ), + type, + persister.getEntityMode(), + session.getFactory() + ); + session.getPersistenceContext().addEntity( euk, entityInstance ); + } + } + + TwoPhaseLoad.postHydrate( + persister, + id, + values, + rowId, + entityInstance, + acquiredLockMode, + !eagerFetch, + session + ); + + } + + @Override + public void registerHydratedEntity(EntityPersister persister, EntityKey entityKey, Object entityInstance) { + if ( currentRowHydratedEntityRegistrationList == null ) { + currentRowHydratedEntityRegistrationList = new ArrayList(); + } + currentRowHydratedEntityRegistrationList.add( new HydratedEntityRegistration( persister, entityKey, entityInstance ) ); + } + + /** + * Package-protected + */ + void finishUpRow() { + if ( currentRowHydratedEntityRegistrationList == null ) { + return; + } + + + // managing the running list of registrations ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + if ( hydratedEntityRegistrationList == null ) { + hydratedEntityRegistrationList = new ArrayList(); + } + hydratedEntityRegistrationList.addAll( currentRowHydratedEntityRegistrationList ); + + + // managing the map forms needed for subselect fetch generation ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + if ( ! hadSubselectFetches ) { + return; + } + if ( subselectLoadableEntityKeyMap == null ) { + subselectLoadableEntityKeyMap = new HashMap>(); + } + for ( HydratedEntityRegistration registration : currentRowHydratedEntityRegistrationList ) { + Set entityKeys = subselectLoadableEntityKeyMap.get( registration.persister ); + if ( entityKeys == null ) { + entityKeys = new HashSet(); + subselectLoadableEntityKeyMap.put( registration.persister, entityKeys ); + } + entityKeys.add( registration.key ); + } + + // release the currentRowHydratedEntityRegistrationList entries + currentRowHydratedEntityRegistrationList.clear(); + } + + /** + * Package-protected + * + * @param afterLoadActionList List of after-load actions to perform + */ + void finishUp(List afterLoadActionList) { + initializeEntitiesAndCollections( afterLoadActionList ); + createSubselects(); + + if ( hydratedEntityRegistrationList != null ) { + hydratedEntityRegistrationList.clear(); + hydratedEntityRegistrationList = null; + } + + if ( subselectLoadableEntityKeyMap != null ) { + subselectLoadableEntityKeyMap.clear(); + subselectLoadableEntityKeyMap = null; + } + } + + private void initializeEntitiesAndCollections(List afterLoadActionList) { + // for arrays, we should end the collection load before resolving the entities, since the + // actual array instances are not instantiated during loading + finishLoadingArrays(); + + + // IMPORTANT: reuse the same event instances for performance! + final PreLoadEvent preLoadEvent; + final PostLoadEvent postLoadEvent; + if ( session.isEventSource() ) { + preLoadEvent = new PreLoadEvent( (EventSource) session ); + postLoadEvent = new PostLoadEvent( (EventSource) session ); + } + else { + preLoadEvent = null; + postLoadEvent = null; + } + + // now finish loading the entities (2-phase load) + performTwoPhaseLoad( preLoadEvent, postLoadEvent ); + + // now we can finalize loading collections + finishLoadingCollections(); + + // finally, perform post-load operations + postLoad( postLoadEvent, afterLoadActionList ); + } + + private void finishLoadingArrays() { + LoadPlanVisitor.visit( + loadPlan, + new LoadPlanVisitationStrategyAdapter() { + @Override + public void handleCollectionReturn(CollectionReturn rootCollectionReturn) { + endLoadingArray( rootCollectionReturn.getCollectionPersister() ); + } + + @Override + public void startingCollectionFetch(CollectionFetch collectionFetch) { + endLoadingArray( collectionFetch.getCollectionPersister() ); + } + + private void endLoadingArray(CollectionPersister persister) { + if ( persister.isArray() ) { + session.getPersistenceContext() + .getLoadContexts() + .getCollectionLoadContext( resultSet ) + .endLoadingCollections( persister ); + } + } + } + ); + } + + private void performTwoPhaseLoad(PreLoadEvent preLoadEvent, PostLoadEvent postLoadEvent) { + final int numberOfHydratedObjects = hydratedEntityRegistrationList == null + ? 0 + : hydratedEntityRegistrationList.size(); + LOG.tracev( "Total objects hydrated: {0}", numberOfHydratedObjects ); + + if ( hydratedEntityRegistrationList == null ) { + return; + } + + for ( HydratedEntityRegistration registration : hydratedEntityRegistrationList ) { + TwoPhaseLoad.initializeEntity( registration.instance, readOnly, session, preLoadEvent, postLoadEvent ); + } + } + + private void finishLoadingCollections() { + LoadPlanVisitor.visit( + loadPlan, + new LoadPlanVisitationStrategyAdapter() { + @Override + public void handleCollectionReturn(CollectionReturn rootCollectionReturn) { + endLoadingArray( rootCollectionReturn.getCollectionPersister() ); + } + + @Override + public void startingCollectionFetch(CollectionFetch collectionFetch) { + endLoadingArray( collectionFetch.getCollectionPersister() ); + } + + private void endLoadingArray(CollectionPersister persister) { + if ( ! persister.isArray() ) { + session.getPersistenceContext() + .getLoadContexts() + .getCollectionLoadContext( resultSet ) + .endLoadingCollections( persister ); + } + } + } + ); + } + + private void postLoad(PostLoadEvent postLoadEvent, List afterLoadActionList) { + // Until this entire method is refactored w/ polymorphism, postLoad was + // split off from initializeEntity. It *must* occur after + // endCollectionLoad to ensure the collection is in the + // persistence context. + if ( hydratedEntityRegistrationList == null ) { + return; + } + + for ( HydratedEntityRegistration registration : hydratedEntityRegistrationList ) { + TwoPhaseLoad.postLoad( registration.instance, session, postLoadEvent ); + if ( afterLoadActionList != null ) { + for ( AfterLoadAction afterLoadAction : afterLoadActionList ) { + afterLoadAction.afterLoad( session, registration.instance, (Loadable) registration.persister ); + } + } + } + } + + private void createSubselects() { + if ( subselectLoadableEntityKeyMap.size() <= 1 ) { + // if we only returned one entity, query by key is more efficient; so do nothing here + return; + } + + final Map namedParameterLocMap = + ResultSetProcessorHelper.buildNamedParameterLocMap( queryParameters, namedParameterContext ); + + for ( Map.Entry> entry : subselectLoadableEntityKeyMap.entrySet() ) { + if ( ! entry.getKey().hasSubselectLoadableCollections() ) { + continue; + } + + SubselectFetch subselectFetch = new SubselectFetch( + //getSQLString(), + null, // aliases[i], + (Loadable) entry.getKey(), + queryParameters, + entry.getValue(), + namedParameterLocMap + ); + + for ( EntityKey key : entry.getValue() ) { + session.getPersistenceContext().getBatchFetchQueue().addSubselect( key, subselectFetch ); + } + + } + } + + private static class HydratedEntityRegistration { + private final EntityPersister persister; + private final EntityKey key; + private final Object instance; + + private HydratedEntityRegistration(EntityPersister persister, EntityKey key, Object instance) { + this.persister = persister; + this.key = key; + this.instance = instance; + } + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/loader/internal/ResultSetProcessorHelper.java b/hibernate-core/src/main/java/org/hibernate/loader/internal/ResultSetProcessorHelper.java new file mode 100644 index 0000000000..8401218694 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/loader/internal/ResultSetProcessorHelper.java @@ -0,0 +1,77 @@ +/* + * 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.loader.internal; + +import java.io.Serializable; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.HashMap; +import java.util.Map; + +import org.hibernate.engine.spi.EntityKey; +import org.hibernate.engine.spi.QueryParameters; +import org.hibernate.engine.spi.SessionImplementor; +import org.hibernate.loader.EntityAliases; +import org.hibernate.loader.plan.spi.EntityReference; +import org.hibernate.loader.plan.spi.Fetch; +import org.hibernate.loader.spi.NamedParameterContext; +import org.hibernate.loader.spi.ResultSetProcessingContext; +import org.hibernate.persister.entity.EntityPersister; +import org.hibernate.type.CompositeType; +import org.hibernate.type.Type; + +/** + * @author Steve Ebersole + */ +public class ResultSetProcessorHelper { + public static EntityKey getOptionalObjectKey(QueryParameters queryParameters, SessionImplementor session) { + final Object optionalObject = queryParameters.getOptionalObject(); + final Serializable optionalId = queryParameters.getOptionalId(); + final String optionalEntityName = queryParameters.getOptionalEntityName(); + + if ( optionalObject != null && optionalEntityName != null ) { + return session.generateEntityKey( optionalId, session.getEntityPersister( optionalEntityName, optionalObject ) ); + } + else { + return null; + } + } + + public static Map buildNamedParameterLocMap( + QueryParameters queryParameters, + NamedParameterContext namedParameterContext) { + if ( queryParameters.getNamedParameters() == null || queryParameters.getNamedParameters().isEmpty() ) { + return null; + } + + final Map namedParameterLocMap = new HashMap(); + for ( String name : queryParameters.getNamedParameters().keySet() ) { + namedParameterLocMap.put( + name, + namedParameterContext.getNamedParameterLocations( name ) + ); + } + return namedParameterLocMap; + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/loader/internal/ResultSetProcessorImpl.java b/hibernate-core/src/main/java/org/hibernate/loader/internal/ResultSetProcessorImpl.java new file mode 100644 index 0000000000..d31278e5f5 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/loader/internal/ResultSetProcessorImpl.java @@ -0,0 +1,207 @@ +/* + * 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.loader.internal; + +import java.io.Serializable; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; + +import org.jboss.logging.Logger; + +import org.hibernate.dialect.pagination.LimitHelper; +import org.hibernate.engine.FetchStyle; +import org.hibernate.engine.spi.QueryParameters; +import org.hibernate.engine.spi.RowSelection; +import org.hibernate.engine.spi.SessionImplementor; +import org.hibernate.loader.plan.spi.CollectionFetch; +import org.hibernate.loader.plan.spi.CollectionReturn; +import org.hibernate.loader.plan.spi.EntityFetch; +import org.hibernate.loader.plan.spi.LoadPlan; +import org.hibernate.loader.plan.spi.LoadPlanVisitationStrategyAdapter; +import org.hibernate.loader.plan.spi.LoadPlanVisitor; +import org.hibernate.loader.plan.spi.Return; +import org.hibernate.loader.spi.AfterLoadAction; +import org.hibernate.loader.spi.NamedParameterContext; +import org.hibernate.loader.spi.OnDemandResultSetProcessor; +import org.hibernate.loader.spi.ResultSetProcessor; +import org.hibernate.persister.collection.CollectionPersister; +import org.hibernate.pretty.MessageHelper; +import org.hibernate.transform.ResultTransformer; + +/** + * @author Steve Ebersole + */ +public class ResultSetProcessorImpl implements ResultSetProcessor { + private static final Logger LOG = Logger.getLogger( ResultSetProcessorImpl.class ); + + private final LoadPlan loadPlan; + + private final boolean hadSubselectFetches; + + public ResultSetProcessorImpl(LoadPlan loadPlan) { + this.loadPlan = loadPlan; + + LocalVisitationStrategy strategy = new LocalVisitationStrategy(); + LoadPlanVisitor.visit( loadPlan, strategy ); + this.hadSubselectFetches = strategy.hadSubselectFetches; + } + + @Override + public OnDemandResultSetProcessor toOnDemandForm() { + return null; //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + public List extractResults( + ResultSet resultSet, + final SessionImplementor session, + QueryParameters queryParameters, + NamedParameterContext namedParameterContext, + boolean returnProxies, + boolean readOnly, + ResultTransformer forcedResultTransformer, + List afterLoadActionList) throws SQLException { + + handlePotentiallyEmptyCollectionRootReturns( queryParameters.getCollectionKeys(), resultSet, session ); + + final int maxRows; + final RowSelection selection = queryParameters.getRowSelection(); + if ( LimitHelper.hasMaxRows( selection ) ) { + maxRows = selection.getMaxRows(); + LOG.tracef( "Limiting ResultSet processing to just %s rows", maxRows ); + } + else { + maxRows = Integer.MAX_VALUE; + } + + final ResultSetProcessingContextImpl context = new ResultSetProcessingContextImpl( + resultSet, + session, + loadPlan, + readOnly, + true, // use optional entity key? for now, always say yes + queryParameters, + namedParameterContext, + hadSubselectFetches + ); + + final List loadResults = new ArrayList(); + + final int rootReturnCount = loadPlan.getReturns().size(); + + LOG.trace( "Processing result set" ); + int count; + for ( count = 0; count < maxRows && resultSet.next(); count++ ) { + LOG.debugf( "Starting ResultSet row #%s", count ); + + Object logicalRow; + if ( rootReturnCount == 1 ) { + loadPlan.getReturns().get( 0 ).hydrate( resultSet, context ); + loadPlan.getReturns().get( 0 ).resolve( resultSet, context ); + + logicalRow = loadPlan.getReturns().get( 0 ).read( resultSet, context ); + } + else { + for ( Return rootReturn : loadPlan.getReturns() ) { + rootReturn.hydrate( resultSet, context ); + } + for ( Return rootReturn : loadPlan.getReturns() ) { + rootReturn.resolve( resultSet, context ); + } + + logicalRow = new Object[ rootReturnCount ]; + int pos = 0; + for ( Return rootReturn : loadPlan.getReturns() ) { + ( (Object[]) logicalRow )[pos] = rootReturn.read( resultSet, context ); + pos++; + } + } + + // todo : apply transformers here? + + loadResults.add( logicalRow ); + + context.finishUpRow(); + } + + LOG.tracev( "Done processing result set ({0} rows)", count ); + + context.finishUp( afterLoadActionList ); + + session.getPersistenceContext().initializeNonLazyCollections(); + + return loadResults; + } + + + private void handlePotentiallyEmptyCollectionRootReturns( + Serializable[] collectionKeys, + ResultSet resultSet, + SessionImplementor session) { + if ( collectionKeys == null ) { + // this is not a collection initializer (and empty collections will be detected by looking for + // the owner's identifier in the result set) + return; + } + + // this is a collection initializer, so we must create a collection + // for each of the passed-in keys, to account for the possibility + // that the collection is empty and has no rows in the result set + // + // todo : move this inside CollectionReturn ? + CollectionPersister persister = ( (CollectionReturn) loadPlan.getReturns().get( 0 ) ).getCollectionPersister(); + for ( Serializable key : collectionKeys ) { + if ( LOG.isDebugEnabled() ) { + LOG.debugf( + "Preparing collection intializer : %s", + MessageHelper.collectionInfoString( persister, key, session.getFactory() ) + ); + session.getPersistenceContext() + .getLoadContexts() + .getCollectionLoadContext( resultSet ) + .getLoadingCollection( persister, key ); + } + } + } + + + private class LocalVisitationStrategy extends LoadPlanVisitationStrategyAdapter { + private boolean hadSubselectFetches = false; + + @Override + public void startingEntityFetch(EntityFetch entityFetch) { +// only collections are currently supported for subselect fetching. +// hadSubselectFetches = hadSubselectFetches +// | entityFetch.getFetchStrategy().getStyle() == FetchStyle.SUBSELECT; + } + + @Override + public void startingCollectionFetch(CollectionFetch collectionFetch) { + hadSubselectFetches = hadSubselectFetches + | collectionFetch.getFetchStrategy().getStyle() == FetchStyle.SUBSELECT; + } + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/internal/LoadPlanBuildingHelper.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/internal/LoadPlanBuildingHelper.java new file mode 100644 index 0000000000..3c617da984 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/internal/LoadPlanBuildingHelper.java @@ -0,0 +1,92 @@ +/* + * 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.loader.plan.internal; + +import org.hibernate.LockMode; +import org.hibernate.engine.FetchStrategy; +import org.hibernate.loader.CollectionAliases; +import org.hibernate.loader.EntityAliases; +import org.hibernate.loader.plan.spi.AbstractFetchOwner; +import org.hibernate.loader.plan.spi.CollectionFetch; +import org.hibernate.loader.plan.spi.CompositeFetch; +import org.hibernate.loader.plan.spi.EntityFetch; +import org.hibernate.loader.plan.spi.FetchOwner; +import org.hibernate.loader.plan.spi.LoadPlanBuildingContext; +import org.hibernate.persister.walking.spi.AssociationAttributeDefinition; +import org.hibernate.persister.walking.spi.CompositionDefinition; + +/** + * @author Steve Ebersole + */ +public class LoadPlanBuildingHelper { + public static CollectionFetch buildStandardCollectionFetch( + FetchOwner fetchOwner, + AssociationAttributeDefinition attributeDefinition, + FetchStrategy fetchStrategy, + LoadPlanBuildingContext loadPlanBuildingContext) { + final CollectionAliases collectionAliases = loadPlanBuildingContext.resolveCollectionColumnAliases( attributeDefinition ); + final EntityAliases elementEntityAliases = loadPlanBuildingContext.resolveEntityColumnAliases( attributeDefinition ); + + return new CollectionFetch( + loadPlanBuildingContext.getSessionFactory(), + loadPlanBuildingContext.resolveFetchSourceAlias( attributeDefinition ), + LockMode.NONE, // todo : for now + fetchOwner, + fetchStrategy, + attributeDefinition.getName(), + collectionAliases, + elementEntityAliases + ); + } + + public static EntityFetch buildStandardEntityFetch( + FetchOwner fetchOwner, + AssociationAttributeDefinition attributeDefinition, + FetchStrategy fetchStrategy, + LoadPlanBuildingContext loadPlanBuildingContext) { + + return new EntityFetch( + loadPlanBuildingContext.getSessionFactory(), + loadPlanBuildingContext.resolveFetchSourceAlias( attributeDefinition ), + LockMode.NONE, // todo : for now + fetchOwner, + attributeDefinition.getName(), + fetchStrategy, + null, // sql table alias + loadPlanBuildingContext.resolveEntityColumnAliases( attributeDefinition ) + ); + } + + public static CompositeFetch buildStandardCompositeFetch( + FetchOwner fetchOwner, + CompositionDefinition attributeDefinition, + LoadPlanBuildingContext loadPlanBuildingContext) { + return new CompositeFetch( + loadPlanBuildingContext.getSessionFactory(), + loadPlanBuildingContext.resolveFetchSourceAlias( attributeDefinition ), + (AbstractFetchOwner) fetchOwner, + attributeDefinition.getName() + ); + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/internal/SingleRootReturnLoadPlanBuilderStrategy.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/internal/SingleRootReturnLoadPlanBuilderStrategy.java index f329b30e26..fd710aa7f6 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/plan/internal/SingleRootReturnLoadPlanBuilderStrategy.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/internal/SingleRootReturnLoadPlanBuilderStrategy.java @@ -32,26 +32,18 @@ import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.internal.util.StringHelper; import org.hibernate.loader.CollectionAliases; -import org.hibernate.loader.DefaultEntityAliases; import org.hibernate.loader.EntityAliases; -import org.hibernate.loader.GeneratedCollectionAliases; import org.hibernate.loader.PropertyPath; -import org.hibernate.loader.plan.spi.AbstractFetchOwner; import org.hibernate.loader.plan.spi.AbstractLoadPlanBuilderStrategy; -import org.hibernate.loader.plan.spi.CollectionFetch; import org.hibernate.loader.plan.spi.CollectionReturn; -import org.hibernate.loader.plan.spi.CompositeFetch; -import org.hibernate.loader.plan.spi.EntityFetch; import org.hibernate.loader.plan.spi.EntityReturn; -import org.hibernate.loader.plan.spi.FetchOwner; import org.hibernate.loader.plan.spi.LoadPlan; import org.hibernate.loader.plan.spi.LoadPlanBuilderStrategy; import org.hibernate.loader.plan.spi.Return; import org.hibernate.persister.collection.CollectionPersister; -import org.hibernate.persister.entity.Loadable; +import org.hibernate.persister.entity.EntityPersister; import org.hibernate.persister.walking.spi.AssociationAttributeDefinition; import org.hibernate.persister.walking.spi.CollectionDefinition; -import org.hibernate.persister.walking.spi.CompositeDefinition; import org.hibernate.persister.walking.spi.EntityDefinition; import org.hibernate.type.EntityType; import org.hibernate.type.Type; @@ -74,7 +66,6 @@ public class SingleRootReturnLoadPlanBuilderStrategy private final LoadQueryInfluencers loadQueryInfluencers; private final String rootAlias; - private int currentSuffixBase; private Return rootReturn; @@ -85,10 +76,9 @@ public SingleRootReturnLoadPlanBuilderStrategy( LoadQueryInfluencers loadQueryInfluencers, String rootAlias, int suffixSeed) { - super( sessionFactory ); + super( sessionFactory, suffixSeed ); this.loadQueryInfluencers = loadQueryInfluencers; this.rootAlias = rootAlias; - this.currentSuffixBase = suffixSeed; } @Override @@ -153,10 +143,7 @@ protected EntityReturn buildRootEntityReturn(EntityDefinition entityDefinition) LockMode.NONE, // todo : for now entityName, StringHelper.generateAlias( StringHelper.unqualifyEntityName( entityName ), currentDepth() ), - new DefaultEntityAliases( - (Loadable) entityDefinition.getEntityPersister(), - Integer.toString( currentSuffixBase++ ) + '_' - ) + generateEntityColumnAliases( entityDefinition.getEntityPersister() ) ); } @@ -165,17 +152,16 @@ protected CollectionReturn buildRootCollectionReturn(CollectionDefinition collec final CollectionPersister persister = collectionDefinition.getCollectionPersister(); final String collectionRole = persister.getRole(); - final CollectionAliases collectionAliases = new GeneratedCollectionAliases( - collectionDefinition.getCollectionPersister(), - Integer.toString( currentSuffixBase++ ) + '_' + final CollectionAliases collectionAliases = generateCollectionColumnAliases( + collectionDefinition.getCollectionPersister() ); + final Type elementType = collectionDefinition.getCollectionPersister().getElementType(); final EntityAliases elementAliases; if ( elementType.isEntityType() ) { final EntityType entityElementType = (EntityType) elementType; - elementAliases = new DefaultEntityAliases( - (Loadable) entityElementType.getAssociatedJoinable( sessionFactory() ), - Integer.toString( currentSuffixBase++ ) + '_' + elementAliases = generateEntityColumnAliases( + (EntityPersister) entityElementType.getAssociatedJoinable( sessionFactory() ) ); } else { @@ -193,76 +179,16 @@ protected CollectionReturn buildRootCollectionReturn(CollectionDefinition collec ); } - @Override - protected CollectionFetch buildCollectionFetch( - FetchOwner fetchOwner, - AssociationAttributeDefinition attributeDefinition, - FetchStrategy fetchStrategy) { - final CollectionDefinition collectionDefinition = attributeDefinition.toCollectionDefinition(); - final CollectionAliases collectionAliases = new GeneratedCollectionAliases( - collectionDefinition.getCollectionPersister(), - Integer.toString( currentSuffixBase++ ) + '_' - ); - final Type elementType = collectionDefinition.getCollectionPersister().getElementType(); - final EntityAliases elementAliases; - if ( elementType.isEntityType() ) { - final EntityType entityElementType = (EntityType) elementType; - elementAliases = new DefaultEntityAliases( - (Loadable) entityElementType.getAssociatedJoinable( sessionFactory() ), - Integer.toString( currentSuffixBase++ ) + '_' - ); - } - else { - elementAliases = null; - } - return new CollectionFetch( - sessionFactory(), - createImplicitAlias(), - LockMode.NONE, // todo : for now - (AbstractFetchOwner) fetchOwner, - fetchStrategy, - attributeDefinition.getName(), - collectionAliases, - elementAliases - ); + // LoadPlanBuildingContext impl ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + @Override + public String resolveRootSourceAlias(EntityDefinition definition) { + return rootAlias; } @Override - protected EntityFetch buildEntityFetch( - FetchOwner fetchOwner, - AssociationAttributeDefinition attributeDefinition, - FetchStrategy fetchStrategy) { - final EntityDefinition entityDefinition = attributeDefinition.toEntityDefinition(); - - return new EntityFetch( - sessionFactory(), - createImplicitAlias(), - LockMode.NONE, // todo : for now - (AbstractFetchOwner) fetchOwner, - attributeDefinition.getName(), - fetchStrategy, - StringHelper.generateAlias( entityDefinition.getEntityPersister().getEntityName(), currentDepth() ), - new DefaultEntityAliases( - (Loadable) entityDefinition.getEntityPersister(), - Integer.toString( currentSuffixBase++ ) + '_' - ) - ); - } - - @Override - protected CompositeFetch buildCompositeFetch(FetchOwner fetchOwner, CompositeDefinition attributeDefinition) { - return new CompositeFetch( - sessionFactory(), - createImplicitAlias(), - (AbstractFetchOwner) fetchOwner, - attributeDefinition.getName() - ); - } - - private int implicitAliasUniqueness = 0; - - private String createImplicitAlias() { - return "ia" + implicitAliasUniqueness++; + public String resolveRootSourceAlias(CollectionDefinition definition) { + return rootAlias; } } diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/AbstractCollectionReference.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/AbstractCollectionReference.java new file mode 100644 index 0000000000..e623f0a898 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/AbstractCollectionReference.java @@ -0,0 +1,143 @@ +/* + * 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.loader.plan.spi; + +import org.hibernate.LockMode; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.loader.CollectionAliases; +import org.hibernate.loader.EntityAliases; +import org.hibernate.loader.PropertyPath; +import org.hibernate.persister.collection.CollectionPersister; +import org.hibernate.type.Type; + +/** + * @author Steve Ebersole + */ +public abstract class AbstractCollectionReference extends AbstractPlanNode implements CollectionReference { + private final String alias; + private final LockMode lockMode; + private final CollectionPersister collectionPersister; + private final PropertyPath propertyPath; + + private final CollectionAliases collectionAliases; + private final EntityAliases elementEntityAliases; + + private final FetchOwner indexGraph; + private final FetchOwner elementGraph; + + protected AbstractCollectionReference( + SessionFactoryImplementor sessionFactory, + String alias, + LockMode lockMode, + CollectionPersister collectionPersister, + PropertyPath propertyPath, + CollectionAliases collectionAliases, + EntityAliases elementEntityAliases) { + super( sessionFactory ); + this.alias = alias; + this.lockMode = lockMode; + this.collectionPersister = collectionPersister; + this.propertyPath = propertyPath; + + this.collectionAliases = collectionAliases; + this.elementEntityAliases = elementEntityAliases; + + this.indexGraph = buildIndexGraph( getCollectionPersister() ); + this.elementGraph = buildElementGraph( getCollectionPersister() ); + } + + private FetchOwner buildIndexGraph(CollectionPersister persister) { + if ( persister.hasIndex() ) { + final Type type = persister.getIndexType(); + if ( type.isAssociationType() ) { + if ( type.isEntityType() ) { + return new EntityIndexGraph( sessionFactory(), this, propertyPath() ); + } + } + else if ( type.isComponentType() ) { + return new CompositeIndexGraph( sessionFactory(), this, propertyPath() ); + } + } + + return null; + } + + private FetchOwner buildElementGraph(CollectionPersister persister) { + final Type type = persister.getElementType(); + if ( type.isAssociationType() ) { + if ( type.isEntityType() ) { + return new EntityElementGraph( sessionFactory(), this, propertyPath() ); + } + } + else if ( type.isComponentType() ) { + return new CompositeElementGraph( sessionFactory(), this, propertyPath() ); + } + + return null; + } + + public PropertyPath propertyPath() { + return propertyPath; + } + + @Override + public String getAlias() { + return alias; + } + + @Override + public LockMode getLockMode() { + return lockMode; + } + + @Override + public CollectionAliases getCollectionAliases() { + return collectionAliases; + } + + @Override + public EntityAliases getElementEntityAliases() { + return elementEntityAliases; + } + + @Override + public CollectionPersister getCollectionPersister() { + return collectionPersister; + } + + @Override + public FetchOwner getIndexGraph() { + return indexGraph; + } + + @Override + public FetchOwner getElementGraph() { + return elementGraph; + } + + @Override + public boolean hasEntityElements() { + return getCollectionPersister().isOneToMany() || getCollectionPersister().isManyToMany(); + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/AbstractFetch.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/AbstractFetch.java index e7d2751247..bb9d9d0c18 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/AbstractFetch.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/AbstractFetch.java @@ -44,7 +44,7 @@ public AbstractFetch( SessionFactoryImplementor factory, String alias, LockMode lockMode, - AbstractFetchOwner owner, + FetchOwner owner, String ownerProperty, FetchStrategy fetchStrategy) { super( factory, alias, lockMode ); @@ -85,4 +85,9 @@ public void validateFetchPlan(FetchStrategy fetchStrategy) { public PropertyPath getPropertyPath() { return propertyPath; } + + @Override + public String toString() { + return "Fetch(" + propertyPath.getFullPath() + ")"; + } } diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/AbstractFetchOwner.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/AbstractFetchOwner.java index 87063b9278..d0dbc8197f 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/AbstractFetchOwner.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/AbstractFetchOwner.java @@ -56,7 +56,8 @@ public LockMode getLockMode() { return lockMode; } - void addFetch(Fetch fetch) { + @Override + public void addFetch(Fetch fetch) { if ( fetch.getOwner() != this ) { throw new IllegalArgumentException( "Fetch and owner did not match" ); } diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/AbstractLoadPlanBuilderStrategy.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/AbstractLoadPlanBuilderStrategy.java index f9324daa96..2ec4457bfe 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/AbstractLoadPlanBuilderStrategy.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/AbstractLoadPlanBuilderStrategy.java @@ -23,29 +23,62 @@ */ package org.hibernate.loader.plan.spi; +import java.io.Serializable; +import java.sql.ResultSet; +import java.sql.SQLException; import java.util.ArrayDeque; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.jboss.logging.Logger; import org.hibernate.HibernateException; +import org.hibernate.LockMode; import org.hibernate.engine.FetchStrategy; import org.hibernate.engine.FetchTiming; +import org.hibernate.engine.spi.EntityKey; import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.internal.util.StringHelper; +import org.hibernate.loader.CollectionAliases; +import org.hibernate.loader.DefaultEntityAliases; +import org.hibernate.loader.EntityAliases; +import org.hibernate.loader.GeneratedCollectionAliases; +import org.hibernate.loader.PropertyPath; +import org.hibernate.loader.plan.internal.LoadPlanBuildingHelper; +import org.hibernate.loader.spi.ResultSetProcessingContext; +import org.hibernate.persister.collection.CollectionPersister; +import org.hibernate.persister.entity.EntityPersister; +import org.hibernate.persister.entity.Loadable; +import org.hibernate.persister.spi.HydratedCompoundValueHandler; import org.hibernate.persister.walking.spi.AssociationAttributeDefinition; import org.hibernate.persister.walking.spi.AttributeDefinition; import org.hibernate.persister.walking.spi.CollectionDefinition; -import org.hibernate.persister.walking.spi.CompositeDefinition; +import org.hibernate.persister.walking.spi.CollectionElementDefinition; +import org.hibernate.persister.walking.spi.CollectionIndexDefinition; +import org.hibernate.persister.walking.spi.CompositionDefinition; import org.hibernate.persister.walking.spi.EntityDefinition; +import org.hibernate.persister.walking.spi.EntityIdentifierDefinition; +import org.hibernate.persister.walking.spi.WalkingException; import org.hibernate.type.Type; +import static org.hibernate.loader.spi.ResultSetProcessingContext.IdentifierResolutionContext; + /** * @author Steve Ebersole */ -public abstract class AbstractLoadPlanBuilderStrategy implements LoadPlanBuilderStrategy { +public abstract class AbstractLoadPlanBuilderStrategy implements LoadPlanBuilderStrategy, LoadPlanBuildingContext { + private static final Logger log = Logger.getLogger( AbstractLoadPlanBuilderStrategy.class ); + private final SessionFactoryImplementor sessionFactory; private ArrayDeque fetchOwnerStack = new ArrayDeque(); + private ArrayDeque collectionReferenceStack = new ArrayDeque(); - protected AbstractLoadPlanBuilderStrategy(SessionFactoryImplementor sessionFactory) { + protected AbstractLoadPlanBuilderStrategy(SessionFactoryImplementor sessionFactory, int suffixSeed) { this.sessionFactory = sessionFactory; + this.currentSuffixBase = suffixSeed; } public SessionFactoryImplementor sessionFactory() { @@ -53,21 +86,39 @@ public SessionFactoryImplementor sessionFactory() { } protected FetchOwner currentFetchOwner() { - return fetchOwnerStack.peekLast(); + return fetchOwnerStack.peekFirst(); } @Override public void start() { - // nothing to do + if ( ! fetchOwnerStack.isEmpty() ) { + throw new WalkingException( + "Fetch owner stack was not empty on start; " + + "be sure to not use LoadPlanBuilderStrategy instances concurrently" + ); + } + if ( ! collectionReferenceStack.isEmpty() ) { + throw new WalkingException( + "Collection reference stack was not empty on start; " + + "be sure to not use LoadPlanBuilderStrategy instances concurrently" + ); + } } @Override public void finish() { - // nothing to do + fetchOwnerStack.clear(); + collectionReferenceStack.clear(); } @Override public void startingEntity(EntityDefinition entityDefinition) { + log.tracef( + "%s Starting entity : %s", + StringHelper.repeat( ">>", fetchOwnerStack.size() ), + entityDefinition.getEntityPersister().getEntityName() + ); + if ( fetchOwnerStack.isEmpty() ) { // this is a root... if ( ! supportsRootEntityReturns() ) { @@ -75,7 +126,7 @@ public void startingEntity(EntityDefinition entityDefinition) { } final EntityReturn entityReturn = buildRootEntityReturn( entityDefinition ); addRootReturn( entityReturn ); - fetchOwnerStack.push( entityReturn ); + pushToStack( entityReturn ); } // otherwise this call should represent a fetch which should have been handled in #startingAttribute } @@ -88,11 +139,112 @@ protected boolean supportsRootEntityReturns() { @Override public void finishingEntity(EntityDefinition entityDefinition) { - // nothing to do + // pop the current fetch owner, and make sure what we just popped represents this entity + final FetchOwner poppedFetchOwner = popFromStack(); + + if ( ! EntityReference.class.isInstance( poppedFetchOwner ) ) { + throw new WalkingException( "Mismatched FetchOwner from stack on pop" ); + } + + final EntityReference entityReference = (EntityReference) poppedFetchOwner; + // NOTE : this is not the most exhaustive of checks because of hierarchical associations (employee/manager) + if ( ! entityReference.getEntityPersister().equals( entityDefinition.getEntityPersister() ) ) { + throw new WalkingException( "Mismatched FetchOwner from stack on pop" ); + } + + log.tracef( + "%s Finished entity : %s", + StringHelper.repeat( "<<", fetchOwnerStack.size() ), + entityDefinition.getEntityPersister().getEntityName() + ); + } + + @Override + public void startingEntityIdentifier(EntityIdentifierDefinition entityIdentifierDefinition) { + log.tracef( + "%s Starting entity identifier : %s", + StringHelper.repeat( ">>", fetchOwnerStack.size() ), + entityIdentifierDefinition.getEntityDefinition().getEntityPersister().getEntityName() + ); + + final EntityReference entityReference = (EntityReference) currentFetchOwner(); + + // perform some stack validation + if ( ! entityReference.getEntityPersister().equals( entityIdentifierDefinition.getEntityDefinition().getEntityPersister() ) ) { + throw new WalkingException( + String.format( + "Encountered unexpected fetch owner [%s] in stack while processing entity identifier for [%s]", + entityReference.getEntityPersister().getEntityName(), + entityIdentifierDefinition.getEntityDefinition().getEntityPersister().getEntityName() + ) + ); + } + + final FetchOwner identifierAttributeCollector; + if ( entityIdentifierDefinition.isEncapsulated() ) { + identifierAttributeCollector = new EncapsulatedIdentifierAttributeCollector( entityReference ); + } + else { + identifierAttributeCollector = new NonEncapsulatedIdentifierAttributeCollector( entityReference ); + } + pushToStack( identifierAttributeCollector ); + } + + @Override + public void finishingEntityIdentifier(EntityIdentifierDefinition entityIdentifierDefinition) { + // perform some stack validation on exit, first on the current stack element we want to pop + { + final FetchOwner poppedFetchOwner = popFromStack(); + + if ( ! AbstractIdentifierAttributeCollector.class.isInstance( poppedFetchOwner ) ) { + throw new WalkingException( "Unexpected state in FetchOwner stack" ); + } + + final EntityReference entityReference = (EntityReference) poppedFetchOwner; + if ( ! entityReference.getEntityPersister().equals( entityIdentifierDefinition.getEntityDefinition().getEntityPersister() ) ) { + throw new WalkingException( + String.format( + "Encountered unexpected fetch owner [%s] in stack while processing entity identifier for [%s]", + entityReference.getEntityPersister().getEntityName(), + entityIdentifierDefinition.getEntityDefinition().getEntityPersister().getEntityName() + ) + ); + } + } + + // and then on the element before it + { + final FetchOwner currentFetchOwner = currentFetchOwner(); + if ( ! EntityReference.class.isInstance( currentFetchOwner ) ) { + throw new WalkingException( "Unexpected state in FetchOwner stack" ); + } + final EntityReference entityReference = (EntityReference) currentFetchOwner; + if ( ! entityReference.getEntityPersister().equals( entityIdentifierDefinition.getEntityDefinition().getEntityPersister() ) ) { + throw new WalkingException( + String.format( + "Encountered unexpected fetch owner [%s] in stack while processing entity identifier for [%s]", + entityReference.getEntityPersister().getEntityName(), + entityIdentifierDefinition.getEntityDefinition().getEntityPersister().getEntityName() + ) + ); + } + } + + log.tracef( + "%s Finished entity identifier : %s", + StringHelper.repeat( "<<", fetchOwnerStack.size() ), + entityIdentifierDefinition.getEntityDefinition().getEntityPersister().getEntityName() + ); } @Override public void startingCollection(CollectionDefinition collectionDefinition) { + log.tracef( + "%s Starting collection : %s", + StringHelper.repeat( ">>", fetchOwnerStack.size() ), + collectionDefinition.getCollectionPersister().getRole() + ); + if ( fetchOwnerStack.isEmpty() ) { // this is a root... if ( ! supportsRootCollectionReturns() ) { @@ -100,7 +252,7 @@ public void startingCollection(CollectionDefinition collectionDefinition) { } final CollectionReturn collectionReturn = buildRootCollectionReturn( collectionDefinition ); addRootReturn( collectionReturn ); - fetchOwnerStack.push( collectionReturn ); + pushToCollectionStack( collectionReturn ); } } @@ -109,24 +261,96 @@ protected boolean supportsRootCollectionReturns() { } @Override - public void finishingCollection(CollectionDefinition collectionDefinition) { - // nothing to do + public void startingCollectionIndex(CollectionIndexDefinition collectionIndexDefinition) { + final Type indexType = collectionIndexDefinition.getType(); + if ( indexType.isAssociationType() || indexType.isComponentType() ) { + final CollectionReference collectionReference = collectionReferenceStack.peekFirst(); + final FetchOwner indexGraph = collectionReference.getIndexGraph(); + if ( indexGraph == null ) { + throw new WalkingException( "Collection reference did not return index handler" ); + } + pushToStack( indexGraph ); + } } @Override - public void startingComposite(CompositeDefinition compositeDefinition) { + public void finishingCollectionIndex(CollectionIndexDefinition collectionIndexDefinition) { + // nothing to do here + // - the element graph pushed while starting would be popped in finishing/Entity/finishingComposite + } + + @Override + public void startingCollectionElements(CollectionElementDefinition elementDefinition) { + if ( elementDefinition.getType().isAssociationType() || elementDefinition.getType().isComponentType() ) { + final CollectionReference collectionReference = collectionReferenceStack.peekFirst(); + final FetchOwner elementGraph = collectionReference.getElementGraph(); + if ( elementGraph == null ) { + throw new WalkingException( "Collection reference did not return element handler" ); + } + pushToStack( elementGraph ); + } + } + + @Override + public void finishingCollectionElements(CollectionElementDefinition elementDefinition) { + // nothing to do here + // - the element graph pushed while starting would be popped in finishing/Entity/finishingComposite + } + + @Override + public void finishingCollection(CollectionDefinition collectionDefinition) { + // pop the current fetch owner, and make sure what we just popped represents this collection + final CollectionReference collectionReference = popFromCollectionStack(); + if ( ! collectionReference.getCollectionPersister().equals( collectionDefinition.getCollectionPersister() ) ) { + throw new WalkingException( "Mismatched FetchOwner from stack on pop" ); + } + + log.tracef( + "%s Finished collection : %s", + StringHelper.repeat( "<<", fetchOwnerStack.size() ), + collectionDefinition.getCollectionPersister().getRole() + ); + } + + @Override + public void startingComposite(CompositionDefinition compositionDefinition) { + log.tracef( + "%s Starting composition : %s", + StringHelper.repeat( ">>", fetchOwnerStack.size() ), + compositionDefinition.getName() + ); + if ( fetchOwnerStack.isEmpty() ) { throw new HibernateException( "A component cannot be the root of a walk nor a graph" ); } } @Override - public void finishingComposite(CompositeDefinition compositeDefinition) { - // nothing to do + public void finishingComposite(CompositionDefinition compositionDefinition) { + // pop the current fetch owner, and make sure what we just popped represents this composition + final FetchOwner poppedFetchOwner = popFromStack(); + + if ( ! CompositeFetch.class.isInstance( poppedFetchOwner ) ) { + throw new WalkingException( "Mismatched FetchOwner from stack on pop" ); + } + + // NOTE : not much else we can really check here atm since on the walking spi side we do not have path + + log.tracef( + "%s Finished composition : %s", + StringHelper.repeat( "<<", fetchOwnerStack.size() ), + compositionDefinition.getName() + ); } @Override public boolean startingAttribute(AttributeDefinition attributeDefinition) { + log.tracef( + "%s Starting attribute %s", + StringHelper.repeat( ">>", fetchOwnerStack.size() ), + attributeDefinition + ); + final Type attributeType = attributeDefinition.getType(); final boolean isComponentType = attributeType.isComponentType(); @@ -136,30 +360,26 @@ public boolean startingAttribute(AttributeDefinition attributeDefinition) { return true; } else if ( isComponentType ) { - return handleCompositeAttribute( (CompositeDefinition) attributeDefinition ); + return handleCompositeAttribute( (CompositionDefinition) attributeDefinition ); } else { return handleAssociationAttribute( (AssociationAttributeDefinition) attributeDefinition ); } } - @Override public void finishingAttribute(AttributeDefinition attributeDefinition) { - final Type attributeType = attributeDefinition.getType(); - - final boolean isComponentType = attributeType.isComponentType(); - final boolean isBasicType = ! ( isComponentType || attributeType.isAssociationType() ); - - if ( ! isBasicType ) { - fetchOwnerStack.removeLast(); - } + log.tracef( + "%s Finishing up attribute : %s", + StringHelper.repeat( "<<", fetchOwnerStack.size() ), + attributeDefinition + ); } - protected boolean handleCompositeAttribute(CompositeDefinition attributeDefinition) { - final FetchOwner fetchOwner = fetchOwnerStack.peekLast(); - final CompositeFetch fetch = buildCompositeFetch( fetchOwner, attributeDefinition ); - fetchOwnerStack.addLast( fetch ); + protected boolean handleCompositeAttribute(CompositionDefinition attributeDefinition) { + final FetchOwner fetchOwner = currentFetchOwner(); + final CompositeFetch fetch = fetchOwner.buildCompositeFetch( attributeDefinition, this ); + pushToStack( fetch ); return true; } @@ -169,17 +389,20 @@ protected boolean handleAssociationAttribute(AssociationAttributeDefinition attr return false; } - final FetchOwner fetchOwner = fetchOwnerStack.peekLast(); + final FetchOwner fetchOwner = currentFetchOwner(); fetchOwner.validateFetchPlan( fetchStrategy ); final Fetch associationFetch; if ( attributeDefinition.isCollection() ) { - associationFetch = buildCollectionFetch( fetchOwner, attributeDefinition, fetchStrategy ); + associationFetch = fetchOwner.buildCollectionFetch( attributeDefinition, fetchStrategy, this ); } else { - associationFetch = buildEntityFetch( fetchOwner, attributeDefinition, fetchStrategy ); + associationFetch = fetchOwner.buildEntityFetch( attributeDefinition, fetchStrategy, this ); + } + + if ( FetchOwner.class.isInstance( associationFetch ) ) { + pushToStack( (FetchOwner) associationFetch ); } - fetchOwnerStack.addLast( associationFetch ); return true; } @@ -194,19 +417,309 @@ protected boolean isTooManyCollections() { return false; } + private void pushToStack(FetchOwner fetchOwner) { + log.trace( "Pushing fetch owner to stack : " + fetchOwner ); + fetchOwnerStack.addFirst( fetchOwner ); + } + + private FetchOwner popFromStack() { + final FetchOwner last = fetchOwnerStack.removeFirst(); + log.trace( "Popped fetch owner from stack : " + last ); + if ( FetchStackAware.class.isInstance( last ) ) { + ( (FetchStackAware) last ).poppedFromStack(); + } + return last; + } + + private void pushToCollectionStack(CollectionReference collectionReference) { + log.trace( "Pushing collection reference to stack : " + collectionReference ); + collectionReferenceStack.addFirst( collectionReference ); + } + + private CollectionReference popFromCollectionStack() { + final CollectionReference last = collectionReferenceStack.removeFirst(); + log.trace( "Popped collection reference from stack : " + last ); + if ( FetchStackAware.class.isInstance( last ) ) { + ( (FetchStackAware) last ).poppedFromStack(); + } + return last; + } + protected abstract EntityReturn buildRootEntityReturn(EntityDefinition entityDefinition); protected abstract CollectionReturn buildRootCollectionReturn(CollectionDefinition collectionDefinition); - protected abstract CollectionFetch buildCollectionFetch( - FetchOwner fetchOwner, - AssociationAttributeDefinition attributeDefinition, - FetchStrategy fetchStrategy); - protected abstract EntityFetch buildEntityFetch( - FetchOwner fetchOwner, - AssociationAttributeDefinition attributeDefinition, - FetchStrategy fetchStrategy); - protected abstract CompositeFetch buildCompositeFetch(FetchOwner fetchOwner, CompositeDefinition attributeDefinition); + // LoadPlanBuildingContext impl ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + private int currentSuffixBase; + private int implicitAliasUniqueness = 0; + + private String createImplicitAlias() { + return "ia" + implicitAliasUniqueness++; + } + + @Override + public SessionFactoryImplementor getSessionFactory() { + return sessionFactory(); + } + + @Override + public EntityAliases resolveEntityColumnAliases(AssociationAttributeDefinition attributeDefinition) { + return generateEntityColumnAliases( attributeDefinition.toEntityDefinition().getEntityPersister() ); + } + + protected EntityAliases generateEntityColumnAliases(EntityPersister persister) { + return new DefaultEntityAliases( (Loadable) persister, Integer.toString( currentSuffixBase++ ) + '_' ); + } + + @Override + public CollectionAliases resolveCollectionColumnAliases(AssociationAttributeDefinition attributeDefinition) { + return generateCollectionColumnAliases( attributeDefinition.toCollectionDefinition().getCollectionPersister() ); + } + + protected CollectionAliases generateCollectionColumnAliases(CollectionPersister persister) { + return new GeneratedCollectionAliases( persister, Integer.toString( currentSuffixBase++ ) + '_' ); + } + + @Override + public String resolveRootSourceAlias(EntityDefinition definition) { + return createImplicitAlias(); + } + + @Override + public String resolveRootSourceAlias(CollectionDefinition definition) { + return createImplicitAlias(); + } + + @Override + public String resolveFetchSourceAlias(AssociationAttributeDefinition attributeDefinition) { + return createImplicitAlias(); + } + + @Override + public String resolveFetchSourceAlias(CompositionDefinition compositionDefinition) { + return createImplicitAlias(); + } + + public static interface FetchStackAware { + public void poppedFromStack(); + } + + protected static abstract class AbstractIdentifierAttributeCollector + implements FetchOwner, EntityReference, FetchStackAware { + + protected final EntityReference entityReference; + private final PropertyPath propertyPath; + + protected final List identifierFetches = new ArrayList(); + protected final Map fetchToHydratedStateExtractorMap + = new HashMap(); + + public AbstractIdentifierAttributeCollector(EntityReference entityReference) { + this.entityReference = entityReference; + this.propertyPath = ( (FetchOwner) entityReference ).getPropertyPath().append( "" ); + } + + @Override + public String getAlias() { + return entityReference.getAlias(); + } + + @Override + public LockMode getLockMode() { + return entityReference.getLockMode(); + } + + @Override + public EntityPersister getEntityPersister() { + return entityReference.getEntityPersister(); + } + + @Override + public IdentifierDescription getIdentifierDescription() { + return entityReference.getIdentifierDescription(); + } + + @Override + public CollectionFetch buildCollectionFetch( + AssociationAttributeDefinition attributeDefinition, + FetchStrategy fetchStrategy, + LoadPlanBuildingContext loadPlanBuildingContext) { + throw new WalkingException( "Entity identifier cannot contain persistent collections" ); + } + + @Override + public EntityFetch buildEntityFetch( + AssociationAttributeDefinition attributeDefinition, + FetchStrategy fetchStrategy, + LoadPlanBuildingContext loadPlanBuildingContext) { + // we have a key-many-to-one + // + // IMPL NOTE: we pass ourselves as the FetchOwner which will route the fetch back throw our #addFetch + // impl. We collect them there and later build the IdentifierDescription + final EntityFetch fetch = LoadPlanBuildingHelper.buildStandardEntityFetch( + this, + attributeDefinition, + fetchStrategy, + loadPlanBuildingContext + ); + fetchToHydratedStateExtractorMap.put( fetch, attributeDefinition.getHydratedCompoundValueExtractor() ); + + return fetch; + } + + @Override + public CompositeFetch buildCompositeFetch( + CompositionDefinition attributeDefinition, LoadPlanBuildingContext loadPlanBuildingContext) { + // nested composition. Unusual, but not disallowed. + // + // IMPL NOTE: we pass ourselves as the FetchOwner which will route the fetch back throw our #addFetch + // impl. We collect them there and later build the IdentifierDescription + return LoadPlanBuildingHelper.buildStandardCompositeFetch( + this, + attributeDefinition, + loadPlanBuildingContext + ); + } + + @Override + public void poppedFromStack() { + final IdentifierDescription identifierDescription = buildIdentifierDescription(); + entityReference.injectIdentifierDescription( identifierDescription ); + } + + protected abstract IdentifierDescription buildIdentifierDescription(); + + @Override + public void addFetch(Fetch fetch) { + identifierFetches.add( (EntityFetch) fetch ); + } + + @Override + public Fetch[] getFetches() { + return ( (FetchOwner) entityReference ).getFetches(); + } + + @Override + public void validateFetchPlan(FetchStrategy fetchStrategy) { + ( (FetchOwner) entityReference ).validateFetchPlan( fetchStrategy ); + } + + @Override + public EntityPersister retrieveFetchSourcePersister() { + return ( (FetchOwner) entityReference ).retrieveFetchSourcePersister(); + } + + @Override + public PropertyPath getPropertyPath() { + return propertyPath; + } + + @Override + public void injectIdentifierDescription(IdentifierDescription identifierDescription) { + throw new WalkingException( + "IdentifierDescription collector should not get injected with IdentifierDescription" + ); + } + } + + protected static class EncapsulatedIdentifierAttributeCollector extends AbstractIdentifierAttributeCollector { + public EncapsulatedIdentifierAttributeCollector(EntityReference entityReference) { + super( entityReference ); + } + + @Override + protected IdentifierDescription buildIdentifierDescription() { + return new IdentifierDescriptionImpl( + entityReference, + identifierFetches.toArray( new EntityFetch[ identifierFetches.size() ] ), + null + ); + } + } + + protected static class NonEncapsulatedIdentifierAttributeCollector extends AbstractIdentifierAttributeCollector { + public NonEncapsulatedIdentifierAttributeCollector(EntityReference entityReference) { + super( entityReference ); + } + + @Override + protected IdentifierDescription buildIdentifierDescription() { + return new IdentifierDescriptionImpl( + entityReference, + identifierFetches.toArray( new EntityFetch[ identifierFetches.size() ] ), + fetchToHydratedStateExtractorMap + ); + } + } + + private static class IdentifierDescriptionImpl implements IdentifierDescription { + private final EntityReference entityReference; + private final EntityFetch[] identifierFetches; + private final Map fetchToHydratedStateExtractorMap; + + private IdentifierDescriptionImpl( + EntityReference entityReference, EntityFetch[] identifierFetches, + Map fetchToHydratedStateExtractorMap) { + this.entityReference = entityReference; + this.identifierFetches = identifierFetches; + this.fetchToHydratedStateExtractorMap = fetchToHydratedStateExtractorMap; + } + + @Override + public Fetch[] getFetches() { + return identifierFetches; + } + + @Override + public void hydrate(ResultSet resultSet, ResultSetProcessingContext context) throws SQLException { + final IdentifierResolutionContext ownerIdentifierResolutionContext = + context.getIdentifierResolutionContext( entityReference ); + final Serializable ownerIdentifierHydratedState = ownerIdentifierResolutionContext.getHydratedForm(); + + for ( EntityFetch fetch : identifierFetches ) { + final IdentifierResolutionContext identifierResolutionContext = + context.getIdentifierResolutionContext( fetch ); + // if the identifier was already hydrated, nothing to do + if ( identifierResolutionContext.getHydratedForm() != null ) { + continue; + } + + // try to extract the sub-hydrated value from the owners tuple array + if ( fetchToHydratedStateExtractorMap != null && ownerIdentifierHydratedState != null ) { + Serializable extracted = (Serializable) fetchToHydratedStateExtractorMap.get( fetch ) + .extract( ownerIdentifierHydratedState ); + identifierResolutionContext.registerHydratedForm( extracted ); + continue; + } + + // if we can't, then read from result set + fetch.hydrate( resultSet, context ); + } + } + + @Override + public EntityKey resolve(ResultSet resultSet, ResultSetProcessingContext context) throws SQLException { + for ( EntityFetch fetch : identifierFetches ) { + final IdentifierResolutionContext identifierResolutionContext = + context.getIdentifierResolutionContext( fetch ); + if ( identifierResolutionContext.getEntityKey() != null ) { + continue; + } + + EntityKey fetchKey = fetch.resolveInIdentifier( resultSet, context ); + identifierResolutionContext.registerEntityKey( fetchKey ); + } + + final IdentifierResolutionContext ownerIdentifierResolutionContext = + context.getIdentifierResolutionContext( entityReference ); + Serializable hydratedState = ownerIdentifierResolutionContext.getHydratedForm(); + Serializable resolvedId = (Serializable) entityReference.getEntityPersister() + .getIdentifierType() + .resolve( hydratedState, context.getSession(), null ); + return context.getSession().generateEntityKey( resolvedId, entityReference.getEntityPersister() ); + } + } } diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/CollectionFetch.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/CollectionFetch.java index 973d147795..b5ad2e9e04 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/CollectionFetch.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/CollectionFetch.java @@ -23,58 +23,75 @@ */ package org.hibernate.loader.plan.spi; +import java.sql.ResultSet; +import java.sql.SQLException; + import org.hibernate.LockMode; import org.hibernate.engine.FetchStrategy; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.loader.CollectionAliases; import org.hibernate.loader.EntityAliases; -import org.hibernate.persister.collection.CollectionPersister; -import org.hibernate.persister.collection.QueryableCollection; -import org.hibernate.persister.entity.EntityPersister; +import org.hibernate.loader.PropertyPath; +import org.hibernate.loader.spi.ResultSetProcessingContext; /** * @author Steve Ebersole */ -public class CollectionFetch extends AbstractFetch implements CollectionReference { - private final CollectionAliases collectionAliases; - private final EntityAliases elementEntityAliases; - - private final CollectionPersister persister; +public class CollectionFetch extends AbstractCollectionReference implements CollectionReference, Fetch { + private final FetchOwner fetchOwner; + private final FetchStrategy fetchStrategy; public CollectionFetch( SessionFactoryImplementor sessionFactory, String alias, LockMode lockMode, - AbstractFetchOwner owner, + FetchOwner fetchOwner, FetchStrategy fetchStrategy, String ownerProperty, CollectionAliases collectionAliases, EntityAliases elementEntityAliases) { - super( sessionFactory, alias, lockMode, owner, ownerProperty, fetchStrategy ); - this.collectionAliases = collectionAliases; - this.elementEntityAliases = elementEntityAliases; - - final String role = owner.retrieveFetchSourcePersister().getEntityName() + '.' + getOwnerPropertyName(); - this.persister = sessionFactory.getCollectionPersister( role ); + super( + sessionFactory, + alias, + lockMode, + sessionFactory.getCollectionPersister( + fetchOwner.retrieveFetchSourcePersister().getEntityName() + '.' + ownerProperty + ), + fetchOwner.getPropertyPath().append( ownerProperty ), + collectionAliases, + elementEntityAliases + ); + this.fetchOwner = fetchOwner; + this.fetchStrategy = fetchStrategy; } @Override - public CollectionAliases getCollectionAliases() { - return collectionAliases; + public FetchOwner getOwner() { + return fetchOwner; } @Override - public EntityAliases getElementEntityAliases() { - return elementEntityAliases; + public String getOwnerPropertyName() { + return getPropertyPath().getProperty(); } @Override - public CollectionPersister getCollectionPersister() { - return persister; + public FetchStrategy getFetchStrategy() { + return fetchStrategy; } @Override - public EntityPersister retrieveFetchSourcePersister() { - return ( (QueryableCollection) getCollectionPersister() ).getElementPersister(); + public PropertyPath getPropertyPath() { + return propertyPath(); + } + + @Override + public void hydrate(ResultSet resultSet, ResultSetProcessingContext context) throws SQLException { + //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + public Object resolve(ResultSet resultSet, ResultSetProcessingContext context) throws SQLException { + return null; //To change body of implemented methods use File | Settings | File Templates. } } diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/CollectionReference.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/CollectionReference.java index fa0460e922..da4acdcbb3 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/CollectionReference.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/CollectionReference.java @@ -55,6 +55,12 @@ public interface CollectionReference { */ public CollectionPersister getCollectionPersister(); + public FetchOwner getIndexGraph(); + + public FetchOwner getElementGraph(); + + public boolean hasEntityElements(); + /** * Returns the description of the aliases in the JDBC ResultSet that identify values "belonging" to the * this collection. diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/CollectionReferenceImplementor.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/CollectionReferenceImplementor.java new file mode 100644 index 0000000000..1738802aef --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/CollectionReferenceImplementor.java @@ -0,0 +1,30 @@ +/* + * 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.loader.plan.spi; + +/** + * @author Steve Ebersole + */ +public interface CollectionReferenceImplementor { +} diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/CollectionReturn.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/CollectionReturn.java index 0dacc39806..5bb106c0af 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/CollectionReturn.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/CollectionReturn.java @@ -23,28 +23,22 @@ */ package org.hibernate.loader.plan.spi; +import java.sql.ResultSet; +import java.sql.SQLException; + import org.hibernate.LockMode; -import org.hibernate.engine.FetchStrategy; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.loader.CollectionAliases; import org.hibernate.loader.EntityAliases; import org.hibernate.loader.PropertyPath; -import org.hibernate.persister.collection.CollectionPersister; -import org.hibernate.persister.collection.QueryableCollection; -import org.hibernate.persister.entity.EntityPersister; +import org.hibernate.loader.spi.ResultSetProcessingContext; /** * @author Steve Ebersole */ -public class CollectionReturn extends AbstractFetchOwner implements Return, FetchOwner, CollectionReference { +public class CollectionReturn extends AbstractCollectionReference implements Return, CollectionReference { private final String ownerEntityName; private final String ownerProperty; - private final CollectionAliases collectionAliases; - private final EntityAliases elementEntityAliases; - - private final CollectionPersister persister; - - private final PropertyPath propertyPath = new PropertyPath(); // its a root public CollectionReturn( SessionFactoryImplementor sessionFactory, @@ -54,14 +48,17 @@ public CollectionReturn( String ownerProperty, CollectionAliases collectionAliases, EntityAliases elementEntityAliases) { - super( sessionFactory, alias, lockMode ); + super( + sessionFactory, + alias, + lockMode, + sessionFactory.getCollectionPersister( ownerEntityName + '.' + ownerProperty ), + new PropertyPath(), // its a root + collectionAliases, + elementEntityAliases + ); this.ownerEntityName = ownerEntityName; this.ownerProperty = ownerProperty; - this.collectionAliases = collectionAliases; - this.elementEntityAliases = elementEntityAliases; - - final String role = ownerEntityName + '.' + ownerProperty; - this.persister = sessionFactory.getCollectionPersister( role ); } /** @@ -83,31 +80,22 @@ public String getOwnerProperty() { } @Override - public CollectionAliases getCollectionAliases() { - return collectionAliases; + public void hydrate(ResultSet resultSet, ResultSetProcessingContext context) throws SQLException { + // todo : anything to do here? } @Override - public EntityAliases getElementEntityAliases() { - return elementEntityAliases; + public void resolve(ResultSet resultSet, ResultSetProcessingContext context) throws SQLException { + // todo : anything to do here? } @Override - public CollectionPersister getCollectionPersister() { - return persister; + public Object read(ResultSet resultSet, ResultSetProcessingContext context) throws SQLException { + return null; //To change body of implemented methods use File | Settings | File Templates. } @Override - public void validateFetchPlan(FetchStrategy fetchStrategy) { - } - - @Override - public EntityPersister retrieveFetchSourcePersister() { - return ( (QueryableCollection) persister ).getElementPersister(); - } - - @Override - public PropertyPath getPropertyPath() { - return propertyPath; + public String toString() { + return "CollectionReturn(" + getCollectionPersister().getRole() + ")"; } } diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/CompositeElementGraph.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/CompositeElementGraph.java new file mode 100644 index 0000000000..c1c450793b --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/CompositeElementGraph.java @@ -0,0 +1,90 @@ +package org.hibernate.loader.plan.spi; + +import java.util.ArrayList; +import java.util.List; + +import org.hibernate.HibernateException; +import org.hibernate.engine.FetchStrategy; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.loader.PropertyPath; +import org.hibernate.loader.plan.internal.LoadPlanBuildingHelper; +import org.hibernate.persister.collection.CollectionPersister; +import org.hibernate.persister.entity.EntityPersister; +import org.hibernate.persister.walking.spi.AssociationAttributeDefinition; +import org.hibernate.persister.walking.spi.CompositionDefinition; + +/** + * @author Steve Ebersole + */ +public class CompositeElementGraph extends AbstractPlanNode implements FetchOwner { + private final CollectionReference collectionReference; + private final PropertyPath propertyPath; + private final CollectionPersister collectionPersister; + + private List fetches; + public CompositeElementGraph( + SessionFactoryImplementor sessionFactory, + CollectionReference collectionReference, + PropertyPath collectionPath) { + super( sessionFactory ); + + this.collectionReference = collectionReference; + this.collectionPersister = collectionReference.getCollectionPersister(); + this.propertyPath = collectionPath.append( "" ); + } + + @Override + public void addFetch(Fetch fetch) { + if ( fetches == null ) { + fetches = new ArrayList(); + } + fetches.add( fetch ); + } + + @Override + public Fetch[] getFetches() { + return fetches == null ? NO_FETCHES : fetches.toArray( new Fetch[ fetches.size() ] ); + } + + @Override + public void validateFetchPlan(FetchStrategy fetchStrategy) { + } + + @Override + public EntityPersister retrieveFetchSourcePersister() { + return collectionPersister.getOwnerEntityPersister(); + } + + @Override + public PropertyPath getPropertyPath() { + return propertyPath; + } + + @Override + public CollectionFetch buildCollectionFetch( + AssociationAttributeDefinition attributeDefinition, + FetchStrategy fetchStrategy, + LoadPlanBuildingContext loadPlanBuildingContext) { + throw new HibernateException( "Collection composite element cannot define collections" ); + } + + @Override + public EntityFetch buildEntityFetch( + AssociationAttributeDefinition attributeDefinition, + FetchStrategy fetchStrategy, + LoadPlanBuildingContext loadPlanBuildingContext) { + return LoadPlanBuildingHelper.buildStandardEntityFetch( + this, + attributeDefinition, + fetchStrategy, + loadPlanBuildingContext + ); + } + + @Override + public CompositeFetch buildCompositeFetch( + CompositionDefinition attributeDefinition, + LoadPlanBuildingContext loadPlanBuildingContext) { + return LoadPlanBuildingHelper.buildStandardCompositeFetch( this, attributeDefinition, loadPlanBuildingContext ); + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/CompositeFetch.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/CompositeFetch.java index 48d2f4c415..77eb3ebd2f 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/CompositeFetch.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/CompositeFetch.java @@ -23,12 +23,18 @@ */ package org.hibernate.loader.plan.spi; +import java.sql.ResultSet; +import java.sql.SQLException; + import org.hibernate.LockMode; import org.hibernate.engine.FetchStrategy; import org.hibernate.engine.FetchStyle; import org.hibernate.engine.FetchTiming; import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.loader.spi.ResultSetProcessingContext; import org.hibernate.persister.entity.EntityPersister; +import org.hibernate.persister.walking.spi.AssociationAttributeDefinition; +import org.hibernate.persister.walking.spi.CompositionDefinition; /** * @author Steve Ebersole @@ -48,4 +54,36 @@ public CompositeFetch( public EntityPersister retrieveFetchSourcePersister() { return getOwner().retrieveFetchSourcePersister(); } + + @Override + public CollectionFetch buildCollectionFetch( + AssociationAttributeDefinition attributeDefinition, + FetchStrategy fetchStrategy, + LoadPlanBuildingContext loadPlanBuildingContext) { + return null; //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + public EntityFetch buildEntityFetch( + AssociationAttributeDefinition attributeDefinition, + FetchStrategy fetchStrategy, + LoadPlanBuildingContext loadPlanBuildingContext) { + return null; //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + public CompositeFetch buildCompositeFetch( + CompositionDefinition attributeDefinition, LoadPlanBuildingContext loadPlanBuildingContext) { + return null; //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + public void hydrate(ResultSet resultSet, ResultSetProcessingContext context) throws SQLException { + //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + public Object resolve(ResultSet resultSet, ResultSetProcessingContext context) throws SQLException { + return null; //To change body of implemented methods use File | Settings | File Templates. + } } diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/CompositeIndexGraph.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/CompositeIndexGraph.java new file mode 100644 index 0000000000..8b482ac2e1 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/CompositeIndexGraph.java @@ -0,0 +1,90 @@ +package org.hibernate.loader.plan.spi; + +import java.util.ArrayList; +import java.util.List; + +import org.hibernate.HibernateException; +import org.hibernate.engine.FetchStrategy; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.loader.PropertyPath; +import org.hibernate.loader.plan.internal.LoadPlanBuildingHelper; +import org.hibernate.persister.collection.CollectionPersister; +import org.hibernate.persister.entity.EntityPersister; +import org.hibernate.persister.walking.spi.AssociationAttributeDefinition; +import org.hibernate.persister.walking.spi.CompositionDefinition; + +/** + * @author Steve Ebersole + */ +public class CompositeIndexGraph extends AbstractPlanNode implements FetchOwner { + private final CollectionReference collectionReference; + private final PropertyPath propertyPath; + private final CollectionPersister collectionPersister; + + private List fetches; + + public CompositeIndexGraph( + SessionFactoryImplementor sessionFactory, + CollectionReference collectionReference, + PropertyPath propertyPath) { + super( sessionFactory ); + this.collectionReference = collectionReference; + this.collectionPersister = collectionReference.getCollectionPersister(); + this.propertyPath = propertyPath.append( "" ); + } + + @Override + public void addFetch(Fetch fetch) { + if ( fetches == null ) { + fetches = new ArrayList(); + } + fetches.add( fetch ); + } + + @Override + public Fetch[] getFetches() { + return fetches == null ? NO_FETCHES : fetches.toArray( new Fetch[ fetches.size() ] ); + } + + @Override + public void validateFetchPlan(FetchStrategy fetchStrategy) { + } + + @Override + public EntityPersister retrieveFetchSourcePersister() { + return collectionPersister.getOwnerEntityPersister(); + } + + @Override + public PropertyPath getPropertyPath() { + return propertyPath; + } + + @Override + public CollectionFetch buildCollectionFetch( + AssociationAttributeDefinition attributeDefinition, + FetchStrategy fetchStrategy, + LoadPlanBuildingContext loadPlanBuildingContext) { + throw new HibernateException( "Composite index cannot define collections" ); + } + + @Override + public EntityFetch buildEntityFetch( + AssociationAttributeDefinition attributeDefinition, + FetchStrategy fetchStrategy, + LoadPlanBuildingContext loadPlanBuildingContext) { + return LoadPlanBuildingHelper.buildStandardEntityFetch( + this, + attributeDefinition, + fetchStrategy, + loadPlanBuildingContext + ); + } + + @Override + public CompositeFetch buildCompositeFetch( + CompositionDefinition attributeDefinition, + LoadPlanBuildingContext loadPlanBuildingContext) { + return LoadPlanBuildingHelper.buildStandardCompositeFetch( this, attributeDefinition, loadPlanBuildingContext ); + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/EntityElementGraph.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/EntityElementGraph.java new file mode 100644 index 0000000000..b7da167727 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/EntityElementGraph.java @@ -0,0 +1,133 @@ +package org.hibernate.loader.plan.spi; + +import java.util.ArrayList; +import java.util.List; + +import org.hibernate.LockMode; +import org.hibernate.engine.FetchStrategy; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.loader.PropertyPath; +import org.hibernate.loader.plan.internal.LoadPlanBuildingHelper; +import org.hibernate.persister.collection.CollectionPersister; +import org.hibernate.persister.entity.EntityPersister; +import org.hibernate.persister.walking.spi.AssociationAttributeDefinition; +import org.hibernate.persister.walking.spi.CompositionDefinition; +import org.hibernate.type.AssociationType; + +/** + * @author Steve Ebersole + */ +public class EntityElementGraph extends AbstractPlanNode implements FetchOwner, EntityReference { + private final CollectionReference collectionReference; + private final CollectionPersister collectionPersister; + private final AssociationType elementType; + private final EntityPersister elementPersister; + private final PropertyPath propertyPath; + + private List fetches; + + private IdentifierDescription identifierDescription; + + public EntityElementGraph( + SessionFactoryImplementor sessionFactory, + CollectionReference collectionReference, + PropertyPath collectionPath) { + super( sessionFactory ); + + this.collectionReference = collectionReference; + this.collectionPersister = collectionReference.getCollectionPersister(); + this.elementType = (AssociationType) collectionPersister.getElementType(); + this.elementPersister = (EntityPersister) this.elementType.getAssociatedJoinable( sessionFactory() ); + this.propertyPath = collectionPath.append( "" ); + } + + @Override + public String getAlias() { + return null; + } + + @Override + public LockMode getLockMode() { + return null; + } + + @Override + public EntityPersister getEntityPersister() { + return elementPersister; + } + + @Override + public IdentifierDescription getIdentifierDescription() { + return identifierDescription; + } + + @Override + public void addFetch(Fetch fetch) { + if ( fetches == null ) { + fetches = new ArrayList(); + } + fetches.add( fetch ); + } + + @Override + public Fetch[] getFetches() { + return fetches == null ? NO_FETCHES : fetches.toArray( new Fetch[ fetches.size() ] ); + } + + @Override + public void validateFetchPlan(FetchStrategy fetchStrategy) { + } + + @Override + public EntityPersister retrieveFetchSourcePersister() { + return elementPersister; + } + + @Override + public PropertyPath getPropertyPath() { + return propertyPath; + } + + @Override + public CollectionFetch buildCollectionFetch( + AssociationAttributeDefinition attributeDefinition, + FetchStrategy fetchStrategy, + LoadPlanBuildingContext loadPlanBuildingContext) { + return LoadPlanBuildingHelper.buildStandardCollectionFetch( + this, + attributeDefinition, + fetchStrategy, + loadPlanBuildingContext + ); + } + + @Override + public EntityFetch buildEntityFetch( + AssociationAttributeDefinition attributeDefinition, + FetchStrategy fetchStrategy, + LoadPlanBuildingContext loadPlanBuildingContext) { + return LoadPlanBuildingHelper.buildStandardEntityFetch( + this, + attributeDefinition, + fetchStrategy, + loadPlanBuildingContext + ); + } + + @Override + public CompositeFetch buildCompositeFetch( + CompositionDefinition attributeDefinition, + LoadPlanBuildingContext loadPlanBuildingContext) { + return LoadPlanBuildingHelper.buildStandardCompositeFetch( this, attributeDefinition, loadPlanBuildingContext ); + } + + @Override + public void injectIdentifierDescription(IdentifierDescription identifierDescription) { + this.identifierDescription = identifierDescription; + } + + @Override + public String toString() { + return "EntityElementGraph(collection=" + collectionPersister.getRole() + ", type=" + elementPersister.getEntityName() + ")"; + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/EntityFetch.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/EntityFetch.java index 252e3e0288..dac6350468 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/EntityFetch.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/EntityFetch.java @@ -23,27 +23,40 @@ */ package org.hibernate.loader.plan.spi; +import java.sql.ResultSet; +import java.sql.SQLException; + import org.hibernate.LockMode; +import org.hibernate.WrongClassException; import org.hibernate.engine.FetchStrategy; +import org.hibernate.engine.FetchTiming; +import org.hibernate.engine.spi.EntityKey; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.loader.EntityAliases; +import org.hibernate.loader.plan.internal.LoadPlanBuildingHelper; +import org.hibernate.loader.spi.ResultSetProcessingContext; import org.hibernate.persister.entity.EntityPersister; +import org.hibernate.persister.walking.spi.AssociationAttributeDefinition; +import org.hibernate.persister.walking.spi.CompositionDefinition; import org.hibernate.type.EntityType; /** * @author Steve Ebersole */ -public class EntityFetch extends AbstractFetch implements EntityReference { +public class EntityFetch extends AbstractFetch implements EntityReference, FetchOwner { private final String sqlTableAlias; private final EntityAliases entityAliases; + private final EntityType associationType; private final EntityPersister persister; + private IdentifierDescription identifierDescription; + public EntityFetch( SessionFactoryImplementor sessionFactory, String alias, LockMode lockMode, - AbstractFetchOwner owner, + FetchOwner owner, String ownerProperty, FetchStrategy fetchStrategy, String sqlTableAlias, @@ -52,8 +65,8 @@ public EntityFetch( this.sqlTableAlias = sqlTableAlias; this.entityAliases = entityAliases; - final EntityType type = (EntityType) owner.retrieveFetchSourcePersister().getPropertyType( ownerProperty ); - this.persister = sessionFactory.getEntityPersister( type.getAssociatedEntityName() ); + this.associationType = (EntityType) owner.retrieveFetchSourcePersister().getPropertyType( ownerProperty ); + this.persister = sessionFactory.getEntityPersister( associationType.getAssociatedEntityName() ); } @Override @@ -62,17 +75,174 @@ public EntityPersister getEntityPersister() { } @Override - public EntityAliases getEntityAliases() { - return entityAliases; - } - - @Override - public String getSqlTableAlias() { - return sqlTableAlias; + public IdentifierDescription getIdentifierDescription() { + return identifierDescription; } @Override public EntityPersister retrieveFetchSourcePersister() { return persister; } + + + @Override + public CollectionFetch buildCollectionFetch( + AssociationAttributeDefinition attributeDefinition, + FetchStrategy fetchStrategy, + LoadPlanBuildingContext loadPlanBuildingContext) { + return LoadPlanBuildingHelper.buildStandardCollectionFetch( + this, + attributeDefinition, + fetchStrategy, + loadPlanBuildingContext + ); + } + + @Override + public EntityFetch buildEntityFetch( + AssociationAttributeDefinition attributeDefinition, + FetchStrategy fetchStrategy, + LoadPlanBuildingContext loadPlanBuildingContext) { + return LoadPlanBuildingHelper.buildStandardEntityFetch( + this, + attributeDefinition, + fetchStrategy, + loadPlanBuildingContext + ); + } + + @Override + public CompositeFetch buildCompositeFetch( + CompositionDefinition attributeDefinition, + LoadPlanBuildingContext loadPlanBuildingContext) { + return LoadPlanBuildingHelper.buildStandardCompositeFetch( this, attributeDefinition, loadPlanBuildingContext ); + } + + @Override + public void injectIdentifierDescription(IdentifierDescription identifierDescription) { + this.identifierDescription = identifierDescription; + } + + @Override + public void hydrate(ResultSet resultSet, ResultSetProcessingContext context) throws SQLException { + EntityKey entityKey = context.getDictatedRootEntityKey(); + if ( entityKey != null ) { + context.getIdentifierResolutionContext( this ).registerEntityKey( entityKey ); + return; + } + + identifierDescription.hydrate( resultSet, context ); + + for ( Fetch fetch : getFetches() ) { + fetch.hydrate( resultSet, context ); + } + } + + @Override + public EntityKey resolve(ResultSet resultSet, ResultSetProcessingContext context) throws SQLException { + final ResultSetProcessingContext.IdentifierResolutionContext identifierResolutionContext = context.getIdentifierResolutionContext( this ); + EntityKey entityKey = identifierResolutionContext.getEntityKey(); + if ( entityKey == null ) { + entityKey = identifierDescription.resolve( resultSet, context ); + if ( entityKey == null ) { + // register the non-existence (though only for one-to-one associations) + if ( associationType.isOneToOne() ) { + // first, find our owner's entity-key... + final EntityKey ownersEntityKey = context.getIdentifierResolutionContext( (EntityReference) getOwner() ).getEntityKey(); + if ( ownersEntityKey != null ) { + context.getSession().getPersistenceContext() + .addNullProperty( ownersEntityKey, associationType.getPropertyName() ); + } + } + } + + identifierResolutionContext.registerEntityKey( entityKey ); + + for ( Fetch fetch : getFetches() ) { + fetch.resolve( resultSet, context ); + } + } + + return entityKey; + } + + public EntityKey resolveInIdentifier(ResultSet resultSet, ResultSetProcessingContext context) throws SQLException { + // todo : may not need to do this if entitykey is already part of the resolution context + + final EntityKey entityKey = resolve( resultSet, context ); + + final Object existing = context.getSession().getEntityUsingInterceptor( entityKey ); + + if ( existing != null ) { + if ( !persister.isInstance( existing ) ) { + throw new WrongClassException( + "loaded object was of wrong class " + existing.getClass(), + entityKey.getIdentifier(), + persister.getEntityName() + ); + } + + if ( getLockMode() != null && getLockMode() != LockMode.NONE ) { + final boolean isVersionCheckNeeded = persister.isVersioned() + && context.getSession().getPersistenceContext().getEntry( existing ).getLockMode().lessThan( getLockMode() ); + + // we don't need to worry about existing version being uninitialized because this block isn't called + // by a re-entrant load (re-entrant loads _always_ have lock mode NONE) + if ( isVersionCheckNeeded ) { + //we only check the version when _upgrading_ lock modes + context.checkVersion( + resultSet, + persister, + entityAliases, + entityKey, + existing + ); + //we need to upgrade the lock mode to the mode requested + context.getSession().getPersistenceContext().getEntry( existing ).setLockMode( getLockMode() ); + } + } + } + else { + final String concreteEntityTypeName = context.getConcreteEntityTypeName( + resultSet, + persister, + entityAliases, + entityKey + ); + + final Object entityInstance = context.getSession().instantiate( + concreteEntityTypeName, + entityKey.getIdentifier() + ); + + //need to hydrate it. + + // grab its state from the ResultSet and keep it in the Session + // (but don't yet initialize the object itself) + // note that we acquire LockMode.READ even if it was not requested + LockMode acquiredLockMode = getLockMode() == LockMode.NONE ? LockMode.READ : getLockMode(); + + context.loadFromResultSet( + resultSet, + entityInstance, + concreteEntityTypeName, + entityKey, + entityAliases, + acquiredLockMode, + persister, + getFetchStrategy().getTiming() == FetchTiming.IMMEDIATE, + associationType + ); + + // materialize associations (and initialize the object) later + context.registerHydratedEntity( persister, entityKey, entityInstance ); + } + + return entityKey; + } + + @Override + public String toString() { + return "EntityFetch(" + getPropertyPath().getFullPath() + " -> " + persister.getEntityName() + ")"; + } } diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/EntityIndexGraph.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/EntityIndexGraph.java new file mode 100644 index 0000000000..8d7c50de55 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/EntityIndexGraph.java @@ -0,0 +1,150 @@ +/* + * 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.loader.plan.spi; + +import java.util.ArrayList; +import java.util.List; + +import org.hibernate.LockMode; +import org.hibernate.engine.FetchStrategy; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.loader.PropertyPath; +import org.hibernate.loader.plan.internal.LoadPlanBuildingHelper; +import org.hibernate.persister.collection.CollectionPersister; +import org.hibernate.persister.entity.EntityPersister; +import org.hibernate.persister.walking.spi.AssociationAttributeDefinition; +import org.hibernate.persister.walking.spi.CompositionDefinition; +import org.hibernate.type.AssociationType; + +/** + * @author Steve Ebersole + */ +public class EntityIndexGraph extends AbstractPlanNode implements FetchOwner, EntityReference { + private final CollectionReference collectionReference; + private final CollectionPersister collectionPersister; + private final AssociationType indexType; + private final EntityPersister indexPersister; + private final PropertyPath propertyPath; + + private List fetches; + + private IdentifierDescription identifierDescription; + + public EntityIndexGraph( + SessionFactoryImplementor sessionFactory, + CollectionReference collectionReference, + PropertyPath collectionPath) { + super( sessionFactory ); + this.collectionReference = collectionReference; + this.collectionPersister = collectionReference.getCollectionPersister(); + this.indexType = (AssociationType) collectionPersister.getIndexType(); + this.indexPersister = (EntityPersister) this.indexType.getAssociatedJoinable( sessionFactory() ); + this.propertyPath = collectionPath.append( "" ); // todo : do we want the part? + } + + @Override + public String getAlias() { + return null; + } + + @Override + public LockMode getLockMode() { + return null; + } + + @Override + public EntityPersister getEntityPersister() { + return indexPersister; + } + + @Override + public IdentifierDescription getIdentifierDescription() { + return identifierDescription; + } + + @Override + public void addFetch(Fetch fetch) { + if ( fetches == null ) { + fetches = new ArrayList(); + } + fetches.add( fetch ); + } + + @Override + public Fetch[] getFetches() { + return fetches == null ? NO_FETCHES : fetches.toArray( new Fetch[ fetches.size() ] ); + } + + @Override + public void validateFetchPlan(FetchStrategy fetchStrategy) { + } + + @Override + public EntityPersister retrieveFetchSourcePersister() { + return indexPersister; + } + + @Override + public PropertyPath getPropertyPath() { + return propertyPath; + } + + @Override + public CollectionFetch buildCollectionFetch( + AssociationAttributeDefinition attributeDefinition, + FetchStrategy fetchStrategy, + LoadPlanBuildingContext loadPlanBuildingContext) { + return LoadPlanBuildingHelper.buildStandardCollectionFetch( + this, + attributeDefinition, + fetchStrategy, + loadPlanBuildingContext + ); + } + + @Override + public EntityFetch buildEntityFetch( + AssociationAttributeDefinition attributeDefinition, + FetchStrategy fetchStrategy, + LoadPlanBuildingContext loadPlanBuildingContext) { + return LoadPlanBuildingHelper.buildStandardEntityFetch( + this, + attributeDefinition, + fetchStrategy, + loadPlanBuildingContext + ); + } + + @Override + public CompositeFetch buildCompositeFetch( + CompositionDefinition attributeDefinition, + LoadPlanBuildingContext loadPlanBuildingContext) { + return LoadPlanBuildingHelper.buildStandardCompositeFetch( this, attributeDefinition, loadPlanBuildingContext ); + } + + @Override + public void injectIdentifierDescription(IdentifierDescription identifierDescription) { + this.identifierDescription = identifierDescription; + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/EntityReference.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/EntityReference.java index d1102acc7b..401a478eed 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/EntityReference.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/EntityReference.java @@ -24,7 +24,6 @@ package org.hibernate.loader.plan.spi; import org.hibernate.LockMode; -import org.hibernate.loader.EntityAliases; import org.hibernate.persister.entity.EntityPersister; /** @@ -32,7 +31,7 @@ * * @author Steve Ebersole */ -public interface EntityReference { +public interface EntityReference extends IdentifierDescriptionInjectable { /** * Retrieve the alias associated with the persister (entity/collection). * @@ -54,20 +53,5 @@ public interface EntityReference { */ public EntityPersister getEntityPersister(); - /** - * Returns the description of the aliases in the JDBC ResultSet that identify values "belonging" to the this entity. - * - * @return The ResultSet alias descriptor. - */ - public EntityAliases getEntityAliases(); - - /** - * Obtain the SQL table alias associated with this entity. - * - * TODO : eventually this needs to not be a String, but a representation like I did for the Antlr3 branch - * (AliasRoot, I think it was called) - * - * @return The SQL table alias for this entity - */ - public String getSqlTableAlias(); + public IdentifierDescription getIdentifierDescription(); } diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/EntityReturn.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/EntityReturn.java index eb14ecf297..7ec852d714 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/EntityReturn.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/EntityReturn.java @@ -23,12 +23,25 @@ */ package org.hibernate.loader.plan.spi; +import java.io.Serializable; +import java.sql.ResultSet; +import java.sql.SQLException; + +import org.hibernate.HibernateException; import org.hibernate.LockMode; import org.hibernate.engine.FetchStrategy; +import org.hibernate.engine.spi.EntityKey; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.loader.EntityAliases; import org.hibernate.loader.PropertyPath; +import org.hibernate.loader.internal.ResultSetProcessorHelper; +import org.hibernate.loader.plan.internal.LoadPlanBuildingHelper; +import org.hibernate.loader.spi.ResultSetProcessingContext; import org.hibernate.persister.entity.EntityPersister; +import org.hibernate.persister.walking.spi.AssociationAttributeDefinition; +import org.hibernate.persister.walking.spi.CompositionDefinition; + +import static org.hibernate.loader.spi.ResultSetProcessingContext.IdentifierResolutionContext; /** * @author Steve Ebersole @@ -41,6 +54,8 @@ public class EntityReturn extends AbstractFetchOwner implements Return, FetchOwn private final PropertyPath propertyPath = new PropertyPath(); // its a root + private IdentifierDescription identifierDescription; + public EntityReturn( SessionFactoryImplementor sessionFactory, String alias, @@ -71,13 +86,8 @@ public EntityPersister getEntityPersister() { } @Override - public EntityAliases getEntityAliases() { - return entityAliases; - } - - @Override - public String getSqlTableAlias() { - return sqlTableAlias; + public IdentifierDescription getIdentifierDescription() { + return identifierDescription; } @Override @@ -93,4 +103,83 @@ public EntityPersister retrieveFetchSourcePersister() { public PropertyPath getPropertyPath() { return propertyPath; } + + @Override + public CollectionFetch buildCollectionFetch( + AssociationAttributeDefinition attributeDefinition, + FetchStrategy fetchStrategy, + LoadPlanBuildingContext loadPlanBuildingContext) { + return LoadPlanBuildingHelper.buildStandardCollectionFetch( + this, + attributeDefinition, + fetchStrategy, + loadPlanBuildingContext + ); + } + + @Override + public EntityFetch buildEntityFetch( + AssociationAttributeDefinition attributeDefinition, + FetchStrategy fetchStrategy, + LoadPlanBuildingContext loadPlanBuildingContext) { + return LoadPlanBuildingHelper.buildStandardEntityFetch( + this, + attributeDefinition, + fetchStrategy, + loadPlanBuildingContext + ); + } + + @Override + public CompositeFetch buildCompositeFetch( + CompositionDefinition attributeDefinition, + LoadPlanBuildingContext loadPlanBuildingContext) { + return LoadPlanBuildingHelper.buildStandardCompositeFetch( this, attributeDefinition, loadPlanBuildingContext ); + } + + @Override + public void hydrate(ResultSet resultSet, ResultSetProcessingContext context) throws SQLException { + EntityKey entityKey = context.getDictatedRootEntityKey(); + if ( entityKey != null ) { + context.getIdentifierResolutionContext( this ).registerEntityKey( entityKey ); + return; + } + + identifierDescription.hydrate( resultSet, context ); + + for ( Fetch fetch : getFetches() ) { + fetch.hydrate( resultSet, context ); + } + } + + @Override + public void resolve(ResultSet resultSet, ResultSetProcessingContext context) throws SQLException { + final IdentifierResolutionContext identifierResolutionContext = context.getIdentifierResolutionContext( this ); + EntityKey entityKey = identifierResolutionContext.getEntityKey(); + if ( entityKey == null ) { + return; + } + + entityKey = identifierDescription.resolve( resultSet, context ); + identifierResolutionContext.registerEntityKey( entityKey ); + + for ( Fetch fetch : getFetches() ) { + fetch.resolve( resultSet, context ); + } + } + + @Override + public Object read(ResultSet resultSet, ResultSetProcessingContext context) throws SQLException { + return null; + } + + @Override + public void injectIdentifierDescription(IdentifierDescription identifierDescription) { + this.identifierDescription = identifierDescription; + } + + @Override + public String toString() { + return "EntityReturn(" + persister.getEntityName() + ")"; + } } diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/Fetch.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/Fetch.java index 4be5ca8bbc..7213e18336 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/Fetch.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/Fetch.java @@ -23,8 +23,12 @@ */ package org.hibernate.loader.plan.spi; +import java.sql.ResultSet; +import java.sql.SQLException; + import org.hibernate.engine.FetchStrategy; import org.hibernate.loader.PropertyPath; +import org.hibernate.loader.spi.ResultSetProcessingContext; /** * Contract for associations that are being fetched. @@ -33,7 +37,7 @@ * * @author Steve Ebersole */ -public interface Fetch extends FetchOwner { +public interface Fetch { /** * Obtain the owner of this fetch. * @@ -56,4 +60,8 @@ public interface Fetch extends FetchOwner { * @return The property path */ public PropertyPath getPropertyPath(); + + public void hydrate(ResultSet resultSet, ResultSetProcessingContext context) throws SQLException; + + public Object resolve(ResultSet resultSet, ResultSetProcessingContext context) throws SQLException; } diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/FetchOwner.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/FetchOwner.java index e28daf1b24..a01e88ab2e 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/FetchOwner.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/FetchOwner.java @@ -26,6 +26,8 @@ import org.hibernate.engine.FetchStrategy; import org.hibernate.loader.PropertyPath; import org.hibernate.persister.entity.EntityPersister; +import org.hibernate.persister.walking.spi.AssociationAttributeDefinition; +import org.hibernate.persister.walking.spi.CompositionDefinition; /** * Contract for owners of fetches. Any non-scalar return could be a fetch owner. @@ -38,6 +40,14 @@ public interface FetchOwner { */ public static final Fetch[] NO_FETCHES = new Fetch[0]; + /** + * Contract to add fetches to this owner. Care should be taken in calling this method; it is intended + * for Hibernate usage + * + * @param fetch The fetch to add + */ + public void addFetch(Fetch fetch); + /** * Retrieve the fetches owned by this return. * @@ -65,4 +75,19 @@ public interface FetchOwner { * @return The property path */ public PropertyPath getPropertyPath(); + + public CollectionFetch buildCollectionFetch( + AssociationAttributeDefinition attributeDefinition, + FetchStrategy fetchStrategy, + LoadPlanBuildingContext loadPlanBuildingContext); + + public EntityFetch buildEntityFetch( + AssociationAttributeDefinition attributeDefinition, + FetchStrategy fetchStrategy, + LoadPlanBuildingContext loadPlanBuildingContext); + + public CompositeFetch buildCompositeFetch( + CompositionDefinition attributeDefinition, + LoadPlanBuildingContext loadPlanBuildingContext); + } diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/IdentifierDescription.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/IdentifierDescription.java new file mode 100644 index 0000000000..62d8371196 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/IdentifierDescription.java @@ -0,0 +1,41 @@ +/* + * 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.loader.plan.spi; + +import java.sql.ResultSet; +import java.sql.SQLException; + +import org.hibernate.engine.spi.EntityKey; +import org.hibernate.loader.spi.ResultSetProcessingContext; + +/** + * @author Steve Ebersole + */ +public interface IdentifierDescription { + public Fetch[] getFetches(); + + public void hydrate(ResultSet resultSet, ResultSetProcessingContext context) throws SQLException; + + public EntityKey resolve(ResultSet resultSet, ResultSetProcessingContext context) throws SQLException; +} diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/IdentifierDescriptionInjectable.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/IdentifierDescriptionInjectable.java new file mode 100644 index 0000000000..4528bfa605 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/IdentifierDescriptionInjectable.java @@ -0,0 +1,33 @@ +/* + * 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.loader.plan.spi; + +/** + * Ugh + * + * @author Steve Ebersole + */ +public interface IdentifierDescriptionInjectable { + public void injectIdentifierDescription(IdentifierDescription identifierDescription); +} diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/LoadPlan.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/LoadPlan.java index 0173b39714..035f6c0a84 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/LoadPlan.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/LoadPlan.java @@ -55,6 +55,7 @@ public interface LoadPlan { public List getReturns(); + // todo : would also like to see "call back" style access for handling "subsequent actions" such as: // 1) follow-on locking // 2) join fetch conversions to subselect fetches diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/LoadPlanBuildingContext.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/LoadPlanBuildingContext.java new file mode 100644 index 0000000000..152133f44c --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/LoadPlanBuildingContext.java @@ -0,0 +1,48 @@ +/* + * 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.loader.plan.spi; + +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.loader.CollectionAliases; +import org.hibernate.loader.EntityAliases; +import org.hibernate.persister.walking.spi.AssociationAttributeDefinition; +import org.hibernate.persister.walking.spi.CollectionDefinition; +import org.hibernate.persister.walking.spi.CompositionDefinition; +import org.hibernate.persister.walking.spi.EntityDefinition; + +/** + * @author Steve Ebersole + */ +public interface LoadPlanBuildingContext { + public SessionFactoryImplementor getSessionFactory(); + + public CollectionAliases resolveCollectionColumnAliases(AssociationAttributeDefinition attributeDefinition); + public EntityAliases resolveEntityColumnAliases(AssociationAttributeDefinition attributeDefinition); + + public String resolveRootSourceAlias(EntityDefinition definition); + public String resolveRootSourceAlias(CollectionDefinition definition); + + public String resolveFetchSourceAlias(AssociationAttributeDefinition attributeDefinition); + public String resolveFetchSourceAlias(CompositionDefinition compositionDefinition); +} diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/ReturnVisitationStrategy.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/LoadPlanVisitationStrategy.java similarity index 97% rename from hibernate-core/src/main/java/org/hibernate/loader/plan/spi/ReturnVisitationStrategy.java rename to hibernate-core/src/main/java/org/hibernate/loader/plan/spi/LoadPlanVisitationStrategy.java index 4140249b3a..976177ed33 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/ReturnVisitationStrategy.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/LoadPlanVisitationStrategy.java @@ -26,16 +26,16 @@ /** * @author Steve Ebersole */ -public interface ReturnVisitationStrategy { +public interface LoadPlanVisitationStrategy { /** * Notification we are preparing to start visitation. */ - public void start(); + public void start(LoadPlan loadPlan); /** * Notification we are finished visitation. */ - public void finish(); + public void finish(LoadPlan loadPlan); /** * Notification that a new root return branch is being started. Will be followed by calls to one of the following diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/LoadPlanVisitationStrategyAdapter.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/LoadPlanVisitationStrategyAdapter.java new file mode 100644 index 0000000000..6734ef990c --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/LoadPlanVisitationStrategyAdapter.java @@ -0,0 +1,104 @@ +/* + * 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.loader.plan.spi; + +/** + * @author Steve Ebersole + */ +public class LoadPlanVisitationStrategyAdapter implements LoadPlanVisitationStrategy { + @Override + public void start(LoadPlan loadPlan) { + //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + public void finish(LoadPlan loadPlan) { + //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + public void startingRootReturn(Return rootReturn) { + //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + public void finishingRootReturn(Return rootReturn) { + //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + public void handleScalarReturn(ScalarReturn scalarReturn) { + //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + public void handleEntityReturn(EntityReturn rootEntityReturn) { + //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + public void handleCollectionReturn(CollectionReturn rootCollectionReturn) { + //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + public void startingFetches(FetchOwner fetchOwner) { + //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + public void finishingFetches(FetchOwner fetchOwner) { + //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + public void startingEntityFetch(EntityFetch entityFetch) { + //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + public void finishingEntityFetch(EntityFetch entityFetch) { + //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + public void startingCollectionFetch(CollectionFetch collectionFetch) { + //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + public void finishingCollectionFetch(CollectionFetch collectionFetch) { + //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + public void startingCompositeFetch(CompositeFetch fetch) { + //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + public void finishingCompositeFetch(CompositeFetch fetch) { + //To change body of implemented methods use File | Settings | File Templates. + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/ReturnVisitor.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/LoadPlanVisitor.java similarity index 78% rename from hibernate-core/src/main/java/org/hibernate/loader/plan/spi/ReturnVisitor.java rename to hibernate-core/src/main/java/org/hibernate/loader/plan/spi/LoadPlanVisitor.java index cf4aaf6ef9..9a371aa011 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/ReturnVisitor.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/LoadPlanVisitor.java @@ -28,25 +28,25 @@ * * @author Steve Ebersole */ -public class ReturnVisitor { - public static void visit(Return[] rootReturns, ReturnVisitationStrategy strategy) { - new ReturnVisitor( strategy ).visitReturns( rootReturns ); +public class LoadPlanVisitor { + public static void visit(LoadPlan loadPlan, LoadPlanVisitationStrategy strategy) { + new LoadPlanVisitor( strategy ).visit( loadPlan ); } - private final ReturnVisitationStrategy strategy; + private final LoadPlanVisitationStrategy strategy; - public ReturnVisitor(ReturnVisitationStrategy strategy) { + public LoadPlanVisitor(LoadPlanVisitationStrategy strategy) { this.strategy = strategy; } - private void visitReturns(Return[] rootReturns) { - strategy.start(); + private void visit(LoadPlan loadPlan) { + strategy.start( loadPlan ); - for ( Return rootReturn : rootReturns ) { + for ( Return rootReturn : loadPlan.getReturns() ) { visitRootReturn( rootReturn ); } - strategy.finish(); + strategy.finish( loadPlan ); } private void visitRootReturn(Return rootReturn) { @@ -69,7 +69,9 @@ private void visitNonScalarRootReturn(Return rootReturn) { } else if ( CollectionReturn.class.isInstance( rootReturn ) ) { strategy.handleCollectionReturn( (CollectionReturn) rootReturn ); - visitFetches( (CollectionReturn) rootReturn ); + final CollectionReturn collectionReturn = (CollectionReturn) rootReturn; + visitFetches( collectionReturn.getIndexGraph() ); + visitFetches( collectionReturn.getElementGraph() ); } else { throw new IllegalStateException( @@ -92,17 +94,18 @@ private void visitFetches(FetchOwner fetchOwner) { private void visitFetch(Fetch fetch) { if ( EntityFetch.class.isInstance( fetch ) ) { strategy.startingEntityFetch( (EntityFetch) fetch ); - visitFetches( fetch ); + visitFetches( (EntityFetch) fetch ); strategy.finishingEntityFetch( (EntityFetch) fetch ); } else if ( CollectionFetch.class.isInstance( fetch ) ) { strategy.startingCollectionFetch( (CollectionFetch) fetch ); - visitFetches( fetch ); + visitFetches( ( (CollectionFetch) fetch ).getIndexGraph() ); + visitFetches( ( (CollectionFetch) fetch ).getElementGraph() ); strategy.finishingCollectionFetch( (CollectionFetch) fetch ); } else if ( CompositeFetch.class.isInstance( fetch ) ) { strategy.startingCompositeFetch( (CompositeFetch) fetch ); - visitFetches( fetch ); + visitFetches( (CompositeFetch) fetch ); strategy.finishingCompositeFetch( (CompositeFetch) fetch ); } else { diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/Return.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/Return.java index b94adfae9d..19c700f57c 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/Return.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/Return.java @@ -23,12 +23,15 @@ */ package org.hibernate.loader.plan.spi; +import java.sql.ResultSet; +import java.sql.SQLException; + +import org.hibernate.loader.spi.ResultSetProcessingContext; + /** * Represents a return value in the query results. Not the same as a result (column) in the JDBC ResultSet! *

- * This is merely a unifying contract; it defines no behavior. - *

- * Return is distinctly different from a {@link Fetch}. + * Return is distinctly different from a {@link Fetch} and so modeled as completely separate hierarchy. * * @see ScalarReturn * @see EntityReturn @@ -37,4 +40,28 @@ * @author Steve Ebersole */ public interface Return { + public void hydrate(ResultSet resultSet, ResultSetProcessingContext context) throws SQLException; + + /** + * Effectively performs first phase of two-phase loading. For scalar results first/second phase is one. For + * entities, first phase is to resolve identifiers; second phase is to resolve the entity instances. + * + * @param resultSet The result set being processed + * @param context The context for the processing + * + * @throws SQLException Indicates a problem access the JDBC result set + */ + public void resolve(ResultSet resultSet, ResultSetProcessingContext context) throws SQLException; + + /** + * Essentially performs the second phase of two-phase loading. + * + * @param resultSet The result set being processed + * @param context The context for the processing + * + * @return The read object + * + * @throws SQLException Indicates a problem access the JDBC result set + */ + public Object read(ResultSet resultSet, ResultSetProcessingContext context) throws SQLException; } diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/ScalarReturn.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/ScalarReturn.java index 9a3d434bbc..d8a86ef117 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/ScalarReturn.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/ScalarReturn.java @@ -23,7 +23,12 @@ */ package org.hibernate.loader.plan.spi; +import java.sql.ResultSet; +import java.sql.SQLException; + import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.loader.internal.ResultSetProcessingContextImpl; +import org.hibernate.loader.spi.ResultSetProcessingContext; import org.hibernate.type.Type; /** @@ -34,19 +39,30 @@ */ public class ScalarReturn extends AbstractPlanNode implements Return { private final Type type; - private final String columnAlias; + private final String[] columnAliases; - public ScalarReturn(SessionFactoryImplementor factory, Type type, String columnAlias) { + public ScalarReturn(SessionFactoryImplementor factory, Type type, String[] columnAliases) { super( factory ); this.type = type; - this.columnAlias = columnAlias; + this.columnAliases = columnAliases; } public Type getType() { return type; } - public String getColumnAlias() { - return columnAlias; + @Override + public void hydrate(ResultSet resultSet, ResultSetProcessingContext context) { + // nothing to do + } + + @Override + public void resolve(ResultSet resultSet, ResultSetProcessingContext context) { + // nothing to do + } + + @Override + public Object read(ResultSet resultSet, ResultSetProcessingContext context) throws SQLException { + return type.nullSafeGet( resultSet, columnAliases, context.getSession(), null ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/loader/spi/AfterLoadAction.java b/hibernate-core/src/main/java/org/hibernate/loader/spi/AfterLoadAction.java new file mode 100644 index 0000000000..3fa9257b9a --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/loader/spi/AfterLoadAction.java @@ -0,0 +1,34 @@ +/* + * 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.loader.spi; + +import org.hibernate.engine.spi.SessionImplementor; +import org.hibernate.persister.entity.Loadable; + +/** +* @author Steve Ebersole +*/ +public interface AfterLoadAction { + public void afterLoad(SessionImplementor session, Object entity, Loadable persister); +} diff --git a/hibernate-core/src/main/java/org/hibernate/loader/spi/Loader.java b/hibernate-core/src/main/java/org/hibernate/loader/spi/Loader.java index 28c5cc36be..1513d61a82 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/spi/Loader.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/spi/Loader.java @@ -33,28 +33,22 @@ import org.hibernate.transform.ResultTransformer; /** - * Definition of the Loader contract. - *

- * Capabilities I'd like to see added (todo):

    - *
  • - * expose the underlying "query" (although what I see here relies heavily on - * https://github.com/hibernate/hibernate-orm/wiki/Proposal---SQL-generation) - *
  • - *
- * + * Definition of the Loader contract. A Loader is intended to perform loading based on a query and a load-plan. + * Under the covers it uses many delegates to perform that work that might be better used individually in + * different situations. In general, Loader is intended for being fed a set of results and processing through + * all of those result rows in one swoop. For cases that do not fit that template, it is probably better to + * individually use the delegates to perform the work. * * @author Gavin King * @author Steve Ebersole */ public interface Loader { - public LoadPlan getLoadPlan(); - /** - * Obtain the on-demand form of this loader, if possible. + * Obtain the LoadPlan this Loader is following. * - * @return The on-demand version of this loader + * @return */ - public OnDemandLoader asOnDemandLoader(); + public LoadPlan getLoadPlan(); public List extractResults( ResultSet resultSet, diff --git a/hibernate-core/src/main/java/org/hibernate/loader/spi/NamedParameterContext.java b/hibernate-core/src/main/java/org/hibernate/loader/spi/NamedParameterContext.java new file mode 100644 index 0000000000..d8b33e98ee --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/loader/spi/NamedParameterContext.java @@ -0,0 +1,36 @@ +/* + * 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.loader.spi; + +/** + * The context for named parameters. + *

+ * NOTE : the hope with the SQL-redesign stuff is that this whole concept goes away, the idea being that + * the parameters are encoded into the query tree and "bind themselves". + * + * @author Steve Ebersole + */ +public interface NamedParameterContext { + public int[] getNamedParameterLocations(String name); +} diff --git a/hibernate-core/src/main/java/org/hibernate/loader/spi/OnDemandLoader.java b/hibernate-core/src/main/java/org/hibernate/loader/spi/OnDemandResultSetProcessor.java similarity index 74% rename from hibernate-core/src/main/java/org/hibernate/loader/spi/OnDemandLoader.java rename to hibernate-core/src/main/java/org/hibernate/loader/spi/OnDemandResultSetProcessor.java index 1a87626f76..27ba73b5a6 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/spi/OnDemandLoader.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/spi/OnDemandResultSetProcessor.java @@ -1,7 +1,7 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2013, Red Hat Inc. or third-party contributors as + * 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. @@ -25,22 +25,24 @@ import java.sql.ResultSet; -import org.hibernate.HibernateException; import org.hibernate.engine.spi.QueryParameters; import org.hibernate.engine.spi.SessionImplementor; /** - * Represents an on-demand loading strategy as need for processing single *logical* rows one at a time as required - * for {@link org.hibernate.ScrollableResults} implementations. + * Contract for processing JDBC ResultSets a single logical row at a time. These are intended for use by + * {@link org.hibernate.ScrollableResults} implementations. + * + * NOTE : these methods initially taken directly from {@link org.hibernate.loader.Loader} counterparts in an effort + * to break Loader into manageable pieces, especially in regards to the processing of result sets. * * @author Steve Ebersole */ -public interface OnDemandLoader { +public interface OnDemandResultSetProcessor { /** - * Given a ResultSet, extract just a single result row. + * Give a ResultSet, extract just a single result row. * - * Copy of {@link org.hibernate.loader.Loader#loadSingleRow(ResultSet, SessionImplementor, QueryParameters, boolean)} + * Copy of {@link org.hibernate.loader.Loader#loadSingleRow(java.sql.ResultSet, org.hibernate.engine.spi.SessionImplementor, org.hibernate.engine.spi.QueryParameters, boolean)} * but dropping the 'returnProxies' (that method has only one use in the entire codebase and it always passes in * false...) * @@ -50,19 +52,19 @@ public interface OnDemandLoader { * * @return The extracted result row * - * @throws HibernateException Indicates a problem extracting values from the result set. + * @throws org.hibernate.HibernateException Indicates a problem extracting values from the result set. */ public Object extractSingleRow( ResultSet resultSet, SessionImplementor session, - QueryParameters queryParameters) throws HibernateException; + QueryParameters queryParameters); /** * Given a ResultSet extract "sequential rows". This is used in cases where we have multi-row fetches that * are sequential within the ResultSet due to ordering. Multiple ResultSet rows are read into a single query * result "row". * - * Copy of {@link org.hibernate.loader.Loader#loadSequentialRowsForward(ResultSet, SessionImplementor, QueryParameters, boolean)} + * Copy of {@link org.hibernate.loader.Loader#loadSequentialRowsForward(java.sql.ResultSet, org.hibernate.engine.spi.SessionImplementor, org.hibernate.engine.spi.QueryParameters, boolean)} * but dropping the 'returnProxies' (that method has only one use in the entire codebase and it always passes in * false...) * @@ -77,12 +79,12 @@ public Object extractSingleRow( public Object extractSequentialRowsForward( final ResultSet resultSet, final SessionImplementor session, - final QueryParameters queryParameters) throws HibernateException; + final QueryParameters queryParameters); /** * Like {@link #extractSequentialRowsForward} but here moving back through the ResultSet. * - * Copy of {@link org.hibernate.loader.Loader#loadSequentialRowsReverse(ResultSet, SessionImplementor, QueryParameters, boolean, boolean)} + * Copy of {@link org.hibernate.loader.Loader#loadSequentialRowsReverse(java.sql.ResultSet, org.hibernate.engine.spi.SessionImplementor, org.hibernate.engine.spi.QueryParameters, boolean, boolean)} * but dropping the 'returnProxies' (that method has only one use in the entire codebase and it always passes in * false...). * @@ -101,5 +103,5 @@ public Object extractSequentialRowsReverse( ResultSet resultSet, SessionImplementor session, QueryParameters queryParameters, - boolean isLogicallyAfterLast) throws HibernateException; + boolean isLogicallyAfterLast); } diff --git a/hibernate-core/src/main/java/org/hibernate/loader/spi/ResultBuilder.java b/hibernate-core/src/main/java/org/hibernate/loader/spi/ResultBuilder.java new file mode 100644 index 0000000000..157e6e22d8 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/loader/spi/ResultBuilder.java @@ -0,0 +1,7 @@ +package org.hibernate.loader.spi; + +/** + * @author Steve Ebersole + */ +public class ResultBuilder { +} diff --git a/hibernate-core/src/main/java/org/hibernate/loader/spi/ResultSetProcessingContext.java b/hibernate-core/src/main/java/org/hibernate/loader/spi/ResultSetProcessingContext.java new file mode 100644 index 0000000000..6af2fb8da1 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/loader/spi/ResultSetProcessingContext.java @@ -0,0 +1,91 @@ +/* + * 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.loader.spi; + +import java.io.Serializable; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.List; + +import org.hibernate.LockMode; +import org.hibernate.engine.spi.EntityKey; +import org.hibernate.engine.spi.QueryParameters; +import org.hibernate.engine.spi.SessionImplementor; +import org.hibernate.loader.EntityAliases; +import org.hibernate.loader.plan.spi.EntityReference; +import org.hibernate.loader.plan.spi.Return; +import org.hibernate.persister.entity.EntityPersister; +import org.hibernate.type.AssociationType; +import org.hibernate.type.EntityType; + +/** + * @author Steve Ebersole + */ +public interface ResultSetProcessingContext { + public SessionImplementor getSession(); + + public QueryParameters getQueryParameters(); + + public EntityKey getDictatedRootEntityKey(); + + public IdentifierResolutionContext getIdentifierResolutionContext(EntityReference entityReference); + + public static interface IdentifierResolutionContext { + public EntityReference getEntityReference(); + + public void registerHydratedForm(Serializable hydratedForm); + + public Serializable getHydratedForm(); + + public void registerEntityKey(EntityKey entityKey); + + public EntityKey getEntityKey(); + } + + public void registerHydratedEntity(EntityPersister persister, EntityKey entityKey, Object entityInstance); + + public void checkVersion( + ResultSet resultSet, + EntityPersister persister, + EntityAliases entityAliases, + EntityKey entityKey, + Object entityInstance) throws SQLException; + + public String getConcreteEntityTypeName( + ResultSet resultSet, + EntityPersister persister, + EntityAliases entityAliases, + EntityKey entityKey) throws SQLException; + + public void loadFromResultSet( + ResultSet resultSet, + Object entityInstance, + String concreteEntityTypeName, + EntityKey entityKey, + EntityAliases entityAliases, + LockMode acquiredLockMode, + EntityPersister persister, + boolean eagerFetch, + EntityType associationType) throws SQLException; +} diff --git a/hibernate-core/src/main/java/org/hibernate/loader/spi/ResultSetProcessor.java b/hibernate-core/src/main/java/org/hibernate/loader/spi/ResultSetProcessor.java new file mode 100644 index 0000000000..4dc630c469 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/loader/spi/ResultSetProcessor.java @@ -0,0 +1,70 @@ +/* + * 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.loader.spi; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.List; + +import org.hibernate.engine.spi.QueryParameters; +import org.hibernate.engine.spi.SessionImplementor; +import org.hibernate.transform.ResultTransformer; + +/** + * Contract for processing JDBC ResultSets. Separated because ResultSets can be chained and we'd really like to + * reuse this logic across all result sets. + *

+ * todo : investigate having this work with non-JDBC results; maybe just typed as Object? or a special Result contract? + * + * @author Steve Ebersole + */ +public interface ResultSetProcessor { + + public OnDemandResultSetProcessor toOnDemandForm(); + + /** + * Process an entire ResultSet, performing all extractions. + * + * Semi-copy of {@link org.hibernate.loader.Loader#doQuery}, with focus on just the ResultSet processing bit. + * + * @param resultSet The result set being processed. + * @param session The originating session + * @param queryParameters The "parameters" used to build the query + * @param returnProxies Can proxies be returned (not the same as can they be created!) + * @param forcedResultTransformer My old "friend" ResultTransformer... + * + * @return The extracted results list. + * + * @throws java.sql.SQLException Indicates a problem access the JDBC ResultSet + */ + public List extractResults( + ResultSet resultSet, + SessionImplementor session, + QueryParameters queryParameters, + NamedParameterContext namedParameterContext, + boolean returnProxies, + boolean readOnly, + ResultTransformer forcedResultTransformer, + List afterLoadActions) throws SQLException; +} diff --git a/hibernate-core/src/main/java/org/hibernate/persister/collection/AbstractCollectionPersister.java b/hibernate-core/src/main/java/org/hibernate/persister/collection/AbstractCollectionPersister.java index 0db82ac72c..3503962eea 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/collection/AbstractCollectionPersister.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/collection/AbstractCollectionPersister.java @@ -82,7 +82,7 @@ import org.hibernate.persister.walking.spi.CollectionDefinition; import org.hibernate.persister.walking.spi.CollectionElementDefinition; import org.hibernate.persister.walking.spi.CollectionIndexDefinition; -import org.hibernate.persister.walking.spi.CompositeDefinition; +import org.hibernate.persister.walking.spi.CompositionDefinition; import org.hibernate.persister.walking.spi.EntityDefinition; import org.hibernate.pretty.MessageHelper; import org.hibernate.sql.Alias; @@ -1974,7 +1974,7 @@ public EntityDefinition toEntityDefinition() { } @Override - public CompositeDefinition toCompositeDefinition() { + public CompositionDefinition toCompositeDefinition() { if ( ! getType().isComponentType() ) { throw new IllegalStateException( "Cannot treat entity collection index type as composite" ); } @@ -2006,7 +2006,7 @@ public EntityDefinition toEntityDefinition() { } @Override - public CompositeDefinition toCompositeDefinition() { + public CompositionDefinition toCompositeDefinition() { if ( ! getType().isComponentType() ) { throw new IllegalStateException( "Cannot treat entity collection element type as composite" ); } diff --git a/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java b/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java index 5456404f04..5f4c423a2b 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java @@ -110,6 +110,11 @@ import org.hibernate.metamodel.relational.DerivedValue; import org.hibernate.metamodel.relational.Value; import org.hibernate.persister.walking.spi.AttributeDefinition; +import org.hibernate.persister.walking.spi.AttributeSource; +import org.hibernate.persister.walking.spi.EncapsulatedEntityIdentifierDefinition; +import org.hibernate.persister.walking.spi.EntityDefinition; +import org.hibernate.persister.walking.spi.EntityIdentifierDefinition; +import org.hibernate.persister.walking.spi.NonEncapsulatedEntityIdentifierDefinition; import org.hibernate.pretty.MessageHelper; import org.hibernate.property.BackrefPropertyAccessor; import org.hibernate.sql.Alias; @@ -5076,11 +5081,12 @@ public CacheEntry buildCacheEntry(Object entity, Object[] state, Object version, // EntityDefinition impl ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + private EntityIdentifierDefinition entityIdentifierDefinition; private Iterable embeddedCompositeIdentifierAttributes; private Iterable attributeDefinitions; protected void generateEntityDefinition() { - collectEmbeddedCompositeIdentifierAttributeDefinitions(); + prepareEntityIdentifierDefinition(); collectAttributeDefinitions(); } @@ -5090,8 +5096,8 @@ public EntityPersister getEntityPersister() { } @Override - public Iterable getEmbeddedCompositeIdentifierAttributes() { - return embeddedCompositeIdentifierAttributes; + public EntityIdentifierDefinition getEntityKeyDefinition() { + return entityIdentifierDefinition; } @Override @@ -5099,52 +5105,85 @@ public Iterable getAttributes() { return attributeDefinitions; } - private synchronized void collectEmbeddedCompositeIdentifierAttributeDefinitions() { + + private void prepareEntityIdentifierDefinition() { final Type idType = getIdentifierType(); + if ( !idType.isComponentType() ) { + entityIdentifierDefinition = buildEncapsulatedIdentifierDefinition(); return; } final CompositeType cidType = (CompositeType) idType; if ( !cidType.isEmbedded() ) { + entityIdentifierDefinition = buildEncapsulatedIdentifierDefinition(); return; } - // we have an embedded composite identifier. Most likely we need to process the composite - // properties separately, although there is an edge case where the identifier is really - // a simple identifier (single value) wrapped in a JPA @IdClass or even in the case of a - // a simple identifier (single value) wrapped in a Hibernate composite type. - // - // We really do not have a built-in method to determine that. However, generally the - // persister would report that there is single, physical identifier property which is - // explicitly at odds with the notion of "embedded composite". So we use that for now - if ( getEntityMetamodel().getIdentifierProperty().isEmbedded() ) { - this.embeddedCompositeIdentifierAttributes = new Iterable() { - @Override - public Iterator iterator() { - return new Iterator() { - private final int numberOfAttributes = countSubclassProperties(); - private int currentAttributeNumber = 0; + entityIdentifierDefinition = new NonEncapsulatedEntityIdentifierDefinition() { + @Override + public Iterable getAttributes() { + // todo : implement + throw new NotYetImplementedException(); + } - @Override - public boolean hasNext() { - return currentAttributeNumber < numberOfAttributes; - } + @Override + public Class getSeparateIdentifierMappingClass() { + // todo : implement + throw new NotYetImplementedException(); + } - @Override - public AttributeDefinition next() { - // todo : implement - throw new NotYetImplementedException(); - } + @Override + public boolean isEncapsulated() { + return false; + } - @Override - public void remove() { - throw new UnsupportedOperationException( "Remove operation not supported here" ); - } - }; - } - }; - } + @Override + public EntityDefinition getEntityDefinition() { + return AbstractEntityPersister.this; + } + }; + } + + private EntityIdentifierDefinition buildEncapsulatedIdentifierDefinition() { + final AttributeDefinition simpleIdentifierAttributeAdapter = new AttributeDefinition() { + @Override + public String getName() { + return entityMetamodel.getIdentifierProperty().getName(); + } + + @Override + public Type getType() { + return entityMetamodel.getIdentifierProperty().getType(); + } + + @Override + public AttributeSource getSource() { + return AbstractEntityPersister.this; + } + + @Override + public String toString() { + return ""; + } + }; + + return new EncapsulatedEntityIdentifierDefinition() { + @Override + public AttributeDefinition getAttributeDefinition() { + return simpleIdentifierAttributeAdapter; + } + + @Override + public boolean isEncapsulated() { + return true; + } + + @Override + public EntityDefinition getEntityDefinition() { + return AbstractEntityPersister.this; + } + }; } private void collectAttributeDefinitions() { diff --git a/hibernate-core/src/main/java/org/hibernate/persister/spi/HydratedCompoundValueHandler.java b/hibernate-core/src/main/java/org/hibernate/persister/spi/HydratedCompoundValueHandler.java new file mode 100644 index 0000000000..4c723a6b2f --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/persister/spi/HydratedCompoundValueHandler.java @@ -0,0 +1,44 @@ +/* + * 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.persister.spi; + +/** + * Where to begin... :) + * + * This gets to the internal concept of 2-phase loading of entity data and how specifically it is done. Essentially + * for composite values, the process of hydration results in a tuple array comprising the composition "atomic" values. + * For example, a Name component's hydrated state might look like {@code ["Steve", "L", "Ebersole"]}. + * + * There are times when we need to be able to extract individual pieces out of the hydrated tuple array. For example, + * for an entity with a composite identifier part of which is an association (a key-many-to-one) we often need to + * attempt 2-phase processing on the association portion of the identifier's hydrated tuple array. + * + * This contract allows us access to portions of the hydrated tuple state. + * + * @author Steve Ebersole + */ +public interface HydratedCompoundValueHandler { + public Object extract(Object hydratedState); + public void inject(Object hydratedState, Object value); +} diff --git a/hibernate-core/src/main/java/org/hibernate/persister/walking/spi/AssociationAttributeDefinition.java b/hibernate-core/src/main/java/org/hibernate/persister/walking/spi/AssociationAttributeDefinition.java index 383b3d4e38..719eb51803 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/walking/spi/AssociationAttributeDefinition.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/walking/spi/AssociationAttributeDefinition.java @@ -27,6 +27,7 @@ import org.hibernate.engine.spi.CascadeStyle; import org.hibernate.engine.spi.LoadQueryInfluencers; import org.hibernate.loader.PropertyPath; +import org.hibernate.persister.spi.HydratedCompoundValueHandler; /** * @author Steve Ebersole @@ -43,4 +44,6 @@ public interface AssociationAttributeDefinition extends AttributeDefinition { public FetchStrategy determineFetchPlan(LoadQueryInfluencers loadQueryInfluencers, PropertyPath propertyPath); public CascadeStyle determineCascadeStyle(); + + public HydratedCompoundValueHandler getHydratedCompoundValueExtractor(); } diff --git a/hibernate-core/src/main/java/org/hibernate/persister/walking/spi/AssociationVisitationStrategy.java b/hibernate-core/src/main/java/org/hibernate/persister/walking/spi/AssociationVisitationStrategy.java index 1cb649b0d8..285ec22270 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/walking/spi/AssociationVisitationStrategy.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/walking/spi/AssociationVisitationStrategy.java @@ -40,11 +40,20 @@ public interface AssociationVisitationStrategy { public void startingEntity(EntityDefinition entityDefinition); public void finishingEntity(EntityDefinition entityDefinition); + public void startingEntityIdentifier(EntityIdentifierDefinition entityIdentifierDefinition); + public void finishingEntityIdentifier(EntityIdentifierDefinition entityIdentifierDefinition); + public void startingCollection(CollectionDefinition collectionDefinition); public void finishingCollection(CollectionDefinition collectionDefinition); - public void startingComposite(CompositeDefinition compositeDefinition); - public void finishingComposite(CompositeDefinition compositeDefinition); + public void startingCollectionIndex(CollectionIndexDefinition collectionIndexDefinition); + public void finishingCollectionIndex(CollectionIndexDefinition collectionIndexDefinition); + + public void startingCollectionElements(CollectionElementDefinition elementDefinition); + public void finishingCollectionElements(CollectionElementDefinition elementDefinition); + + public void startingComposite(CompositionDefinition compositionDefinition); + public void finishingComposite(CompositionDefinition compositionDefinition); public boolean startingAttribute(AttributeDefinition attributeDefinition); public void finishingAttribute(AttributeDefinition attributeDefinition); diff --git a/hibernate-core/src/main/java/org/hibernate/persister/walking/spi/CollectionElementDefinition.java b/hibernate-core/src/main/java/org/hibernate/persister/walking/spi/CollectionElementDefinition.java index fd48366c3a..b42f8b0ddc 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/walking/spi/CollectionElementDefinition.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/walking/spi/CollectionElementDefinition.java @@ -35,5 +35,5 @@ public interface CollectionElementDefinition { public EntityDefinition toEntityDefinition(); - public CompositeDefinition toCompositeDefinition(); + public CompositionDefinition toCompositeDefinition(); } diff --git a/hibernate-core/src/main/java/org/hibernate/persister/walking/spi/CollectionIndexDefinition.java b/hibernate-core/src/main/java/org/hibernate/persister/walking/spi/CollectionIndexDefinition.java index 700e2b5070..ece06e6e36 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/walking/spi/CollectionIndexDefinition.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/walking/spi/CollectionIndexDefinition.java @@ -35,5 +35,5 @@ public interface CollectionIndexDefinition { public EntityDefinition toEntityDefinition(); - public CompositeDefinition toCompositeDefinition(); + public CompositionDefinition toCompositeDefinition(); } diff --git a/hibernate-core/src/main/java/org/hibernate/persister/walking/spi/CompositeDefinition.java b/hibernate-core/src/main/java/org/hibernate/persister/walking/spi/CompositionDefinition.java similarity index 92% rename from hibernate-core/src/main/java/org/hibernate/persister/walking/spi/CompositeDefinition.java rename to hibernate-core/src/main/java/org/hibernate/persister/walking/spi/CompositionDefinition.java index 51c88333f4..e9d7c251cf 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/walking/spi/CompositeDefinition.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/walking/spi/CompositionDefinition.java @@ -26,5 +26,5 @@ /** * @author Steve Ebersole */ -public interface CompositeDefinition extends AttributeDefinition, AttributeSource { +public interface CompositionDefinition extends AttributeDefinition, AttributeSource { } diff --git a/hibernate-core/src/main/java/org/hibernate/persister/walking/spi/EncapsulatedEntityIdentifierDefinition.java b/hibernate-core/src/main/java/org/hibernate/persister/walking/spi/EncapsulatedEntityIdentifierDefinition.java new file mode 100644 index 0000000000..657f2da50d --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/persister/walking/spi/EncapsulatedEntityIdentifierDefinition.java @@ -0,0 +1,31 @@ +/* + * 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.persister.walking.spi; + +/** + * @author Steve Ebersole + */ +public interface EncapsulatedEntityIdentifierDefinition extends EntityIdentifierDefinition { + public AttributeDefinition getAttributeDefinition(); +} diff --git a/hibernate-core/src/main/java/org/hibernate/persister/walking/spi/EntityDefinition.java b/hibernate-core/src/main/java/org/hibernate/persister/walking/spi/EntityDefinition.java index 1e02b42106..38faf26c4a 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/walking/spi/EntityDefinition.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/walking/spi/EntityDefinition.java @@ -32,5 +32,5 @@ */ public interface EntityDefinition extends AttributeSource { public EntityPersister getEntityPersister(); - public Iterable getEmbeddedCompositeIdentifierAttributes(); + public EntityIdentifierDefinition getEntityKeyDefinition(); } diff --git a/hibernate-core/src/main/java/org/hibernate/persister/walking/spi/EntityIdentifierDefinition.java b/hibernate-core/src/main/java/org/hibernate/persister/walking/spi/EntityIdentifierDefinition.java new file mode 100644 index 0000000000..8ecb616a64 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/persister/walking/spi/EntityIdentifierDefinition.java @@ -0,0 +1,43 @@ +/* + * 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.persister.walking.spi; + +/** + * Describes aspects of the identifier for an entity + * + * @author Steve Ebersole + */ +public interface EntityIdentifierDefinition { + /** + * Is the entity identifier encapsulated? Meaning, is it represented by a single attribute? + * + * @return {@code true} indicates the identifier is encapsulated (and therefore this is castable to + * {@link EncapsulatedEntityIdentifierDefinition}); {@code false} means it is not encapsulated (and therefore + * castable to {@link NonEncapsulatedEntityIdentifierDefinition}). + * + */ + public boolean isEncapsulated(); + + public EntityDefinition getEntityDefinition(); +} diff --git a/hibernate-core/src/main/java/org/hibernate/persister/walking/spi/MetadataDrivenModelGraphVisitor.java b/hibernate-core/src/main/java/org/hibernate/persister/walking/spi/MetadataDrivenModelGraphVisitor.java index ccbbceb6bb..dd205aa9e8 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/walking/spi/MetadataDrivenModelGraphVisitor.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/walking/spi/MetadataDrivenModelGraphVisitor.java @@ -81,26 +81,26 @@ public MetadataDrivenModelGraphVisitor(AssociationVisitationStrategy strategy, S private void visitEntityDefinition(EntityDefinition entityDefinition) { strategy.startingEntity( entityDefinition ); - try { - visitAttributes( entityDefinition ); - optionallyVisitEmbeddedCompositeIdentifier( entityDefinition ); - } - finally { - strategy.finishingEntity( entityDefinition ); - } + + visitAttributes( entityDefinition ); + visitIdentifierDefinition( entityDefinition.getEntityKeyDefinition() ); + + strategy.finishingEntity( entityDefinition ); } - private void optionallyVisitEmbeddedCompositeIdentifier(EntityDefinition entityDefinition) { - // if the entity has a composite identifier, see if we need to handle its sub-properties separately - final Iterable embeddedCompositeIdentifierAttributes = - entityDefinition.getEmbeddedCompositeIdentifierAttributes(); - if ( embeddedCompositeIdentifierAttributes == null ) { - return; + private void visitIdentifierDefinition(EntityIdentifierDefinition entityIdentifierDefinition) { + strategy.startingEntityIdentifier( entityIdentifierDefinition ); + + if ( entityIdentifierDefinition.isEncapsulated() ) { + visitAttributeDefinition( ( (EncapsulatedEntityIdentifierDefinition) entityIdentifierDefinition).getAttributeDefinition() ); + } + else { + for ( AttributeDefinition attributeDefinition : ( (NonEncapsulatedEntityIdentifierDefinition) entityIdentifierDefinition).getAttributes() ) { + visitAttributeDefinition( attributeDefinition ); + } } - for ( AttributeDefinition attributeDefinition : embeddedCompositeIdentifierAttributes ) { - visitAttributeDefinition( attributeDefinition ); - } + strategy.finishingEntityIdentifier( entityIdentifierDefinition ); } private void visitAttributes(AttributeSource attributeSource) { @@ -122,7 +122,7 @@ private void visitAttributeDefinition(AttributeDefinition attributeDefinition) { visitAssociation( (AssociationAttributeDefinition) attributeDefinition ); } else if ( attributeDefinition.getType().isComponentType() ) { - visitCompositeDefinition( (CompositeDefinition) attributeDefinition ); + visitCompositeDefinition( (CompositionDefinition) attributeDefinition ); } } finally { @@ -148,42 +148,34 @@ private void visitAssociation(AssociationAttributeDefinition attribute) { } } - private void visitCompositeDefinition(CompositeDefinition compositeDefinition) { - strategy.startingComposite( compositeDefinition ); - try { - visitAttributes( compositeDefinition ); - } - finally { - strategy.finishingComposite( compositeDefinition ); - } + private void visitCompositeDefinition(CompositionDefinition compositionDefinition) { + strategy.startingComposite( compositionDefinition ); + + visitAttributes( compositionDefinition ); + + strategy.finishingComposite( compositionDefinition ); } private void visitCollectionDefinition(CollectionDefinition collectionDefinition) { strategy.startingCollection( collectionDefinition ); - try { - visitCollectionIndex( collectionDefinition.getIndexDefinition() ); + visitCollectionIndex( collectionDefinition ); + visitCollectionElements( collectionDefinition ); - final CollectionElementDefinition elementDefinition = collectionDefinition.getElementDefinition(); - if ( elementDefinition.getType().isComponentType() ) { - visitCompositeDefinition( elementDefinition.toCompositeDefinition() ); - } - else { - visitEntityDefinition( elementDefinition.toEntityDefinition() ); - } - } - finally { - strategy.finishingCollection( collectionDefinition ); - } + strategy.finishingCollection( collectionDefinition ); } - private void visitCollectionIndex(CollectionIndexDefinition collectionIndexDefinition) { + private void visitCollectionIndex(CollectionDefinition collectionDefinition) { + final CollectionIndexDefinition collectionIndexDefinition = collectionDefinition.getIndexDefinition(); if ( collectionIndexDefinition == null ) { return; } - log.debug( "Visiting collection index : " + currentPropertyPath.getFullPath() ); - currentPropertyPath = currentPropertyPath.append( "" ); + strategy.startingCollectionIndex( collectionIndexDefinition ); + + log.debug( "Visiting index for collection : " + currentPropertyPath.getFullPath() ); + currentPropertyPath = currentPropertyPath.append( "" ); + try { final Type collectionIndexType = collectionIndexDefinition.getType(); if ( collectionIndexType.isComponentType() ) { @@ -196,6 +188,22 @@ else if ( collectionIndexType.isAssociationType() ) { finally { currentPropertyPath = currentPropertyPath.getParent(); } + + strategy.finishingCollectionIndex( collectionIndexDefinition ); + } + + private void visitCollectionElements(CollectionDefinition collectionDefinition) { + final CollectionElementDefinition elementDefinition = collectionDefinition.getElementDefinition(); + strategy.startingCollectionElements( elementDefinition ); + + if ( elementDefinition.getType().isComponentType() ) { + visitCompositeDefinition( elementDefinition.toCompositeDefinition() ); + } + else { + visitEntityDefinition( elementDefinition.toEntityDefinition() ); + } + + strategy.finishingCollectionElements( elementDefinition ); } diff --git a/hibernate-core/src/main/java/org/hibernate/persister/walking/spi/NonEncapsulatedEntityIdentifierDefinition.java b/hibernate-core/src/main/java/org/hibernate/persister/walking/spi/NonEncapsulatedEntityIdentifierDefinition.java new file mode 100644 index 0000000000..4a07579867 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/persister/walking/spi/NonEncapsulatedEntityIdentifierDefinition.java @@ -0,0 +1,33 @@ +/* + * 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.persister.walking.spi; + +/** + * @author Steve Ebersole + */ +public interface NonEncapsulatedEntityIdentifierDefinition extends EntityIdentifierDefinition { + public Iterable getAttributes(); + + public Class getSeparateIdentifierMappingClass(); +} diff --git a/hibernate-core/src/main/java/org/hibernate/persister/walking/spi/WalkingException.java b/hibernate-core/src/main/java/org/hibernate/persister/walking/spi/WalkingException.java new file mode 100644 index 0000000000..881c32c392 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/persister/walking/spi/WalkingException.java @@ -0,0 +1,41 @@ +/* + * 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.persister.walking.spi; + +import org.hibernate.HibernateError; + +/** + * Indicates a problem walking the domain tree. Almost always this indicates an internal error in Hibernate + * + * @author Steve Ebersole + */ +public class WalkingException extends HibernateError { + public WalkingException(String message) { + super( message ); + } + + public WalkingException(String message, Throwable root) { + super( message, root ); + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/result/internal/ResultImpl.java b/hibernate-core/src/main/java/org/hibernate/result/internal/ResultImpl.java index fe405ec56f..9377303efa 100644 --- a/hibernate-core/src/main/java/org/hibernate/result/internal/ResultImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/result/internal/ResultImpl.java @@ -37,6 +37,7 @@ import org.hibernate.loader.custom.CustomLoader; import org.hibernate.loader.custom.CustomQuery; import org.hibernate.loader.custom.sql.SQLQueryReturnProcessor; +import org.hibernate.loader.spi.AfterLoadAction; import org.hibernate.result.NoMoreReturnsException; import org.hibernate.result.Result; import org.hibernate.result.Return; diff --git a/hibernate-core/src/main/java/org/hibernate/tuple/AbstractNonIdentifierAttribute.java b/hibernate-core/src/main/java/org/hibernate/tuple/AbstractNonIdentifierAttribute.java index b01458fe64..9b9a161370 100644 --- a/hibernate-core/src/main/java/org/hibernate/tuple/AbstractNonIdentifierAttribute.java +++ b/hibernate-core/src/main/java/org/hibernate/tuple/AbstractNonIdentifierAttribute.java @@ -126,8 +126,12 @@ public FetchMode getFetchMode() { return attributeInformation.getFetchMode(); } + protected String loggableMetadata() { + return "non-identifier"; + } + @Override public String toString() { - return "Attribute[non-identifier]( " + getName() + ")"; + return "Attribute(name=" + getName() + ", type=" + getType().getName() + " [" + loggableMetadata() + "])"; } } diff --git a/hibernate-core/src/main/java/org/hibernate/tuple/PropertyFactory.java b/hibernate-core/src/main/java/org/hibernate/tuple/PropertyFactory.java index 8db4f2048e..977ab5350c 100644 --- a/hibernate-core/src/main/java/org/hibernate/tuple/PropertyFactory.java +++ b/hibernate-core/src/main/java/org/hibernate/tuple/PropertyFactory.java @@ -54,7 +54,7 @@ import org.hibernate.property.PropertyAccessorFactory; import org.hibernate.tuple.entity.EntityBasedAssociationAttribute; import org.hibernate.tuple.entity.EntityBasedBasicAttribute; -import org.hibernate.tuple.entity.EntityBasedCompositeAttribute; +import org.hibernate.tuple.entity.EntityBasedCompositionAttribute; import org.hibernate.tuple.entity.VersionProperty; import org.hibernate.type.AssociationType; import org.hibernate.type.CompositeType; @@ -282,7 +282,7 @@ public static NonIdentifierAttribute buildEntityBasedAttribute( ); } case COMPOSITE: { - return new EntityBasedCompositeAttribute( + return new EntityBasedCompositionAttribute( persister, sessionFactory, attributeNumber, diff --git a/hibernate-core/src/main/java/org/hibernate/tuple/component/AbstractCompositeBasedAttribute.java b/hibernate-core/src/main/java/org/hibernate/tuple/component/AbstractCompositeBasedAttribute.java index 5c62859939..a225b8a05f 100644 --- a/hibernate-core/src/main/java/org/hibernate/tuple/component/AbstractCompositeBasedAttribute.java +++ b/hibernate-core/src/main/java/org/hibernate/tuple/component/AbstractCompositeBasedAttribute.java @@ -39,7 +39,7 @@ public abstract class AbstractCompositeBasedAttribute private final int ownerAttributeNumber; public AbstractCompositeBasedAttribute( - AbstractCompositeDefinition source, + AbstractCompositionDefinition source, SessionFactoryImplementor sessionFactory, int attributeNumber, String attributeName, @@ -55,7 +55,7 @@ protected int ownerAttributeNumber() { } @Override - public AbstractCompositeDefinition getSource() { - return (AbstractCompositeDefinition) super.getSource(); + public AbstractCompositionDefinition getSource() { + return (AbstractCompositionDefinition) super.getSource(); } } diff --git a/hibernate-core/src/main/java/org/hibernate/tuple/component/AbstractCompositeDefinition.java b/hibernate-core/src/main/java/org/hibernate/tuple/component/AbstractCompositionDefinition.java similarity index 76% rename from hibernate-core/src/main/java/org/hibernate/tuple/component/AbstractCompositeDefinition.java rename to hibernate-core/src/main/java/org/hibernate/tuple/component/AbstractCompositionDefinition.java index 17b4b0ccb1..0584f843ff 100644 --- a/hibernate-core/src/main/java/org/hibernate/tuple/component/AbstractCompositeDefinition.java +++ b/hibernate-core/src/main/java/org/hibernate/tuple/component/AbstractCompositionDefinition.java @@ -32,7 +32,7 @@ import org.hibernate.persister.walking.spi.AssociationKey; import org.hibernate.persister.walking.spi.AttributeDefinition; import org.hibernate.persister.walking.spi.AttributeSource; -import org.hibernate.persister.walking.spi.CompositeDefinition; +import org.hibernate.persister.walking.spi.CompositionDefinition; import org.hibernate.persister.walking.spi.EntityDefinition; import org.hibernate.tuple.AbstractNonIdentifierAttribute; import org.hibernate.tuple.BaselineAttributeInformation; @@ -48,8 +48,9 @@ /** * @author Steve Ebersole */ -public abstract class AbstractCompositeDefinition extends AbstractNonIdentifierAttribute implements CompositeDefinition { - protected AbstractCompositeDefinition( +public abstract class AbstractCompositionDefinition extends AbstractNonIdentifierAttribute implements + CompositionDefinition { + protected AbstractCompositionDefinition( AttributeSource source, SessionFactoryImplementor sessionFactory, int attributeNumber, @@ -119,41 +120,41 @@ public AttributeDefinition next() { } return new CompositeBasedAssociationAttribute( - AbstractCompositeDefinition.this, + AbstractCompositionDefinition.this, sessionFactory(), currentAttributeNumber, name, (AssociationType) type, new BaselineAttributeInformation.Builder() - .setInsertable( AbstractCompositeDefinition.this.isInsertable() ) - .setUpdateable( AbstractCompositeDefinition.this.isUpdateable() ) - .setInsertGenerated( AbstractCompositeDefinition.this.isInsertGenerated() ) - .setUpdateGenerated( AbstractCompositeDefinition.this.isUpdateGenerated() ) + .setInsertable( AbstractCompositionDefinition.this.isInsertable() ) + .setUpdateable( AbstractCompositionDefinition.this.isUpdateable() ) + .setInsertGenerated( AbstractCompositionDefinition.this.isInsertGenerated() ) + .setUpdateGenerated( AbstractCompositionDefinition.this.isUpdateGenerated() ) .setNullable( getType().getPropertyNullability()[currentAttributeNumber] ) .setDirtyCheckable( true ) - .setVersionable( AbstractCompositeDefinition.this.isVersionable() ) + .setVersionable( AbstractCompositionDefinition.this.isVersionable() ) .setCascadeStyle( getType().getCascadeStyle( currentAttributeNumber ) ) .setFetchMode( getType().getFetchMode( currentAttributeNumber ) ) .createInformation(), - AbstractCompositeDefinition.this.attributeNumber(), + AbstractCompositionDefinition.this.attributeNumber(), associationKey ); } else if ( type.isComponentType() ) { - return new CompositeBasedCompositeAttribute( - AbstractCompositeDefinition.this, + return new CompositionBasedCompositionAttribute( + AbstractCompositionDefinition.this, sessionFactory(), currentAttributeNumber, name, (CompositeType) type, new BaselineAttributeInformation.Builder() - .setInsertable( AbstractCompositeDefinition.this.isInsertable() ) - .setUpdateable( AbstractCompositeDefinition.this.isUpdateable() ) - .setInsertGenerated( AbstractCompositeDefinition.this.isInsertGenerated() ) - .setUpdateGenerated( AbstractCompositeDefinition.this.isUpdateGenerated() ) + .setInsertable( AbstractCompositionDefinition.this.isInsertable() ) + .setUpdateable( AbstractCompositionDefinition.this.isUpdateable() ) + .setInsertGenerated( AbstractCompositionDefinition.this.isInsertGenerated() ) + .setUpdateGenerated( AbstractCompositionDefinition.this.isUpdateGenerated() ) .setNullable( getType().getPropertyNullability()[currentAttributeNumber] ) .setDirtyCheckable( true ) - .setVersionable( AbstractCompositeDefinition.this.isVersionable() ) + .setVersionable( AbstractCompositionDefinition.this.isVersionable() ) .setCascadeStyle( getType().getCascadeStyle( currentAttributeNumber ) ) .setFetchMode( getType().getFetchMode( currentAttributeNumber ) ) .createInformation() @@ -161,19 +162,19 @@ else if ( type.isComponentType() ) { } else { return new CompositeBasedBasicAttribute( - AbstractCompositeDefinition.this, + AbstractCompositionDefinition.this, sessionFactory(), currentAttributeNumber, name, type, new BaselineAttributeInformation.Builder() - .setInsertable( AbstractCompositeDefinition.this.isInsertable() ) - .setUpdateable( AbstractCompositeDefinition.this.isUpdateable() ) - .setInsertGenerated( AbstractCompositeDefinition.this.isInsertGenerated() ) - .setUpdateGenerated( AbstractCompositeDefinition.this.isUpdateGenerated() ) + .setInsertable( AbstractCompositionDefinition.this.isInsertable() ) + .setUpdateable( AbstractCompositionDefinition.this.isUpdateable() ) + .setInsertGenerated( AbstractCompositionDefinition.this.isInsertGenerated() ) + .setUpdateGenerated( AbstractCompositionDefinition.this.isUpdateGenerated() ) .setNullable( getType().getPropertyNullability()[currentAttributeNumber] ) .setDirtyCheckable( true ) - .setVersionable( AbstractCompositeDefinition.this.isVersionable() ) + .setVersionable( AbstractCompositionDefinition.this.isVersionable() ) .setCascadeStyle( getType().getCascadeStyle( currentAttributeNumber ) ) .setFetchMode( getType().getFetchMode( currentAttributeNumber ) ) .createInformation() @@ -195,8 +196,13 @@ public EntityPersister locateOwningPersister() { return ( (EntityDefinition) getSource() ).getEntityPersister(); } else { - return ( (AbstractCompositeDefinition) getSource() ).locateOwningPersister(); + return ( (AbstractCompositionDefinition) getSource() ).locateOwningPersister(); } } + + @Override + protected String loggableMetadata() { + return super.loggableMetadata() + ",composition"; + } } diff --git a/hibernate-core/src/main/java/org/hibernate/tuple/component/CompositeBasedAssociationAttribute.java b/hibernate-core/src/main/java/org/hibernate/tuple/component/CompositeBasedAssociationAttribute.java index 0a8be97a92..eb7224d94d 100644 --- a/hibernate-core/src/main/java/org/hibernate/tuple/component/CompositeBasedAssociationAttribute.java +++ b/hibernate-core/src/main/java/org/hibernate/tuple/component/CompositeBasedAssociationAttribute.java @@ -23,6 +23,8 @@ */ package org.hibernate.tuple.component; +import java.io.Serializable; + import org.hibernate.FetchMode; import org.hibernate.engine.FetchStrategy; import org.hibernate.engine.FetchStyle; @@ -34,6 +36,7 @@ import org.hibernate.persister.collection.CollectionPersister; import org.hibernate.persister.entity.EntityPersister; import org.hibernate.persister.entity.Joinable; +import org.hibernate.persister.spi.HydratedCompoundValueHandler; import org.hibernate.persister.walking.internal.Helper; import org.hibernate.persister.walking.spi.AssociationAttributeDefinition; import org.hibernate.persister.walking.spi.AssociationKey; @@ -54,7 +57,7 @@ public class CompositeBasedAssociationAttribute private Joinable joinable; public CompositeBasedAssociationAttribute( - AbstractCompositeDefinition source, + AbstractCompositionDefinition source, SessionFactoryImplementor factory, int attributeNumber, String attributeName, @@ -154,4 +157,29 @@ public CascadeStyle determineCascadeStyle() { final CompositeType compositeType = (CompositeType) locateOwningPersister().getPropertyType( getName() ); return compositeType.getCascadeStyle( attributeNumber() ); } + + private HydratedCompoundValueHandler hydratedCompoundValueHandler; + + @Override + public HydratedCompoundValueHandler getHydratedCompoundValueExtractor() { + if ( hydratedCompoundValueHandler == null ) { + hydratedCompoundValueHandler = new HydratedCompoundValueHandler() { + @Override + public Object extract(Object hydratedState) { + return ( (Object[] ) hydratedState )[ attributeNumber() ]; + } + + @Override + public void inject(Object hydratedState, Object value) { + ( (Object[] ) hydratedState )[ attributeNumber() ] = value; + } + }; + } + return hydratedCompoundValueHandler; + } + + @Override + protected String loggableMetadata() { + return super.loggableMetadata() + ",association"; + } } diff --git a/hibernate-core/src/main/java/org/hibernate/tuple/component/CompositeBasedCompositeAttribute.java b/hibernate-core/src/main/java/org/hibernate/tuple/component/CompositionBasedCompositionAttribute.java similarity index 85% rename from hibernate-core/src/main/java/org/hibernate/tuple/component/CompositeBasedCompositeAttribute.java rename to hibernate-core/src/main/java/org/hibernate/tuple/component/CompositionBasedCompositionAttribute.java index 4094ededd1..7beee25984 100644 --- a/hibernate-core/src/main/java/org/hibernate/tuple/component/CompositeBasedCompositeAttribute.java +++ b/hibernate-core/src/main/java/org/hibernate/tuple/component/CompositionBasedCompositionAttribute.java @@ -24,18 +24,18 @@ package org.hibernate.tuple.component; import org.hibernate.engine.spi.SessionFactoryImplementor; -import org.hibernate.persister.walking.spi.CompositeDefinition; +import org.hibernate.persister.walking.spi.CompositionDefinition; import org.hibernate.tuple.BaselineAttributeInformation; import org.hibernate.type.CompositeType; /** * @author Steve Ebersole */ -public class CompositeBasedCompositeAttribute - extends AbstractCompositeDefinition - implements CompositeDefinition { - public CompositeBasedCompositeAttribute( - CompositeDefinition source, +public class CompositionBasedCompositionAttribute + extends AbstractCompositionDefinition + implements CompositionDefinition { + public CompositionBasedCompositionAttribute( + CompositionDefinition source, SessionFactoryImplementor sessionFactory, int attributeNumber, String attributeName, diff --git a/hibernate-core/src/main/java/org/hibernate/tuple/entity/EntityBasedAssociationAttribute.java b/hibernate-core/src/main/java/org/hibernate/tuple/entity/EntityBasedAssociationAttribute.java index 7177552bbd..d5641ebd87 100644 --- a/hibernate-core/src/main/java/org/hibernate/tuple/entity/EntityBasedAssociationAttribute.java +++ b/hibernate-core/src/main/java/org/hibernate/tuple/entity/EntityBasedAssociationAttribute.java @@ -33,6 +33,7 @@ import org.hibernate.persister.entity.EntityPersister; import org.hibernate.persister.entity.Joinable; import org.hibernate.persister.entity.OuterJoinLoadable; +import org.hibernate.persister.spi.HydratedCompoundValueHandler; import org.hibernate.persister.walking.internal.Helper; import org.hibernate.persister.walking.spi.AssociationAttributeDefinition; import org.hibernate.persister.walking.spi.AssociationKey; @@ -152,4 +153,29 @@ public FetchStrategy determineFetchPlan(LoadQueryInfluencers loadQueryInfluencer public CascadeStyle determineCascadeStyle() { return getSource().getEntityPersister().getPropertyCascadeStyles()[attributeNumber()]; } + + private HydratedCompoundValueHandler hydratedCompoundValueHandler; + + @Override + public HydratedCompoundValueHandler getHydratedCompoundValueExtractor() { + if ( hydratedCompoundValueHandler == null ) { + hydratedCompoundValueHandler = new HydratedCompoundValueHandler() { + @Override + public Object extract(Object hydratedState) { + return ( (Object[] ) hydratedState )[ attributeNumber() ]; + } + + @Override + public void inject(Object hydratedState, Object value) { + ( (Object[] ) hydratedState )[ attributeNumber() ] = value; + } + }; + } + return hydratedCompoundValueHandler; + } + + @Override + protected String loggableMetadata() { + return super.loggableMetadata() + ",association"; + } } diff --git a/hibernate-core/src/main/java/org/hibernate/tuple/entity/EntityBasedCompositeAttribute.java b/hibernate-core/src/main/java/org/hibernate/tuple/entity/EntityBasedCompositionAttribute.java similarity index 84% rename from hibernate-core/src/main/java/org/hibernate/tuple/entity/EntityBasedCompositeAttribute.java rename to hibernate-core/src/main/java/org/hibernate/tuple/entity/EntityBasedCompositionAttribute.java index 8f3a9a6e80..e283cae94b 100644 --- a/hibernate-core/src/main/java/org/hibernate/tuple/entity/EntityBasedCompositeAttribute.java +++ b/hibernate-core/src/main/java/org/hibernate/tuple/entity/EntityBasedCompositionAttribute.java @@ -25,19 +25,19 @@ import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.persister.entity.EntityPersister; -import org.hibernate.tuple.component.AbstractCompositeDefinition; -import org.hibernate.persister.walking.spi.CompositeDefinition; +import org.hibernate.tuple.component.AbstractCompositionDefinition; +import org.hibernate.persister.walking.spi.CompositionDefinition; import org.hibernate.tuple.BaselineAttributeInformation; import org.hibernate.type.CompositeType; /** * @author Steve Ebersole */ -public class EntityBasedCompositeAttribute - extends AbstractCompositeDefinition - implements CompositeDefinition { +public class EntityBasedCompositionAttribute + extends AbstractCompositionDefinition + implements CompositionDefinition { - public EntityBasedCompositeAttribute( + public EntityBasedCompositionAttribute( EntityPersister source, SessionFactoryImplementor factory, int attributeNumber, diff --git a/hibernate-core/src/test/java/org/hibernate/loader/plan/spi/LoadPlanBuilderTest.java b/hibernate-core/src/test/java/org/hibernate/loader/plan/spi/LoadPlanBuilderTest.java index 597b900344..9491d61b95 100644 --- a/hibernate-core/src/test/java/org/hibernate/loader/plan/spi/LoadPlanBuilderTest.java +++ b/hibernate-core/src/test/java/org/hibernate/loader/plan/spi/LoadPlanBuilderTest.java @@ -119,9 +119,9 @@ public void testCollectionInitializerCase() { CollectionReturn collectionReturn = ExtraAssertions.assertTyping( CollectionReturn.class, rtn ); assertEquals( "abc", collectionReturn.getAlias() ); - assertNotNull( collectionReturn.getFetches() ); - assertEquals( 1, collectionReturn.getFetches().length ); // the collection elements are fetched - Fetch fetch = collectionReturn.getFetches()[0]; + assertNotNull( collectionReturn.getElementGraph().getFetches() ); + assertEquals( 1, collectionReturn.getElementGraph().getFetches().length ); // the collection elements are fetched + Fetch fetch = collectionReturn.getElementGraph().getFetches()[0]; EntityFetch entityFetch = ExtraAssertions.assertTyping( EntityFetch.class, fetch ); assertNotNull( entityFetch.getFetches() ); assertEquals( 0, entityFetch.getFetches().length ); @@ -130,8 +130,8 @@ public void testCollectionInitializerCase() { @Entity( name = "Message" ) public static class Message { @Id - private Integer id; - private String name; + private Integer mid; + private String msgTxt; @ManyToOne( cascade = CascadeType.MERGE ) @JoinColumn private Poster poster; @@ -140,7 +140,7 @@ public static class Message { @Entity( name = "Poster" ) public static class Poster { @Id - private Integer id; + private Integer pid; private String name; @OneToMany(mappedBy = "poster") private List messages; diff --git a/hibernate-core/src/test/java/org/hibernate/persister/walking/BasicWalkingTest.java b/hibernate-core/src/test/java/org/hibernate/persister/walking/BasicWalkingTest.java index 07c193bb13..da8bc7f961 100644 --- a/hibernate-core/src/test/java/org/hibernate/persister/walking/BasicWalkingTest.java +++ b/hibernate-core/src/test/java/org/hibernate/persister/walking/BasicWalkingTest.java @@ -35,8 +35,11 @@ import org.hibernate.persister.walking.spi.AssociationVisitationStrategy; import org.hibernate.persister.walking.spi.AttributeDefinition; import org.hibernate.persister.walking.spi.CollectionDefinition; -import org.hibernate.persister.walking.spi.CompositeDefinition; +import org.hibernate.persister.walking.spi.CollectionElementDefinition; +import org.hibernate.persister.walking.spi.CollectionIndexDefinition; +import org.hibernate.persister.walking.spi.CompositionDefinition; import org.hibernate.persister.walking.spi.EntityDefinition; +import org.hibernate.persister.walking.spi.EntityIdentifierDefinition; import org.hibernate.persister.walking.spi.MetadataDrivenModelGraphVisitor; import org.junit.Test; @@ -91,6 +94,16 @@ public void finishingEntity(EntityDefinition entityDefinition) { ); } + @Override + public void startingEntityIdentifier(EntityIdentifierDefinition entityIdentifierDefinition) { + //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + public void finishingEntityIdentifier(EntityIdentifierDefinition entityIdentifierDefinition) { + //To change body of implemented methods use File | Settings | File Templates. + } + @Override public void startingCollection(CollectionDefinition collectionDefinition) { System.out.println( @@ -114,23 +127,43 @@ public void finishingCollection(CollectionDefinition collectionDefinition) { } @Override - public void startingComposite(CompositeDefinition compositeDefinition) { + public void startingCollectionIndex(CollectionIndexDefinition collectionIndexDefinition) { + //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + public void finishingCollectionIndex(CollectionIndexDefinition collectionIndexDefinition) { + //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + public void startingCollectionElements(CollectionElementDefinition elementDefinition) { + //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + public void finishingCollectionElements(CollectionElementDefinition elementDefinition) { + //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + public void startingComposite(CompositionDefinition compositionDefinition) { System.out.println( String.format( "%s Starting composite (%s)", StringHelper.repeat( ">>", ++depth ), - compositeDefinition.toString() + compositionDefinition.toString() ) ); } @Override - public void finishingComposite(CompositeDefinition compositeDefinition) { + public void finishingComposite(CompositionDefinition compositionDefinition) { System.out.println( String.format( "%s Finishing composite (%s)", StringHelper.repeat( ">>", depth-- ), - compositeDefinition.toString() + compositionDefinition.toString() ) ); } diff --git a/hibernate-core/src/test/java/org/hibernate/test/cfg/persister/GoofyPersisterClassProvider.java b/hibernate-core/src/test/java/org/hibernate/test/cfg/persister/GoofyPersisterClassProvider.java index 6af678c8a5..cd85045871 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/cfg/persister/GoofyPersisterClassProvider.java +++ b/hibernate-core/src/test/java/org/hibernate/test/cfg/persister/GoofyPersisterClassProvider.java @@ -58,6 +58,7 @@ import org.hibernate.persister.walking.spi.AttributeDefinition; import org.hibernate.persister.walking.spi.CollectionElementDefinition; import org.hibernate.persister.walking.spi.CollectionIndexDefinition; +import org.hibernate.persister.walking.spi.EntityIdentifierDefinition; import org.hibernate.tuple.entity.EntityMetamodel; import org.hibernate.tuple.entity.EntityTuplizer; import org.hibernate.tuple.entity.NonPojoInstrumentationMetadata; @@ -590,8 +591,8 @@ public EntityPersister getEntityPersister() { } @Override - public Iterable getEmbeddedCompositeIdentifierAttributes() { - throw new NotYetImplementedException(); + public EntityIdentifierDefinition getEntityKeyDefinition() { + return null; //To change body of implemented methods use File | Settings | File Templates. } @Override diff --git a/hibernate-core/src/test/java/org/hibernate/test/legacy/CustomPersister.java b/hibernate-core/src/test/java/org/hibernate/test/legacy/CustomPersister.java index 55b96323ab..ba4ff61bf5 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/legacy/CustomPersister.java +++ b/hibernate-core/src/test/java/org/hibernate/test/legacy/CustomPersister.java @@ -36,6 +36,7 @@ import org.hibernate.metadata.ClassMetadata; import org.hibernate.persister.entity.EntityPersister; import org.hibernate.persister.walking.spi.AttributeDefinition; +import org.hibernate.persister.walking.spi.EntityIdentifierDefinition; import org.hibernate.tuple.entity.EntityMetamodel; import org.hibernate.tuple.entity.EntityTuplizer; import org.hibernate.tuple.entity.NonPojoInstrumentationMetadata; @@ -680,7 +681,7 @@ public EntityPersister getEntityPersister() { } @Override - public Iterable getEmbeddedCompositeIdentifierAttributes() { + public EntityIdentifierDefinition getEntityKeyDefinition() { throw new NotYetImplementedException(); } diff --git a/hibernate-core/src/test/resources/log4j.properties b/hibernate-core/src/test/resources/log4j.properties index 686aae8fc2..73d5935aea 100644 --- a/hibernate-core/src/test/resources/log4j.properties +++ b/hibernate-core/src/test/resources/log4j.properties @@ -9,6 +9,8 @@ log4j.rootLogger=info, stdout log4j.logger.org.hibernate.tool.hbm2ddl=trace log4j.logger.org.hibernate.testing.cache=debug +log4j.logger.org.hibernate.loader.plan=trace + # SQL Logging - HHH-6833 log4j.logger.org.hibernate.SQL=debug From 8b7091e1c74b233d8bafdc961c501857de26df77 Mon Sep 17 00:00:00 2001 From: Steve Ebersole Date: Tue, 12 Mar 2013 10:57:25 -0500 Subject: [PATCH 34/54] HHH-7841 - Redesign Loader --- .../internal/ResultSetProcessorImpl.java | 8 +++++--- ...a => ScrollableResultSetProcessorImpl.java} | 8 ++++---- .../loader/spi/ResultSetProcessor.java | 2 +- ....java => ScrollableResultSetProcessor.java} | 18 +++++++++--------- 4 files changed, 19 insertions(+), 17 deletions(-) rename hibernate-core/src/main/java/org/hibernate/loader/internal/{OnDemandResultSetProcessorImpl.java => ScrollableResultSetProcessorImpl.java} (88%) rename hibernate-core/src/main/java/org/hibernate/loader/spi/{OnDemandResultSetProcessor.java => ScrollableResultSetProcessor.java} (82%) diff --git a/hibernate-core/src/main/java/org/hibernate/loader/internal/ResultSetProcessorImpl.java b/hibernate-core/src/main/java/org/hibernate/loader/internal/ResultSetProcessorImpl.java index d31278e5f5..b97b55f62f 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/internal/ResultSetProcessorImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/internal/ResultSetProcessorImpl.java @@ -31,6 +31,7 @@ import org.jboss.logging.Logger; +import org.hibernate.cfg.NotYetImplementedException; import org.hibernate.dialect.pagination.LimitHelper; import org.hibernate.engine.FetchStyle; import org.hibernate.engine.spi.QueryParameters; @@ -45,7 +46,7 @@ import org.hibernate.loader.plan.spi.Return; import org.hibernate.loader.spi.AfterLoadAction; import org.hibernate.loader.spi.NamedParameterContext; -import org.hibernate.loader.spi.OnDemandResultSetProcessor; +import org.hibernate.loader.spi.ScrollableResultSetProcessor; import org.hibernate.loader.spi.ResultSetProcessor; import org.hibernate.persister.collection.CollectionPersister; import org.hibernate.pretty.MessageHelper; @@ -70,8 +71,9 @@ public ResultSetProcessorImpl(LoadPlan loadPlan) { } @Override - public OnDemandResultSetProcessor toOnDemandForm() { - return null; //To change body of implemented methods use File | Settings | File Templates. + public ScrollableResultSetProcessor toOnDemandForm() { + // todo : implement + throw new NotYetImplementedException(); } @Override diff --git a/hibernate-core/src/main/java/org/hibernate/loader/internal/OnDemandResultSetProcessorImpl.java b/hibernate-core/src/main/java/org/hibernate/loader/internal/ScrollableResultSetProcessorImpl.java similarity index 88% rename from hibernate-core/src/main/java/org/hibernate/loader/internal/OnDemandResultSetProcessorImpl.java rename to hibernate-core/src/main/java/org/hibernate/loader/internal/ScrollableResultSetProcessorImpl.java index 8fc816c9e6..5e2d06104e 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/internal/OnDemandResultSetProcessorImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/internal/ScrollableResultSetProcessorImpl.java @@ -27,12 +27,12 @@ import org.hibernate.engine.spi.QueryParameters; import org.hibernate.engine.spi.SessionImplementor; -import org.hibernate.loader.spi.OnDemandResultSetProcessor; +import org.hibernate.loader.spi.ScrollableResultSetProcessor; /** * @author Steve Ebersole */ -public class OnDemandResultSetProcessorImpl implements OnDemandResultSetProcessor { +public class ScrollableResultSetProcessorImpl implements ScrollableResultSetProcessor { @Override public Object extractSingleRow( ResultSet resultSet, @@ -42,13 +42,13 @@ public Object extractSingleRow( } @Override - public Object extractSequentialRowsForward( + public Object extractLogicalRowForward( ResultSet resultSet, SessionImplementor session, QueryParameters queryParameters) { return null; //To change body of implemented methods use File | Settings | File Templates. } @Override - public Object extractSequentialRowsReverse( + public Object extractLogicalRowReverse( ResultSet resultSet, SessionImplementor session, QueryParameters queryParameters, diff --git a/hibernate-core/src/main/java/org/hibernate/loader/spi/ResultSetProcessor.java b/hibernate-core/src/main/java/org/hibernate/loader/spi/ResultSetProcessor.java index 4dc630c469..89c439dc94 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/spi/ResultSetProcessor.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/spi/ResultSetProcessor.java @@ -41,7 +41,7 @@ */ public interface ResultSetProcessor { - public OnDemandResultSetProcessor toOnDemandForm(); + public ScrollableResultSetProcessor toOnDemandForm(); /** * Process an entire ResultSet, performing all extractions. diff --git a/hibernate-core/src/main/java/org/hibernate/loader/spi/OnDemandResultSetProcessor.java b/hibernate-core/src/main/java/org/hibernate/loader/spi/ScrollableResultSetProcessor.java similarity index 82% rename from hibernate-core/src/main/java/org/hibernate/loader/spi/OnDemandResultSetProcessor.java rename to hibernate-core/src/main/java/org/hibernate/loader/spi/ScrollableResultSetProcessor.java index 27ba73b5a6..3892bba3f5 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/spi/OnDemandResultSetProcessor.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/spi/ScrollableResultSetProcessor.java @@ -37,12 +37,12 @@ * * @author Steve Ebersole */ -public interface OnDemandResultSetProcessor { +public interface ScrollableResultSetProcessor { /** * Give a ResultSet, extract just a single result row. * - * Copy of {@link org.hibernate.loader.Loader#loadSingleRow(java.sql.ResultSet, org.hibernate.engine.spi.SessionImplementor, org.hibernate.engine.spi.QueryParameters, boolean)} + * Copy of {@link org.hibernate.loader.Loader#loadSingleRow(ResultSet, SessionImplementor, QueryParameters, boolean)} * but dropping the 'returnProxies' (that method has only one use in the entire codebase and it always passes in * false...) * @@ -60,11 +60,11 @@ public Object extractSingleRow( QueryParameters queryParameters); /** - * Given a ResultSet extract "sequential rows". This is used in cases where we have multi-row fetches that - * are sequential within the ResultSet due to ordering. Multiple ResultSet rows are read into a single query + * Given a scrollable ResultSet, extract a logical row. The assumption here is that the ResultSet is already + * properly ordered to account for any to-many fetches. Multiple ResultSet rows are read into a single query * result "row". * - * Copy of {@link org.hibernate.loader.Loader#loadSequentialRowsForward(java.sql.ResultSet, org.hibernate.engine.spi.SessionImplementor, org.hibernate.engine.spi.QueryParameters, boolean)} + * Copy of {@link org.hibernate.loader.Loader#loadSequentialRowsForward(ResultSet, SessionImplementor, QueryParameters, boolean)} * but dropping the 'returnProxies' (that method has only one use in the entire codebase and it always passes in * false...) * @@ -76,15 +76,15 @@ public Object extractSingleRow( * * @throws org.hibernate.HibernateException Indicates a problem extracting values from the result set. */ - public Object extractSequentialRowsForward( + public Object extractLogicalRowForward( final ResultSet resultSet, final SessionImplementor session, final QueryParameters queryParameters); /** - * Like {@link #extractSequentialRowsForward} but here moving back through the ResultSet. + * Like {@link #extractLogicalRowForward} but here moving through the ResultSet in reverse. * - * Copy of {@link org.hibernate.loader.Loader#loadSequentialRowsReverse(java.sql.ResultSet, org.hibernate.engine.spi.SessionImplementor, org.hibernate.engine.spi.QueryParameters, boolean, boolean)} + * Copy of {@link org.hibernate.loader.Loader#loadSequentialRowsReverse(ResultSet, SessionImplementor, QueryParameters, boolean, boolean)} * but dropping the 'returnProxies' (that method has only one use in the entire codebase and it always passes in * false...). * @@ -99,7 +99,7 @@ public Object extractSequentialRowsForward( * * @throws org.hibernate.HibernateException Indicates a problem extracting values from the result set. */ - public Object extractSequentialRowsReverse( + public Object extractLogicalRowReverse( ResultSet resultSet, SessionImplementor session, QueryParameters queryParameters, From 6ea20fa308b5477c496f0520c1e6f4d604dac55f Mon Sep 17 00:00:00 2001 From: Gail Badner Date: Tue, 26 Mar 2013 23:18:46 -0700 Subject: [PATCH 35/54] HHH-7841 : Add LoadQuery for generating SQL --- .../plan/internal/EntityLoadQueryImpl.java | 66 +++++++++++++++++++ .../loader/plan/internal/LoadPlanImpl.java | 15 ++++- ...ngleRootReturnLoadPlanBuilderStrategy.java | 20 +++++- .../hibernate/loader/plan/spi/LoadPlan.java | 3 + .../hibernate/loader/plan/spi/LoadQuery.java | 32 +++++++++ .../loader/plan/spi/LoadPlanBuilderTest.java | 4 ++ 6 files changed, 136 insertions(+), 4 deletions(-) create mode 100644 hibernate-core/src/main/java/org/hibernate/loader/plan/internal/EntityLoadQueryImpl.java create mode 100644 hibernate-core/src/main/java/org/hibernate/loader/plan/spi/LoadQuery.java diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/internal/EntityLoadQueryImpl.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/internal/EntityLoadQueryImpl.java new file mode 100644 index 0000000000..77e89e5502 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/internal/EntityLoadQueryImpl.java @@ -0,0 +1,66 @@ +/* + * 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.loader.plan.internal; + +import org.hibernate.LockMode; +import org.hibernate.engine.spi.LoadQueryInfluencers; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.loader.entity.EntityJoinWalker; +import org.hibernate.loader.plan.spi.LoadQuery; +import org.hibernate.persister.entity.OuterJoinLoadable; + +/** + * @author Gail Badner + */ +public class EntityLoadQueryImpl implements LoadQuery { + final SessionFactoryImplementor sessionFactory; + final LoadQueryInfluencers loadQueryInfluencers; + final LockMode lockMode; + final OuterJoinLoadable entityPersister; + + public EntityLoadQueryImpl( + SessionFactoryImplementor sessionFactory, + LoadQueryInfluencers loadQueryInfluencers, + LockMode lockMode, + OuterJoinLoadable entityPersister) { + this.sessionFactory = sessionFactory; + this.loadQueryInfluencers = loadQueryInfluencers; + this.lockMode = lockMode; + this.entityPersister = entityPersister; + + } + + @Override + public String generateSql(int batchSize) { + final EntityJoinWalker entityJoinWalker = new EntityJoinWalker( + entityPersister, + entityPersister.getIdentifierColumnNames(), + batchSize, + lockMode, + sessionFactory, + loadQueryInfluencers + ); + return entityJoinWalker.getSQLString(); + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/internal/LoadPlanImpl.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/internal/LoadPlanImpl.java index 47daeb3c13..959f9223cf 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/plan/internal/LoadPlanImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/internal/LoadPlanImpl.java @@ -26,7 +26,9 @@ import java.util.Collections; import java.util.List; +import org.hibernate.engine.spi.LoadQueryInfluencers; import org.hibernate.loader.plan.spi.LoadPlan; +import org.hibernate.loader.plan.spi.LoadQuery; import org.hibernate.loader.plan.spi.Return; /** @@ -37,14 +39,16 @@ public class LoadPlanImpl implements LoadPlan { private final boolean hasScalars; private final List returns; + private final LoadQuery loadQuery; - public LoadPlanImpl(boolean hasScalars, List returns) { + public LoadPlanImpl(LoadQuery loadQuery, boolean hasScalars, List returns) { + this.loadQuery = loadQuery; this.hasScalars = hasScalars; this.returns = returns; } - public LoadPlanImpl(boolean hasScalars, Return rootReturn) { - this( hasScalars, Collections.singletonList( rootReturn ) ); + public LoadPlanImpl(LoadQuery loadQuery, boolean hasScalars, Return rootReturn) { + this( loadQuery, hasScalars, Collections.singletonList( rootReturn ) ); } @Override @@ -56,4 +60,9 @@ public boolean hasAnyScalarReturns() { public List getReturns() { return returns; } + + @Override + public LoadQuery getLoadQuery() { + return loadQuery; + } } diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/internal/SingleRootReturnLoadPlanBuilderStrategy.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/internal/SingleRootReturnLoadPlanBuilderStrategy.java index fd710aa7f6..181be31b77 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/plan/internal/SingleRootReturnLoadPlanBuilderStrategy.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/internal/SingleRootReturnLoadPlanBuilderStrategy.java @@ -39,9 +39,11 @@ import org.hibernate.loader.plan.spi.EntityReturn; import org.hibernate.loader.plan.spi.LoadPlan; import org.hibernate.loader.plan.spi.LoadPlanBuilderStrategy; +import org.hibernate.loader.plan.spi.LoadQuery; import org.hibernate.loader.plan.spi.Return; import org.hibernate.persister.collection.CollectionPersister; import org.hibernate.persister.entity.EntityPersister; +import org.hibernate.persister.entity.OuterJoinLoadable; import org.hibernate.persister.walking.spi.AssociationAttributeDefinition; import org.hibernate.persister.walking.spi.CollectionDefinition; import org.hibernate.persister.walking.spi.EntityDefinition; @@ -101,7 +103,23 @@ protected void addRootReturn(Return rootReturn) { @Override public LoadPlan buildLoadPlan() { - return new LoadPlanImpl( false, rootReturn ); + return new LoadPlanImpl( createLoadQuery(), false, rootReturn ); + } + + private LoadQuery createLoadQuery() { + if ( EntityReturn.class.isInstance( rootReturn ) ) { + final EntityReturn entityReturn = (EntityReturn) rootReturn; + return new EntityLoadQueryImpl( + sessionFactory(), + loadQueryInfluencers, + entityReturn.getLockMode(), + (OuterJoinLoadable) entityReturn.getEntityPersister() + ); + } + else { + // TODO: create a LoadQuery for other types of returns. + return null; + } } @Override diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/LoadPlan.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/LoadPlan.java index 035f6c0a84..2e999284c4 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/LoadPlan.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/LoadPlan.java @@ -25,6 +25,8 @@ import java.util.List; +import org.hibernate.engine.spi.LoadQueryInfluencers; + /** * Describes a plan for performing a load of results. * @@ -55,6 +57,7 @@ public interface LoadPlan { public List getReturns(); + public LoadQuery getLoadQuery(); // todo : would also like to see "call back" style access for handling "subsequent actions" such as: // 1) follow-on locking diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/LoadQuery.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/LoadQuery.java new file mode 100644 index 0000000000..aa4c82038a --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/LoadQuery.java @@ -0,0 +1,32 @@ +/* + * jDocBook, processing of DocBook sources + * + * 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.loader.plan.spi; + +/** + * @author Gail Badner + */ +public interface LoadQuery { + + String generateSql(int batchSize); +} diff --git a/hibernate-core/src/test/java/org/hibernate/loader/plan/spi/LoadPlanBuilderTest.java b/hibernate-core/src/test/java/org/hibernate/loader/plan/spi/LoadPlanBuilderTest.java index 9491d61b95..f26afd3dea 100644 --- a/hibernate-core/src/test/java/org/hibernate/loader/plan/spi/LoadPlanBuilderTest.java +++ b/hibernate-core/src/test/java/org/hibernate/loader/plan/spi/LoadPlanBuilderTest.java @@ -77,6 +77,10 @@ public void testSimpleBuild() { EntityFetch entityFetch = ExtraAssertions.assertTyping( EntityFetch.class, fetch ); assertNotNull( entityFetch.getFetches() ); assertEquals( 0, entityFetch.getFetches().length ); + + String loadSql = plan.getLoadQuery().generateSql( 1 ); + // TODO: assert that aliases used in loadSql match up with those in entityReturn and entityFetch + // (they currently do not match up) } @Test From 87012e81012ff10fc0ced74f6b86cccd7970cb9f Mon Sep 17 00:00:00 2001 From: Steve Ebersole Date: Mon, 18 Mar 2013 09:30:13 -0500 Subject: [PATCH 36/54] HHH-8077 - Add MDC usage into attribute walking to help decode logs from recursive calls --- .../hibernate/engine/internal/Cascade.java | 2 +- .../hql/internal/ast/tree/DotNode.java | 4 +-- .../internal/ast/tree/FromElementType.java | 4 +-- .../plan/spi/AbstractCollectionReference.java | 11 +++--- .../spi/AbstractLoadPlanBuilderStrategy.java | 29 +++++++++++++++ .../loader/plan/spi/CollectionFetch.java | 5 --- .../loader/plan/spi/CollectionReference.java | 3 ++ .../src/test/resources/log4j.properties | 35 +++++++++++++++++-- .../PersisterClassProviderTest.java | 17 +++++++++ 9 files changed, 93 insertions(+), 17 deletions(-) diff --git a/hibernate-core/src/main/java/org/hibernate/engine/internal/Cascade.java b/hibernate-core/src/main/java/org/hibernate/engine/internal/Cascade.java index cc446c5414..1b9b2e29bf 100644 --- a/hibernate-core/src/main/java/org/hibernate/engine/internal/Cascade.java +++ b/hibernate-core/src/main/java/org/hibernate/engine/internal/Cascade.java @@ -249,7 +249,7 @@ else if ( type.isComponentType() ) { // orphaned value, something a delete with a subquery to // match the owner. // final EntityType entityType = (EntityType) type; -// final String propertyPath = composePropertyPath( entityType.getPropertyName() ); +// final String getPropertyPath = composePropertyPath( entityType.getPropertyName() ); loadedValue = null; } if ( loadedValue != null ) { diff --git a/hibernate-core/src/main/java/org/hibernate/hql/internal/ast/tree/DotNode.java b/hibernate-core/src/main/java/org/hibernate/hql/internal/ast/tree/DotNode.java index 024d4c56a2..c83370e8cd 100644 --- a/hibernate-core/src/main/java/org/hibernate/hql/internal/ast/tree/DotNode.java +++ b/hibernate-core/src/main/java/org/hibernate/hql/internal/ast/tree/DotNode.java @@ -141,7 +141,7 @@ public String getDisplayText() { FromElement fromElement = getFromElement(); buf.append( "{propertyName=" ).append( propertyName ); buf.append( ",dereferenceType=" ).append( getWalker().getASTPrinter().getTokenTypeName( dereferenceType ) ); - buf.append( ",propertyPath=" ).append( propertyPath ); + buf.append( ",getPropertyPath=" ).append( propertyPath ); buf.append( ",path=" ).append( getPath() ); if ( fromElement != null ) { buf.append( ",tableAlias=" ).append( fromElement.getTableAlias() ); @@ -585,7 +585,7 @@ private void setPropertyNameAndPath(AST parent) { LOG.debugf( "Unresolved property path is now '%s'", dotNode.propertyPath ); } else { - LOG.debugf( "Terminal propertyPath = [%s]", propertyPath ); + LOG.debugf( "Terminal getPropertyPath = [%s]", propertyPath ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/hql/internal/ast/tree/FromElementType.java b/hibernate-core/src/main/java/org/hibernate/hql/internal/ast/tree/FromElementType.java index fea26dbc6f..dea3517a6e 100644 --- a/hibernate-core/src/main/java/org/hibernate/hql/internal/ast/tree/FromElementType.java +++ b/hibernate-core/src/main/java/org/hibernate/hql/internal/ast/tree/FromElementType.java @@ -295,13 +295,13 @@ public QueryableCollection getQueryableCollection() { * * @param propertyName The last part of the full path to the property. * @return The type. - * @0param propertyPath The full property path. + * @0param getPropertyPath The full property path. */ public Type getPropertyType(String propertyName, String propertyPath) { checkInitialized(); Type type = null; // If this is an entity and the property is the identifier property, then use getIdentifierType(). - // Note that the propertyName.equals( propertyPath ) checks whether we have a component + // Note that the propertyName.equals( getPropertyPath ) checks whether we have a component // key reference, where the component class property name is the same as the // entity id property name; if the two are not equal, this is the case and // we'd need to "fall through" to using the property mapping. diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/AbstractCollectionReference.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/AbstractCollectionReference.java index e623f0a898..996f7106c2 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/AbstractCollectionReference.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/AbstractCollectionReference.java @@ -72,11 +72,11 @@ private FetchOwner buildIndexGraph(CollectionPersister persister) { final Type type = persister.getIndexType(); if ( type.isAssociationType() ) { if ( type.isEntityType() ) { - return new EntityIndexGraph( sessionFactory(), this, propertyPath() ); + return new EntityIndexGraph( sessionFactory(), this, getPropertyPath() ); } } else if ( type.isComponentType() ) { - return new CompositeIndexGraph( sessionFactory(), this, propertyPath() ); + return new CompositeIndexGraph( sessionFactory(), this, getPropertyPath() ); } } @@ -87,17 +87,18 @@ private FetchOwner buildElementGraph(CollectionPersister persister) { final Type type = persister.getElementType(); if ( type.isAssociationType() ) { if ( type.isEntityType() ) { - return new EntityElementGraph( sessionFactory(), this, propertyPath() ); + return new EntityElementGraph( sessionFactory(), this, getPropertyPath() ); } } else if ( type.isComponentType() ) { - return new CompositeElementGraph( sessionFactory(), this, propertyPath() ); + return new CompositeElementGraph( sessionFactory(), this, getPropertyPath() ); } return null; } - public PropertyPath propertyPath() { + @Override + public PropertyPath getPropertyPath() { return propertyPath; } diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/AbstractLoadPlanBuilderStrategy.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/AbstractLoadPlanBuilderStrategy.java index 2ec4457bfe..2ab7a1ab29 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/AbstractLoadPlanBuilderStrategy.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/AbstractLoadPlanBuilderStrategy.java @@ -33,6 +33,7 @@ import java.util.Map; import org.jboss.logging.Logger; +import org.jboss.logging.MDC; import org.hibernate.HibernateException; import org.hibernate.LockMode; @@ -70,6 +71,7 @@ */ public abstract class AbstractLoadPlanBuilderStrategy implements LoadPlanBuilderStrategy, LoadPlanBuildingContext { private static final Logger log = Logger.getLogger( AbstractLoadPlanBuilderStrategy.class ); + private static final String MDC_KEY = "hibernateLoadPlanWalkPath"; private final SessionFactoryImplementor sessionFactory; @@ -103,10 +105,12 @@ public void start() { "be sure to not use LoadPlanBuilderStrategy instances concurrently" ); } + MDC.put( MDC_KEY, new MDCStack() ); } @Override public void finish() { + MDC.remove( MDC_KEY ); fetchOwnerStack.clear(); collectionReferenceStack.clear(); } @@ -419,12 +423,18 @@ protected boolean isTooManyCollections() { private void pushToStack(FetchOwner fetchOwner) { log.trace( "Pushing fetch owner to stack : " + fetchOwner ); + mdcStack().push( fetchOwner.getPropertyPath() ); fetchOwnerStack.addFirst( fetchOwner ); } + private MDCStack mdcStack() { + return (MDCStack) MDC.get( MDC_KEY ); + } + private FetchOwner popFromStack() { final FetchOwner last = fetchOwnerStack.removeFirst(); log.trace( "Popped fetch owner from stack : " + last ); + mdcStack().pop(); if ( FetchStackAware.class.isInstance( last ) ) { ( (FetchStackAware) last ).poppedFromStack(); } @@ -433,12 +443,14 @@ private FetchOwner popFromStack() { private void pushToCollectionStack(CollectionReference collectionReference) { log.trace( "Pushing collection reference to stack : " + collectionReference ); + mdcStack().push( collectionReference.getPropertyPath() ); collectionReferenceStack.addFirst( collectionReference ); } private CollectionReference popFromCollectionStack() { final CollectionReference last = collectionReferenceStack.removeFirst(); log.trace( "Popped collection reference from stack : " + last ); + mdcStack().pop(); if ( FetchStackAware.class.isInstance( last ) ) { ( (FetchStackAware) last ).poppedFromStack(); } @@ -722,4 +734,21 @@ public EntityKey resolve(ResultSet resultSet, ResultSetProcessingContext context return context.getSession().generateEntityKey( resolvedId, entityReference.getEntityPersister() ); } } + + public static class MDCStack { + private ArrayDeque pathStack = new ArrayDeque(); + + public void push(PropertyPath path) { + pathStack.addFirst( path ); + } + + public void pop() { + pathStack.removeFirst(); + } + + public String toString() { + final PropertyPath path = pathStack.peekFirst(); + return path == null ? "" : path.getFullPath(); + } + } } diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/CollectionFetch.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/CollectionFetch.java index b5ad2e9e04..ae79e5db80 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/CollectionFetch.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/CollectionFetch.java @@ -80,11 +80,6 @@ public FetchStrategy getFetchStrategy() { return fetchStrategy; } - @Override - public PropertyPath getPropertyPath() { - return propertyPath(); - } - @Override public void hydrate(ResultSet resultSet, ResultSetProcessingContext context) throws SQLException { //To change body of implemented methods use File | Settings | File Templates. diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/CollectionReference.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/CollectionReference.java index da4acdcbb3..c67f803793 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/CollectionReference.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/CollectionReference.java @@ -26,6 +26,7 @@ import org.hibernate.LockMode; import org.hibernate.loader.CollectionAliases; import org.hibernate.loader.EntityAliases; +import org.hibernate.loader.PropertyPath; import org.hibernate.persister.collection.CollectionPersister; /** @@ -59,6 +60,8 @@ public interface CollectionReference { public FetchOwner getElementGraph(); + public PropertyPath getPropertyPath(); + public boolean hasEntityElements(); /** diff --git a/hibernate-core/src/test/resources/log4j.properties b/hibernate-core/src/test/resources/log4j.properties index 73d5935aea..51025a3b1e 100644 --- a/hibernate-core/src/test/resources/log4j.properties +++ b/hibernate-core/src/test/resources/log4j.properties @@ -1,16 +1,47 @@ +# +# 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 +# log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.Target=System.out log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n +#log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L (hibernateLoadPlanWalkPath->%X{hibernateLoadPlanWalkPath}) - %m%n +log4j.appender.stdout-mdc=org.apache.log4j.ConsoleAppender +log4j.appender.stdout-mdc.Target=System.out +log4j.appender.stdout-mdc.layout=org.apache.log4j.PatternLayout +log4j.appender.stdout-mdc.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L (walk path -> %X{hibernateLoadPlanWalkPath}) - %m%n log4j.rootLogger=info, stdout +log4j.logger.org.hibernate.loader.plan=trace, stdout-mdc +log4j.additivity.org.hibernate.loader.plan=false +log4j.logger.org.hibernate.persister.walking=trace, stdout-mdc +log4j.additivity.org.hibernate.persister.walking=false + log4j.logger.org.hibernate.tool.hbm2ddl=trace log4j.logger.org.hibernate.testing.cache=debug -log4j.logger.org.hibernate.loader.plan=trace - # SQL Logging - HHH-6833 log4j.logger.org.hibernate.SQL=debug diff --git a/hibernate-entitymanager/src/test/java/org/hibernate/jpa/test/ejb3configuration/PersisterClassProviderTest.java b/hibernate-entitymanager/src/test/java/org/hibernate/jpa/test/ejb3configuration/PersisterClassProviderTest.java index e217265aa0..c506af986c 100644 --- a/hibernate-entitymanager/src/test/java/org/hibernate/jpa/test/ejb3configuration/PersisterClassProviderTest.java +++ b/hibernate-entitymanager/src/test/java/org/hibernate/jpa/test/ejb3configuration/PersisterClassProviderTest.java @@ -60,6 +60,8 @@ import org.hibernate.persister.entity.EntityPersister; import org.hibernate.persister.internal.PersisterClassResolverInitiator; import org.hibernate.persister.spi.PersisterClassResolver; +import org.hibernate.persister.walking.spi.AttributeDefinition; +import org.hibernate.persister.walking.spi.EntityIdentifierDefinition; import org.hibernate.tuple.entity.EntityMetamodel; import org.hibernate.tuple.entity.EntityTuplizer; import org.hibernate.tuple.entity.NonPojoInstrumentationMetadata; @@ -609,6 +611,21 @@ public CacheEntry buildCacheEntry(Object entity, Object[] state, Object version, // TODO Auto-generated method stub return null; } + + @Override + public EntityPersister getEntityPersister() { + return this; + } + + @Override + public EntityIdentifierDefinition getEntityKeyDefinition() { + return null; //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + public Iterable getAttributes() { + return null; //To change body of implemented methods use File | Settings | File Templates. + } } public static class GoofyException extends RuntimeException { From 1b10ee72f534540f65eecf64946c652091a3d096 Mon Sep 17 00:00:00 2001 From: Steve Ebersole Date: Wed, 27 Mar 2013 08:17:50 -0500 Subject: [PATCH 37/54] HHH-7841 - Redesign Loader - initial test of ResultSetProcessor --- .../ResultSetProcessingContextImpl.java | 8 +- .../internal/ResultSetProcessorImpl.java | 3 +- .../spi/AbstractLoadPlanBuilderStrategy.java | 54 +++--- .../loader/plan/spi/EntityElementGraph.java | 6 + .../loader/plan/spi/EntityFetch.java | 5 + .../loader/plan/spi/EntityIndexGraph.java | 6 + .../loader/plan/spi/EntityReference.java | 8 + .../loader/plan/spi/EntityReturn.java | 89 +++++++++- .../spi/ResultSetProcessingContext.java | 4 +- .../loader/SimpleResultSetProcessorTest.java | 158 ++++++++++++++++++ 10 files changed, 310 insertions(+), 31 deletions(-) create mode 100644 hibernate-core/src/test/java/org/hibernate/loader/SimpleResultSetProcessorTest.java diff --git a/hibernate-core/src/main/java/org/hibernate/loader/internal/ResultSetProcessingContextImpl.java b/hibernate-core/src/main/java/org/hibernate/loader/internal/ResultSetProcessingContextImpl.java index 2e390c980b..98d87b43e7 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/internal/ResultSetProcessingContextImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/internal/ResultSetProcessingContextImpl.java @@ -141,7 +141,7 @@ public IdentifierResolutionContext getIdentifierResolutionContext(final EntityRe IdentifierResolutionContext context = identifierResolutionContextMap.get( entityReference ); if ( context == null ) { context = new IdentifierResolutionContext() { - private Serializable hydratedForm; + private Object hydratedForm; private EntityKey entityKey; @Override @@ -150,7 +150,7 @@ public EntityReference getEntityReference() { } @Override - public void registerHydratedForm(Serializable hydratedForm) { + public void registerHydratedForm(Object hydratedForm) { if ( this.hydratedForm != null ) { // this could be bad... } @@ -158,7 +158,7 @@ public void registerHydratedForm(Serializable hydratedForm) { } @Override - public Serializable getHydratedForm() { + public Object getHydratedForm() { return hydratedForm; } @@ -514,7 +514,7 @@ private void postLoad(PostLoadEvent postLoadEvent, List afterLo } private void createSubselects() { - if ( subselectLoadableEntityKeyMap.size() <= 1 ) { + if ( subselectLoadableEntityKeyMap == null || subselectLoadableEntityKeyMap.size() <= 1 ) { // if we only returned one entity, query by key is more efficient; so do nothing here return; } diff --git a/hibernate-core/src/main/java/org/hibernate/loader/internal/ResultSetProcessorImpl.java b/hibernate-core/src/main/java/org/hibernate/loader/internal/ResultSetProcessorImpl.java index b97b55f62f..479f12e6b9 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/internal/ResultSetProcessorImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/internal/ResultSetProcessorImpl.java @@ -104,7 +104,8 @@ public List extractResults( session, loadPlan, readOnly, - true, // use optional entity key? for now, always say yes +// true, // use optional entity key? for now, always say yes + false, // use optional entity key? actually for now always say no since in the simple test cases true causes failures because there is no optional key queryParameters, namedParameterContext, hadSubselectFetches diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/AbstractLoadPlanBuilderStrategy.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/AbstractLoadPlanBuilderStrategy.java index 2ab7a1ab29..8c61e92a60 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/AbstractLoadPlanBuilderStrategy.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/AbstractLoadPlanBuilderStrategy.java @@ -629,6 +629,11 @@ public PropertyPath getPropertyPath() { return propertyPath; } + @Override + public EntityAliases getEntityAliases() { + return entityReference.getEntityAliases(); + } + @Override public void injectIdentifierDescription(IdentifierDescription identifierDescription) { throw new WalkingException( @@ -689,27 +694,38 @@ public Fetch[] getFetches() { public void hydrate(ResultSet resultSet, ResultSetProcessingContext context) throws SQLException { final IdentifierResolutionContext ownerIdentifierResolutionContext = context.getIdentifierResolutionContext( entityReference ); - final Serializable ownerIdentifierHydratedState = ownerIdentifierResolutionContext.getHydratedForm(); + final Object ownerIdentifierHydratedState = ownerIdentifierResolutionContext.getHydratedForm(); - for ( EntityFetch fetch : identifierFetches ) { - final IdentifierResolutionContext identifierResolutionContext = - context.getIdentifierResolutionContext( fetch ); - // if the identifier was already hydrated, nothing to do - if ( identifierResolutionContext.getHydratedForm() != null ) { - continue; + if ( ownerIdentifierHydratedState != null ) { + for ( EntityFetch fetch : identifierFetches ) { + final IdentifierResolutionContext identifierResolutionContext = + context.getIdentifierResolutionContext( fetch ); + // if the identifier was already hydrated, nothing to do + if ( identifierResolutionContext.getHydratedForm() != null ) { + continue; + } + + // try to extract the sub-hydrated value from the owners tuple array + if ( fetchToHydratedStateExtractorMap != null && ownerIdentifierHydratedState != null ) { + Serializable extracted = (Serializable) fetchToHydratedStateExtractorMap.get( fetch ) + .extract( ownerIdentifierHydratedState ); + identifierResolutionContext.registerHydratedForm( extracted ); + continue; + } + + // if we can't, then read from result set + fetch.hydrate( resultSet, context ); } - - // try to extract the sub-hydrated value from the owners tuple array - if ( fetchToHydratedStateExtractorMap != null && ownerIdentifierHydratedState != null ) { - Serializable extracted = (Serializable) fetchToHydratedStateExtractorMap.get( fetch ) - .extract( ownerIdentifierHydratedState ); - identifierResolutionContext.registerHydratedForm( extracted ); - continue; - } - - // if we can't, then read from result set - fetch.hydrate( resultSet, context ); + return; } + + final Object hydratedIdentifierState = entityReference.getEntityPersister().getIdentifierType().hydrate( + resultSet, + entityReference.getEntityAliases().getSuffixedKeyAliases(), + context.getSession(), + null + ); + context.getIdentifierResolutionContext( entityReference ).registerHydratedForm( hydratedIdentifierState ); } @Override @@ -727,7 +743,7 @@ public EntityKey resolve(ResultSet resultSet, ResultSetProcessingContext context final IdentifierResolutionContext ownerIdentifierResolutionContext = context.getIdentifierResolutionContext( entityReference ); - Serializable hydratedState = ownerIdentifierResolutionContext.getHydratedForm(); + Object hydratedState = ownerIdentifierResolutionContext.getHydratedForm(); Serializable resolvedId = (Serializable) entityReference.getEntityPersister() .getIdentifierType() .resolve( hydratedState, context.getSession(), null ); diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/EntityElementGraph.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/EntityElementGraph.java index b7da167727..dbb2dc1129 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/EntityElementGraph.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/EntityElementGraph.java @@ -6,6 +6,7 @@ import org.hibernate.LockMode; import org.hibernate.engine.FetchStrategy; import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.loader.EntityAliases; import org.hibernate.loader.PropertyPath; import org.hibernate.loader.plan.internal.LoadPlanBuildingHelper; import org.hibernate.persister.collection.CollectionPersister; @@ -61,6 +62,11 @@ public IdentifierDescription getIdentifierDescription() { return identifierDescription; } + @Override + public EntityAliases getEntityAliases() { + return collectionReference.getElementEntityAliases(); + } + @Override public void addFetch(Fetch fetch) { if ( fetches == null ) { diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/EntityFetch.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/EntityFetch.java index dac6350468..7b4ebd1436 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/EntityFetch.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/EntityFetch.java @@ -79,6 +79,11 @@ public IdentifierDescription getIdentifierDescription() { return identifierDescription; } + @Override + public EntityAliases getEntityAliases() { + return entityAliases; + } + @Override public EntityPersister retrieveFetchSourcePersister() { return persister; diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/EntityIndexGraph.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/EntityIndexGraph.java index 8d7c50de55..234efab221 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/EntityIndexGraph.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/EntityIndexGraph.java @@ -29,6 +29,7 @@ import org.hibernate.LockMode; import org.hibernate.engine.FetchStrategy; import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.loader.EntityAliases; import org.hibernate.loader.PropertyPath; import org.hibernate.loader.plan.internal.LoadPlanBuildingHelper; import org.hibernate.persister.collection.CollectionPersister; @@ -83,6 +84,11 @@ public IdentifierDescription getIdentifierDescription() { return identifierDescription; } + @Override + public EntityAliases getEntityAliases() { + return null; + } + @Override public void addFetch(Fetch fetch) { if ( fetches == null ) { diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/EntityReference.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/EntityReference.java index 401a478eed..a0ee50051e 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/EntityReference.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/EntityReference.java @@ -24,6 +24,7 @@ package org.hibernate.loader.plan.spi; import org.hibernate.LockMode; +import org.hibernate.loader.EntityAliases; import org.hibernate.persister.entity.EntityPersister; /** @@ -54,4 +55,11 @@ public interface EntityReference extends IdentifierDescriptionInjectable { public EntityPersister getEntityPersister(); public IdentifierDescription getIdentifierDescription(); + + /** + * Ugh. *Really* hate this here. + * + * @return + */ + public EntityAliases getEntityAliases(); } diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/EntityReturn.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/EntityReturn.java index 7ec852d714..cb22dfac20 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/EntityReturn.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/EntityReturn.java @@ -23,18 +23,17 @@ */ package org.hibernate.loader.plan.spi; -import java.io.Serializable; import java.sql.ResultSet; import java.sql.SQLException; -import org.hibernate.HibernateException; +import org.hibernate.AssertionFailure; import org.hibernate.LockMode; +import org.hibernate.WrongClassException; import org.hibernate.engine.FetchStrategy; import org.hibernate.engine.spi.EntityKey; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.loader.EntityAliases; import org.hibernate.loader.PropertyPath; -import org.hibernate.loader.internal.ResultSetProcessorHelper; import org.hibernate.loader.plan.internal.LoadPlanBuildingHelper; import org.hibernate.loader.spi.ResultSetProcessingContext; import org.hibernate.persister.entity.EntityPersister; @@ -90,6 +89,11 @@ public IdentifierDescription getIdentifierDescription() { return identifierDescription; } + @Override + public EntityAliases getEntityAliases() { + return entityAliases; + } + @Override public void validateFetchPlan(FetchStrategy fetchStrategy) { } @@ -156,7 +160,7 @@ public void hydrate(ResultSet resultSet, ResultSetProcessingContext context) thr public void resolve(ResultSet resultSet, ResultSetProcessingContext context) throws SQLException { final IdentifierResolutionContext identifierResolutionContext = context.getIdentifierResolutionContext( this ); EntityKey entityKey = identifierResolutionContext.getEntityKey(); - if ( entityKey == null ) { + if ( entityKey != null ) { return; } @@ -170,7 +174,82 @@ public void resolve(ResultSet resultSet, ResultSetProcessingContext context) thr @Override public Object read(ResultSet resultSet, ResultSetProcessingContext context) throws SQLException { - return null; + final IdentifierResolutionContext identifierResolutionContext = context.getIdentifierResolutionContext( this ); + EntityKey entityKey = identifierResolutionContext.getEntityKey(); + if ( entityKey == null ) { + throw new AssertionFailure( "Could not locate resolved EntityKey"); + } + + final Object existing = context.getSession().getEntityUsingInterceptor( entityKey ); + + if ( existing != null ) { + if ( !persister.isInstance( existing ) ) { + throw new WrongClassException( + "loaded object was of wrong class " + existing.getClass(), + entityKey.getIdentifier(), + persister.getEntityName() + ); + } + + if ( getLockMode() != null && getLockMode() != LockMode.NONE ) { + final boolean isVersionCheckNeeded = persister.isVersioned() + && context.getSession().getPersistenceContext().getEntry( existing ).getLockMode().lessThan( getLockMode() ); + + // we don't need to worry about existing version being uninitialized because this block isn't called + // by a re-entrant load (re-entrant loads _always_ have lock mode NONE) + if ( isVersionCheckNeeded ) { + //we only check the version when _upgrading_ lock modes + context.checkVersion( + resultSet, + persister, + entityAliases, + entityKey, + existing + ); + //we need to upgrade the lock mode to the mode requested + context.getSession().getPersistenceContext().getEntry( existing ).setLockMode( getLockMode() ); + } + } + + return existing; + } + else { + final String concreteEntityTypeName = context.getConcreteEntityTypeName( + resultSet, + persister, + entityAliases, + entityKey + ); + + final Object entityInstance = context.getSession().instantiate( + concreteEntityTypeName, + entityKey.getIdentifier() + ); + + //need to hydrate it. + + // grab its state from the ResultSet and keep it in the Session + // (but don't yet initialize the object itself) + // note that we acquire LockMode.READ even if it was not requested + LockMode acquiredLockMode = getLockMode() == LockMode.NONE ? LockMode.READ : getLockMode(); + + context.loadFromResultSet( + resultSet, + entityInstance, + concreteEntityTypeName, + entityKey, + entityAliases, + acquiredLockMode, + persister, + true, + persister.getEntityMetamodel().getEntityType() + ); + + // materialize associations (and initialize the object) later + context.registerHydratedEntity( persister, entityKey, entityInstance ); + + return entityInstance; + } } @Override diff --git a/hibernate-core/src/main/java/org/hibernate/loader/spi/ResultSetProcessingContext.java b/hibernate-core/src/main/java/org/hibernate/loader/spi/ResultSetProcessingContext.java index 6af2fb8da1..e6a65aa32d 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/spi/ResultSetProcessingContext.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/spi/ResultSetProcessingContext.java @@ -54,9 +54,9 @@ public interface ResultSetProcessingContext { public static interface IdentifierResolutionContext { public EntityReference getEntityReference(); - public void registerHydratedForm(Serializable hydratedForm); + public void registerHydratedForm(Object hydratedForm); - public Serializable getHydratedForm(); + public Object getHydratedForm(); public void registerEntityKey(EntityKey entityKey); diff --git a/hibernate-core/src/test/java/org/hibernate/loader/SimpleResultSetProcessorTest.java b/hibernate-core/src/test/java/org/hibernate/loader/SimpleResultSetProcessorTest.java new file mode 100644 index 0000000000..23f983628e --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/loader/SimpleResultSetProcessorTest.java @@ -0,0 +1,158 @@ +/* + * 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.loader; + +import javax.persistence.Entity; +import javax.persistence.Id; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import org.hibernate.LockMode; +import org.hibernate.Session; +import org.hibernate.engine.jdbc.spi.StatementPreparer; +import org.hibernate.engine.spi.LoadQueryInfluencers; +import org.hibernate.engine.spi.QueryParameters; +import org.hibernate.engine.spi.SessionImplementor; +import org.hibernate.jdbc.Work; +import org.hibernate.loader.entity.BatchingEntityLoaderBuilder; +import org.hibernate.loader.entity.EntityLoader; +import org.hibernate.loader.internal.ResultSetProcessorImpl; +import org.hibernate.loader.plan.internal.SingleRootReturnLoadPlanBuilderStrategy; +import org.hibernate.loader.plan.spi.LoadPlan; +import org.hibernate.loader.plan.spi.LoadPlanBuilder; +import org.hibernate.loader.spi.NamedParameterContext; +import org.hibernate.persister.entity.EntityPersister; +import org.hibernate.persister.entity.OuterJoinLoadable; + +import org.junit.Test; + +import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; +import org.hibernate.testing.junit4.ExtraAssertions; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +/** + * @author Steve Ebersole + */ +public class SimpleResultSetProcessorTest extends BaseCoreFunctionalTestCase { + + @Override + protected Class[] getAnnotatedClasses() { + return new Class[] { SimpleEntity.class }; + } + + @Test + public void testSimpleEntityProcessing() throws Exception { + // create some test data + Session session = openSession(); + session.beginTransaction(); + session.save( new SimpleEntity( 1, "the only" ) ); + session.getTransaction().commit(); + session.close(); + + { + final Session workSession = openSession(); + workSession.beginTransaction(); + final EntityPersister entityPersister = sessionFactory().getEntityPersister( SimpleEntity.class.getName() ); + final EntityLoader loader = (EntityLoader) BatchingEntityLoaderBuilder.getBuilder( sessionFactory() ) + .buildLoader( (OuterJoinLoadable) entityPersister, -1, LockMode.NONE, sessionFactory(), LoadQueryInfluencers.NONE ); + final String sql = loader.getSQLString(); + final SingleRootReturnLoadPlanBuilderStrategy strategy = new SingleRootReturnLoadPlanBuilderStrategy( + sessionFactory(), + LoadQueryInfluencers.NONE, + "abc", + 0 + ); + final LoadPlan plan = LoadPlanBuilder.buildRootEntityLoadPlan( strategy, entityPersister ); + final ResultSetProcessorImpl resultSetProcessor = new ResultSetProcessorImpl( plan ); + final List results = new ArrayList(); + workSession.doWork( + new Work() { + @Override + public void execute(Connection connection) throws SQLException { + PreparedStatement ps = connection.prepareStatement( sql ); + ps.setInt( 1, 1 ); + ResultSet resultSet = ps.executeQuery(); + results.addAll( + resultSetProcessor.extractResults( + resultSet, + (SessionImplementor) workSession, + new QueryParameters(), + new NamedParameterContext() { + @Override + public int[] getNamedParameterLocations(String name) { + return new int[0]; + } + }, + true, + false, + null, + null + ) + ); + resultSet.close(); + ps.close(); + } + } + ); + assertEquals( 1, results.size() ); + Object result = results.get( 0 ); + assertNotNull( result ); + + SimpleEntity workEntity = ExtraAssertions.assertTyping( SimpleEntity.class, result ); + assertEquals( 1, workEntity.id.intValue() ); + assertEquals( "the only", workEntity.name ); + workSession.getTransaction().commit(); + workSession.close(); + } + + // clean up test data + session = openSession(); + session.beginTransaction(); + session.createQuery( "delete SimpleEntity" ).executeUpdate(); + session.getTransaction().commit(); + session.close(); + } + + @Entity(name = "SimpleEntity") + public static class SimpleEntity { + @Id public Integer id; + public String name; + + public SimpleEntity() { + } + + public SimpleEntity(Integer id, String name) { + this.id = id; + this.name = name; + } + } +} From 88d5c02d7f8c68b035445ca5d3d1ba87879c39b6 Mon Sep 17 00:00:00 2001 From: Steve Ebersole Date: Wed, 27 Mar 2013 08:29:24 -0500 Subject: [PATCH 38/54] HHH-7841 - Redesign Loader --- .../loader/SimpleResultSetProcessorTest.java | 20 +++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/hibernate-core/src/test/java/org/hibernate/loader/SimpleResultSetProcessorTest.java b/hibernate-core/src/test/java/org/hibernate/loader/SimpleResultSetProcessorTest.java index 23f983628e..1674f43f54 100644 --- a/hibernate-core/src/test/java/org/hibernate/loader/SimpleResultSetProcessorTest.java +++ b/hibernate-core/src/test/java/org/hibernate/loader/SimpleResultSetProcessorTest.java @@ -44,6 +44,7 @@ import org.hibernate.loader.entity.BatchingEntityLoaderBuilder; import org.hibernate.loader.entity.EntityLoader; import org.hibernate.loader.internal.ResultSetProcessorImpl; +import org.hibernate.loader.plan.internal.EntityLoadQueryImpl; import org.hibernate.loader.plan.internal.SingleRootReturnLoadPlanBuilderStrategy; import org.hibernate.loader.plan.spi.LoadPlan; import org.hibernate.loader.plan.spi.LoadPlanBuilder; @@ -71,6 +72,8 @@ protected Class[] getAnnotatedClasses() { @Test public void testSimpleEntityProcessing() throws Exception { + final EntityPersister entityPersister = sessionFactory().getEntityPersister( SimpleEntity.class.getName() ); + // create some test data Session session = openSession(); session.beginTransaction(); @@ -79,12 +82,14 @@ public void testSimpleEntityProcessing() throws Exception { session.close(); { - final Session workSession = openSession(); - workSession.beginTransaction(); - final EntityPersister entityPersister = sessionFactory().getEntityPersister( SimpleEntity.class.getName() ); - final EntityLoader loader = (EntityLoader) BatchingEntityLoaderBuilder.getBuilder( sessionFactory() ) - .buildLoader( (OuterJoinLoadable) entityPersister, -1, LockMode.NONE, sessionFactory(), LoadQueryInfluencers.NONE ); - final String sql = loader.getSQLString(); + final EntityLoadQueryImpl queryBuilder = new EntityLoadQueryImpl( + sessionFactory(), + LoadQueryInfluencers.NONE, + LockMode.NONE, + (OuterJoinLoadable) entityPersister + ); + final String sql = queryBuilder.generateSql( 1 ); + final SingleRootReturnLoadPlanBuilderStrategy strategy = new SingleRootReturnLoadPlanBuilderStrategy( sessionFactory(), LoadQueryInfluencers.NONE, @@ -94,6 +99,9 @@ public void testSimpleEntityProcessing() throws Exception { final LoadPlan plan = LoadPlanBuilder.buildRootEntityLoadPlan( strategy, entityPersister ); final ResultSetProcessorImpl resultSetProcessor = new ResultSetProcessorImpl( plan ); final List results = new ArrayList(); + + final Session workSession = openSession(); + workSession.beginTransaction(); workSession.doWork( new Work() { @Override From 3f8699c9139be43048c27c4e5a6069900cf72dde Mon Sep 17 00:00:00 2001 From: Steve Ebersole Date: Wed, 27 Mar 2013 09:11:11 -0500 Subject: [PATCH 39/54] HHH-7841 - Redesign Loader --- .../ResultSetProcessingContextImpl.java | 176 +++++++++++++++--- .../loader/plan/spi/EntityReturn.java | 77 +------- .../loader/spi/NamedParameterContext.java | 2 +- .../hibernate/loader/spi/ResultBuilder.java | 7 - .../spi/ResultSetProcessingContext.java | 19 +- 5 files changed, 167 insertions(+), 114 deletions(-) delete mode 100644 hibernate-core/src/main/java/org/hibernate/loader/spi/ResultBuilder.java diff --git a/hibernate-core/src/main/java/org/hibernate/loader/internal/ResultSetProcessingContextImpl.java b/hibernate-core/src/main/java/org/hibernate/loader/internal/ResultSetProcessingContextImpl.java index 98d87b43e7..9ff106ee58 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/internal/ResultSetProcessingContextImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/internal/ResultSetProcessingContextImpl.java @@ -187,22 +187,31 @@ public void checkVersion( EntityPersister persister, EntityAliases entityAliases, EntityKey entityKey, - Object entityInstance) throws SQLException { + Object entityInstance) { final Object version = session.getPersistenceContext().getEntry( entityInstance ).getVersion(); if ( version != null ) { //null version means the object is in the process of being loaded somewhere else in the ResultSet VersionType versionType = persister.getVersionType(); - Object currentVersion = versionType.nullSafeGet( - resultSet, - entityAliases.getSuffixedVersionAliases(), - session, - null - ); - if ( !versionType.isEqual(version, currentVersion) ) { + final Object currentVersion; + try { + currentVersion = versionType.nullSafeGet( + resultSet, + entityAliases.getSuffixedVersionAliases(), + session, + null + ); + } + catch (SQLException e) { + throw getSession().getFactory().getJdbcServices().getSqlExceptionHelper().convert( + e, + "Could not read version value from result set" + ); + } + + if ( !versionType.isEqual( version, currentVersion ) ) { if ( session.getFactory().getStatistics().isStatisticsEnabled() ) { - session.getFactory().getStatisticsImplementor() - .optimisticFailure( persister.getEntityName() ); + session.getFactory().getStatisticsImplementor().optimisticFailure( persister.getEntityName() ); } throw new StaleObjectStateException( persister.getEntityName(), entityKey.getIdentifier() ); } @@ -214,19 +223,28 @@ public String getConcreteEntityTypeName( final ResultSet rs, final EntityPersister persister, final EntityAliases entityAliases, - final EntityKey entityKey) throws SQLException { + final EntityKey entityKey) { final Loadable loadable = (Loadable) persister; if ( ! loadable.hasSubclasses() ) { return persister.getEntityName(); } - final Object discriminatorValue = loadable.getDiscriminatorType().nullSafeGet( - rs, - entityAliases.getSuffixedDiscriminatorAlias(), - session, - null - ); + final Object discriminatorValue; + try { + discriminatorValue = loadable.getDiscriminatorType().nullSafeGet( + rs, + entityAliases.getSuffixedDiscriminatorAlias(), + session, + null + ); + } + catch (SQLException e) { + throw getSession().getFactory().getJdbcServices().getSqlExceptionHelper().convert( + e, + "Could not read discriminator value from ResultSet" + ); + } final String result = loadable.getSubclassForDiscriminatorValue( discriminatorValue ); @@ -242,6 +260,90 @@ public String getConcreteEntityTypeName( return result; } + @Override + public Object resolveEntityKey(EntityKey entityKey, EntityKeyResolutionContext entityKeyContext) { + final Object existing = getSession().getEntityUsingInterceptor( entityKey ); + + if ( existing != null ) { + if ( !entityKeyContext.getEntityPersister().isInstance( existing ) ) { + throw new WrongClassException( + "loaded object was of wrong class " + existing.getClass(), + entityKey.getIdentifier(), + entityKeyContext.getEntityPersister().getEntityName() + ); + } + + final LockMode requestedLockMode = entityKeyContext.getLockMode() == null + ? LockMode.NONE + : entityKeyContext.getLockMode(); + + if ( requestedLockMode != LockMode.NONE ) { + final LockMode currentLockMode = getSession().getPersistenceContext().getEntry( existing ).getLockMode(); + final boolean isVersionCheckNeeded = entityKeyContext.getEntityPersister().isVersioned() + && currentLockMode.lessThan( requestedLockMode ); + + // we don't need to worry about existing version being uninitialized because this block isn't called + // by a re-entrant load (re-entrant loads *always* have lock mode NONE) + if ( isVersionCheckNeeded ) { + //we only check the version when *upgrading* lock modes + checkVersion( + resultSet, + entityKeyContext.getEntityPersister(), + entityKeyContext.getEntityAliases(), + entityKey, + existing + ); + //we need to upgrade the lock mode to the mode requested + getSession().getPersistenceContext().getEntry( existing ).setLockMode( requestedLockMode ); + } + } + + return existing; + } + else { + final String concreteEntityTypeName = getConcreteEntityTypeName( + resultSet, + entityKeyContext.getEntityPersister(), + entityKeyContext.getEntityAliases(), + entityKey + ); + + final Object entityInstance = getSession().instantiate( + concreteEntityTypeName, + entityKey.getIdentifier() + ); + + //need to hydrate it. + + // grab its state from the ResultSet and keep it in the Session + // (but don't yet initialize the object itself) + // note that we acquire LockMode.READ even if it was not requested + final LockMode requestedLockMode = entityKeyContext.getLockMode() == null + ? LockMode.NONE + : entityKeyContext.getLockMode(); + final LockMode acquiredLockMode = requestedLockMode == LockMode.NONE + ? LockMode.READ + : requestedLockMode; + + loadFromResultSet( + resultSet, + entityInstance, + concreteEntityTypeName, + entityKey, + entityKeyContext.getEntityAliases(), + acquiredLockMode, + entityKeyContext.getEntityPersister(), + true, + entityKeyContext.getEntityPersister().getEntityMetamodel().getEntityType() + ); + + // materialize associations (and initialize the object) later + registerHydratedEntity( entityKeyContext.getEntityPersister(), entityKey, entityInstance ); + + return entityInstance; + } + } + @Override public void loadFromResultSet( ResultSet resultSet, @@ -252,7 +354,7 @@ public void loadFromResultSet( LockMode acquiredLockMode, EntityPersister rootPersister, boolean eagerFetch, - EntityType associationType) throws SQLException { + EntityType associationType) { final Serializable id = entityKey.getIdentifier(); @@ -287,17 +389,35 @@ public void loadFromResultSet( entityAliases.getSuffixedPropertyAliases() : entityAliases.getSuffixedPropertyAliases(persister); - final Object[] values = persister.hydrate( - resultSet, - id, - entityInstance, - (Loadable) rootPersister, - cols, - eagerFetch, - session - ); + final Object[] values; + try { + values = persister.hydrate( + resultSet, + id, + entityInstance, + (Loadable) rootPersister, + cols, + eagerFetch, + session + ); + } + catch (SQLException e) { + throw getSession().getFactory().getJdbcServices().getSqlExceptionHelper().convert( + e, + "Could not read entity state from ResultSet : " + entityKey + ); + } - final Object rowId = persister.hasRowId() ? resultSet.getObject( entityAliases.getRowIdAlias() ) : null; + final Object rowId; + try { + rowId = persister.hasRowId() ? resultSet.getObject( entityAliases.getRowIdAlias() ) : null; + } + catch (SQLException e) { + throw getSession().getFactory().getJdbcServices().getSqlExceptionHelper().convert( + e, + "Could not read entity row-id from ResultSet : " + entityKey + ); + } if ( associationType != null ) { String ukName = associationType.getRHSUniqueKeyPropertyName(); diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/EntityReturn.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/EntityReturn.java index cb22dfac20..9666aa0158 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/EntityReturn.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/EntityReturn.java @@ -28,7 +28,6 @@ import org.hibernate.AssertionFailure; import org.hibernate.LockMode; -import org.hibernate.WrongClassException; import org.hibernate.engine.FetchStrategy; import org.hibernate.engine.spi.EntityKey; import org.hibernate.engine.spi.SessionFactoryImplementor; @@ -45,7 +44,10 @@ /** * @author Steve Ebersole */ -public class EntityReturn extends AbstractFetchOwner implements Return, FetchOwner, EntityReference { +public class EntityReturn + extends AbstractFetchOwner + implements Return, FetchOwner, EntityReference, ResultSetProcessingContext.EntityKeyResolutionContext { + private final EntityAliases entityAliases; private final String sqlTableAlias; @@ -180,76 +182,7 @@ public Object read(ResultSet resultSet, ResultSetProcessingContext context) thro throw new AssertionFailure( "Could not locate resolved EntityKey"); } - final Object existing = context.getSession().getEntityUsingInterceptor( entityKey ); - - if ( existing != null ) { - if ( !persister.isInstance( existing ) ) { - throw new WrongClassException( - "loaded object was of wrong class " + existing.getClass(), - entityKey.getIdentifier(), - persister.getEntityName() - ); - } - - if ( getLockMode() != null && getLockMode() != LockMode.NONE ) { - final boolean isVersionCheckNeeded = persister.isVersioned() - && context.getSession().getPersistenceContext().getEntry( existing ).getLockMode().lessThan( getLockMode() ); - - // we don't need to worry about existing version being uninitialized because this block isn't called - // by a re-entrant load (re-entrant loads _always_ have lock mode NONE) - if ( isVersionCheckNeeded ) { - //we only check the version when _upgrading_ lock modes - context.checkVersion( - resultSet, - persister, - entityAliases, - entityKey, - existing - ); - //we need to upgrade the lock mode to the mode requested - context.getSession().getPersistenceContext().getEntry( existing ).setLockMode( getLockMode() ); - } - } - - return existing; - } - else { - final String concreteEntityTypeName = context.getConcreteEntityTypeName( - resultSet, - persister, - entityAliases, - entityKey - ); - - final Object entityInstance = context.getSession().instantiate( - concreteEntityTypeName, - entityKey.getIdentifier() - ); - - //need to hydrate it. - - // grab its state from the ResultSet and keep it in the Session - // (but don't yet initialize the object itself) - // note that we acquire LockMode.READ even if it was not requested - LockMode acquiredLockMode = getLockMode() == LockMode.NONE ? LockMode.READ : getLockMode(); - - context.loadFromResultSet( - resultSet, - entityInstance, - concreteEntityTypeName, - entityKey, - entityAliases, - acquiredLockMode, - persister, - true, - persister.getEntityMetamodel().getEntityType() - ); - - // materialize associations (and initialize the object) later - context.registerHydratedEntity( persister, entityKey, entityInstance ); - - return entityInstance; - } + return context.resolveEntityKey( entityKey, this ); } @Override diff --git a/hibernate-core/src/main/java/org/hibernate/loader/spi/NamedParameterContext.java b/hibernate-core/src/main/java/org/hibernate/loader/spi/NamedParameterContext.java index d8b33e98ee..ed4412b42b 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/spi/NamedParameterContext.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/spi/NamedParameterContext.java @@ -27,7 +27,7 @@ * The context for named parameters. *

* NOTE : the hope with the SQL-redesign stuff is that this whole concept goes away, the idea being that - * the parameters are encoded into the query tree and "bind themselves". + * the parameters are encoded into the query tree and "bind themselves"; see {@link org.hibernate.param.ParameterSpecification}. * * @author Steve Ebersole */ diff --git a/hibernate-core/src/main/java/org/hibernate/loader/spi/ResultBuilder.java b/hibernate-core/src/main/java/org/hibernate/loader/spi/ResultBuilder.java deleted file mode 100644 index 157e6e22d8..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/loader/spi/ResultBuilder.java +++ /dev/null @@ -1,7 +0,0 @@ -package org.hibernate.loader.spi; - -/** - * @author Steve Ebersole - */ -public class ResultBuilder { -} diff --git a/hibernate-core/src/main/java/org/hibernate/loader/spi/ResultSetProcessingContext.java b/hibernate-core/src/main/java/org/hibernate/loader/spi/ResultSetProcessingContext.java index e6a65aa32d..e1f0321cf5 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/spi/ResultSetProcessingContext.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/spi/ResultSetProcessingContext.java @@ -23,10 +23,8 @@ */ package org.hibernate.loader.spi; -import java.io.Serializable; import java.sql.ResultSet; import java.sql.SQLException; -import java.util.List; import org.hibernate.LockMode; import org.hibernate.engine.spi.EntityKey; @@ -34,9 +32,7 @@ import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.loader.EntityAliases; import org.hibernate.loader.plan.spi.EntityReference; -import org.hibernate.loader.plan.spi.Return; import org.hibernate.persister.entity.EntityPersister; -import org.hibernate.type.AssociationType; import org.hibernate.type.EntityType; /** @@ -49,8 +45,6 @@ public interface ResultSetProcessingContext { public EntityKey getDictatedRootEntityKey(); - public IdentifierResolutionContext getIdentifierResolutionContext(EntityReference entityReference); - public static interface IdentifierResolutionContext { public EntityReference getEntityReference(); @@ -63,8 +57,21 @@ public static interface IdentifierResolutionContext { public EntityKey getEntityKey(); } + public IdentifierResolutionContext getIdentifierResolutionContext(EntityReference entityReference); + public void registerHydratedEntity(EntityPersister persister, EntityKey entityKey, Object entityInstance); + public static interface EntityKeyResolutionContext { + public EntityPersister getEntityPersister(); + public LockMode getLockMode(); + public EntityAliases getEntityAliases(); + } + + public Object resolveEntityKey(EntityKey entityKey, EntityKeyResolutionContext entityKeyContext); + + + // should be able to get rid of the methods below here from the interface ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + public void checkVersion( ResultSet resultSet, EntityPersister persister, From b3791bc3c3f2f4e11426381fc19398b99746ae9f Mon Sep 17 00:00:00 2001 From: Gail Badner Date: Wed, 3 Apr 2013 00:55:20 -0700 Subject: [PATCH 40/54] HHH-7841 : Redesign Loader --- .../loader/DefaultEntityAliases.java | 5 + .../org/hibernate/loader/EntityAliases.java | 5 + .../internal/AbstractEntityLoadQueryImpl.java | 114 +++++++ .../internal/AbstractLoadQueryImpl.java | 241 ++++++++++++++ .../internal/EntityLoadQueryBuilderImpl.java | 140 ++++++++ .../loader/internal/EntityLoadQueryImpl.java | 61 ++++ .../internal/JoinableAssociationImpl.java | 227 +++++++++++++ .../ResultSetProcessingContextImpl.java | 8 + .../plan/internal/EntityLoadQueryImpl.java | 66 ---- .../plan/internal/LoadPlanBuildingHelper.java | 3 +- .../loader/plan/internal/LoadPlanImpl.java | 15 +- ...ngleRootReturnLoadPlanBuilderStrategy.java | 20 +- .../loader/plan/spi/AbstractFetchOwner.java | 3 + .../spi/AbstractLoadPlanBuilderStrategy.java | 18 +- ...va => AbstractSingularAttributeFetch.java} | 4 +- .../loader/plan/spi/CollectionFetch.java | 3 +- .../loader/plan/spi/CollectionReturn.java | 2 +- .../plan/spi/CompositeElementGraph.java | 2 + .../loader/plan/spi/CompositeFetch.java | 4 +- .../loader/plan/spi/CompositeIndexGraph.java | 2 + .../loader/plan/spi/EntityElementGraph.java | 7 + .../loader/plan/spi/EntityFetch.java | 14 +- .../loader/plan/spi/EntityIndexGraph.java | 7 + .../loader/plan/spi/EntityReference.java | 12 +- .../loader/plan/spi/EntityReturn.java | 29 +- .../hibernate/loader/plan/spi/FetchOwner.java | 1 + .../hibernate/loader/plan/spi/LoadPlan.java | 4 - .../LoadQueryBuilder.java} | 4 +- .../spi/ResultSetProcessingContext.java | 3 + .../entity/AbstractEntityPersister.java | 7 + .../persister/entity/EntityPersister.java | 1 + .../AssociationResultSetProcessorTest.java | 312 ++++++++++++++++++ .../loader/SimpleResultSetProcessorTest.java | 23 +- .../loader/plan/spi/LoadPlanBuilderTest.java | 7 +- 34 files changed, 1233 insertions(+), 141 deletions(-) create mode 100755 hibernate-core/src/main/java/org/hibernate/loader/internal/AbstractEntityLoadQueryImpl.java create mode 100755 hibernate-core/src/main/java/org/hibernate/loader/internal/AbstractLoadQueryImpl.java create mode 100644 hibernate-core/src/main/java/org/hibernate/loader/internal/EntityLoadQueryBuilderImpl.java create mode 100755 hibernate-core/src/main/java/org/hibernate/loader/internal/EntityLoadQueryImpl.java create mode 100644 hibernate-core/src/main/java/org/hibernate/loader/internal/JoinableAssociationImpl.java delete mode 100644 hibernate-core/src/main/java/org/hibernate/loader/plan/internal/EntityLoadQueryImpl.java rename hibernate-core/src/main/java/org/hibernate/loader/plan/spi/{AbstractFetch.java => AbstractSingularAttributeFetch.java} (94%) rename hibernate-core/src/main/java/org/hibernate/loader/{plan/spi/LoadQuery.java => spi/LoadQueryBuilder.java} (94%) create mode 100644 hibernate-core/src/test/java/org/hibernate/loader/AssociationResultSetProcessorTest.java diff --git a/hibernate-core/src/main/java/org/hibernate/loader/DefaultEntityAliases.java b/hibernate-core/src/main/java/org/hibernate/loader/DefaultEntityAliases.java index 6602cfbffb..ec9fdf17a5 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/DefaultEntityAliases.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/DefaultEntityAliases.java @@ -188,6 +188,11 @@ public String getRowIdAlias() { return rowIdAlias; } + @Override + public String getSuffix() { + return suffix; + } + private static void intern(String[] strings) { for (int i=0; i associations, + List suffixes) { + super( factory, associations, suffixes ); + this.entityReturn = entityReturn; + } + + protected final String generateSql( + final String whereString, + final String orderByString, + final LockOptions lockOptions) throws MappingException { + return generateSql( null, whereString, orderByString, "", lockOptions ); + } + + private String generateSql( + final String projection, + final String condition, + final String orderBy, + final String groupBy, + final LockOptions lockOptions) throws MappingException { + + JoinFragment ojf = mergeOuterJoins(); + + Select select = new Select( getDialect() ) + .setLockOptions( lockOptions ) + .setSelectClause( + projection == null ? + getPersister().selectFragment( getAlias(), entityReturn.getEntityAliases().getSuffix() ) + associationSelectString() : + projection + ) + .setFromClause( + getDialect().appendLockHint( lockOptions, getPersister().fromTableFragment( getAlias() ) ) + + getPersister().fromJoinFragment( getAlias(), true, true ) + ) + .setWhereClause( condition ) + .setOuterJoins( + ojf.toFromFragmentString(), + ojf.toWhereFragmentString() + getWhereFragment() + ) + .setOrderByClause( orderBy( orderBy ) ) + .setGroupByClause( groupBy ); + + if ( getFactory().getSettings().isCommentsEnabled() ) { + select.setComment( getComment() ); + } + return select.toStatementString(); + } + + protected String getWhereFragment() throws MappingException { + // here we do not bother with the discriminator. + return getPersister().whereJoinFragment( getAlias(), true, true ); + } + + public abstract String getComment(); + + public final OuterJoinLoadable getPersister() { + return (OuterJoinLoadable) entityReturn.getEntityPersister(); + } + + public final String getAlias() { + return entityReturn.getSqlTableAlias(); + } + + public String toString() { + return getClass().getName() + '(' + getPersister().getEntityName() + ')'; + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/loader/internal/AbstractLoadQueryImpl.java b/hibernate-core/src/main/java/org/hibernate/loader/internal/AbstractLoadQueryImpl.java new file mode 100755 index 0000000000..1ccd8ff2b8 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/loader/internal/AbstractLoadQueryImpl.java @@ -0,0 +1,241 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as + * indicated by the @author tags or express copyright attribution + * statements applied by the authors. All third-party contributions are + * distributed under license by Red Hat Inc. + * + * This copyrighted material is made available to anyone wishing to use, modify, + * copy, or redistribute it subject to the terms and conditions of the GNU + * Lesser General Public License, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this distribution; if not, write to: + * Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor + * Boston, MA 02110-1301 USA + */ +package org.hibernate.loader.internal; +import java.util.Iterator; +import java.util.List; + +import org.hibernate.MappingException; +import org.hibernate.dialect.Dialect; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.persister.collection.QueryableCollection; +import org.hibernate.persister.entity.Joinable; +import org.hibernate.sql.ConditionFragment; +import org.hibernate.sql.DisjunctionFragment; +import org.hibernate.sql.InFragment; +import org.hibernate.sql.JoinFragment; +import org.hibernate.sql.JoinType; + +/** + * Walks the metamodel, searching for joins, and collecting + * together information needed by OuterJoinLoader. + * + * @see org.hibernate.loader.OuterJoinLoader + * @author Gavin King, Jon Lipsky + */ +public abstract class AbstractLoadQueryImpl { + + private final SessionFactoryImplementor factory; + private final List associations; + private final List suffixes; + + private String[] collectionSuffixes; + + protected AbstractLoadQueryImpl( + SessionFactoryImplementor factory, + List associations, + List suffixes) { + this.factory = factory; + this.associations = associations; + // TODO: we should be able to get the suffixes out of associations. + this.suffixes = suffixes; + } + + protected SessionFactoryImplementor getFactory() { + return factory; + } + + protected Dialect getDialect() { + return factory.getDialect(); + } + + protected String orderBy(final String orderBy) { + return mergeOrderings( orderBy( associations ), orderBy ); + } + + protected static String mergeOrderings(String ordering1, String ordering2) { + if ( ordering1.length() == 0 ) { + return ordering2; + } + else if ( ordering2.length() == 0 ) { + return ordering1; + } + else { + return ordering1 + ", " + ordering2; + } + } + + /** + * Generate a sequence of LEFT OUTER JOIN clauses for the given associations. + */ + protected final JoinFragment mergeOuterJoins() + throws MappingException { + JoinFragment outerjoin = getDialect().createOuterJoinFragment(); + JoinableAssociationImpl last = null; + for ( JoinableAssociationImpl oj : associations ) { + if ( last != null && last.isManyToManyWith( oj ) ) { + oj.addManyToManyJoin( outerjoin, ( QueryableCollection ) last.getJoinable() ); + } + else { + oj.addJoins(outerjoin); + } + last = oj; + } + return outerjoin; + } + + /** + * Count the number of instances of Joinable which are actually + * also instances of PersistentCollection which are being fetched + * by outer join + */ + protected static final int countCollectionPersisters(List associations) + throws MappingException { + int result = 0; + Iterator iter = associations.iterator(); + while ( iter.hasNext() ) { + JoinableAssociationImpl oj = (JoinableAssociationImpl) iter.next(); + if ( oj.getJoinType()==JoinType.LEFT_OUTER_JOIN && + oj.getJoinable().isCollection() && + ! oj.hasRestriction() ) { + result++; + } + } + return result; + } + + /** + * Get the order by string required for collection fetching + */ + protected static final String orderBy(List associations) + throws MappingException { + StringBuilder buf = new StringBuilder(); + JoinableAssociationImpl last = null; + for ( JoinableAssociationImpl oj : associations ) { + if ( oj.getJoinType() == JoinType.LEFT_OUTER_JOIN ) { // why does this matter? + if ( oj.getJoinable().isCollection() ) { + final QueryableCollection queryableCollection = (QueryableCollection) oj.getJoinable(); + if ( queryableCollection.hasOrdering() ) { + final String orderByString = queryableCollection.getSQLOrderByString( oj.getRHSAlias() ); + buf.append( orderByString ).append(", "); + } + } + else { + // it might still need to apply a collection ordering based on a + // many-to-many defined order-by... + if ( last != null && last.getJoinable().isCollection() ) { + final QueryableCollection queryableCollection = (QueryableCollection) last.getJoinable(); + if ( queryableCollection.isManyToMany() && last.isManyToManyWith( oj ) ) { + if ( queryableCollection.hasManyToManyOrdering() ) { + final String orderByString = queryableCollection.getManyToManyOrderByString( oj.getRHSAlias() ); + buf.append( orderByString ).append(", "); + } + } + } + } + } + last = oj; + } + if ( buf.length()>0 ) buf.setLength( buf.length()-2 ); + return buf.toString(); + } + + /** + * Render the where condition for a (batch) load by identifier / collection key + */ + protected StringBuilder whereString(String alias, String[] columnNames, int batchSize) { + if ( columnNames.length==1 ) { + // if not a composite key, use "foo in (?, ?, ?)" for batching + // if no batch, and not a composite key, use "foo = ?" + InFragment in = new InFragment().setColumn( alias, columnNames[0] ); + for ( int i=0; i= suffixes.size() ) + ? null + : suffixes.get( entityAliasCount ); + final String collectionSuffix = ( collectionSuffixes == null || collectionAliasCount >= collectionSuffixes.length ) + ? null + : collectionSuffixes[collectionAliasCount]; + final String selectFragment = joinable.selectFragment( + next == null ? null : next.getJoinable(), + next == null ? null : next.getRHSAlias(), + join.getRHSAlias(), + entitySuffix, + collectionSuffix, + join.getJoinType()==JoinType.LEFT_OUTER_JOIN + ); + if (selectFragment.trim().length() > 0) { + buf.append(", ").append(selectFragment); + } + if ( joinable.consumesEntityAlias() ) entityAliasCount++; + if ( joinable.consumesCollectionAlias() && join.getJoinType()==JoinType.LEFT_OUTER_JOIN ) collectionAliasCount++; + } + return buf.toString(); + } + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/loader/internal/EntityLoadQueryBuilderImpl.java b/hibernate-core/src/main/java/org/hibernate/loader/internal/EntityLoadQueryBuilderImpl.java new file mode 100644 index 0000000000..e0d6e2246f --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/loader/internal/EntityLoadQueryBuilderImpl.java @@ -0,0 +1,140 @@ +/* + * 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.loader.internal; + +import java.util.ArrayList; +import java.util.List; + +import org.hibernate.engine.spi.LoadQueryInfluencers; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.loader.plan.spi.CollectionFetch; +import org.hibernate.loader.plan.spi.CompositeFetch; +import org.hibernate.loader.plan.spi.EntityFetch; +import org.hibernate.loader.plan.spi.EntityReturn; +import org.hibernate.loader.plan.spi.LoadPlan; +import org.hibernate.loader.plan.spi.LoadPlanVisitationStrategyAdapter; +import org.hibernate.loader.plan.spi.LoadPlanVisitor; +import org.hibernate.loader.spi.LoadQueryBuilder; +import org.hibernate.persister.entity.OuterJoinLoadable; + +/** + * @author Gail Badner + */ +public class EntityLoadQueryBuilderImpl implements LoadQueryBuilder { + private final SessionFactoryImplementor sessionFactory; + private final LoadQueryInfluencers loadQueryInfluencers; + private final LoadPlan loadPlan; + private final List associations; + private final List suffixes; + + public EntityLoadQueryBuilderImpl( + SessionFactoryImplementor sessionFactory, + LoadQueryInfluencers loadQueryInfluencers, + LoadPlan loadPlan) { + this.sessionFactory = sessionFactory; + this.loadQueryInfluencers = loadQueryInfluencers; + this.loadPlan = loadPlan; + LocalVisitationStrategy strategy = new LocalVisitationStrategy(); + LoadPlanVisitor.visit( loadPlan, strategy ); + this.associations = strategy.associations; + this.suffixes = strategy.suffixes; + } + + @Override + public String generateSql(int batchSize) { + return generateSql( batchSize, getOuterJoinLoadable().getKeyColumnNames() ); + } + + public String generateSql(int batchSize, String[] uniqueKey) { + final EntityLoadQueryImpl loadQuery = new EntityLoadQueryImpl( + sessionFactory, + getRootEntityReturn(), + associations, + suffixes + ); + return loadQuery.generateSql( uniqueKey, batchSize, getRootEntityReturn().getLockMode() ); + } + + private EntityReturn getRootEntityReturn() { + return (EntityReturn) loadPlan.getReturns().get( 0 ); + } + + private OuterJoinLoadable getOuterJoinLoadable() { + return (OuterJoinLoadable) getRootEntityReturn().getEntityPersister(); + } + private class LocalVisitationStrategy extends LoadPlanVisitationStrategyAdapter { + private final List associations = new ArrayList(); + private final List suffixes = new ArrayList(); + + private EntityReturn entityRootReturn; + + @Override + public void handleEntityReturn(EntityReturn rootEntityReturn) { + this.entityRootReturn = rootEntityReturn; + } + + @Override + public void startingEntityFetch(EntityFetch entityFetch) { + JoinableAssociationImpl assoc = new JoinableAssociationImpl( + entityFetch, + "", // getWithClause( entityFetch.getPropertyPath() ) + false, // hasRestriction( entityFetch.getPropertyPath() ) + sessionFactory, + loadQueryInfluencers.getEnabledFilters() + ); + associations.add( assoc ); + suffixes.add( entityFetch.getEntityAliases().getSuffix() ); + } + + @Override + public void finishingEntityFetch(EntityFetch entityFetch) { + //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + public void startingCollectionFetch(CollectionFetch collectionFetch) { + //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + public void finishingCollectionFetch(CollectionFetch collectionFetch) { + //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + public void startingCompositeFetch(CompositeFetch fetch) { + //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + public void finishingCompositeFetch(CompositeFetch fetch) { + //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + public void finish(LoadPlan loadPlan) { + //suffixes.add( entityRootReturn.getEntityAliases().getSuffix() ); + } + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/loader/internal/EntityLoadQueryImpl.java b/hibernate-core/src/main/java/org/hibernate/loader/internal/EntityLoadQueryImpl.java new file mode 100755 index 0000000000..a5fe1f22d4 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/loader/internal/EntityLoadQueryImpl.java @@ -0,0 +1,61 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as + * indicated by the @author tags or express copyright attribution + * statements applied by the authors. All third-party contributions are + * distributed under license by Red Hat Inc. + * + * This copyrighted material is made available to anyone wishing to use, modify, + * copy, or redistribute it subject to the terms and conditions of the GNU + * Lesser General Public License, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this distribution; if not, write to: + * Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor + * Boston, MA 02110-1301 USA + */ +package org.hibernate.loader.internal; +import java.util.Collections; +import java.util.List; + +import org.hibernate.LockMode; +import org.hibernate.LockOptions; +import org.hibernate.MappingException; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.loader.plan.spi.EntityReturn; + +/** + * A walker for loaders that fetch entities + * + * @see org.hibernate.loader.entity.EntityLoader + * @author Gavin King + */ +public class EntityLoadQueryImpl extends AbstractEntityLoadQueryImpl { + + public EntityLoadQueryImpl( + final SessionFactoryImplementor factory, + EntityReturn entityReturn, + List associations, + List suffixes) throws MappingException { + super( factory, entityReturn, associations, suffixes ); + } + + public String generateSql(String[] uniqueKey, int batchSize, LockMode lockMode) { + StringBuilder whereCondition = whereString( getAlias(), uniqueKey, batchSize ) + //include the discriminator and class-level where, but not filters + .append( getPersister().filterFragment( getAlias(), Collections.EMPTY_MAP ) ); + return generateSql( whereCondition.toString(), "", new LockOptions().setLockMode( lockMode ) ); + } + + public String getComment() { + return "load " + getPersister().getEntityName(); + } + +} \ No newline at end of file diff --git a/hibernate-core/src/main/java/org/hibernate/loader/internal/JoinableAssociationImpl.java b/hibernate-core/src/main/java/org/hibernate/loader/internal/JoinableAssociationImpl.java new file mode 100644 index 0000000000..c853dba050 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/loader/internal/JoinableAssociationImpl.java @@ -0,0 +1,227 @@ +/* + * 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.loader.internal; +import java.util.List; +import java.util.Map; + +import org.hibernate.MappingException; +import org.hibernate.cfg.NotYetImplementedException; +import org.hibernate.engine.FetchStyle; +import org.hibernate.engine.internal.JoinHelper; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.loader.PropertyPath; +import org.hibernate.loader.plan.spi.EntityFetch; +import org.hibernate.loader.plan.spi.EntityReference; +import org.hibernate.persister.collection.QueryableCollection; +import org.hibernate.persister.entity.EntityPersister; +import org.hibernate.persister.entity.Joinable; +import org.hibernate.persister.entity.OuterJoinLoadable; +import org.hibernate.sql.JoinFragment; +import org.hibernate.sql.JoinType; +import org.hibernate.type.AssociationType; +import org.hibernate.type.EntityType; + +/** + * Part of the Hibernate SQL rendering internals. This class represents + * a joinable association. + * + * @author Gavin King + * @author Gail Badner + */ +public final class JoinableAssociationImpl { + private final PropertyPath propertyPath; + private final AssociationType joinableType; + private final Joinable joinable; + private final String lhsAlias; // belong to other persister + private final String[] lhsColumns; // belong to other persister + private final String rhsAlias; + private final String[] rhsColumns; + private final JoinType joinType; + private final String on; + private final Map enabledFilters; + private final boolean hasRestriction; + + public JoinableAssociationImpl( + EntityFetch entityFetch, + String withClause, + boolean hasRestriction, + SessionFactoryImplementor factory, + Map enabledFilters) throws MappingException { + this.propertyPath = entityFetch.getPropertyPath(); + this.joinableType = entityFetch.getAssociationType(); + // TODO: this is not correct + final EntityPersister fetchSourcePersister = entityFetch.getOwner().retrieveFetchSourcePersister(); + final int propertyNumber = fetchSourcePersister.getEntityMetamodel().getPropertyIndex( entityFetch.getOwnerPropertyName() ); + + if ( EntityReference.class.isInstance( entityFetch.getOwner() ) ) { + this.lhsAlias = ( (EntityReference) entityFetch.getOwner() ).getSqlTableAlias(); + } + else { + throw new NotYetImplementedException( "Cannot determine LHS alias for a FetchOwner that is not an EntityReference." ); + } + final OuterJoinLoadable ownerPersister = (OuterJoinLoadable) entityFetch.getOwner().retrieveFetchSourcePersister(); + this.lhsColumns = JoinHelper.getAliasedLHSColumnNames( + entityFetch.getAssociationType(), lhsAlias, propertyNumber, ownerPersister, factory + ); + this.rhsAlias = entityFetch.getSqlTableAlias(); + + final boolean isNullable = ownerPersister.isSubclassPropertyNullable( propertyNumber ); + if ( entityFetch.getFetchStrategy().getStyle() == FetchStyle.JOIN ) { + joinType = isNullable ? JoinType.LEFT_OUTER_JOIN : JoinType.INNER_JOIN; + } + else { + joinType = JoinType.NONE; + } + this.joinable = joinableType.getAssociatedJoinable(factory); + this.rhsColumns = JoinHelper.getRHSColumnNames(joinableType, factory); + this.on = joinableType.getOnCondition( rhsAlias, factory, enabledFilters ) + + ( withClause == null || withClause.trim().length() == 0 ? "" : " and ( " + withClause + " )" ); + this.hasRestriction = hasRestriction; + this.enabledFilters = enabledFilters; // needed later for many-to-many/filter application + } + + public PropertyPath getPropertyPath() { + return propertyPath; + } + + public JoinType getJoinType() { + return joinType; + } + + public String getLhsAlias() { + return lhsAlias; + } + + public String getRHSAlias() { + return rhsAlias; + } + + private boolean isOneToOne() { + if ( joinableType.isEntityType() ) { + EntityType etype = (EntityType) joinableType; + return etype.isOneToOne() /*&& etype.isReferenceToPrimaryKey()*/; + } + else { + return false; + } + } + + public AssociationType getJoinableType() { + return joinableType; + } + + public String getRHSUniqueKeyName() { + return joinableType.getRHSUniqueKeyPropertyName(); + } + + public boolean isCollection() { + return joinableType.isCollectionType(); + } + + public Joinable getJoinable() { + return joinable; + } + + public boolean hasRestriction() { + return hasRestriction; + } + + public int getOwner(final List associations) { + if ( isOneToOne() || isCollection() ) { + return getPosition(lhsAlias, associations); + } + else { + return -1; + } + } + + /** + * Get the position of the join with the given alias in the + * list of joins + */ + private static int getPosition(String lhsAlias, List associations) { + int result = 0; + for ( int i=0; i getIdentifierResolutionContexts() { + return Collections.unmodifiableSet( + new HashSet( identifierResolutionContextMap.values() ) + ); + } + @Override public void checkVersion( ResultSet resultSet, diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/internal/EntityLoadQueryImpl.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/internal/EntityLoadQueryImpl.java deleted file mode 100644 index 77e89e5502..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/loader/plan/internal/EntityLoadQueryImpl.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * 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.loader.plan.internal; - -import org.hibernate.LockMode; -import org.hibernate.engine.spi.LoadQueryInfluencers; -import org.hibernate.engine.spi.SessionFactoryImplementor; -import org.hibernate.loader.entity.EntityJoinWalker; -import org.hibernate.loader.plan.spi.LoadQuery; -import org.hibernate.persister.entity.OuterJoinLoadable; - -/** - * @author Gail Badner - */ -public class EntityLoadQueryImpl implements LoadQuery { - final SessionFactoryImplementor sessionFactory; - final LoadQueryInfluencers loadQueryInfluencers; - final LockMode lockMode; - final OuterJoinLoadable entityPersister; - - public EntityLoadQueryImpl( - SessionFactoryImplementor sessionFactory, - LoadQueryInfluencers loadQueryInfluencers, - LockMode lockMode, - OuterJoinLoadable entityPersister) { - this.sessionFactory = sessionFactory; - this.loadQueryInfluencers = loadQueryInfluencers; - this.lockMode = lockMode; - this.entityPersister = entityPersister; - - } - - @Override - public String generateSql(int batchSize) { - final EntityJoinWalker entityJoinWalker = new EntityJoinWalker( - entityPersister, - entityPersister.getIdentifierColumnNames(), - batchSize, - lockMode, - sessionFactory, - loadQueryInfluencers - ); - return entityJoinWalker.getSQLString(); - } -} diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/internal/LoadPlanBuildingHelper.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/internal/LoadPlanBuildingHelper.java index 3c617da984..35c8df1d63 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/plan/internal/LoadPlanBuildingHelper.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/internal/LoadPlanBuildingHelper.java @@ -64,6 +64,7 @@ public static EntityFetch buildStandardEntityFetch( FetchOwner fetchOwner, AssociationAttributeDefinition attributeDefinition, FetchStrategy fetchStrategy, + String sqlTableAlias, LoadPlanBuildingContext loadPlanBuildingContext) { return new EntityFetch( @@ -73,7 +74,7 @@ public static EntityFetch buildStandardEntityFetch( fetchOwner, attributeDefinition.getName(), fetchStrategy, - null, // sql table alias + sqlTableAlias, loadPlanBuildingContext.resolveEntityColumnAliases( attributeDefinition ) ); } diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/internal/LoadPlanImpl.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/internal/LoadPlanImpl.java index 959f9223cf..47daeb3c13 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/plan/internal/LoadPlanImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/internal/LoadPlanImpl.java @@ -26,9 +26,7 @@ import java.util.Collections; import java.util.List; -import org.hibernate.engine.spi.LoadQueryInfluencers; import org.hibernate.loader.plan.spi.LoadPlan; -import org.hibernate.loader.plan.spi.LoadQuery; import org.hibernate.loader.plan.spi.Return; /** @@ -39,16 +37,14 @@ public class LoadPlanImpl implements LoadPlan { private final boolean hasScalars; private final List returns; - private final LoadQuery loadQuery; - public LoadPlanImpl(LoadQuery loadQuery, boolean hasScalars, List returns) { - this.loadQuery = loadQuery; + public LoadPlanImpl(boolean hasScalars, List returns) { this.hasScalars = hasScalars; this.returns = returns; } - public LoadPlanImpl(LoadQuery loadQuery, boolean hasScalars, Return rootReturn) { - this( loadQuery, hasScalars, Collections.singletonList( rootReturn ) ); + public LoadPlanImpl(boolean hasScalars, Return rootReturn) { + this( hasScalars, Collections.singletonList( rootReturn ) ); } @Override @@ -60,9 +56,4 @@ public boolean hasAnyScalarReturns() { public List getReturns() { return returns; } - - @Override - public LoadQuery getLoadQuery() { - return loadQuery; - } } diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/internal/SingleRootReturnLoadPlanBuilderStrategy.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/internal/SingleRootReturnLoadPlanBuilderStrategy.java index 181be31b77..fd710aa7f6 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/plan/internal/SingleRootReturnLoadPlanBuilderStrategy.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/internal/SingleRootReturnLoadPlanBuilderStrategy.java @@ -39,11 +39,9 @@ import org.hibernate.loader.plan.spi.EntityReturn; import org.hibernate.loader.plan.spi.LoadPlan; import org.hibernate.loader.plan.spi.LoadPlanBuilderStrategy; -import org.hibernate.loader.plan.spi.LoadQuery; import org.hibernate.loader.plan.spi.Return; import org.hibernate.persister.collection.CollectionPersister; import org.hibernate.persister.entity.EntityPersister; -import org.hibernate.persister.entity.OuterJoinLoadable; import org.hibernate.persister.walking.spi.AssociationAttributeDefinition; import org.hibernate.persister.walking.spi.CollectionDefinition; import org.hibernate.persister.walking.spi.EntityDefinition; @@ -103,23 +101,7 @@ protected void addRootReturn(Return rootReturn) { @Override public LoadPlan buildLoadPlan() { - return new LoadPlanImpl( createLoadQuery(), false, rootReturn ); - } - - private LoadQuery createLoadQuery() { - if ( EntityReturn.class.isInstance( rootReturn ) ) { - final EntityReturn entityReturn = (EntityReturn) rootReturn; - return new EntityLoadQueryImpl( - sessionFactory(), - loadQueryInfluencers, - entityReturn.getLockMode(), - (OuterJoinLoadable) entityReturn.getEntityPersister() - ); - } - else { - // TODO: create a LoadQuery for other types of returns. - return null; - } + return new LoadPlanImpl( false, rootReturn ); } @Override diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/AbstractFetchOwner.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/AbstractFetchOwner.java index d0dbc8197f..ce1d1aef82 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/AbstractFetchOwner.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/AbstractFetchOwner.java @@ -26,9 +26,12 @@ import java.util.ArrayList; import java.util.List; +import org.hibernate.AssertionFailure; import org.hibernate.HibernateException; import org.hibernate.LockMode; +import org.hibernate.engine.spi.EntityKey; import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.loader.spi.ResultSetProcessingContext; /** * @author Steve Ebersole diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/AbstractLoadPlanBuilderStrategy.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/AbstractLoadPlanBuilderStrategy.java index 8c61e92a60..405b318dcc 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/AbstractLoadPlanBuilderStrategy.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/AbstractLoadPlanBuilderStrategy.java @@ -401,7 +401,12 @@ protected boolean handleAssociationAttribute(AssociationAttributeDefinition attr associationFetch = fetchOwner.buildCollectionFetch( attributeDefinition, fetchStrategy, this ); } else { - associationFetch = fetchOwner.buildEntityFetch( attributeDefinition, fetchStrategy, this ); + associationFetch = fetchOwner.buildEntityFetch( + attributeDefinition, + fetchStrategy, + generateEntityFetchSqlTableAlias( attributeDefinition.toEntityDefinition().getEntityPersister().getEntityName() ), + this + ); } if ( FetchOwner.class.isInstance( associationFetch ) ) { @@ -477,6 +482,10 @@ public SessionFactoryImplementor getSessionFactory() { return sessionFactory(); } + protected String generateEntityFetchSqlTableAlias(String entityName) { + return StringHelper.generateAlias( StringHelper.unqualifyEntityName( entityName ), currentDepth() ); + } + @Override public EntityAliases resolveEntityColumnAliases(AssociationAttributeDefinition attributeDefinition) { return generateEntityColumnAliases( attributeDefinition.toEntityDefinition().getEntityPersister() ); @@ -539,6 +548,11 @@ public String getAlias() { return entityReference.getAlias(); } + @Override + public String getSqlTableAlias() { + return entityReference.getSqlTableAlias(); + } + @Override public LockMode getLockMode() { return entityReference.getLockMode(); @@ -566,6 +580,7 @@ public CollectionFetch buildCollectionFetch( public EntityFetch buildEntityFetch( AssociationAttributeDefinition attributeDefinition, FetchStrategy fetchStrategy, + String sqlTableAlias, LoadPlanBuildingContext loadPlanBuildingContext) { // we have a key-many-to-one // @@ -575,6 +590,7 @@ public EntityFetch buildEntityFetch( this, attributeDefinition, fetchStrategy, + sqlTableAlias, loadPlanBuildingContext ); fetchToHydratedStateExtractorMap.put( fetch, attributeDefinition.getHydratedCompoundValueExtractor() ); diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/AbstractFetch.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/AbstractSingularAttributeFetch.java similarity index 94% rename from hibernate-core/src/main/java/org/hibernate/loader/plan/spi/AbstractFetch.java rename to hibernate-core/src/main/java/org/hibernate/loader/plan/spi/AbstractSingularAttributeFetch.java index bb9d9d0c18..d3a376dd09 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/AbstractFetch.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/AbstractSingularAttributeFetch.java @@ -33,14 +33,14 @@ /** * @author Steve Ebersole */ -public abstract class AbstractFetch extends AbstractFetchOwner implements Fetch { +public abstract class AbstractSingularAttributeFetch extends AbstractFetchOwner implements Fetch { private final FetchOwner owner; private final String ownerProperty; private final FetchStrategy fetchStrategy; private final PropertyPath propertyPath; - public AbstractFetch( + public AbstractSingularAttributeFetch( SessionFactoryImplementor factory, String alias, LockMode lockMode, diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/CollectionFetch.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/CollectionFetch.java index ae79e5db80..89d82d4370 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/CollectionFetch.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/CollectionFetch.java @@ -31,13 +31,12 @@ import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.loader.CollectionAliases; import org.hibernate.loader.EntityAliases; -import org.hibernate.loader.PropertyPath; import org.hibernate.loader.spi.ResultSetProcessingContext; /** * @author Steve Ebersole */ -public class CollectionFetch extends AbstractCollectionReference implements CollectionReference, Fetch { +public class CollectionFetch extends AbstractCollectionReference implements Fetch { private final FetchOwner fetchOwner; private final FetchStrategy fetchStrategy; diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/CollectionReturn.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/CollectionReturn.java index 5bb106c0af..13b27be1b1 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/CollectionReturn.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/CollectionReturn.java @@ -36,7 +36,7 @@ /** * @author Steve Ebersole */ -public class CollectionReturn extends AbstractCollectionReference implements Return, CollectionReference { +public class CollectionReturn extends AbstractCollectionReference implements Return { private final String ownerEntityName; private final String ownerProperty; diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/CompositeElementGraph.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/CompositeElementGraph.java index c1c450793b..306b8eb83d 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/CompositeElementGraph.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/CompositeElementGraph.java @@ -72,11 +72,13 @@ public CollectionFetch buildCollectionFetch( public EntityFetch buildEntityFetch( AssociationAttributeDefinition attributeDefinition, FetchStrategy fetchStrategy, + String sqlTableAlias, LoadPlanBuildingContext loadPlanBuildingContext) { return LoadPlanBuildingHelper.buildStandardEntityFetch( this, attributeDefinition, fetchStrategy, + sqlTableAlias, loadPlanBuildingContext ); } diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/CompositeFetch.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/CompositeFetch.java index 77eb3ebd2f..01a6140c81 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/CompositeFetch.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/CompositeFetch.java @@ -39,7 +39,7 @@ /** * @author Steve Ebersole */ -public class CompositeFetch extends AbstractFetch implements Fetch { +public class CompositeFetch extends AbstractSingularAttributeFetch { public static final FetchStrategy FETCH_PLAN = new FetchStrategy( FetchTiming.IMMEDIATE, FetchStyle.JOIN ); public CompositeFetch( @@ -67,7 +67,7 @@ public CollectionFetch buildCollectionFetch( public EntityFetch buildEntityFetch( AssociationAttributeDefinition attributeDefinition, FetchStrategy fetchStrategy, - LoadPlanBuildingContext loadPlanBuildingContext) { + String sqlTableAlias, LoadPlanBuildingContext loadPlanBuildingContext) { return null; //To change body of implemented methods use File | Settings | File Templates. } diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/CompositeIndexGraph.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/CompositeIndexGraph.java index 8b482ac2e1..fce9033b72 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/CompositeIndexGraph.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/CompositeIndexGraph.java @@ -72,11 +72,13 @@ public CollectionFetch buildCollectionFetch( public EntityFetch buildEntityFetch( AssociationAttributeDefinition attributeDefinition, FetchStrategy fetchStrategy, + String sqlTableAlias, LoadPlanBuildingContext loadPlanBuildingContext) { return LoadPlanBuildingHelper.buildStandardEntityFetch( this, attributeDefinition, fetchStrategy, + sqlTableAlias, loadPlanBuildingContext ); } diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/EntityElementGraph.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/EntityElementGraph.java index dbb2dc1129..7f55b638bf 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/EntityElementGraph.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/EntityElementGraph.java @@ -47,6 +47,11 @@ public String getAlias() { return null; } + @Override + public String getSqlTableAlias() { + return null; //To change body of implemented methods use File | Settings | File Templates. + } + @Override public LockMode getLockMode() { return null; @@ -111,11 +116,13 @@ public CollectionFetch buildCollectionFetch( public EntityFetch buildEntityFetch( AssociationAttributeDefinition attributeDefinition, FetchStrategy fetchStrategy, + String sqlTableAlias, LoadPlanBuildingContext loadPlanBuildingContext) { return LoadPlanBuildingHelper.buildStandardEntityFetch( this, attributeDefinition, fetchStrategy, + sqlTableAlias, loadPlanBuildingContext ); } diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/EntityFetch.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/EntityFetch.java index 7b4ebd1436..54f7a61a7e 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/EntityFetch.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/EntityFetch.java @@ -38,12 +38,13 @@ import org.hibernate.persister.entity.EntityPersister; import org.hibernate.persister.walking.spi.AssociationAttributeDefinition; import org.hibernate.persister.walking.spi.CompositionDefinition; +import org.hibernate.type.AssociationType; import org.hibernate.type.EntityType; /** * @author Steve Ebersole */ -public class EntityFetch extends AbstractFetch implements EntityReference, FetchOwner { +public class EntityFetch extends AbstractSingularAttributeFetch implements EntityReference { private final String sqlTableAlias; private final EntityAliases entityAliases; @@ -69,6 +70,10 @@ public EntityFetch( this.persister = sessionFactory.getEntityPersister( associationType.getAssociatedEntityName() ); } + public EntityType getAssociationType() { + return associationType; + } + @Override public EntityPersister getEntityPersister() { return persister; @@ -79,6 +84,11 @@ public IdentifierDescription getIdentifierDescription() { return identifierDescription; } + @Override + public String getSqlTableAlias() { + return sqlTableAlias; + } + @Override public EntityAliases getEntityAliases() { return entityAliases; @@ -107,11 +117,13 @@ public CollectionFetch buildCollectionFetch( public EntityFetch buildEntityFetch( AssociationAttributeDefinition attributeDefinition, FetchStrategy fetchStrategy, + String sqlTableAlias, LoadPlanBuildingContext loadPlanBuildingContext) { return LoadPlanBuildingHelper.buildStandardEntityFetch( this, attributeDefinition, fetchStrategy, + sqlTableAlias, loadPlanBuildingContext ); } diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/EntityIndexGraph.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/EntityIndexGraph.java index 234efab221..806567396c 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/EntityIndexGraph.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/EntityIndexGraph.java @@ -69,6 +69,11 @@ public String getAlias() { return null; } + @Override + public String getSqlTableAlias() { + return null; //To change body of implemented methods use File | Settings | File Templates. + } + @Override public LockMode getLockMode() { return null; @@ -133,11 +138,13 @@ public CollectionFetch buildCollectionFetch( public EntityFetch buildEntityFetch( AssociationAttributeDefinition attributeDefinition, FetchStrategy fetchStrategy, + String sqlTableAlias, LoadPlanBuildingContext loadPlanBuildingContext) { return LoadPlanBuildingHelper.buildStandardEntityFetch( this, attributeDefinition, fetchStrategy, + sqlTableAlias, loadPlanBuildingContext ); } diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/EntityReference.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/EntityReference.java index a0ee50051e..da0f1067a0 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/EntityReference.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/EntityReference.java @@ -23,8 +23,11 @@ */ package org.hibernate.loader.plan.spi; +import org.hibernate.AssertionFailure; import org.hibernate.LockMode; +import org.hibernate.engine.spi.EntityKey; import org.hibernate.loader.EntityAliases; +import org.hibernate.loader.spi.ResultSetProcessingContext; import org.hibernate.persister.entity.EntityPersister; /** @@ -32,7 +35,7 @@ * * @author Steve Ebersole */ -public interface EntityReference extends IdentifierDescriptionInjectable { +public interface EntityReference extends IdentifierDescriptionInjectable, ResultSetProcessingContext.EntityKeyResolutionContext { /** * Retrieve the alias associated with the persister (entity/collection). * @@ -40,6 +43,13 @@ public interface EntityReference extends IdentifierDescriptionInjectable { */ public String getAlias(); + /** + * Retrieve the SQL table alias. + * + * @return The SQL table alias + */ + public String getSqlTableAlias(); + /** * Retrieve the lock mode associated with this return. * diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/EntityReturn.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/EntityReturn.java index 9666aa0158..682696a64c 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/EntityReturn.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/EntityReturn.java @@ -44,9 +44,7 @@ /** * @author Steve Ebersole */ -public class EntityReturn - extends AbstractFetchOwner - implements Return, FetchOwner, EntityReference, ResultSetProcessingContext.EntityKeyResolutionContext { +public class EntityReturn extends AbstractFetchOwner implements Return, EntityReference { private final EntityAliases entityAliases; private final String sqlTableAlias; @@ -76,6 +74,11 @@ public String getAlias() { return super.getAlias(); } + @Override + public String getSqlTableAlias() { + return sqlTableAlias; + } + @Override public LockMode getLockMode() { return super.getLockMode(); @@ -127,11 +130,13 @@ public CollectionFetch buildCollectionFetch( public EntityFetch buildEntityFetch( AssociationAttributeDefinition attributeDefinition, FetchStrategy fetchStrategy, + String sqlTableAlias, LoadPlanBuildingContext loadPlanBuildingContext) { return LoadPlanBuildingHelper.buildStandardEntityFetch( this, attributeDefinition, fetchStrategy, + sqlTableAlias, loadPlanBuildingContext ); } @@ -176,13 +181,19 @@ public void resolve(ResultSet resultSet, ResultSetProcessingContext context) thr @Override public Object read(ResultSet resultSet, ResultSetProcessingContext context) throws SQLException { - final IdentifierResolutionContext identifierResolutionContext = context.getIdentifierResolutionContext( this ); - EntityKey entityKey = identifierResolutionContext.getEntityKey(); - if ( entityKey == null ) { - throw new AssertionFailure( "Could not locate resolved EntityKey"); + Object objectForThisEntityReturn = null; + for ( IdentifierResolutionContext identifierResolutionContext : context.getIdentifierResolutionContexts() ) { + final EntityReference entityReference = identifierResolutionContext.getEntityReference(); + final EntityKey entityKey = identifierResolutionContext.getEntityKey(); + if ( entityKey == null ) { + throw new AssertionFailure( "Could not locate resolved EntityKey"); + } + final Object object = context.resolveEntityKey( entityKey, entityReference ); + if ( this == entityReference ) { + objectForThisEntityReturn = object; + } } - - return context.resolveEntityKey( entityKey, this ); + return objectForThisEntityReturn; } @Override diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/FetchOwner.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/FetchOwner.java index a01e88ab2e..94958f221d 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/FetchOwner.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/FetchOwner.java @@ -84,6 +84,7 @@ public CollectionFetch buildCollectionFetch( public EntityFetch buildEntityFetch( AssociationAttributeDefinition attributeDefinition, FetchStrategy fetchStrategy, + String sqlTableAlias, LoadPlanBuildingContext loadPlanBuildingContext); public CompositeFetch buildCompositeFetch( diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/LoadPlan.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/LoadPlan.java index 2e999284c4..0173b39714 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/LoadPlan.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/LoadPlan.java @@ -25,8 +25,6 @@ import java.util.List; -import org.hibernate.engine.spi.LoadQueryInfluencers; - /** * Describes a plan for performing a load of results. * @@ -57,8 +55,6 @@ public interface LoadPlan { public List getReturns(); - public LoadQuery getLoadQuery(); - // todo : would also like to see "call back" style access for handling "subsequent actions" such as: // 1) follow-on locking // 2) join fetch conversions to subselect fetches diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/LoadQuery.java b/hibernate-core/src/main/java/org/hibernate/loader/spi/LoadQueryBuilder.java similarity index 94% rename from hibernate-core/src/main/java/org/hibernate/loader/plan/spi/LoadQuery.java rename to hibernate-core/src/main/java/org/hibernate/loader/spi/LoadQueryBuilder.java index aa4c82038a..773f145ddb 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/LoadQuery.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/spi/LoadQueryBuilder.java @@ -21,12 +21,12 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.loader.plan.spi; +package org.hibernate.loader.spi; /** * @author Gail Badner */ -public interface LoadQuery { +public interface LoadQueryBuilder { String generateSql(int batchSize); } diff --git a/hibernate-core/src/main/java/org/hibernate/loader/spi/ResultSetProcessingContext.java b/hibernate-core/src/main/java/org/hibernate/loader/spi/ResultSetProcessingContext.java index e1f0321cf5..2a6dce6f43 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/spi/ResultSetProcessingContext.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/spi/ResultSetProcessingContext.java @@ -25,6 +25,7 @@ import java.sql.ResultSet; import java.sql.SQLException; +import java.util.Set; import org.hibernate.LockMode; import org.hibernate.engine.spi.EntityKey; @@ -59,6 +60,8 @@ public static interface IdentifierResolutionContext { public IdentifierResolutionContext getIdentifierResolutionContext(EntityReference entityReference); + public Set getIdentifierResolutionContexts(); + public void registerHydratedEntity(EntityPersister persister, EntityKey entityKey, Object entityInstance); public static interface EntityKeyResolutionContext { diff --git a/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java b/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java index 5f4c423a2b..299b2626e3 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java @@ -96,6 +96,9 @@ import org.hibernate.loader.entity.CascadeEntityLoader; import org.hibernate.loader.entity.EntityLoader; import org.hibernate.loader.entity.UniqueEntityLoader; +import org.hibernate.loader.plan.internal.SingleRootReturnLoadPlanBuilderStrategy; +import org.hibernate.loader.plan.spi.LoadPlan; +import org.hibernate.loader.plan.spi.LoadPlanBuilder; import org.hibernate.mapping.Column; import org.hibernate.mapping.Component; import org.hibernate.mapping.PersistentClass; @@ -127,6 +130,10 @@ import org.hibernate.sql.SimpleSelect; import org.hibernate.sql.Template; import org.hibernate.sql.Update; +import org.hibernate.sql.ordering.antlr.ColumnMapper; +import org.hibernate.sql.ordering.antlr.ColumnReference; +import org.hibernate.sql.ordering.antlr.FormulaReference; +import org.hibernate.sql.ordering.antlr.SqlValueReference; import org.hibernate.tuple.entity.EntityMetamodel; import org.hibernate.tuple.entity.EntityTuplizer; import org.hibernate.type.AssociationType; diff --git a/hibernate-core/src/main/java/org/hibernate/persister/entity/EntityPersister.java b/hibernate-core/src/main/java/org/hibernate/persister/entity/EntityPersister.java index 46d3fd8bee..d3ca57955e 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/entity/EntityPersister.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/entity/EntityPersister.java @@ -45,6 +45,7 @@ import org.hibernate.internal.FilterAliasGenerator; import org.hibernate.metadata.ClassMetadata; import org.hibernate.persister.walking.spi.EntityDefinition; +import org.hibernate.sql.ordering.antlr.ColumnMapper; import org.hibernate.tuple.entity.EntityMetamodel; import org.hibernate.tuple.entity.EntityTuplizer; import org.hibernate.type.Type; diff --git a/hibernate-core/src/test/java/org/hibernate/loader/AssociationResultSetProcessorTest.java b/hibernate-core/src/test/java/org/hibernate/loader/AssociationResultSetProcessorTest.java new file mode 100644 index 0000000000..b41cf73572 --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/loader/AssociationResultSetProcessorTest.java @@ -0,0 +1,312 @@ +/* + * 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.loader; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; +import javax.persistence.CascadeType; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.OneToMany; + +import org.junit.Test; + +import org.hibernate.Hibernate; +import org.hibernate.Session; +import org.hibernate.engine.spi.LoadQueryInfluencers; +import org.hibernate.engine.spi.QueryParameters; +import org.hibernate.engine.spi.SessionImplementor; +import org.hibernate.jdbc.Work; +import org.hibernate.loader.internal.EntityLoadQueryBuilderImpl; +import org.hibernate.loader.internal.ResultSetProcessorImpl; +import org.hibernate.loader.plan.internal.SingleRootReturnLoadPlanBuilderStrategy; +import org.hibernate.loader.plan.spi.LoadPlan; +import org.hibernate.loader.plan.spi.LoadPlanBuilder; +import org.hibernate.loader.spi.NamedParameterContext; +import org.hibernate.persister.entity.EntityPersister; +import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; +import org.hibernate.testing.junit4.ExtraAssertions; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +/** + * @author Steve Ebersole + */ +public class AssociationResultSetProcessorTest extends BaseCoreFunctionalTestCase { + + @Override + protected Class[] getAnnotatedClasses() { + return new Class[] { Message.class, Poster.class, ReportedMessage.class }; + } + + @Test + public void testManyToOneEntityProcessing() throws Exception { + final EntityPersister entityPersister = sessionFactory().getEntityPersister( Message.class.getName() ); + + // create some test data + Session session = openSession(); + session.beginTransaction(); + Message message = new Message( 1, "the message" ); + Poster poster = new Poster( 2, "the poster" ); + session.save( message ); + session.save( poster ); + message.poster = poster; + poster.messages.add( message ); + session.getTransaction().commit(); + session.close(); + + { + final SingleRootReturnLoadPlanBuilderStrategy strategy = new SingleRootReturnLoadPlanBuilderStrategy( + sessionFactory(), + LoadQueryInfluencers.NONE, + "abc", + 0 + ); + final LoadPlan plan = LoadPlanBuilder.buildRootEntityLoadPlan( strategy, entityPersister ); + final EntityLoadQueryBuilderImpl queryBuilder = new EntityLoadQueryBuilderImpl( + sessionFactory(), + LoadQueryInfluencers.NONE, + plan + ); + final String sql = queryBuilder.generateSql( 1 ); + + final ResultSetProcessorImpl resultSetProcessor = new ResultSetProcessorImpl( plan ); + final List results = new ArrayList(); + + final Session workSession = openSession(); + workSession.beginTransaction(); + workSession.doWork( + new Work() { + @Override + public void execute(Connection connection) throws SQLException { + PreparedStatement ps = connection.prepareStatement( sql ); + ps.setInt( 1, 1 ); + ResultSet resultSet = ps.executeQuery(); + results.addAll( + resultSetProcessor.extractResults( + resultSet, + (SessionImplementor) workSession, + new QueryParameters(), + new NamedParameterContext() { + @Override + public int[] getNamedParameterLocations(String name) { + return new int[0]; + } + }, + true, + false, + null, + null + ) + ); + resultSet.close(); + ps.close(); + } + } + ); + assertEquals( 1, results.size() ); + Object result = results.get( 0 ); + assertNotNull( result ); + + Message workMessage = ExtraAssertions.assertTyping( Message.class, result ); + assertEquals( 1, workMessage.mid.intValue() ); + assertEquals( "the message", workMessage.msgTxt ); + assertTrue( Hibernate.isInitialized( workMessage.poster ) ); + Poster workPoster = workMessage.poster; + assertEquals( 2, workPoster.pid.intValue() ); + assertEquals( "the poster", workPoster.name ); + assertFalse( Hibernate.isInitialized( workPoster.messages ) ); + + workSession.getTransaction().commit(); + workSession.close(); + } + + // clean up test data + session = openSession(); + session.beginTransaction(); + session.createQuery( "delete Message" ).executeUpdate(); + session.createQuery( "delete Poster" ).executeUpdate(); + session.getTransaction().commit(); + session.close(); + } + + @Test + public void testNestedManyToOneEntityProcessing() throws Exception { + final EntityPersister entityPersister = sessionFactory().getEntityPersister( ReportedMessage.class.getName() ); + + // create some test data + Session session = openSession(); + session.beginTransaction(); + Message message = new Message( 1, "the message" ); + Poster poster = new Poster( 2, "the poster" ); + session.save( message ); + session.save( poster ); + message.poster = poster; + poster.messages.add( message ); + ReportedMessage reportedMessage = new ReportedMessage( 0, "inappropriate", message ); + session.save( reportedMessage ); + session.getTransaction().commit(); + session.close(); + + { + final SingleRootReturnLoadPlanBuilderStrategy strategy = new SingleRootReturnLoadPlanBuilderStrategy( + sessionFactory(), + LoadQueryInfluencers.NONE, + "abc", + 0 + ); + final LoadPlan plan = LoadPlanBuilder.buildRootEntityLoadPlan( strategy, entityPersister ); + final EntityLoadQueryBuilderImpl queryBuilder = new EntityLoadQueryBuilderImpl( + sessionFactory(), + LoadQueryInfluencers.NONE, + plan + ); + final String sql = queryBuilder.generateSql( 1 ); + + final ResultSetProcessorImpl resultSetProcessor = new ResultSetProcessorImpl( plan ); + final List results = new ArrayList(); + + final Session workSession = openSession(); + workSession.beginTransaction(); + workSession.doWork( + new Work() { + @Override + public void execute(Connection connection) throws SQLException { + PreparedStatement ps = connection.prepareStatement( sql ); + ps.setInt( 1, 0 ); + ResultSet resultSet = ps.executeQuery(); + results.addAll( + resultSetProcessor.extractResults( + resultSet, + (SessionImplementor) workSession, + new QueryParameters(), + new NamedParameterContext() { + @Override + public int[] getNamedParameterLocations(String name) { + return new int[0]; + } + }, + true, + false, + null, + null + ) + ); + resultSet.close(); + ps.close(); + } + } + ); + assertEquals( 1, results.size() ); + Object result = results.get( 0 ); + assertNotNull( result ); + + ReportedMessage workReportedMessage = ExtraAssertions.assertTyping( ReportedMessage.class, result ); + assertEquals( 0, workReportedMessage.id.intValue() ); + assertEquals( "inappropriate", workReportedMessage.reason ); + Message workMessage = workReportedMessage.message; + assertNotNull( workMessage ); + assertTrue( Hibernate.isInitialized( workMessage ) ); + assertEquals( 1, workMessage.mid.intValue() ); + assertEquals( "the message", workMessage.msgTxt ); + assertTrue( Hibernate.isInitialized( workMessage.poster ) ); + Poster workPoster = workMessage.poster; + assertEquals( 2, workPoster.pid.intValue() ); + assertEquals( "the poster", workPoster.name ); + assertFalse( Hibernate.isInitialized( workPoster.messages ) ); + + workSession.getTransaction().commit(); + workSession.close(); + } + + // clean up test data + session = openSession(); + session.beginTransaction(); + session.createQuery( "delete ReportedMessage" ).executeUpdate(); + session.createQuery( "delete Message" ).executeUpdate(); + session.createQuery( "delete Poster" ).executeUpdate(); + session.getTransaction().commit(); + session.close(); + } + + @Entity( name = "ReportedMessage" ) + public static class ReportedMessage { + @Id + private Integer id; + private String reason; + @ManyToOne + @JoinColumn + private Message message; + + public ReportedMessage() {} + + public ReportedMessage(Integer id, String reason, Message message) { + this.id = id; + this.reason = reason; + this.message = message; + } + } + + @Entity( name = "Message" ) + public static class Message { + @Id + private Integer mid; + private String msgTxt; + @ManyToOne( cascade = CascadeType.MERGE ) + @JoinColumn + private Poster poster; + + public Message() {} + + public Message(Integer mid, String msgTxt) { + this.mid = mid; + this.msgTxt = msgTxt; + } + } + + @Entity( name = "Poster" ) + public static class Poster { + @Id + private Integer pid; + private String name; + @OneToMany(mappedBy = "poster") + private List messages = new ArrayList(); + + public Poster() {} + + public Poster(Integer pid, String name) { + this.pid = pid; + this.name = name; + } + } +} diff --git a/hibernate-core/src/test/java/org/hibernate/loader/SimpleResultSetProcessorTest.java b/hibernate-core/src/test/java/org/hibernate/loader/SimpleResultSetProcessorTest.java index 1674f43f54..b420e0ec29 100644 --- a/hibernate-core/src/test/java/org/hibernate/loader/SimpleResultSetProcessorTest.java +++ b/hibernate-core/src/test/java/org/hibernate/loader/SimpleResultSetProcessorTest.java @@ -31,26 +31,20 @@ import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; -import java.util.Collections; import java.util.List; -import org.hibernate.LockMode; import org.hibernate.Session; -import org.hibernate.engine.jdbc.spi.StatementPreparer; import org.hibernate.engine.spi.LoadQueryInfluencers; import org.hibernate.engine.spi.QueryParameters; import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.jdbc.Work; -import org.hibernate.loader.entity.BatchingEntityLoaderBuilder; -import org.hibernate.loader.entity.EntityLoader; +import org.hibernate.loader.internal.EntityLoadQueryBuilderImpl; import org.hibernate.loader.internal.ResultSetProcessorImpl; -import org.hibernate.loader.plan.internal.EntityLoadQueryImpl; import org.hibernate.loader.plan.internal.SingleRootReturnLoadPlanBuilderStrategy; import org.hibernate.loader.plan.spi.LoadPlan; import org.hibernate.loader.plan.spi.LoadPlanBuilder; import org.hibernate.loader.spi.NamedParameterContext; import org.hibernate.persister.entity.EntityPersister; -import org.hibernate.persister.entity.OuterJoinLoadable; import org.junit.Test; @@ -82,14 +76,6 @@ public void testSimpleEntityProcessing() throws Exception { session.close(); { - final EntityLoadQueryImpl queryBuilder = new EntityLoadQueryImpl( - sessionFactory(), - LoadQueryInfluencers.NONE, - LockMode.NONE, - (OuterJoinLoadable) entityPersister - ); - final String sql = queryBuilder.generateSql( 1 ); - final SingleRootReturnLoadPlanBuilderStrategy strategy = new SingleRootReturnLoadPlanBuilderStrategy( sessionFactory(), LoadQueryInfluencers.NONE, @@ -97,6 +83,13 @@ public void testSimpleEntityProcessing() throws Exception { 0 ); final LoadPlan plan = LoadPlanBuilder.buildRootEntityLoadPlan( strategy, entityPersister ); + final EntityLoadQueryBuilderImpl queryBuilder = new EntityLoadQueryBuilderImpl( + sessionFactory(), + LoadQueryInfluencers.NONE, + plan + ); + final String sql = queryBuilder.generateSql( 1 ); + final ResultSetProcessorImpl resultSetProcessor = new ResultSetProcessorImpl( plan ); final List results = new ArrayList(); diff --git a/hibernate-core/src/test/java/org/hibernate/loader/plan/spi/LoadPlanBuilderTest.java b/hibernate-core/src/test/java/org/hibernate/loader/plan/spi/LoadPlanBuilderTest.java index f26afd3dea..43d51cb3f4 100644 --- a/hibernate-core/src/test/java/org/hibernate/loader/plan/spi/LoadPlanBuilderTest.java +++ b/hibernate-core/src/test/java/org/hibernate/loader/plan/spi/LoadPlanBuilderTest.java @@ -33,8 +33,10 @@ import org.hibernate.engine.spi.CascadingActions; import org.hibernate.engine.spi.LoadQueryInfluencers; +import org.hibernate.loader.internal.EntityLoadQueryBuilderImpl; import org.hibernate.loader.plan.internal.CascadeLoadPlanBuilderStrategy; import org.hibernate.loader.plan.internal.SingleRootReturnLoadPlanBuilderStrategy; +import org.hibernate.loader.spi.LoadQueryBuilder; import org.hibernate.persister.collection.CollectionPersister; import org.hibernate.persister.entity.EntityPersister; @@ -78,9 +80,8 @@ public void testSimpleBuild() { assertNotNull( entityFetch.getFetches() ); assertEquals( 0, entityFetch.getFetches().length ); - String loadSql = plan.getLoadQuery().generateSql( 1 ); - // TODO: assert that aliases used in loadSql match up with those in entityReturn and entityFetch - // (they currently do not match up) + LoadQueryBuilder loadQueryBuilder = new EntityLoadQueryBuilderImpl( sessionFactory(), LoadQueryInfluencers.NONE, plan ); + String sql = loadQueryBuilder.generateSql( 1 ); } @Test From 560a397a01e4ff7043a7c82bce4091e18ed8c49b Mon Sep 17 00:00:00 2001 From: Gail Badner Date: Wed, 10 Apr 2013 16:17:27 -0700 Subject: [PATCH 41/54] HHH-7841 - Redesign Loader --- .../internal/AbstractEntityLoadQueryImpl.java | 9 +- .../internal/AbstractLoadQueryImpl.java | 53 +----- .../internal/EntityLoadQueryBuilderImpl.java | 89 ++++++++- .../loader/internal/EntityLoadQueryImpl.java | 5 +- .../internal/JoinableAssociationImpl.java | 60 +++++- .../ResultSetProcessingContextImpl.java | 139 ++++++++++++-- .../internal/ResultSetProcessorImpl.java | 2 + .../plan/internal/LoadPlanBuildingHelper.java | 7 +- .../spi/AbstractLoadPlanBuilderStrategy.java | 1 + .../loader/plan/spi/CollectionFetch.java | 2 + .../loader/plan/spi/LoadPlanVisitor.java | 12 +- .../spi/MetadataDrivenModelGraphVisitor.java | 2 +- ...ityAssociationResultSetProcessorTest.java} | 4 +- ...yWithCollectionResultSetProcessorTest.java | 174 ++++++++++++++++++ 14 files changed, 475 insertions(+), 84 deletions(-) rename hibernate-core/src/test/java/org/hibernate/loader/{AssociationResultSetProcessorTest.java => EntityAssociationResultSetProcessorTest.java} (98%) create mode 100644 hibernate-core/src/test/java/org/hibernate/loader/EntityWithCollectionResultSetProcessorTest.java diff --git a/hibernate-core/src/main/java/org/hibernate/loader/internal/AbstractEntityLoadQueryImpl.java b/hibernate-core/src/main/java/org/hibernate/loader/internal/AbstractEntityLoadQueryImpl.java index b5c1243515..d2b4a1ff90 100755 --- a/hibernate-core/src/main/java/org/hibernate/loader/internal/AbstractEntityLoadQueryImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/internal/AbstractEntityLoadQueryImpl.java @@ -46,9 +46,8 @@ public abstract class AbstractEntityLoadQueryImpl extends AbstractLoadQueryImpl public AbstractEntityLoadQueryImpl( SessionFactoryImplementor factory, EntityReturn entityReturn, - List associations, - List suffixes) { - super( factory, associations, suffixes ); + List associations) { + super( factory, associations ); this.entityReturn = entityReturn; } @@ -68,6 +67,10 @@ private String generateSql( JoinFragment ojf = mergeOuterJoins(); + // If no projection, then the last suffix should be for the entity return. + // TODO: simplify how suffixes are generated/processed. + + Select select = new Select( getDialect() ) .setLockOptions( lockOptions ) .setSelectClause( diff --git a/hibernate-core/src/main/java/org/hibernate/loader/internal/AbstractLoadQueryImpl.java b/hibernate-core/src/main/java/org/hibernate/loader/internal/AbstractLoadQueryImpl.java index 1ccd8ff2b8..e934434b6b 100755 --- a/hibernate-core/src/main/java/org/hibernate/loader/internal/AbstractLoadQueryImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/internal/AbstractLoadQueryImpl.java @@ -22,7 +22,6 @@ * Boston, MA 02110-1301 USA */ package org.hibernate.loader.internal; -import java.util.Iterator; import java.util.List; import org.hibernate.MappingException; @@ -47,18 +46,12 @@ public abstract class AbstractLoadQueryImpl { private final SessionFactoryImplementor factory; private final List associations; - private final List suffixes; - - private String[] collectionSuffixes; protected AbstractLoadQueryImpl( SessionFactoryImplementor factory, - List associations, - List suffixes) { + List associations) { this.factory = factory; this.associations = associations; - // TODO: we should be able to get the suffixes out of associations. - this.suffixes = suffixes; } protected SessionFactoryImplementor getFactory() { @@ -104,30 +97,10 @@ protected final JoinFragment mergeOuterJoins() return outerjoin; } - /** - * Count the number of instances of Joinable which are actually - * also instances of PersistentCollection which are being fetched - * by outer join - */ - protected static final int countCollectionPersisters(List associations) - throws MappingException { - int result = 0; - Iterator iter = associations.iterator(); - while ( iter.hasNext() ) { - JoinableAssociationImpl oj = (JoinableAssociationImpl) iter.next(); - if ( oj.getJoinType()==JoinType.LEFT_OUTER_JOIN && - oj.getJoinable().isCollection() && - ! oj.hasRestriction() ) { - result++; - } - } - return result; - } - /** * Get the order by string required for collection fetching */ - protected static final String orderBy(List associations) + protected static String orderBy(List associations) throws MappingException { StringBuilder buf = new StringBuilder(); JoinableAssociationImpl last = null; @@ -156,7 +129,9 @@ protected static final String orderBy(List associations } last = oj; } - if ( buf.length()>0 ) buf.setLength( buf.length()-2 ); + if ( buf.length() > 0 ) { + buf.setLength( buf.length() - 2 ); + } return buf.toString(); } @@ -168,7 +143,9 @@ protected StringBuilder whereString(String alias, String[] columnNames, int batc // if not a composite key, use "foo in (?, ?, ?)" for batching // if no batch, and not a composite key, use "foo = ?" InFragment in = new InFragment().setColumn( alias, columnNames[0] ); - for ( int i=0; i= suffixes.size() ) - ? null - : suffixes.get( entityAliasCount ); - final String collectionSuffix = ( collectionSuffixes == null || collectionAliasCount >= collectionSuffixes.length ) - ? null - : collectionSuffixes[collectionAliasCount]; final String selectFragment = joinable.selectFragment( next == null ? null : next.getJoinable(), next == null ? null : next.getRHSAlias(), join.getRHSAlias(), - entitySuffix, - collectionSuffix, + associations.get( i ).getCurrentEntitySuffix(), + associations.get( i ).getCurrentCollectionSuffix(), join.getJoinType()==JoinType.LEFT_OUTER_JOIN ); if (selectFragment.trim().length() > 0) { buf.append(", ").append(selectFragment); } - if ( joinable.consumesEntityAlias() ) entityAliasCount++; - if ( joinable.consumesCollectionAlias() && join.getJoinType()==JoinType.LEFT_OUTER_JOIN ) collectionAliasCount++; } return buf.toString(); } diff --git a/hibernate-core/src/main/java/org/hibernate/loader/internal/EntityLoadQueryBuilderImpl.java b/hibernate-core/src/main/java/org/hibernate/loader/internal/EntityLoadQueryBuilderImpl.java index e0d6e2246f..be11977031 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/internal/EntityLoadQueryBuilderImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/internal/EntityLoadQueryBuilderImpl.java @@ -23,11 +23,15 @@ */ package org.hibernate.loader.internal; +import java.util.ArrayDeque; import java.util.ArrayList; +import java.util.Deque; import java.util.List; import org.hibernate.engine.spi.LoadQueryInfluencers; import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.loader.CollectionAliases; +import org.hibernate.loader.EntityAliases; import org.hibernate.loader.plan.spi.CollectionFetch; import org.hibernate.loader.plan.spi.CompositeFetch; import org.hibernate.loader.plan.spi.EntityFetch; @@ -35,8 +39,10 @@ import org.hibernate.loader.plan.spi.LoadPlan; import org.hibernate.loader.plan.spi.LoadPlanVisitationStrategyAdapter; import org.hibernate.loader.plan.spi.LoadPlanVisitor; +import org.hibernate.loader.plan.spi.Return; import org.hibernate.loader.spi.LoadQueryBuilder; import org.hibernate.persister.entity.OuterJoinLoadable; +import org.hibernate.persister.walking.spi.WalkingException; /** * @author Gail Badner @@ -46,7 +52,6 @@ public class EntityLoadQueryBuilderImpl implements LoadQueryBuilder { private final LoadQueryInfluencers loadQueryInfluencers; private final LoadPlan loadPlan; private final List associations; - private final List suffixes; public EntityLoadQueryBuilderImpl( SessionFactoryImplementor sessionFactory, @@ -58,7 +63,6 @@ public EntityLoadQueryBuilderImpl( LocalVisitationStrategy strategy = new LocalVisitationStrategy(); LoadPlanVisitor.visit( loadPlan, strategy ); this.associations = strategy.associations; - this.suffixes = strategy.suffixes; } @Override @@ -70,8 +74,7 @@ public String generateSql(int batchSize, String[] uniqueKey) { final EntityLoadQueryImpl loadQuery = new EntityLoadQueryImpl( sessionFactory, getRootEntityReturn(), - associations, - suffixes + associations ); return loadQuery.generateSql( uniqueKey, batchSize, getRootEntityReturn().getLockMode() ); } @@ -85,7 +88,8 @@ private OuterJoinLoadable getOuterJoinLoadable() { } private class LocalVisitationStrategy extends LoadPlanVisitationStrategyAdapter { private final List associations = new ArrayList(); - private final List suffixes = new ArrayList(); + private Deque entityAliasStack = new ArrayDeque(); + private Deque collectionAliasStack = new ArrayDeque(); private EntityReturn entityRootReturn; @@ -94,32 +98,71 @@ public void handleEntityReturn(EntityReturn rootEntityReturn) { this.entityRootReturn = rootEntityReturn; } + @Override + public void startingRootReturn(Return rootReturn) { + if ( !EntityReturn.class.isInstance( rootReturn ) ) { + throw new WalkingException( + String.format( + "Unexpected type of return; expected [%s]; instead it was [%s]", + EntityReturn.class.getName(), + rootReturn.getClass().getName() + ) + ); + } + this.entityRootReturn = (EntityReturn) rootReturn; + pushToStack( entityAliasStack, entityRootReturn.getEntityAliases() ); + } + + @Override + public void finishingRootReturn(Return rootReturn) { + if ( !EntityReturn.class.isInstance( rootReturn ) ) { + throw new WalkingException( + String.format( + "Unexpected type of return; expected [%s]; instead it was [%s]", + EntityReturn.class.getName(), + rootReturn.getClass().getName() + ) + ); + } + popFromStack( entityAliasStack, ( (EntityReturn) rootReturn ).getEntityAliases() ); + } + @Override public void startingEntityFetch(EntityFetch entityFetch) { JoinableAssociationImpl assoc = new JoinableAssociationImpl( entityFetch, + getCurrentCollectionSuffix(), "", // getWithClause( entityFetch.getPropertyPath() ) false, // hasRestriction( entityFetch.getPropertyPath() ) sessionFactory, loadQueryInfluencers.getEnabledFilters() ); associations.add( assoc ); - suffixes.add( entityFetch.getEntityAliases().getSuffix() ); + pushToStack( entityAliasStack, entityFetch.getEntityAliases() ); } @Override public void finishingEntityFetch(EntityFetch entityFetch) { - //To change body of implemented methods use File | Settings | File Templates. + popFromStack( entityAliasStack, entityFetch.getEntityAliases() ); } @Override public void startingCollectionFetch(CollectionFetch collectionFetch) { - //To change body of implemented methods use File | Settings | File Templates. + JoinableAssociationImpl assoc = new JoinableAssociationImpl( + collectionFetch, + getCurrentEntitySuffix(), + "", // getWithClause( entityFetch.getPropertyPath() ) + false, // hasRestriction( entityFetch.getPropertyPath() ) + sessionFactory, + loadQueryInfluencers.getEnabledFilters() + ); + associations.add( assoc ); + pushToStack( collectionAliasStack, collectionFetch.getCollectionAliases() ); } @Override public void finishingCollectionFetch(CollectionFetch collectionFetch) { - //To change body of implemented methods use File | Settings | File Templates. + popFromStack( collectionAliasStack, collectionFetch.getCollectionAliases() ); } @Override @@ -134,7 +177,33 @@ public void finishingCompositeFetch(CompositeFetch fetch) { @Override public void finish(LoadPlan loadPlan) { - //suffixes.add( entityRootReturn.getEntityAliases().getSuffix() ); + entityAliasStack.clear(); + collectionAliasStack.clear(); + } + + private String getCurrentEntitySuffix() { + return entityAliasStack.peekFirst() == null ? null : entityAliasStack.peekFirst().getSuffix(); + } + + private String getCurrentCollectionSuffix() { + return collectionAliasStack.peekFirst() == null ? null : collectionAliasStack.peekFirst().getSuffix(); + } + + private void pushToStack(Deque stack, T value) { + stack.push( value ); + } + + private void popFromStack(Deque stack, T expectedValue) { + T poppedValue = stack.pop(); + if ( poppedValue != expectedValue ) { + throw new WalkingException( + String.format( + "Unexpected value from stack. Expected=[%s]; instead it was [%s].", + expectedValue, + poppedValue + ) + ); + } } } } diff --git a/hibernate-core/src/main/java/org/hibernate/loader/internal/EntityLoadQueryImpl.java b/hibernate-core/src/main/java/org/hibernate/loader/internal/EntityLoadQueryImpl.java index a5fe1f22d4..2eedf8a88f 100755 --- a/hibernate-core/src/main/java/org/hibernate/loader/internal/EntityLoadQueryImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/internal/EntityLoadQueryImpl.java @@ -42,9 +42,8 @@ public class EntityLoadQueryImpl extends AbstractEntityLoadQueryImpl { public EntityLoadQueryImpl( final SessionFactoryImplementor factory, EntityReturn entityReturn, - List associations, - List suffixes) throws MappingException { - super( factory, entityReturn, associations, suffixes ); + List associations) throws MappingException { + super( factory, entityReturn, associations ); } public String generateSql(String[] uniqueKey, int batchSize, LockMode lockMode) { diff --git a/hibernate-core/src/main/java/org/hibernate/loader/internal/JoinableAssociationImpl.java b/hibernate-core/src/main/java/org/hibernate/loader/internal/JoinableAssociationImpl.java index c853dba050..da8361304e 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/internal/JoinableAssociationImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/internal/JoinableAssociationImpl.java @@ -31,6 +31,7 @@ import org.hibernate.engine.internal.JoinHelper; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.loader.PropertyPath; +import org.hibernate.loader.plan.spi.CollectionFetch; import org.hibernate.loader.plan.spi.EntityFetch; import org.hibernate.loader.plan.spi.EntityReference; import org.hibernate.persister.collection.QueryableCollection; @@ -40,6 +41,7 @@ import org.hibernate.sql.JoinFragment; import org.hibernate.sql.JoinType; import org.hibernate.type.AssociationType; +import org.hibernate.type.CollectionType; import org.hibernate.type.EntityType; /** @@ -57,6 +59,8 @@ public final class JoinableAssociationImpl { private final String[] lhsColumns; // belong to other persister private final String rhsAlias; private final String[] rhsColumns; + private final String currentEntitySuffix; + private final String currentCollectionSuffix; private final JoinType joinType; private final String on; private final Map enabledFilters; @@ -64,6 +68,7 @@ public final class JoinableAssociationImpl { public JoinableAssociationImpl( EntityFetch entityFetch, + String currentCollectionSuffix, String withClause, boolean hasRestriction, SessionFactoryImplementor factory, @@ -94,7 +99,52 @@ public JoinableAssociationImpl( joinType = JoinType.NONE; } this.joinable = joinableType.getAssociatedJoinable(factory); - this.rhsColumns = JoinHelper.getRHSColumnNames(joinableType, factory); + this.rhsColumns = JoinHelper.getRHSColumnNames( joinableType, factory ); + this.currentEntitySuffix = entityFetch.getEntityAliases().getSuffix(); + this.currentCollectionSuffix = currentCollectionSuffix; + this.on = joinableType.getOnCondition( rhsAlias, factory, enabledFilters ) + + ( withClause == null || withClause.trim().length() == 0 ? "" : " and ( " + withClause + " )" ); + this.hasRestriction = hasRestriction; + this.enabledFilters = enabledFilters; // needed later for many-to-many/filter application + } + + public JoinableAssociationImpl( + CollectionFetch collectionFetch, + String currentEntitySuffix, + String withClause, + boolean hasRestriction, + SessionFactoryImplementor factory, + Map enabledFilters) throws MappingException { + this.propertyPath = collectionFetch.getPropertyPath(); + final CollectionType collectionType = collectionFetch.getCollectionPersister().getCollectionType(); + this.joinableType = collectionType; + // TODO: this is not correct + final EntityPersister fetchSourcePersister = collectionFetch.getOwner().retrieveFetchSourcePersister(); + final int propertyNumber = fetchSourcePersister.getEntityMetamodel().getPropertyIndex( collectionFetch.getOwnerPropertyName() ); + + if ( EntityReference.class.isInstance( collectionFetch.getOwner() ) ) { + this.lhsAlias = ( (EntityReference) collectionFetch.getOwner() ).getSqlTableAlias(); + } + else { + throw new NotYetImplementedException( "Cannot determine LHS alias for a FetchOwner that is not an EntityReference." ); + } + final OuterJoinLoadable ownerPersister = (OuterJoinLoadable) collectionFetch.getOwner().retrieveFetchSourcePersister(); + this.lhsColumns = JoinHelper.getAliasedLHSColumnNames( + collectionType, lhsAlias, propertyNumber, ownerPersister, factory + ); + this.rhsAlias = collectionFetch.getAlias(); + + final boolean isNullable = ownerPersister.isSubclassPropertyNullable( propertyNumber ); + if ( collectionFetch.getFetchStrategy().getStyle() == FetchStyle.JOIN ) { + joinType = isNullable ? JoinType.LEFT_OUTER_JOIN : JoinType.INNER_JOIN; + } + else { + joinType = JoinType.NONE; + } + this.joinable = joinableType.getAssociatedJoinable(factory); + this.rhsColumns = JoinHelper.getRHSColumnNames( joinableType, factory ); + this.currentEntitySuffix = currentEntitySuffix; + this.currentCollectionSuffix = collectionFetch.getCollectionAliases().getSuffix(); this.on = joinableType.getOnCondition( rhsAlias, factory, enabledFilters ) + ( withClause == null || withClause.trim().length() == 0 ? "" : " and ( " + withClause + " )" ); this.hasRestriction = hasRestriction; @@ -117,6 +167,14 @@ public String getRHSAlias() { return rhsAlias; } + public String getCurrentEntitySuffix() { + return currentEntitySuffix; + } + + public String getCurrentCollectionSuffix() { + return currentCollectionSuffix; + } + private boolean isOneToOne() { if ( joinableType.isEntityType() ) { EntityType etype = (EntityType) joinableType; diff --git a/hibernate-core/src/main/java/org/hibernate/loader/internal/ResultSetProcessingContextImpl.java b/hibernate-core/src/main/java/org/hibernate/loader/internal/ResultSetProcessingContextImpl.java index 1163ef8125..a66e8acbc9 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/internal/ResultSetProcessingContextImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/internal/ResultSetProcessingContextImpl.java @@ -40,15 +40,18 @@ import org.hibernate.LockMode; import org.hibernate.StaleObjectStateException; import org.hibernate.WrongClassException; +import org.hibernate.collection.spi.PersistentCollection; import org.hibernate.engine.internal.TwoPhaseLoad; import org.hibernate.engine.spi.EntityKey; import org.hibernate.engine.spi.EntityUniqueKey; +import org.hibernate.engine.spi.PersistenceContext; import org.hibernate.engine.spi.QueryParameters; import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.engine.spi.SubselectFetch; import org.hibernate.event.spi.EventSource; import org.hibernate.event.spi.PostLoadEvent; import org.hibernate.event.spi.PreLoadEvent; +import org.hibernate.loader.CollectionAliases; import org.hibernate.loader.EntityAliases; import org.hibernate.loader.plan.spi.CollectionFetch; import org.hibernate.loader.plan.spi.CollectionReturn; @@ -463,6 +466,113 @@ public void loadFromResultSet( } + public void readCollectionElements(final Object[] row) { + LoadPlanVisitor.visit( + loadPlan, + new LoadPlanVisitationStrategyAdapter() { + @Override + public void handleCollectionReturn(CollectionReturn rootCollectionReturn) { + readCollectionElement( + null, + null, + rootCollectionReturn.getCollectionPersister(), + rootCollectionReturn.getCollectionAliases(), + resultSet, + session + ); + } + + @Override + public void startingCollectionFetch(CollectionFetch collectionFetch) { + // TODO: determine which element is the owner. + final Object owner = row[ 0 ]; + readCollectionElement( + owner, + collectionFetch.getCollectionPersister().getCollectionType().getKeyOfOwner( owner, session ), + collectionFetch.getCollectionPersister(), + collectionFetch.getCollectionAliases(), + resultSet, + session + ); + } + + private void readCollectionElement( + final Object optionalOwner, + final Serializable optionalKey, + final CollectionPersister persister, + final CollectionAliases descriptor, + final ResultSet rs, + final SessionImplementor session) { + + try { + final PersistenceContext persistenceContext = session.getPersistenceContext(); + + final Serializable collectionRowKey = (Serializable) persister.readKey( + rs, + descriptor.getSuffixedKeyAliases(), + session + ); + + if ( collectionRowKey != null ) { + // we found a collection element in the result set + + if ( LOG.isDebugEnabled() ) { + LOG.debugf( "Found row of collection: %s", + MessageHelper.collectionInfoString( persister, collectionRowKey, session.getFactory() ) ); + } + + Object owner = optionalOwner; + if ( owner == null ) { + owner = persistenceContext.getCollectionOwner( collectionRowKey, persister ); + if ( owner == null ) { + //TODO: This is assertion is disabled because there is a bug that means the + // original owner of a transient, uninitialized collection is not known + // if the collection is re-referenced by a different object associated + // with the current Session + //throw new AssertionFailure("bug loading unowned collection"); + } + } + + PersistentCollection rowCollection = persistenceContext.getLoadContexts() + .getCollectionLoadContext( rs ) + .getLoadingCollection( persister, collectionRowKey ); + + if ( rowCollection != null ) { + rowCollection.readFrom( rs, persister, descriptor, owner ); + } + + } + else if ( optionalKey != null ) { + // we did not find a collection element in the result set, so we + // ensure that a collection is created with the owner's identifier, + // since what we have is an empty collection + + if ( LOG.isDebugEnabled() ) { + LOG.debugf( "Result set contains (possibly empty) collection: %s", + MessageHelper.collectionInfoString( persister, optionalKey, session.getFactory() ) ); + } + + persistenceContext.getLoadContexts() + .getCollectionLoadContext( rs ) + .getLoadingCollection( persister, optionalKey ); // handle empty collection + + } + + // else no collection element, but also no owner + } + catch ( SQLException sqle ) { + // TODO: would be nice to have the SQL string that failed... + throw session.getFactory().getSQLExceptionHelper().convert( + sqle, + "could not read next row of results" + ); + } + } + + } + ); + } + @Override public void registerHydratedEntity(EntityPersister persister, EntityKey entityKey, Object entityInstance) { if ( currentRowHydratedEntityRegistrationList == null ) { @@ -488,19 +598,18 @@ void finishUpRow() { // managing the map forms needed for subselect fetch generation ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - if ( ! hadSubselectFetches ) { - return; - } - if ( subselectLoadableEntityKeyMap == null ) { - subselectLoadableEntityKeyMap = new HashMap>(); - } - for ( HydratedEntityRegistration registration : currentRowHydratedEntityRegistrationList ) { - Set entityKeys = subselectLoadableEntityKeyMap.get( registration.persister ); - if ( entityKeys == null ) { - entityKeys = new HashSet(); - subselectLoadableEntityKeyMap.put( registration.persister, entityKeys ); + if ( hadSubselectFetches ) { + if ( subselectLoadableEntityKeyMap == null ) { + subselectLoadableEntityKeyMap = new HashMap>(); + } + for ( HydratedEntityRegistration registration : currentRowHydratedEntityRegistrationList ) { + Set entityKeys = subselectLoadableEntityKeyMap.get( registration.persister ); + if ( entityKeys == null ) { + entityKeys = new HashSet(); + subselectLoadableEntityKeyMap.put( registration.persister, entityKeys ); + } + entityKeys.add( registration.key ); } - entityKeys.add( registration.key ); } // release the currentRowHydratedEntityRegistrationList entries @@ -602,15 +711,15 @@ private void finishLoadingCollections() { new LoadPlanVisitationStrategyAdapter() { @Override public void handleCollectionReturn(CollectionReturn rootCollectionReturn) { - endLoadingArray( rootCollectionReturn.getCollectionPersister() ); + endLoadingCollection( rootCollectionReturn.getCollectionPersister() ); } @Override public void startingCollectionFetch(CollectionFetch collectionFetch) { - endLoadingArray( collectionFetch.getCollectionPersister() ); + endLoadingCollection( collectionFetch.getCollectionPersister() ); } - private void endLoadingArray(CollectionPersister persister) { + private void endLoadingCollection(CollectionPersister persister) { if ( ! persister.isArray() ) { session.getPersistenceContext() .getLoadContexts() diff --git a/hibernate-core/src/main/java/org/hibernate/loader/internal/ResultSetProcessorImpl.java b/hibernate-core/src/main/java/org/hibernate/loader/internal/ResultSetProcessorImpl.java index 479f12e6b9..e9176048e6 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/internal/ResultSetProcessorImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/internal/ResultSetProcessorImpl.java @@ -126,6 +126,7 @@ public List extractResults( loadPlan.getReturns().get( 0 ).resolve( resultSet, context ); logicalRow = loadPlan.getReturns().get( 0 ).read( resultSet, context ); + context.readCollectionElements( new Object[] { logicalRow } ); } else { for ( Return rootReturn : loadPlan.getReturns() ) { @@ -141,6 +142,7 @@ public List extractResults( ( (Object[]) logicalRow )[pos] = rootReturn.read( resultSet, context ); pos++; } + context.readCollectionElements( (Object[]) logicalRow ); } // todo : apply transformers here? diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/internal/LoadPlanBuildingHelper.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/internal/LoadPlanBuildingHelper.java index 35c8df1d63..0c1cc20723 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/plan/internal/LoadPlanBuildingHelper.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/internal/LoadPlanBuildingHelper.java @@ -34,6 +34,7 @@ import org.hibernate.loader.plan.spi.FetchOwner; import org.hibernate.loader.plan.spi.LoadPlanBuildingContext; import org.hibernate.persister.walking.spi.AssociationAttributeDefinition; +import org.hibernate.persister.walking.spi.CollectionDefinition; import org.hibernate.persister.walking.spi.CompositionDefinition; /** @@ -46,7 +47,11 @@ public static CollectionFetch buildStandardCollectionFetch( FetchStrategy fetchStrategy, LoadPlanBuildingContext loadPlanBuildingContext) { final CollectionAliases collectionAliases = loadPlanBuildingContext.resolveCollectionColumnAliases( attributeDefinition ); - final EntityAliases elementEntityAliases = loadPlanBuildingContext.resolveEntityColumnAliases( attributeDefinition ); + final CollectionDefinition collectionDefinition = attributeDefinition.toCollectionDefinition(); + final EntityAliases elementEntityAliases = + collectionDefinition.getElementDefinition().getType().isEntityType() ? + loadPlanBuildingContext.resolveEntityColumnAliases( attributeDefinition ) : + null; return new CollectionFetch( loadPlanBuildingContext.getSessionFactory(), diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/AbstractLoadPlanBuilderStrategy.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/AbstractLoadPlanBuilderStrategy.java index 405b318dcc..a1162cbe33 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/AbstractLoadPlanBuilderStrategy.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/AbstractLoadPlanBuilderStrategy.java @@ -399,6 +399,7 @@ protected boolean handleAssociationAttribute(AssociationAttributeDefinition attr final Fetch associationFetch; if ( attributeDefinition.isCollection() ) { associationFetch = fetchOwner.buildCollectionFetch( attributeDefinition, fetchStrategy, this ); + pushToCollectionStack( (CollectionReference) associationFetch ); } else { associationFetch = fetchOwner.buildEntityFetch( diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/CollectionFetch.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/CollectionFetch.java index 89d82d4370..ab4e012ece 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/CollectionFetch.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/CollectionFetch.java @@ -62,6 +62,8 @@ public CollectionFetch( ); this.fetchOwner = fetchOwner; this.fetchStrategy = fetchStrategy; + + fetchOwner.addFetch( this ); } @Override diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/LoadPlanVisitor.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/LoadPlanVisitor.java index 9a371aa011..304ace31ec 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/LoadPlanVisitor.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/LoadPlanVisitor.java @@ -82,13 +82,15 @@ else if ( CollectionReturn.class.isInstance( rootReturn ) ) { } private void visitFetches(FetchOwner fetchOwner) { - strategy.startingFetches( fetchOwner ); + if ( fetchOwner != null ) { + strategy.startingFetches( fetchOwner ); - for ( Fetch fetch : fetchOwner.getFetches() ) { - visitFetch( fetch ); + for ( Fetch fetch : fetchOwner.getFetches() ) { + visitFetch( fetch ); + } + + strategy.finishingFetches( fetchOwner ); } - - strategy.finishingFetches( fetchOwner ); } private void visitFetch(Fetch fetch) { diff --git a/hibernate-core/src/main/java/org/hibernate/persister/walking/spi/MetadataDrivenModelGraphVisitor.java b/hibernate-core/src/main/java/org/hibernate/persister/walking/spi/MetadataDrivenModelGraphVisitor.java index dd205aa9e8..f22d172bec 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/walking/spi/MetadataDrivenModelGraphVisitor.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/walking/spi/MetadataDrivenModelGraphVisitor.java @@ -199,7 +199,7 @@ private void visitCollectionElements(CollectionDefinition collectionDefinition) if ( elementDefinition.getType().isComponentType() ) { visitCompositeDefinition( elementDefinition.toCompositeDefinition() ); } - else { + else if ( elementDefinition.getType().isEntityType() ) { visitEntityDefinition( elementDefinition.toEntityDefinition() ); } diff --git a/hibernate-core/src/test/java/org/hibernate/loader/AssociationResultSetProcessorTest.java b/hibernate-core/src/test/java/org/hibernate/loader/EntityAssociationResultSetProcessorTest.java similarity index 98% rename from hibernate-core/src/test/java/org/hibernate/loader/AssociationResultSetProcessorTest.java rename to hibernate-core/src/test/java/org/hibernate/loader/EntityAssociationResultSetProcessorTest.java index b41cf73572..f8eb3a0bcc 100644 --- a/hibernate-core/src/test/java/org/hibernate/loader/AssociationResultSetProcessorTest.java +++ b/hibernate-core/src/test/java/org/hibernate/loader/EntityAssociationResultSetProcessorTest.java @@ -60,9 +60,9 @@ import static org.junit.Assert.assertTrue; /** - * @author Steve Ebersole + * @author Gail Badner */ -public class AssociationResultSetProcessorTest extends BaseCoreFunctionalTestCase { +public class EntityAssociationResultSetProcessorTest extends BaseCoreFunctionalTestCase { @Override protected Class[] getAnnotatedClasses() { diff --git a/hibernate-core/src/test/java/org/hibernate/loader/EntityWithCollectionResultSetProcessorTest.java b/hibernate-core/src/test/java/org/hibernate/loader/EntityWithCollectionResultSetProcessorTest.java new file mode 100644 index 0000000000..d83804e815 --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/loader/EntityWithCollectionResultSetProcessorTest.java @@ -0,0 +1,174 @@ +/* + * 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.loader; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import javax.persistence.CascadeType; +import javax.persistence.ElementCollection; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.OneToMany; + +import org.junit.Test; + +import org.hibernate.Hibernate; +import org.hibernate.Session; +import org.hibernate.engine.spi.LoadQueryInfluencers; +import org.hibernate.engine.spi.QueryParameters; +import org.hibernate.engine.spi.SessionImplementor; +import org.hibernate.internal.util.collections.IdentitySet; +import org.hibernate.jdbc.Work; +import org.hibernate.loader.internal.EntityLoadQueryBuilderImpl; +import org.hibernate.loader.internal.ResultSetProcessorImpl; +import org.hibernate.loader.plan.internal.SingleRootReturnLoadPlanBuilderStrategy; +import org.hibernate.loader.plan.spi.LoadPlan; +import org.hibernate.loader.plan.spi.LoadPlanBuilder; +import org.hibernate.loader.spi.NamedParameterContext; +import org.hibernate.persister.entity.EntityPersister; +import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; +import org.hibernate.testing.junit4.ExtraAssertions; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; + +/** + * @author Gail Badner + */ +public class EntityWithCollectionResultSetProcessorTest extends BaseCoreFunctionalTestCase { + + @Override + protected Class[] getAnnotatedClasses() { + return new Class[] { Person.class }; + } + + @Test + public void testEntityWithSet() throws Exception { + final EntityPersister entityPersister = sessionFactory().getEntityPersister( Person.class.getName() ); + + // create some test data + Session session = openSession(); + session.beginTransaction(); + Person person = new Person(); + person.id = 1; + person.name = "John Doe"; + person.nickNames.add( "Jack" ); + person.nickNames.add( "Johnny" ); + session.save( person ); + session.getTransaction().commit(); + session.close(); + + { + final SingleRootReturnLoadPlanBuilderStrategy strategy = new SingleRootReturnLoadPlanBuilderStrategy( + sessionFactory(), + LoadQueryInfluencers.NONE, + "abc", + 0 + ); + final LoadPlan plan = LoadPlanBuilder.buildRootEntityLoadPlan( strategy, entityPersister ); + final EntityLoadQueryBuilderImpl queryBuilder = new EntityLoadQueryBuilderImpl( + sessionFactory(), + LoadQueryInfluencers.NONE, + plan + ); + final String sql = queryBuilder.generateSql( 1 ); + + final ResultSetProcessorImpl resultSetProcessor = new ResultSetProcessorImpl( plan ); + final List results = new ArrayList(); + + final Session workSession = openSession(); + workSession.beginTransaction(); + workSession.doWork( + new Work() { + @Override + public void execute(Connection connection) throws SQLException { + PreparedStatement ps = connection.prepareStatement( sql ); + ps.setInt( 1, 1 ); + ResultSet resultSet = ps.executeQuery(); + results.addAll( + resultSetProcessor.extractResults( + resultSet, + (SessionImplementor) workSession, + new QueryParameters(), + new NamedParameterContext() { + @Override + public int[] getNamedParameterLocations(String name) { + return new int[0]; + } + }, + true, + false, + null, + null + ) + ); + resultSet.close(); + ps.close(); + } + } + ); + assertEquals( 2, results.size() ); + Object result1 = results.get( 0 ); + assertSame( result1, results.get( 1 ) ); + assertNotNull( result1 ); + + Person workPerson = ExtraAssertions.assertTyping( Person.class, result1 ); + assertEquals( 1, workPerson.id.intValue() ); + assertEquals( person.name, workPerson.name ); + assertTrue( Hibernate.isInitialized( workPerson.nickNames ) ); + assertEquals( 2, workPerson.nickNames.size() ); + assertEquals( person.nickNames, workPerson.nickNames ); + workSession.getTransaction().commit(); + workSession.close(); + } + + // clean up test data + session = openSession(); + session.beginTransaction(); + session.delete( person ); + session.getTransaction().commit(); + session.close(); + } + + @Entity( name = "Person" ) + public static class Person { + @Id + private Integer id; + private String name; + @ElementCollection( fetch = FetchType.EAGER ) + private Set nickNames = new HashSet(); + } +} From ba1b02ed22ea08a265b9df8fdaa1db85019051ae Mon Sep 17 00:00:00 2001 From: Steve Ebersole Date: Thu, 11 Apr 2013 14:57:43 -0500 Subject: [PATCH 42/54] HHH-7841 - Redesign Loader --- .../persister/collection/AbstractCollectionPersister.java | 1 + 1 file changed, 1 insertion(+) diff --git a/hibernate-core/src/main/java/org/hibernate/persister/collection/AbstractCollectionPersister.java b/hibernate-core/src/main/java/org/hibernate/persister/collection/AbstractCollectionPersister.java index 3503962eea..96cf05b129 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/collection/AbstractCollectionPersister.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/collection/AbstractCollectionPersister.java @@ -45,6 +45,7 @@ import org.hibernate.cache.spi.entry.StructuredMapCacheEntry; import org.hibernate.cache.spi.entry.UnstructuredCacheEntry; import org.hibernate.cfg.Configuration; +import org.hibernate.cfg.NotYetImplementedException; import org.hibernate.collection.spi.PersistentCollection; import org.hibernate.dialect.Dialect; import org.hibernate.engine.jdbc.batch.internal.BasicBatchKey; From fb54d0f3a50f61880f2a67dac5a59fbbe0273f71 Mon Sep 17 00:00:00 2001 From: Lukasz Antoniak Date: Fri, 22 Mar 2013 18:54:05 +0100 Subject: [PATCH 43/54] HHH-8103 - Oracle LOBs with SequenceIdentityGenerator --- .../entity/AbstractEntityPersister.java | 13 ++- .../test/annotations/lob/Document.java | 99 +++++++++++++++++++ .../LobWithSequenceIdentityGeneratorTest.java | 79 +++++++++++++++ .../lob/OracleSeqIdGenDialect.java | 14 +++ 4 files changed, 203 insertions(+), 2 deletions(-) create mode 100644 hibernate-core/src/test/java/org/hibernate/test/annotations/lob/Document.java create mode 100644 hibernate-core/src/test/java/org/hibernate/test/annotations/lob/LobWithSequenceIdentityGeneratorTest.java create mode 100644 hibernate-core/src/test/java/org/hibernate/test/annotations/lob/OracleSeqIdGenDialect.java diff --git a/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java b/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java index 299b2626e3..36e2fd8345 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java @@ -2718,14 +2718,23 @@ protected String generateIdentityInsertString(boolean[] includeProperty) { Insert insert = identityDelegate.prepareIdentifierGeneratingInsert(); insert.setTableName( getTableName( 0 ) ); - // add normal properties + // add normal properties except lobs for ( int i = 0; i < entityMetamodel.getPropertySpan(); i++ ) { - if ( includeProperty[i] && isPropertyOfTable( i, 0 ) ) { + if ( includeProperty[i] && isPropertyOfTable( i, 0 ) && !lobProperties.contains( i ) ) { // this property belongs on the table and is to be inserted insert.addColumns( getPropertyColumnNames(i), propertyColumnInsertable[i], propertyColumnWriters[i] ); } } + // HHH-4635 & HHH-8103 + // Oracle expects all Lob properties to be last in inserts + // and updates. Insert them at the end. + for ( int i : lobProperties ) { + if ( includeProperty[i] && isPropertyOfTable( i, 0 ) ) { + insert.addColumns( getPropertyColumnNames(i), propertyColumnInsertable[i], propertyColumnWriters[i] ); + } + } + // add the discriminator addDiscriminatorToInsert( insert ); diff --git a/hibernate-core/src/test/java/org/hibernate/test/annotations/lob/Document.java b/hibernate-core/src/test/java/org/hibernate/test/annotations/lob/Document.java new file mode 100644 index 0000000000..8540e37e6b --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/test/annotations/lob/Document.java @@ -0,0 +1,99 @@ +package org.hibernate.test.annotations.lob; + +import java.io.Serializable; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Lob; + +/** + * @author Lukasz Antoniak (lukasz dot antoniak at gmail dot com) + */ +@Entity +public class Document implements Serializable { + @Id + @GeneratedValue(strategy = GenerationType.AUTO) // Required to use SequenceIdentityGenerator in test case for HHH-8103. + private Long id; + + private Integer revision; + + @Lob + @Column(length = 5000) + private String fullText; + + @Column(length = 120) + private String shortDescription; + + public Document() { + } + + public Document(Integer revision, String shortDescription, String fullText) { + this.revision = revision; + this.shortDescription = shortDescription; + this.fullText = fullText; + } + + @Override + public boolean equals(Object o) { + if ( this == o ) return true; + if ( !( o instanceof Document ) ) return false; + + Document document = (Document) o; + + if ( fullText != null ? !fullText.equals( document.fullText ) : document.fullText != null ) return false; + if ( id != null ? !id.equals( document.id ) : document.id != null ) return false; + if ( revision != null ? !revision.equals( document.revision ) : document.revision != null ) return false; + if ( shortDescription != null ? !shortDescription.equals( document.shortDescription ) : document.shortDescription != null ) return false; + + return true; + } + + @Override + public int hashCode() { + int result = id != null ? id.hashCode() : 0; + result = 31 * result + ( revision != null ? revision.hashCode() : 0 ); + result = 31 * result + ( shortDescription != null ? shortDescription.hashCode() : 0 ); + result = 31 * result + ( fullText != null ? fullText.hashCode() : 0 ); + return result; + } + + @Override + public String toString() { + return "Document(id = " + id + ", revision = " + revision + ", shortDescription = " + + shortDescription + ", fullText = " + fullText + ")"; + } + + public String getFullText() { + return fullText; + } + + public void setFullText(String fullText) { + this.fullText = fullText; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public Integer getRevision() { + return revision; + } + + public void setRevision(Integer revision) { + this.revision = revision; + } + + public String getShortDescription() { + return shortDescription; + } + + public void setShortDescription(String shortDescription) { + this.shortDescription = shortDescription; + } +} diff --git a/hibernate-core/src/test/java/org/hibernate/test/annotations/lob/LobWithSequenceIdentityGeneratorTest.java b/hibernate-core/src/test/java/org/hibernate/test/annotations/lob/LobWithSequenceIdentityGeneratorTest.java new file mode 100644 index 0000000000..06641cd262 --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/test/annotations/lob/LobWithSequenceIdentityGeneratorTest.java @@ -0,0 +1,79 @@ +package org.hibernate.test.annotations.lob; + +import org.junit.Assert; +import org.junit.Test; + +import org.hibernate.Session; +import org.hibernate.cfg.Configuration; +import org.hibernate.cfg.Environment; +import org.hibernate.dialect.Oracle8iDialect; +import org.hibernate.testing.RequiresDialect; +import org.hibernate.testing.TestForIssue; +import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; + +/** + * @author Lukasz Antoniak (lukasz dot antoniak at gmail dot com) + */ +@TestForIssue( jiraKey = "HHH-8103" ) +@RequiresDialect( Oracle8iDialect.class ) +public class LobWithSequenceIdentityGeneratorTest extends BaseCoreFunctionalTestCase { + @Override + protected void configure(Configuration configuration) { + configuration.setProperty( Environment.DIALECT, OracleSeqIdGenDialect.class.getName() ); + configuration.setProperty( Environment.USE_NEW_ID_GENERATOR_MAPPINGS, "false" ); + configuration.setProperty( Environment.USE_GET_GENERATED_KEYS, "true" ); + } + + @Override + protected Class[] getAnnotatedClasses() { + return new Class[] { Document.class }; + } + + @Test + public void testLobInsertUpdateDeleteSelect() { + Session session = openSession(); + + // Insert + session.getTransaction().begin(); + Document document = new Document( 1, "HHH-8103", "Oracle expects all LOB properties to be last in INSERT and UPDATE statements." ); + session.persist( document ); + session.getTransaction().commit(); + + session.clear(); + + session.getTransaction().begin(); + Assert.assertEquals( document, session.get( Document.class, document.getId() ) ); + session.getTransaction().commit(); + + session.clear(); + + // Update + session.getTransaction().begin(); + document = (Document) session.get( Document.class, document.getId() ); + document.setFullText( "Correct!" ); + session.update( document ); + session.getTransaction().commit(); + + session.clear(); + + session.getTransaction().begin(); + Assert.assertEquals( document, session.get( Document.class, document.getId() ) ); + session.getTransaction().commit(); + + session.clear(); + + // Delete + session.getTransaction().begin(); + document = (Document) session.get( Document.class, document.getId() ); + session.delete( document ); + session.getTransaction().commit(); + + session.clear(); + + session.getTransaction().begin(); + Assert.assertNull( session.get( Document.class, document.getId() ) ); + session.getTransaction().commit(); + + session.close(); + } +} diff --git a/hibernate-core/src/test/java/org/hibernate/test/annotations/lob/OracleSeqIdGenDialect.java b/hibernate-core/src/test/java/org/hibernate/test/annotations/lob/OracleSeqIdGenDialect.java new file mode 100644 index 0000000000..7a7f703b8c --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/test/annotations/lob/OracleSeqIdGenDialect.java @@ -0,0 +1,14 @@ +package org.hibernate.test.annotations.lob; + +import org.hibernate.dialect.Oracle10gDialect; +import org.hibernate.id.SequenceIdentityGenerator; + +/** + * @author Lukasz Antoniak (lukasz dot antoniak at gmail dot com) + */ +public class OracleSeqIdGenDialect extends Oracle10gDialect { + @Override + public Class getNativeIdentifierGeneratorClass() { + return SequenceIdentityGenerator.class; + } +} From 6d6dcdf26710c9fe6569088dfd1c942abc152c9b Mon Sep 17 00:00:00 2001 From: Lukasz Antoniak Date: Mon, 8 Apr 2013 15:53:58 +0200 Subject: [PATCH 44/54] HHH-7605 - Event cache descriptive error messages --- .../internal/DefaultMergeEventListener.java | 2 +- .../hibernate/event/internal/EventCache.java | 68 ++++++++++-- .../event/internal/EventCacheTest.java | 104 ++++++++++++------ 3 files changed, 129 insertions(+), 45 deletions(-) diff --git a/hibernate-core/src/main/java/org/hibernate/event/internal/DefaultMergeEventListener.java b/hibernate-core/src/main/java/org/hibernate/event/internal/DefaultMergeEventListener.java index 5d00d6afad..d3a1a5a876 100755 --- a/hibernate-core/src/main/java/org/hibernate/event/internal/DefaultMergeEventListener.java +++ b/hibernate-core/src/main/java/org/hibernate/event/internal/DefaultMergeEventListener.java @@ -73,7 +73,7 @@ protected Map getMergeMap(Object anything) { * @throws HibernateException */ public void onMerge(MergeEvent event) throws HibernateException { - EventCache copyCache = new EventCache(); + EventCache copyCache = new EventCache( event.getSession() ); onMerge( event, copyCache ); copyCache.clear(); copyCache = null; diff --git a/hibernate-core/src/main/java/org/hibernate/event/internal/EventCache.java b/hibernate-core/src/main/java/org/hibernate/event/internal/EventCache.java index 9bdf9f47f5..7c4bc9a26a 100644 --- a/hibernate-core/src/main/java/org/hibernate/event/internal/EventCache.java +++ b/hibernate-core/src/main/java/org/hibernate/event/internal/EventCache.java @@ -30,6 +30,8 @@ import java.util.Set; import org.hibernate.AssertionFailure; +import org.hibernate.event.spi.EventSource; +import org.hibernate.pretty.MessageHelper; /** * EventCache is a Map implementation that can be used by an event @@ -59,6 +61,8 @@ * @author Gail Badner */ class EventCache implements Map { + private final EventSource session; + private Map entityToCopyMap = new IdentityHashMap(10); // key is an entity involved with the operation performed by the listener; // value can be either a copy of the entity or the entity itself @@ -70,6 +74,10 @@ class EventCache implements Map { // key is an entity involved with the operation performed by the listener; // value is a flag indicating if the listener explicitly operates on the entity + EventCache(EventSource session) { + this.session = session; + } + /** * Clears the EventCache. */ @@ -181,10 +189,16 @@ public Object put(Object entity, Object copy) { if ( oldCopy == null ) { if ( oldEntity != null ) { - throw new IllegalStateException( "An entity copy was already assigned to a different entity." ); + throw new IllegalStateException( + "Error occurred while storing entity " + printEntity( entity ) + ". An entity copy " + printEntity( copy ) + + " was already assigned to a different entity " + printEntity( oldEntity ) + "." + ); } if ( oldOperatedOn != null ) { - throw new IllegalStateException( "entityToOperatedOnFlagMap contains an entity, but entityToCopyMap does not." ); + throw new IllegalStateException( + "EventCache#entityToOperatedOnFlagMap contains an entity " + printEntity( entity ) + + ", but EventCache#entityToCopyMap does not." + ); } } else { @@ -193,21 +207,33 @@ public Object put(Object entity, Object copy) { // to synch things up. Object removedEntity = copyToEntityMap.remove( oldCopy ); if ( removedEntity != entity ) { - throw new IllegalStateException( "An unexpected entity was associated with the old entity copy." ); + throw new IllegalStateException( + "Error occurred while storing entity " + printEntity( entity ) + ". An unexpected entity " + printEntity( removedEntity ) + + " was associated with the old entity copy " + printEntity( oldCopy ) + "." + ); } if ( oldEntity != null ) { - throw new IllegalStateException( "A new entity copy is already associated with a different entity." ); + throw new IllegalStateException( + "Error occurred while storing entity " + printEntity( entity ) + ". A new entity copy " + printEntity( copy ) + + " is already associated with a different entity " + printEntity( oldEntity ) + "." + ); } } else { // Replaced an entity copy with the same copy in entityToCopyMap. // Make sure that copy is associated with the same entity in copyToEntityMap. if ( oldEntity != entity ) { - throw new IllegalStateException( "An entity copy was associated with a different entity than provided." ); + throw new IllegalStateException( + "An entity copy " + printEntity( copy ) + " was associated with a different entity " + + printEntity( oldEntity ) + " than provided " + printEntity( entity ) + "." + ); } } if ( oldOperatedOn == null ) { - throw new IllegalStateException( "entityToCopyMap contained an entity, but entityToOperatedOnFlagMap did not." ); + throw new IllegalStateException( + "EventCache#entityToCopyMap contained an entity " + printEntity( entity ) + + ", but EventCache#entityToOperatedOnFlagMap did not." + ); } } @@ -242,18 +268,30 @@ public Object remove(Object entity) { if ( oldCopy == null ) { if ( oldOperatedOn != null ) { - throw new IllegalStateException( "Removed entity from entityToOperatedOnFlagMap, but entityToCopyMap did not contain the entity." ); + throw new IllegalStateException( + "Removed entity " + printEntity( entity ) + + " from EventCache#entityToOperatedOnFlagMap, but EventCache#entityToCopyMap did not contain the entity." + ); } } else { if ( oldEntity == null ) { - throw new IllegalStateException( "Removed entity from entityToCopyMap, but copyToEntityMap did not contain the entity." ); + throw new IllegalStateException( + "Removed entity " + printEntity( entity ) + + " from EventCache#entityToCopyMap, but EventCache#copyToEntityMap did not contain the entity." + ); } if ( oldOperatedOn == null ) { - throw new IllegalStateException( "entityToCopyMap contained an entity, but entityToOperatedOnFlagMap did not." ); + throw new IllegalStateException( + "EventCache#entityToCopyMap contained an entity " + printEntity( entity ) + + ", but EventCache#entityToOperatedOnFlagMap did not." + ); } if ( oldEntity != entity ) { - throw new IllegalStateException( "An entity copy was associated with a different entity than provided." ); + throw new IllegalStateException( + "An entity copy " + printEntity( oldCopy ) + " was associated with a different entity " + + printEntity( oldEntity ) + " than provided " + printEntity( entity ) + "." + ); } } @@ -303,7 +341,7 @@ public boolean isOperatedOn(Object entity) { } if ( ! entityToOperatedOnFlagMap.containsKey( entity ) || ! entityToCopyMap.containsKey( entity ) ) { - throw new AssertionFailure( "called EventCache.setOperatedOn() for entity not found in EventCache" ); + throw new AssertionFailure( "called EventCache#setOperatedOn() for entity not found in EventCache" ); } entityToOperatedOnFlagMap.put( entity, isOperatedOn ); } @@ -317,4 +355,12 @@ public boolean isOperatedOn(Object entity) { public Map invertMap() { return Collections.unmodifiableMap( copyToEntityMap ); } + + private String printEntity(Object entity) { + if ( session.getPersistenceContext().getEntry( entity ) != null ) { + return MessageHelper.infoString( session.getEntityName( entity ), session.getIdentifier( entity ) ); + } + // Entity was not found in current persistence context. Use Object#toString() method. + return "[" + entity + "]"; + } } \ No newline at end of file diff --git a/hibernate-core/src/test/java/org/hibernate/event/internal/EventCacheTest.java b/hibernate-core/src/test/java/org/hibernate/event/internal/EventCacheTest.java index 780b6fd072..ff3576e59e 100644 --- a/hibernate-core/src/test/java/org/hibernate/event/internal/EventCacheTest.java +++ b/hibernate-core/src/test/java/org/hibernate/event/internal/EventCacheTest.java @@ -29,20 +29,53 @@ import java.util.Iterator; import java.util.Map; import java.util.Set; +import javax.persistence.Entity; +import javax.persistence.Id; -import junit.framework.TestCase; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import org.hibernate.Session; +import org.hibernate.event.spi.EventSource; +import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; /** - * 2011/10/20 Unit test for code added in EventCache for performance improvement. - * @author Wim Ockerman @ CISCO - * - * + * 2011/10/20 Unit test for code added in EventCache for performance improvement. * + * @author Wim Ockerman @ CISCO */ -public class EventCacheTest extends TestCase { - +public class EventCacheTest extends BaseCoreFunctionalTestCase { + private Session session = null; + private EventCache cache = null; + + @Override + protected Class[] getAnnotatedClasses() { + return new Class[] { Simple.class }; + } + + @Before + public void setUp() { + session = openSession(); + cache = new EventCache( ( EventSource) session ); + } + + @After + public void tearDown() { + cache = null; + session.close(); + session = null; + } + + @Test public void testEntityToCopyFillFollowedByCopyToEntityMapping() { - EventCache cache = new EventCache(); Object entity = new Simple( 1 ); Object copy = new Simple( 2 ); @@ -66,8 +99,8 @@ public void testEntityToCopyFillFollowedByCopyToEntityMapping() { assertFalse(cache.invertMap().containsKey(copy)); } + @Test public void testEntityToCopyFillFollowedByCopyToEntityMappingOnRemove() { - EventCache cache = new EventCache(); Object entity = new Simple( 1 ); Object copy = new Simple( 2 ); @@ -88,9 +121,9 @@ public void testEntityToCopyFillFollowedByCopyToEntityMappingOnRemove() { assertFalse(cache.containsKey(entity)); assertFalse(cache.invertMap().containsKey(copy)); } - + + @Test public void testEntityToCopyFillFollowedByCopyToEntityUsingPutAll() { - EventCache cache = new EventCache(); Map input = new HashMap(); Object entity1 = new Simple( 1 ); // @@ -114,9 +147,9 @@ public void testEntityToCopyFillFollowedByCopyToEntityUsingPutAll() { assertTrue(cache.invertMap().containsKey(copy2)); assertFalse(cache.invertMap().containsKey(entity2)); } - + + @Test public void testEntityToCopyFillFollowedByCopyToEntityMappingUsingPutWithSetOperatedOnArg() { - EventCache cache = new EventCache(); Object entity = new Simple( 1 ); Object copy = new Simple( 2 ); @@ -142,8 +175,8 @@ public void testEntityToCopyFillFollowedByCopyToEntityMappingUsingPutWithSetOper assertFalse(cache.containsKey(copy)); } + @Test public void testEntityToCopyFillFollowedByIterateEntrySet() { - EventCache cache = new EventCache(); Object entity = new Simple( 1 ); Object copy = new Simple( 2 ); @@ -160,8 +193,8 @@ public void testEntityToCopyFillFollowedByIterateEntrySet() { } + @Test public void testEntityToCopyFillFollowedByModifyEntrySet() { - EventCache cache = new EventCache(); Object entity = new Simple( 1 ); Object copy = new Simple( 2 ); @@ -215,8 +248,8 @@ public Object setValue(Object value) { } + @Test public void testEntityToCopyFillFollowedByModifyKeys() { - EventCache cache = new EventCache(); Object entity = new Simple( 1 ); Object copy = new Simple( 2 ); @@ -249,8 +282,8 @@ public void testEntityToCopyFillFollowedByModifyKeys() { } } + @Test public void testEntityToCopyFillFollowedByModifyValues() { - EventCache cache = new EventCache(); Object entity = new Simple( 1 ); Object copy = new Simple( 2 ); @@ -283,9 +316,8 @@ public void testEntityToCopyFillFollowedByModifyValues() { } } + @Test public void testEntityToCopyFillFollowedByModifyKeyOfEntrySetElement() { - - EventCache cache = new EventCache(); Simple entity = new Simple( 1 ); Simple copy = new Simple( 0 ); cache.put(entity, copy, true); @@ -301,9 +333,8 @@ public void testEntityToCopyFillFollowedByModifyKeyOfEntrySetElement() { assertSame( copy, entry.getValue() ); } + @Test public void testEntityToCopyFillFollowedByModifyValueOfEntrySetElement() { - - EventCache cache = new EventCache(); Simple entity = new Simple( 1 ); Simple copy = new Simple( 0 ); cache.put(entity, copy, true); @@ -319,9 +350,8 @@ public void testEntityToCopyFillFollowedByModifyValueOfEntrySetElement() { assertSame( copy, entry.getValue() ); } + @Test public void testReplaceEntityCopy() { - - EventCache cache = new EventCache(); Simple entity = new Simple( 1 ); Simple copy = new Simple( 0 ); cache.put(entity, copy); @@ -340,12 +370,14 @@ public void testReplaceEntityCopy() { checkCacheConsistency( cache, 1 ); } + @Test public void testCopyAssociatedWithNewAndExistingEntity() { - - EventCache cache = new EventCache(); + session.getTransaction().begin(); Simple entity = new Simple( 1 ); Simple copy = new Simple( 0 ); + session.persist( entity ); cache.put(entity, copy); + session.flush(); try { cache.put( new Simple( 1 ), copy ); @@ -353,19 +385,23 @@ public void testCopyAssociatedWithNewAndExistingEntity() { } catch( IllegalStateException ex ) { // expected + assertTrue( ex.getMessage().startsWith( "Error occurred while storing entity [org.hibernate.event.internal.EventCacheTest$Simple@" ) ); } - + session.getTransaction().rollback(); } + @Test public void testCopyAssociatedWith2ExistingEntities() { - - EventCache cache = new EventCache(); + session.getTransaction().begin(); Simple entity1 = new Simple( 1 ); - Simple copy1 = new Simple( 0 ); + session.persist( entity1 ); + Simple copy1 = new Simple( 1 ); cache.put(entity1, copy1); Simple entity2 = new Simple( 2 ); - Simple copy2 = new Simple( 0 ); + session.persist( entity2 ); + Simple copy2 = new Simple( 2 ); cache.put( entity2, copy2 ); + session.flush(); try { cache.put( entity1, copy2 ); @@ -373,17 +409,17 @@ public void testCopyAssociatedWith2ExistingEntities() { } catch( IllegalStateException ex ) { // expected + assertTrue( ex.getMessage().startsWith( "Error occurred while storing entity [org.hibernate.event.internal.EventCacheTest$Simple#1]." ) ); } + session.getTransaction().rollback(); } + @Test public void testRemoveNonExistingEntity() { - - EventCache cache = new EventCache(); assertNull( cache.remove( new Simple( 1 ) ) ); } private void checkCacheConsistency(EventCache cache, int expectedSize) { - Set entrySet = cache.entrySet(); Set cacheKeys = cache.keySet(); Collection cacheValues = cache.values(); @@ -404,7 +440,9 @@ private void checkCacheConsistency(EventCache cache, int expectedSize) { } } + @Entity private static class Simple { + @Id private int value; public Simple(int value) { From bd315f01a98b2570ba294f14527f17185485c827 Mon Sep 17 00:00:00 2001 From: Lukasz Antoniak Date: Sat, 30 Mar 2013 18:02:48 +0100 Subject: [PATCH 45/54] HHH-7357 - Constraint violation exception while inserting NULL to not nullable column --- .../java/org/hibernate/dialect/H2Dialect.java | 7 ++ .../hibernate/dialect/Oracle8iDialect.java | 9 +++ .../dialect/SybaseASE157Dialect.java | 7 ++ .../internal/SQLStateConversionDelegate.java | 7 +- .../exception/SQLExceptionConversionTest.java | 75 +++++++++++++++---- .../org/hibernate/test/exception/User.hbm.xml | 2 +- 6 files changed, 87 insertions(+), 20 deletions(-) diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/H2Dialect.java b/hibernate-core/src/main/java/org/hibernate/dialect/H2Dialect.java index 9adc838f0b..288e205985 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/H2Dialect.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/H2Dialect.java @@ -30,6 +30,7 @@ import org.hibernate.dialect.function.NoArgSQLFunction; import org.hibernate.dialect.function.StandardSQLFunction; import org.hibernate.dialect.function.VarArgsSQLFunction; +import org.hibernate.exception.ConstraintViolationException; import org.hibernate.exception.LockAcquisitionException; import org.hibernate.exception.spi.SQLExceptionConversionDelegate; import org.hibernate.exception.spi.TemplatedViolatedConstraintNameExtracter; @@ -313,6 +314,12 @@ public JDBCException convert(SQLException sqlException, String message, String s exception = new PessimisticLockException(message, sqlException, sql); } + if ( 90006 == errorCode ) { + // NULL not allowed for column [90006-145] + final String constraintName = getViolatedConstraintNameExtracter().extractConstraintName( sqlException ); + exception = new ConstraintViolationException( message, sqlException, sql, constraintName ); + } + return exception; } }; diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/Oracle8iDialect.java b/hibernate-core/src/main/java/org/hibernate/dialect/Oracle8iDialect.java index 123e38e249..5a0d243feb 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/Oracle8iDialect.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/Oracle8iDialect.java @@ -37,6 +37,7 @@ import org.hibernate.dialect.function.SQLFunctionTemplate; import org.hibernate.dialect.function.StandardSQLFunction; import org.hibernate.dialect.function.VarArgsSQLFunction; +import org.hibernate.exception.ConstraintViolationException; import org.hibernate.exception.LockAcquisitionException; import org.hibernate.exception.LockTimeoutException; import org.hibernate.exception.spi.SQLExceptionConversionDelegate; @@ -462,6 +463,14 @@ else if ( 4020 == errorCode ) { } + // data integrity violation ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + if ( 1407 == errorCode ) { + // ORA-01407: cannot update column to NULL + final String constraintName = getViolatedConstraintNameExtracter().extractConstraintName( sqlException ); + return new ConstraintViolationException( message, sqlException, sql, constraintName ); + } + return null; } }; diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/SybaseASE157Dialect.java b/hibernate-core/src/main/java/org/hibernate/dialect/SybaseASE157Dialect.java index dc9a08b50e..1096672ecd 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/SybaseASE157Dialect.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/SybaseASE157Dialect.java @@ -31,6 +31,7 @@ import org.hibernate.LockOptions; import org.hibernate.QueryTimeoutException; import org.hibernate.dialect.function.SQLFunctionTemplate; +import org.hibernate.exception.ConstraintViolationException; import org.hibernate.exception.LockAcquisitionException; import org.hibernate.exception.LockTimeoutException; import org.hibernate.exception.spi.SQLExceptionConversionDelegate; @@ -104,9 +105,15 @@ public SQLExceptionConversionDelegate buildSQLExceptionConversionDelegate() { @Override public JDBCException convert(SQLException sqlException, String message, String sql) { final String sqlState = JdbcExceptionHelper.extractSqlState( sqlException ); + final int errorCode = JdbcExceptionHelper.extractErrorCode( sqlException ); if("JZ0TO".equals( sqlState ) || "JZ006".equals( sqlState )){ throw new LockTimeoutException( message, sqlException, sql ); } + if ( 515 == errorCode && "ZZZZZ".equals( sqlState ) ) { + // Attempt to insert NULL value into column; column does not allow nulls. + final String constraintName = getViolatedConstraintNameExtracter().extractConstraintName( sqlException ); + return new ConstraintViolationException( message, sqlException, sql, constraintName ); + } return null; } }; diff --git a/hibernate-core/src/main/java/org/hibernate/exception/internal/SQLStateConversionDelegate.java b/hibernate-core/src/main/java/org/hibernate/exception/internal/SQLStateConversionDelegate.java index f92c37929b..b7a5ac2659 100644 --- a/hibernate-core/src/main/java/org/hibernate/exception/internal/SQLStateConversionDelegate.java +++ b/hibernate-core/src/main/java/org/hibernate/exception/internal/SQLStateConversionDelegate.java @@ -112,7 +112,8 @@ public SQLStateConversionDelegate(ConversionContext conversionContext) { @Override public JDBCException convert(SQLException sqlException, String message, String sql) { - String sqlState = JdbcExceptionHelper.extractSqlState( sqlException ); + final String sqlState = JdbcExceptionHelper.extractSqlState( sqlException ); + final int errorCode = JdbcExceptionHelper.extractErrorCode( sqlException ); if ( sqlState != null ) { String sqlStateClassCode = JdbcExceptionHelper.determineSqlStateClassCode( sqlState ); @@ -146,8 +147,8 @@ else if ( DATA_CATEGORIES.contains( sqlStateClassCode ) ) { // MySQL Query execution was interrupted if ( "70100".equals( sqlState ) || - // Oracle user requested cancel of current operation - "72000".equals( sqlState ) ) { + // Oracle user requested cancel of current operation + ( "72000".equals( sqlState ) && errorCode == 1013 ) ) { throw new QueryTimeoutException( message, sqlException, sql ); } } diff --git a/hibernate-core/src/test/java/org/hibernate/test/exception/SQLExceptionConversionTest.java b/hibernate-core/src/test/java/org/hibernate/test/exception/SQLExceptionConversionTest.java index c3ce0b3ef5..811f8edc63 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/exception/SQLExceptionConversionTest.java +++ b/hibernate-core/src/test/java/org/hibernate/test/exception/SQLExceptionConversionTest.java @@ -26,16 +26,21 @@ import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; +import java.sql.Types; import org.junit.Test; import org.hibernate.Session; import org.hibernate.dialect.MySQLMyISAMDialect; +import org.hibernate.engine.jdbc.spi.JdbcCoordinator; +import org.hibernate.engine.jdbc.spi.ResultSetReturn; +import org.hibernate.engine.jdbc.spi.StatementPreparer; import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.exception.ConstraintViolationException; import org.hibernate.exception.SQLGrammarException; import org.hibernate.jdbc.Work; import org.hibernate.testing.SkipForDialect; +import org.hibernate.testing.TestForIssue; import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; import static org.junit.Assert.fail; @@ -78,14 +83,7 @@ public void execute(Connection connection) throws SQLException { // expected outcome } finally { - if ( ps != null ) { - try { - ((SessionImplementor)session).getTransactionCoordinator().getJdbcCoordinator().release( ps ); - } - catch( Throwable ignore ) { - // ignore... - } - } + releaseStatement( session, ps ); } } } @@ -116,14 +114,7 @@ public void execute(Connection connection) throws SQLException { // expected outcome } finally { - if ( ps != null ) { - try { - ((SessionImplementor)session).getTransactionCoordinator().getJdbcCoordinator().release( ps ); - } - catch( Throwable ignore ) { - // ignore... - } - } + releaseStatement( session, ps ); } } } @@ -132,4 +123,56 @@ public void execute(Connection connection) throws SQLException { session.getTransaction().rollback(); session.close(); } + + @Test + @TestForIssue(jiraKey = "HHH-7357") + public void testNotNullConstraint() { + final Session session = openSession(); + session.beginTransaction(); + + final User user = new User(); + user.setUsername( "Lukasz" ); + session.save( user ); + session.flush(); + + session.doWork( + new Work() { + @Override + public void execute(Connection connection) throws SQLException { + final JdbcCoordinator jdbcCoordinator = ( (SessionImplementor) session ).getTransactionCoordinator().getJdbcCoordinator(); + final StatementPreparer statementPreparer = jdbcCoordinator.getStatementPreparer(); + final ResultSetReturn resultSetReturn = jdbcCoordinator.getResultSetReturn(); + PreparedStatement ps = null; + try { + ps = statementPreparer.prepareStatement( "UPDATE T_USER SET user_name = ? WHERE user_id = ?" ); + ps.setNull( 1, Types.VARCHAR ); // Attempt to update user name to NULL (NOT NULL constraint defined). + ps.setLong( 2, user.getId() ); + resultSetReturn.executeUpdate( ps ); + + fail( "UPDATE should have failed because of not NULL constraint." ); + } + catch ( ConstraintViolationException ignore ) { + // expected outcome + } + finally { + releaseStatement( session, ps ); + } + } + } + ); + + session.getTransaction().rollback(); + session.close(); + } + + private void releaseStatement(Session session, PreparedStatement ps) { + if ( ps != null ) { + try { + ( (SessionImplementor) session ).getTransactionCoordinator().getJdbcCoordinator().release( ps ); + } + catch ( Throwable ignore ) { + // ignore... + } + } + } } diff --git a/hibernate-core/src/test/java/org/hibernate/test/exception/User.hbm.xml b/hibernate-core/src/test/java/org/hibernate/test/exception/User.hbm.xml index a18408ddac..110e5635c5 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/exception/User.hbm.xml +++ b/hibernate-core/src/test/java/org/hibernate/test/exception/User.hbm.xml @@ -6,7 +6,7 @@ - + From 7778aae3b7366137643f9dd3f1c088ca498051cb Mon Sep 17 00:00:00 2001 From: Jeremy Whiting Date: Thu, 11 Apr 2013 17:52:20 -0400 Subject: [PATCH 46/54] HHH-8180 Checks for logging level. Logging level check moved to variable outside for loop. --- .../main/java/org/hibernate/loader/Loader.java | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/hibernate-core/src/main/java/org/hibernate/loader/Loader.java b/hibernate-core/src/main/java/org/hibernate/loader/Loader.java index 2ad4cf8479..1430604082 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/Loader.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/Loader.java @@ -931,8 +931,10 @@ protected List processResultSet( EntityKey[] keys = new EntityKey[entitySpan]; //we can reuse it for each row LOG.trace( "Processing result set" ); int count; + boolean isDebugEnabled = LOG.isDebugEnabled(); for ( count = 0; count < maxRows && rs.next(); count++ ) { - LOG.debugf( "Result set row: %s", count ); + if ( isDebugEnabled ) + LOG.debugf( "Result set row: %s", count ); Object result = getRowFromResultSet( rs, session, @@ -951,7 +953,8 @@ protected List processResultSet( } } - LOG.tracev( "Done processing result set ({0} rows)", count ); + if ( LOG.isTraceEnabled() ) + LOG.tracev( "Done processing result set ({0} rows)", count ); initializeEntitiesAndCollections( hydratedObjects, @@ -1093,7 +1096,8 @@ private void initializeEntitiesAndCollections( if ( hydratedObjects!=null ) { int hydratedObjectsSize = hydratedObjects.size(); - LOG.tracev( "Total objects hydrated: {0}", hydratedObjectsSize ); + if ( LOG.isTraceEnabled() ) + LOG.tracev( "Total objects hydrated: {0}", hydratedObjectsSize ); for ( int i = 0; i < hydratedObjectsSize; i++ ) { TwoPhaseLoad.initializeEntity( hydratedObjects.get(i), readOnly, session, pre, post ); } @@ -1901,7 +1905,8 @@ else if ( dialect.isLockTimeoutParameterized() ) { } } - LOG.tracev( "Bound [{0}] parameters total", col ); + if ( LOG.isTraceEnabled() ) + LOG.tracev( "Bound [{0}] parameters total", col ); } catch ( SQLException sqle ) { session.getTransactionCoordinator().getJdbcCoordinator().release( st ); @@ -2057,7 +2062,8 @@ private synchronized ResultSet wrapResultSetIfEnabled(final ResultSet rs, final // potential deadlock issues due to nature of code. if ( session.getFactory().getSettings().isWrapResultSetsEnabled() ) { try { - LOG.debugf( "Wrapping result set [%s]", rs ); + if ( LOG.isDebugEnabled() ) + LOG.debugf( "Wrapping result set [%s]", rs ); return session.getFactory() .getJdbcServices() .getResultSetWrapper().wrap( rs, retreiveColumnNameToIndexCache( rs ) ); From 6be8b4aad03e42f8758df217546010371ec3ee23 Mon Sep 17 00:00:00 2001 From: Lukasz Antoniak Date: Fri, 8 Feb 2013 11:15:43 +0100 Subject: [PATCH 47/54] HHH-7478 - Fix and test --- .../org/hibernate/engine/spi/ActionQueue.java | 11 ++- .../envers/internal/tools/MutableInteger.java | 19 ++++- .../basic/RegisterUserEventListenersTest.java | 83 +++++++++++++++++++ 3 files changed, 108 insertions(+), 5 deletions(-) create mode 100644 hibernate-envers/src/test/java/org/hibernate/envers/test/integration/basic/RegisterUserEventListenersTest.java diff --git a/hibernate-core/src/main/java/org/hibernate/engine/spi/ActionQueue.java b/hibernate-core/src/main/java/org/hibernate/engine/spi/ActionQueue.java index f4c943c10c..a70c2bf3d5 100644 --- a/hibernate-core/src/main/java/org/hibernate/engine/spi/ActionQueue.java +++ b/hibernate-core/src/main/java/org/hibernate/engine/spi/ActionQueue.java @@ -32,7 +32,9 @@ import java.util.HashSet; import java.util.LinkedList; import java.util.List; +import java.util.Queue; import java.util.Set; +import java.util.concurrent.ConcurrentLinkedQueue; import org.jboss.logging.Logger; @@ -643,7 +645,9 @@ public static ActionQueue deserialize( private static class BeforeTransactionCompletionProcessQueue { private SessionImplementor session; - private List processes = new ArrayList(); + // Concurrency handling required when transaction completion process is dynamically registered + // inside event listener (HHH-7478). + private Queue processes = new ConcurrentLinkedQueue(); private BeforeTransactionCompletionProcessQueue(SessionImplementor session) { this.session = session; @@ -675,8 +679,9 @@ public void beforeTransactionCompletion() { private static class AfterTransactionCompletionProcessQueue { private SessionImplementor session; private Set querySpacesToInvalidate = new HashSet(); - private List processes - = new ArrayList( INIT_QUEUE_LIST_SIZE * 3 ); + // Concurrency handling required when transaction completion process is dynamically registered + // inside event listener (HHH-7478). + private Queue processes = new ConcurrentLinkedQueue(); private AfterTransactionCompletionProcessQueue(SessionImplementor session) { this.session = session; diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/internal/tools/MutableInteger.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/tools/MutableInteger.java index bc48be544a..3696510645 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/internal/tools/MutableInteger.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/tools/MutableInteger.java @@ -23,17 +23,32 @@ */ package org.hibernate.envers.internal.tools; - /** * @author Adam Warski (adam at warski dot org) */ public class MutableInteger { - private int value; + private int value = 0; public MutableInteger() { } + public MutableInteger(int value) { + this.value = value; + } + public int getAndIncrease() { return value++; } + + public int get() { + return value; + } + + public void set(int value) { + this.value = value; + } + + public void increase() { + ++value; + } } \ No newline at end of file diff --git a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/basic/RegisterUserEventListenersTest.java b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/basic/RegisterUserEventListenersTest.java new file mode 100644 index 0000000000..c7712e2de3 --- /dev/null +++ b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/basic/RegisterUserEventListenersTest.java @@ -0,0 +1,83 @@ +package org.hibernate.envers.test.integration.basic; + +import org.junit.Assert; +import org.junit.Test; + +import org.hibernate.Session; +import org.hibernate.action.spi.AfterTransactionCompletionProcess; +import org.hibernate.action.spi.BeforeTransactionCompletionProcess; +import org.hibernate.engine.spi.SessionImplementor; +import org.hibernate.envers.test.BaseEnversFunctionalTestCase; +import org.hibernate.envers.test.entities.StrTestEntity; +import org.hibernate.envers.tools.MutableInteger; +import org.hibernate.event.service.spi.EventListenerRegistry; +import org.hibernate.event.spi.EventType; +import org.hibernate.event.spi.PostInsertEvent; +import org.hibernate.event.spi.PostInsertEventListener; +import org.hibernate.persister.entity.EntityPersister; +import org.hibernate.testing.TestForIssue; + +/** + * @author Lukasz Antoniak (lukasz dot antoniak at gmail dot com) + */ +public class RegisterUserEventListenersTest extends BaseEnversFunctionalTestCase { + @Override + protected Class[] getAnnotatedClasses() { + return new Class[] { StrTestEntity.class }; + } + + @Test + @TestForIssue( jiraKey = "HHH-7478" ) + public void testTransactionProcessSynchronization() { + final EventListenerRegistry registry = sessionFactory().getServiceRegistry().getService( EventListenerRegistry.class ); + final CountingPostInsertTransactionBoundaryListener listener = new CountingPostInsertTransactionBoundaryListener(); + + registry.getEventListenerGroup( EventType.POST_INSERT ).appendListener( listener ); + + Session session = openSession(); + session.getTransaction().begin(); + StrTestEntity entity = new StrTestEntity( "str1" ); + session.save( entity ); + session.getTransaction().commit(); + session.close(); + + // Post insert listener invoked three times - before/after insertion of original data, + // revision entity and audit row. + Assert.assertEquals( 3, listener.getBeforeCount() ); + Assert.assertEquals( 3, listener.getAfterCount() ); + } + + private static class CountingPostInsertTransactionBoundaryListener implements PostInsertEventListener { + private final MutableInteger beforeCounter = new MutableInteger(); + private final MutableInteger afterCounter = new MutableInteger(); + + @Override + public void onPostInsert(PostInsertEvent event) { + event.getSession().getActionQueue().registerProcess(new BeforeTransactionCompletionProcess() { + @Override + public void doBeforeTransactionCompletion(SessionImplementor session) { + beforeCounter.increase(); + } + }); + event.getSession().getActionQueue().registerProcess(new AfterTransactionCompletionProcess() { + @Override + public void doAfterTransactionCompletion(boolean success, SessionImplementor session) { + afterCounter.increase(); + } + }); + } + + @Override + public boolean requiresPostCommitHanding(EntityPersister persister) { + return true; + } + + public int getBeforeCount() { + return beforeCounter.get(); + } + + public int getAfterCount() { + return afterCounter.get(); + } + } +} From 505904026de766c60ff00c5e201e486839452800 Mon Sep 17 00:00:00 2001 From: Brett Meyer Date: Thu, 11 Apr 2013 18:16:10 -0400 Subject: [PATCH 48/54] HHH-7478 Corrected test for envers package changes --- .../integration/basic/RegisterUserEventListenersTest.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/basic/RegisterUserEventListenersTest.java b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/basic/RegisterUserEventListenersTest.java index c7712e2de3..094a08fb52 100644 --- a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/basic/RegisterUserEventListenersTest.java +++ b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/basic/RegisterUserEventListenersTest.java @@ -1,21 +1,20 @@ package org.hibernate.envers.test.integration.basic; -import org.junit.Assert; -import org.junit.Test; - import org.hibernate.Session; import org.hibernate.action.spi.AfterTransactionCompletionProcess; import org.hibernate.action.spi.BeforeTransactionCompletionProcess; import org.hibernate.engine.spi.SessionImplementor; +import org.hibernate.envers.internal.tools.MutableInteger; import org.hibernate.envers.test.BaseEnversFunctionalTestCase; import org.hibernate.envers.test.entities.StrTestEntity; -import org.hibernate.envers.tools.MutableInteger; import org.hibernate.event.service.spi.EventListenerRegistry; import org.hibernate.event.spi.EventType; import org.hibernate.event.spi.PostInsertEvent; import org.hibernate.event.spi.PostInsertEventListener; import org.hibernate.persister.entity.EntityPersister; import org.hibernate.testing.TestForIssue; +import org.junit.Assert; +import org.junit.Test; /** * @author Lukasz Antoniak (lukasz dot antoniak at gmail dot com) From 03daecfe496b880daaea36fc58e6fe3d60528481 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbyn=C4=9Bk=20Roubal=C3=ADk?= Date: Fri, 15 Mar 2013 14:34:43 +0100 Subject: [PATCH 49/54] Test fix: em2 should be closed before we do latch.countDown() --- .../test/java/org/hibernate/jpa/test/lock/UpgradeLockTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hibernate-entitymanager/src/test/java/org/hibernate/jpa/test/lock/UpgradeLockTest.java b/hibernate-entitymanager/src/test/java/org/hibernate/jpa/test/lock/UpgradeLockTest.java index bb323a53fe..1cee21c474 100644 --- a/hibernate-entitymanager/src/test/java/org/hibernate/jpa/test/lock/UpgradeLockTest.java +++ b/hibernate-entitymanager/src/test/java/org/hibernate/jpa/test/lock/UpgradeLockTest.java @@ -82,8 +82,8 @@ public void run() { } finally { em2.getTransaction().commit(); - latch.countDown(); // signal that tx2 is committed em2.close(); + latch.countDown(); // signal that tx2 is committed } } } ); From cbbadea5381a8dd12613202ff0a492cf34746aa5 Mon Sep 17 00:00:00 2001 From: Nikolay Shestakov Date: Fri, 12 Apr 2013 09:56:41 -0400 Subject: [PATCH 50/54] HHH-7908 Logging level checking Conflicts: hibernate-core/src/main/java/org/hibernate/internal/SessionFactoryImpl.java --- .../UnresolvedEntityInsertActions.java | 12 ++++++---- .../org/hibernate/cfg/AnnotationBinder.java | 7 +++--- .../hibernate/cfg/CollectionSecondPass.java | 7 ++++-- .../java/org/hibernate/cfg/HbmBinder.java | 3 ++- .../cfg/annotations/CollectionBinder.java | 6 +++-- .../hibernate/engine/internal/Cascade.java | 15 +++++++----- .../engine/internal/Collections.java | 2 +- .../engine/internal/ParameterBinder.java | 3 ++- .../engine/internal/TwoPhaseLoad.java | 9 +++---- .../engine/jdbc/spi/SqlExceptionHelper.java | 9 ++++--- .../internal/CollectionLoadContext.java | 14 +++++++---- .../internal/AbstractSaveEventListener.java | 9 +++---- .../DefaultFlushEntityEventListener.java | 2 +- ...aultInitializeCollectionEventListener.java | 15 ++++++++---- .../DefaultReplicateEventListener.java | 7 +++--- .../DefaultSaveOrUpdateEventListener.java | 15 +++++++----- .../hql/internal/ast/tree/FromElement.java | 2 +- .../org/hibernate/id/IncrementGenerator.java | 7 ++++-- .../internal/SessionFactoryImpl.java | 24 ++++++++++++------- .../org/hibernate/internal/SessionImpl.java | 3 ++- .../java/org/hibernate/loader/Loader.java | 4 ++-- .../entity/AbstractEntityPersister.java | 5 ++-- .../java/org/hibernate/type/EnumType.java | 15 +++++++----- .../type/descriptor/sql/BasicBinder.java | 5 ++-- .../type/descriptor/sql/BasicExtractor.java | 21 +++++++++++----- .../functional/ConcurrentWriteTest.java | 2 +- 26 files changed, 139 insertions(+), 84 deletions(-) diff --git a/hibernate-core/src/main/java/org/hibernate/action/internal/UnresolvedEntityInsertActions.java b/hibernate-core/src/main/java/org/hibernate/action/internal/UnresolvedEntityInsertActions.java index 09b694ea1d..e6e18e9acf 100644 --- a/hibernate-core/src/main/java/org/hibernate/action/internal/UnresolvedEntityInsertActions.java +++ b/hibernate-core/src/main/java/org/hibernate/action/internal/UnresolvedEntityInsertActions.java @@ -204,11 +204,13 @@ public Set resolveDependentActions(Object managedEnt if ( entityEntry.getStatus() != Status.MANAGED && entityEntry.getStatus() != Status.READ_ONLY ) { throw new IllegalArgumentException( "EntityEntry did not have status MANAGED or READ_ONLY: " + entityEntry ); } + + final boolean traceEnabled = LOG.isTraceEnabled(); // Find out if there are any unresolved insertions that are waiting for the // specified entity to be resolved. Set dependentActions = dependentActionsByTransientEntity.remove( managedEntity ); if ( dependentActions == null ) { - if ( LOG.isTraceEnabled() ) { + if ( traceEnabled ) { LOG.tracev( "No unresolved entity inserts that depended on [{0}]", MessageHelper.infoString( entityEntry.getEntityName(), entityEntry.getId() ) @@ -217,7 +219,7 @@ public Set resolveDependentActions(Object managedEnt return Collections.emptySet(); //NOTE EARLY EXIT! } Set resolvedActions = new IdentitySet( ); - if ( LOG.isTraceEnabled() ) { + if ( traceEnabled ) { LOG.tracev( "Unresolved inserts before resolving [{0}]: [{1}]", MessageHelper.infoString( entityEntry.getEntityName(), entityEntry.getId() ), @@ -225,7 +227,7 @@ public Set resolveDependentActions(Object managedEnt ); } for ( AbstractEntityInsertAction dependentAction : dependentActions ) { - if ( LOG.isTraceEnabled() ) { + if ( traceEnabled ) { LOG.tracev( "Resolving insert [{0}] dependency on [{1}]", MessageHelper.infoString( dependentAction.getEntityName(), dependentAction.getId() ), @@ -235,7 +237,7 @@ public Set resolveDependentActions(Object managedEnt NonNullableTransientDependencies dependencies = dependenciesByAction.get( dependentAction ); dependencies.resolveNonNullableTransientEntity( managedEntity ); if ( dependencies.isEmpty() ) { - if ( LOG.isTraceEnabled() ) { + if ( traceEnabled ) { LOG.tracev( "Resolving insert [{0}] (only depended on [{1}])", dependentAction, @@ -247,7 +249,7 @@ public Set resolveDependentActions(Object managedEnt resolvedActions.add( dependentAction ); } } - if ( LOG.isTraceEnabled() ) { + if ( traceEnabled ) { LOG.tracev( "Unresolved inserts after resolving [{0}]: [{1}]", MessageHelper.infoString( entityEntry.getEntityName(), entityEntry.getId() ), diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/AnnotationBinder.java b/hibernate-core/src/main/java/org/hibernate/cfg/AnnotationBinder.java index 3e11ef67bf..aa940d9c27 100644 --- a/hibernate-core/src/main/java/org/hibernate/cfg/AnnotationBinder.java +++ b/hibernate-core/src/main/java/org/hibernate/cfg/AnnotationBinder.java @@ -1476,7 +1476,8 @@ private static void processElementAnnotations( * ordering does not matter */ - if ( LOG.isTraceEnabled() ) { + final boolean traceEnabled = LOG.isTraceEnabled(); + if ( traceEnabled ) { LOG.tracev( "Processing annotations of {0}.{1}" , propertyHolder.getEntityName(), inferredData.getPropertyName() ); } @@ -1542,7 +1543,7 @@ private static void processElementAnnotations( + propertyHolder.getEntityName() ); } - if ( LOG.isTraceEnabled() ) { + if ( traceEnabled ) { LOG.tracev( "{0} is a version property", inferredData.getPropertyName() ); } RootClass rootClass = ( RootClass ) propertyHolder.getPersistentClass(); @@ -1568,7 +1569,7 @@ private static void processElementAnnotations( SimpleValue simpleValue = ( SimpleValue ) prop.getValue(); simpleValue.setNullValue( "undefined" ); rootClass.setOptimisticLockMode( Versioning.OPTIMISTIC_LOCK_VERSION ); - if ( LOG.isTraceEnabled() ) { + if ( traceEnabled ) { LOG.tracev( "Version name: {0}, unsavedValue: {1}", rootClass.getVersion().getName(), ( (SimpleValue) rootClass.getVersion().getValue() ).getNullValue() ); } diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/CollectionSecondPass.java b/hibernate-core/src/main/java/org/hibernate/cfg/CollectionSecondPass.java index 89a6a676ee..d7a3efac6b 100644 --- a/hibernate-core/src/main/java/org/hibernate/cfg/CollectionSecondPass.java +++ b/hibernate-core/src/main/java/org/hibernate/cfg/CollectionSecondPass.java @@ -61,12 +61,15 @@ public CollectionSecondPass(Mappings mappings, Collection collection) { public void doSecondPass(java.util.Map persistentClasses) throws MappingException { - LOG.debugf( "Second pass for collection: %s", collection.getRole() ); + final boolean debugEnabled = LOG.isDebugEnabled(); + if ( debugEnabled ) { + LOG.debugf( "Second pass for collection: %s", collection.getRole() ); + } secondPass( persistentClasses, localInheritedMetas ); // using local since the inheritedMetas at this point is not the correct map since it is always the empty map collection.createAllKeys(); - if ( LOG.isDebugEnabled() ) { + if ( debugEnabled ) { String msg = "Mapped collection key: " + columns( collection.getKey() ); if ( collection.isIndexed() ) msg += ", index: " + columns( ( (IndexedCollection) collection ).getIndex() ); diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/HbmBinder.java b/hibernate-core/src/main/java/org/hibernate/cfg/HbmBinder.java index 472fbcfd34..8422356dd3 100644 --- a/hibernate-core/src/main/java/org/hibernate/cfg/HbmBinder.java +++ b/hibernate-core/src/main/java/org/hibernate/cfg/HbmBinder.java @@ -2657,6 +2657,7 @@ private static void bindManyToManySubelements( "not valid within collection using join fetching [" + collection.getRole() + "]" ); } + final boolean debugEnabled = LOG.isDebugEnabled(); while ( filters.hasNext() ) { final Element filterElement = ( Element ) filters.next(); final String name = filterElement.attributeValue( "name" ); @@ -2674,7 +2675,7 @@ private static void bindManyToManySubelements( Element alias = (Element) aliasesIterator.next(); aliasTables.put(alias.attributeValue("alias"), alias.attributeValue("table")); } - if ( LOG.isDebugEnabled() ) { + if ( debugEnabled ) { LOG.debugf( "Applying many-to-many filter [%s] as [%s] to role [%s]", name, condition, collection.getRole() ); } String autoAliasInjectionText = filterElement.attributeValue("autoAliasInjection"); diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/annotations/CollectionBinder.java b/hibernate-core/src/main/java/org/hibernate/cfg/annotations/CollectionBinder.java index 8d5d5be9f2..03cf238d6b 100644 --- a/hibernate-core/src/main/java/org/hibernate/cfg/annotations/CollectionBinder.java +++ b/hibernate-core/src/main/java/org/hibernate/cfg/annotations/CollectionBinder.java @@ -814,7 +814,9 @@ protected void bindOneToManySecondPass( boolean ignoreNotFound, Mappings mappings, Map inheritanceStatePerClass) { - if ( LOG.isDebugEnabled() ) { + + final boolean debugEnabled = LOG.isDebugEnabled(); + if ( debugEnabled ) { LOG.debugf( "Binding a OneToMany: %s.%s through a foreign key", propertyHolder.getEntityName(), propertyName ); } org.hibernate.mapping.OneToMany oneToMany = new org.hibernate.mapping.OneToMany( mappings, collection.getOwner() ); @@ -855,7 +857,7 @@ protected void bindOneToManySecondPass( column.setJoins( joins ); collection.setCollectionTable( column.getTable() ); } - if ( LOG.isDebugEnabled() ) { + if ( debugEnabled ) { LOG.debugf( "Mapping collection: %s -> %s", collection.getRole(), collection.getCollectionTable().getName() ); } bindFilters( false ); diff --git a/hibernate-core/src/main/java/org/hibernate/engine/internal/Cascade.java b/hibernate-core/src/main/java/org/hibernate/engine/internal/Cascade.java index 1b9b2e29bf..e4776059fe 100644 --- a/hibernate-core/src/main/java/org/hibernate/engine/internal/Cascade.java +++ b/hibernate-core/src/main/java/org/hibernate/engine/internal/Cascade.java @@ -146,7 +146,8 @@ public void cascade(final EntityPersister persister, final Object parent, final throws HibernateException { if ( persister.hasCascades() || action.requiresNoCascadeChecking() ) { // performance opt - if ( LOG.isTraceEnabled() ) { + final boolean traceEnabled = LOG.isTraceEnabled(); + if ( traceEnabled ) { LOG.tracev( "Processing cascade {0} for: {1}", action, persister.getEntityName() ); } @@ -183,7 +184,7 @@ else if ( action.requiresNoCascadeChecking() ) { } } - if ( LOG.isTraceEnabled() ) { + if ( traceEnabled ) { LOG.tracev( "Done processing cascade {0} for: {1}", action, persister.getEntityName() ); } } @@ -407,7 +408,8 @@ private void cascadeCollectionElements( boolean reallyDoCascade = style.reallyDoCascade(action) && child!=CollectionType.UNFETCHED_COLLECTION; if ( reallyDoCascade ) { - if ( LOG.isTraceEnabled() ) { + final boolean traceEnabled = LOG.isTraceEnabled(); + if ( traceEnabled ) { LOG.tracev( "Cascade {0} for collection: {1}", action, collectionType.getRole() ); } @@ -424,7 +426,7 @@ private void cascadeCollectionElements( ); } - if ( LOG.isTraceEnabled() ) { + if ( traceEnabled ) { LOG.tracev( "Done cascade {0} for collection: {1}", action, collectionType.getRole() ); } } @@ -435,7 +437,8 @@ private void cascadeCollectionElements( child instanceof PersistentCollection; //a newly instantiated collection can't have orphans if ( deleteOrphans ) { // handle orphaned entities!! - if ( LOG.isTraceEnabled() ) { + final boolean traceEnabled = LOG.isTraceEnabled(); + if ( traceEnabled ) { LOG.tracev( "Deleting orphans for collection: {0}", collectionType.getRole() ); } // we can do the cast since orphan-delete does not apply to: @@ -444,7 +447,7 @@ private void cascadeCollectionElements( final String entityName = collectionType.getAssociatedEntityName( eventSource.getFactory() ); deleteOrphans( entityName, (PersistentCollection) child ); - if ( LOG.isTraceEnabled() ) { + if ( traceEnabled ) { LOG.tracev( "Done deleting orphans for collection: {0}", collectionType.getRole() ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/engine/internal/Collections.java b/hibernate-core/src/main/java/org/hibernate/engine/internal/Collections.java index 2c6a840ba3..9e2f3baf73 100755 --- a/hibernate-core/src/main/java/org/hibernate/engine/internal/Collections.java +++ b/hibernate-core/src/main/java/org/hibernate/engine/internal/Collections.java @@ -72,7 +72,7 @@ private static void processDereferencedCollection(PersistentCollection coll, Ses CollectionEntry entry = persistenceContext.getCollectionEntry(coll); final CollectionPersister loadedPersister = entry.getLoadedPersister(); - if ( LOG.isDebugEnabled() && loadedPersister != null ) { + if ( loadedPersister != null && LOG.isDebugEnabled() ) { LOG.debugf( "Collection dereferenced: %s", MessageHelper.collectionInfoString( loadedPersister, diff --git a/hibernate-core/src/main/java/org/hibernate/engine/internal/ParameterBinder.java b/hibernate-core/src/main/java/org/hibernate/engine/internal/ParameterBinder.java index e4cc3d5745..1926cf3d84 100644 --- a/hibernate-core/src/main/java/org/hibernate/engine/internal/ParameterBinder.java +++ b/hibernate-core/src/main/java/org/hibernate/engine/internal/ParameterBinder.java @@ -112,6 +112,7 @@ public static int bindNamedParameters( final NamedParameterSource source, final SessionImplementor session) throws SQLException, HibernateException { if ( namedParams != null ) { + final boolean debugEnabled = LOG.isDebugEnabled(); // assumes that types are all of span 1 Iterator iter = namedParams.entrySet().iterator(); int result = 0; @@ -121,7 +122,7 @@ public static int bindNamedParameters( TypedValue typedval = (TypedValue) e.getValue(); int[] locations = source.getNamedParameterLocations( name ); for ( int i = 0; i < locations.length; i++ ) { - if ( LOG.isDebugEnabled() ) { + if ( debugEnabled ) { LOG.debugf("bindNamedParameters() %s -> %s [%s]", typedval.getValue(), name, locations[i] + start); } typedval.getType().nullSafeSet( ps, typedval.getValue(), locations[i] + start, session ); diff --git a/hibernate-core/src/main/java/org/hibernate/engine/internal/TwoPhaseLoad.java b/hibernate-core/src/main/java/org/hibernate/engine/internal/TwoPhaseLoad.java index e5ac56a056..2cdf7f9c88 100755 --- a/hibernate-core/src/main/java/org/hibernate/engine/internal/TwoPhaseLoad.java +++ b/hibernate-core/src/main/java/org/hibernate/engine/internal/TwoPhaseLoad.java @@ -101,7 +101,7 @@ public static void postHydrate( lazyPropertiesAreUnfetched ); - if ( LOG.isTraceEnabled() && version != null ) { + if ( version != null && LOG.isTraceEnabled() ) { String versionStr = persister.isVersioned() ? persister.getVersionType().toLoggableString( version, session.getFactory() ) : "null"; @@ -153,7 +153,8 @@ private static void doInitializeEntity( Serializable id = entityEntry.getId(); Object[] hydratedState = entityEntry.getLoadedState(); - if ( LOG.isDebugEnabled() ) { + final boolean debugEnabled = LOG.isDebugEnabled(); + if ( debugEnabled ) { LOG.debugf( "Resolving associations for %s", MessageHelper.infoString( persister, id, session.getFactory() ) @@ -187,7 +188,7 @@ private static void doInitializeEntity( final SessionFactoryImplementor factory = session.getFactory(); if ( persister.hasCache() && session.getCacheMode().isPutEnabled() ) { - if ( LOG.isDebugEnabled() ) { + if ( debugEnabled ) { LOG.debugf( "Adding entity to second-level cache: %s", MessageHelper.infoString( persister, id, session.getFactory() ) @@ -272,7 +273,7 @@ private static void doInitializeEntity( session ); - if ( LOG.isDebugEnabled() ) { + if ( debugEnabled ) { LOG.debugf( "Done materializing entity %s", MessageHelper.infoString( persister, id, session.getFactory() ) diff --git a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/spi/SqlExceptionHelper.java b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/spi/SqlExceptionHelper.java index 0581f82b1d..f1d56fb263 100644 --- a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/spi/SqlExceptionHelper.java +++ b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/spi/SqlExceptionHelper.java @@ -136,11 +136,14 @@ public void logExceptions( SQLException sqlException, if (LOG.isEnabled(Level.ERROR)) { if (LOG.isDebugEnabled()) { message = StringHelper.isNotEmpty(message) ? message : DEFAULT_EXCEPTION_MSG; - LOG.debug( message, sqlException ); + LOG.debug( message, sqlException ); } + final boolean warnEnabled = LOG.isEnabled( Level.WARN ); while (sqlException != null) { - StringBuilder buf = new StringBuilder(30).append("SQL Error: ").append(sqlException.getErrorCode()).append(", SQLState: ").append(sqlException.getSQLState()); - LOG.warn(buf.toString()); + if ( warnEnabled ) { + StringBuilder buf = new StringBuilder(30).append("SQL Error: ").append(sqlException.getErrorCode()).append(", SQLState: ").append(sqlException.getSQLState()); + LOG.warn(buf.toString()); + } LOG.error(sqlException.getMessage()); sqlException = sqlException.getNextException(); } diff --git a/hibernate-core/src/main/java/org/hibernate/engine/loading/internal/CollectionLoadContext.java b/hibernate-core/src/main/java/org/hibernate/engine/loading/internal/CollectionLoadContext.java index 831711265a..a23b662f30 100644 --- a/hibernate-core/src/main/java/org/hibernate/engine/loading/internal/CollectionLoadContext.java +++ b/hibernate-core/src/main/java/org/hibernate/engine/loading/internal/CollectionLoadContext.java @@ -219,20 +219,21 @@ else if ( lce.getResultSet() == resultSet && lce.getPersister() == persister ) { } private void endLoadingCollections(CollectionPersister persister, List matchedCollectionEntries) { + final boolean debugEnabled = LOG.isDebugEnabled(); if ( matchedCollectionEntries == null ) { - if ( LOG.isDebugEnabled()) LOG.debugf( "No collections were found in result set for role: %s", persister.getRole() ); + if ( debugEnabled ) LOG.debugf( "No collections were found in result set for role: %s", persister.getRole() ); return; } final int count = matchedCollectionEntries.size(); - if ( LOG.isDebugEnabled()) LOG.debugf("%s collections were found in result set for role: %s", count, persister.getRole()); + if ( debugEnabled ) LOG.debugf("%s collections were found in result set for role: %s", count, persister.getRole()); for ( int i = 0; i < count; i++ ) { LoadingCollectionEntry lce = ( LoadingCollectionEntry ) matchedCollectionEntries.get( i ); endLoadingCollection( lce, persister ); } - if ( LOG.isDebugEnabled() ) LOG.debugf( "%s collections initialized for role: %s", count, persister.getRole() ); + if ( debugEnabled ) LOG.debugf( "%s collections initialized for role: %s", count, persister.getRole() ); } private void endLoadingCollection(LoadingCollectionEntry lce, CollectionPersister persister) { @@ -287,13 +288,16 @@ private void addCollectionToCache(LoadingCollectionEntry lce, CollectionPersiste final SessionImplementor session = getLoadContext().getPersistenceContext().getSession(); final SessionFactoryImplementor factory = session.getFactory(); - if ( LOG.isDebugEnabled() ) { + final boolean debugEnabled = LOG.isDebugEnabled(); + if ( debugEnabled ) { LOG.debugf( "Caching collection: %s", MessageHelper.collectionInfoString( persister, lce.getCollection(), lce.getKey(), session ) ); } if ( !session.getEnabledFilters().isEmpty() && persister.isAffectedByEnabledFilters( session ) ) { // some filters affecting the collection are enabled on the session, so do not do the put into the cache. - LOG.debug( "Refusing to add to cache due to enabled filters" ); + if ( debugEnabled ) { + LOG.debug( "Refusing to add to cache due to enabled filters" ); + } // todo : add the notion of enabled filters to the CacheKey to differentiate filtered collections from non-filtered; // but CacheKey is currently used for both collections and entities; would ideally need to define two seperate ones; // currently this works in conjuction with the check on diff --git a/hibernate-core/src/main/java/org/hibernate/event/internal/AbstractSaveEventListener.java b/hibernate-core/src/main/java/org/hibernate/event/internal/AbstractSaveEventListener.java index 235e1711ce..3f23c01350 100644 --- a/hibernate-core/src/main/java/org/hibernate/event/internal/AbstractSaveEventListener.java +++ b/hibernate-core/src/main/java/org/hibernate/event/internal/AbstractSaveEventListener.java @@ -472,18 +472,19 @@ protected EntityState getEntityState( EntityEntry entry, //pass this as an argument only to avoid double looking SessionImplementor source) { + final boolean traceEnabled = LOG.isTraceEnabled(); if ( entry != null ) { // the object is persistent //the entity is associated with the session, so check its status if ( entry.getStatus() != Status.DELETED ) { // do nothing for persistent instances - if ( LOG.isTraceEnabled() ) { + if ( traceEnabled ) { LOG.tracev( "Persistent instance of: {0}", getLoggableName( entityName, entity ) ); } return EntityState.PERSISTENT; } // ie. e.status==DELETED - if ( LOG.isTraceEnabled() ) { + if ( traceEnabled ) { LOG.tracev( "Deleted instance of: {0}", getLoggableName( entityName, entity ) ); } return EntityState.DELETED; @@ -494,12 +495,12 @@ protected EntityState getEntityState( // try interceptor and unsaved-value if ( ForeignKeys.isTransient( entityName, entity, getAssumedUnsaved(), source )) { - if ( LOG.isTraceEnabled() ) { + if ( traceEnabled ) { LOG.tracev( "Transient instance of: {0}", getLoggableName( entityName, entity ) ); } return EntityState.TRANSIENT; } - if ( LOG.isTraceEnabled() ) { + if ( traceEnabled ) { LOG.tracev( "Detached instance of: {0}", getLoggableName( entityName, entity ) ); } return EntityState.DETACHED; diff --git a/hibernate-core/src/main/java/org/hibernate/event/internal/DefaultFlushEntityEventListener.java b/hibernate-core/src/main/java/org/hibernate/event/internal/DefaultFlushEntityEventListener.java index c40942ea64..cf99ea572e 100755 --- a/hibernate-core/src/main/java/org/hibernate/event/internal/DefaultFlushEntityEventListener.java +++ b/hibernate-core/src/main/java/org/hibernate/event/internal/DefaultFlushEntityEventListener.java @@ -633,7 +633,7 @@ public int[] visitAttributes(CustomEntityDirtinessStrategy.AttributeChecker attr } private void logDirtyProperties(Serializable id, int[] dirtyProperties, EntityPersister persister) { - if ( LOG.isTraceEnabled() && dirtyProperties != null && dirtyProperties.length > 0 ) { + if ( dirtyProperties != null && dirtyProperties.length > 0 && LOG.isTraceEnabled() ) { final String[] allPropertyNames = persister.getPropertyNames(); final String[] dirtyPropertyNames = new String[ dirtyProperties.length ]; for ( int i = 0; i < dirtyProperties.length; i++ ) { diff --git a/hibernate-core/src/main/java/org/hibernate/event/internal/DefaultInitializeCollectionEventListener.java b/hibernate-core/src/main/java/org/hibernate/event/internal/DefaultInitializeCollectionEventListener.java index 033682d5df..4ce8666ddf 100755 --- a/hibernate-core/src/main/java/org/hibernate/event/internal/DefaultInitializeCollectionEventListener.java +++ b/hibernate-core/src/main/java/org/hibernate/event/internal/DefaultInitializeCollectionEventListener.java @@ -59,12 +59,13 @@ public void onInitializeCollection(InitializeCollectionEvent event) CollectionEntry ce = source.getPersistenceContext().getCollectionEntry(collection); if (ce==null) throw new HibernateException("collection was evicted"); if ( !collection.wasInitialized() ) { - if ( LOG.isTraceEnabled() ) { + final boolean traceEnabled = LOG.isTraceEnabled(); + if ( traceEnabled ) { LOG.tracev( "Initializing collection {0}", MessageHelper.collectionInfoString( ce.getLoadedPersister(), collection, ce.getLoadedKey(), source ) ); + LOG.trace( "Checking second-level cache" ); } - LOG.trace( "Checking second-level cache" ); final boolean foundInCache = initializeCollectionFromCache( ce.getLoadedKey(), ce.getLoadedPersister(), @@ -72,13 +73,17 @@ public void onInitializeCollection(InitializeCollectionEvent event) source ); - if ( foundInCache ) { + if ( foundInCache && traceEnabled ) { LOG.trace( "Collection initialized from cache" ); } else { - LOG.trace( "Collection not cached" ); + if ( traceEnabled ) { + LOG.trace( "Collection not cached" ); + } ce.getLoadedPersister().initialize( ce.getLoadedKey(), source ); - LOG.trace( "Collection initialized" ); + if ( traceEnabled ) { + LOG.trace( "Collection initialized" ); + } if ( source.getFactory().getStatistics().isStatisticsEnabled() ) { source.getFactory().getStatisticsImplementor().fetchCollection( diff --git a/hibernate-core/src/main/java/org/hibernate/event/internal/DefaultReplicateEventListener.java b/hibernate-core/src/main/java/org/hibernate/event/internal/DefaultReplicateEventListener.java index 7885ea6c4c..910faabf3c 100644 --- a/hibernate-core/src/main/java/org/hibernate/event/internal/DefaultReplicateEventListener.java +++ b/hibernate-core/src/main/java/org/hibernate/event/internal/DefaultReplicateEventListener.java @@ -101,8 +101,9 @@ public void onReplicate(ReplicateEvent event) { oldVersion = persister.getCurrentVersion( id, source ); } + final boolean traceEnabled = LOG.isTraceEnabled(); if ( oldVersion != null ) { - if ( LOG.isTraceEnabled() ) { + if ( traceEnabled ) { LOG.tracev( "Found existing row for {0}", MessageHelper.infoString( persister, id, source.getFactory() ) ); } @@ -120,14 +121,14 @@ public void onReplicate(ReplicateEvent event) { // else do nothing (don't even reassociate object!) if ( canReplicate ) performReplication( entity, id, realOldVersion, persister, replicationMode, source ); - else + else if ( traceEnabled ) LOG.trace( "No need to replicate" ); //TODO: would it be better to do a refresh from db? } else { // no existing row - do an insert - if ( LOG.isTraceEnabled() ) { + if ( traceEnabled ) { LOG.tracev( "No existing row, replicating new instance {0}", MessageHelper.infoString( persister, id, source.getFactory() ) ); } diff --git a/hibernate-core/src/main/java/org/hibernate/event/internal/DefaultSaveOrUpdateEventListener.java b/hibernate-core/src/main/java/org/hibernate/event/internal/DefaultSaveOrUpdateEventListener.java index 8fe131bc3d..7948e31c4a 100755 --- a/hibernate-core/src/main/java/org/hibernate/event/internal/DefaultSaveOrUpdateEventListener.java +++ b/hibernate-core/src/main/java/org/hibernate/event/internal/DefaultSaveOrUpdateEventListener.java @@ -117,8 +117,10 @@ protected Serializable performSaveOrUpdate(SaveOrUpdateEvent event) { } protected Serializable entityIsPersistent(SaveOrUpdateEvent event) throws HibernateException { - LOG.trace( "Ignoring persistent instance" ); - + final boolean traceEnabled = LOG.isTraceEnabled(); + if ( traceEnabled ) { + LOG.trace( "Ignoring persistent instance" ); + } EntityEntry entityEntry = event.getEntry(); if ( entityEntry == null ) { throw new AssertionFailure( "entity was transient or detached" ); @@ -153,7 +155,7 @@ protected Serializable entityIsPersistent(SaveOrUpdateEvent event) throws Hibern } - if ( LOG.isTraceEnabled() ) { + if ( traceEnabled ) { LOG.tracev( "Object already associated with session: {0}", MessageHelper.infoString( entityEntry.getPersister(), savedId, factory ) ); } @@ -279,11 +281,12 @@ protected void performUpdate( Object entity, EntityPersister persister) throws HibernateException { - if ( !persister.isMutable() ) { + final boolean traceEnabled = LOG.isTraceEnabled(); + if ( traceEnabled && !persister.isMutable() ) { LOG.trace( "Immutable instance passed to performUpdate()" ); } - if ( LOG.isTraceEnabled() ) { + if ( traceEnabled ) { LOG.tracev( "Updating {0}", MessageHelper.infoString( persister, event.getRequestedId(), event.getSession().getFactory() ) ); } @@ -329,7 +332,7 @@ protected void performUpdate( persister.afterReassociate(entity, source); - if ( LOG.isTraceEnabled() ) { + if ( traceEnabled ) { LOG.tracev( "Updating {0}", MessageHelper.infoString( persister, event.getRequestedId(), source.getFactory() ) ); } diff --git a/hibernate-core/src/main/java/org/hibernate/hql/internal/ast/tree/FromElement.java b/hibernate-core/src/main/java/org/hibernate/hql/internal/ast/tree/FromElement.java index 177eb0c189..ceb1b87ab8 100644 --- a/hibernate-core/src/main/java/org/hibernate/hql/internal/ast/tree/FromElement.java +++ b/hibernate-core/src/main/java/org/hibernate/hql/internal/ast/tree/FromElement.java @@ -311,7 +311,7 @@ public JoinSequence getJoinSequence() { } public void setIncludeSubclasses(boolean includeSubclasses) { - if ( LOG.isTraceEnabled() && isDereferencedBySuperclassOrSubclassProperty() && !includeSubclasses ) + if ( !includeSubclasses && isDereferencedBySuperclassOrSubclassProperty() && LOG.isTraceEnabled() ) LOG.trace( "Attempt to disable subclass-inclusions : ", new Exception( "Stack-trace source" ) ); this.includeSubclasses = includeSubclasses; } diff --git a/hibernate-core/src/main/java/org/hibernate/id/IncrementGenerator.java b/hibernate-core/src/main/java/org/hibernate/id/IncrementGenerator.java index 584a84d390..7e1694ca91 100644 --- a/hibernate-core/src/main/java/org/hibernate/id/IncrementGenerator.java +++ b/hibernate-core/src/main/java/org/hibernate/id/IncrementGenerator.java @@ -122,7 +122,10 @@ public void configure(Type type, Properties params, Dialect dialect) throws Mapp private void initializePreviousValueHolder(SessionImplementor session) { previousValueHolder = IdentifierGeneratorHelper.getIntegralDataTypeHolder( returnClass ); - LOG.debugf( "Fetching initial value: %s", sql ); + final boolean debugEnabled = LOG.isDebugEnabled(); + if ( debugEnabled ) { + LOG.debugf( "Fetching initial value: %s", sql ); + } try { PreparedStatement st = session.getTransactionCoordinator().getJdbcCoordinator().getStatementPreparer().prepareStatement( sql ); try { @@ -131,7 +134,7 @@ private void initializePreviousValueHolder(SessionImplementor session) { if (rs.next()) previousValueHolder.initialize(rs, 0L).increment(); else previousValueHolder.initialize(1L); sql = null; - if ( LOG.isDebugEnabled() ) { + if ( debugEnabled ) { LOG.debugf( "First free id: %s", previousValueHolder.makeValue() ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/internal/SessionFactoryImpl.java b/hibernate-core/src/main/java/org/hibernate/internal/SessionFactoryImpl.java index a1376df623..3f5549efd8 100644 --- a/hibernate-core/src/main/java/org/hibernate/internal/SessionFactoryImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/internal/SessionFactoryImpl.java @@ -54,7 +54,6 @@ import org.hibernate.MappingException; import org.hibernate.MultiTenancyStrategy; import org.hibernate.ObjectNotFoundException; -import org.hibernate.QueryException; import org.hibernate.Session; import org.hibernate.SessionBuilder; import org.hibernate.SessionFactory; @@ -103,7 +102,6 @@ import org.hibernate.engine.profile.Fetch; import org.hibernate.engine.profile.FetchProfile; import org.hibernate.engine.query.spi.QueryPlanCache; -import org.hibernate.engine.query.spi.sql.NativeSQLQuerySpecification; import org.hibernate.engine.spi.CacheImplementor; import org.hibernate.engine.spi.FilterDefinition; import org.hibernate.engine.spi.Mapping; @@ -657,7 +655,12 @@ public SessionFactoryImpl( MetadataImplementor metadata, SessionFactoryOptions sessionFactoryOptions, SessionFactoryObserver observer) throws HibernateException { - LOG.debug( "Building session factory" ); + + final boolean traceEnabled = LOG.isTraceEnabled(); + final boolean debugEnabled = traceEnabled || LOG.isDebugEnabled(); + if ( debugEnabled ) { + LOG.debug( "Building session factory" ); + } this.sessionFactoryOptions = sessionFactoryOptions; @@ -699,9 +702,10 @@ public SessionFactoryImpl( filters.put( filterDefinition.getFilterName(), filterDefinition ); } - LOG.debugf( "Session factory constructed with filter configurations : %s", filters ); - LOG.debugf( "Instantiating session factory with properties: %s", properties ); - + if ( debugEnabled ) { + LOG.debugf( "Session factory constructed with filter configurations : %s", filters ); + LOG.debugf( "Instantiating session factory with properties: %s", properties ); + } this.queryPlanCache = new QueryPlanCache( this ); class IntegratorObserver implements SessionFactoryObserver { @@ -768,7 +772,7 @@ public void sessionFactoryClosed(SessionFactory factory) { accessStrategy = EntityRegionAccessStrategy.class.cast( entityAccessStrategies.get( cacheRegionName ) ); if ( accessStrategy == null ) { final AccessType accessType = model.getHierarchyDetails().getCaching().getAccessType(); - if ( LOG.isTraceEnabled() ) { + if ( traceEnabled ) { LOG.tracev( "Building cache for entity data [{0}]", model.getEntity().getName() ); } EntityRegion entityRegion = settings.getRegionFactory().buildEntityRegion( @@ -803,7 +807,7 @@ public void sessionFactoryClosed(SessionFactory factory) { final AccessType accessType = model.getCaching().getAccessType(); CollectionRegionAccessStrategy accessStrategy = null; if ( accessType != null && settings.isSecondLevelCacheEnabled() ) { - if ( LOG.isTraceEnabled() ) { + if ( traceEnabled ) { LOG.tracev( "Building cache for collection data [{0}]", model.getAttribute().getRole() ); } CollectionRegion collectionRegion = settings.getRegionFactory().buildCollectionRegion( @@ -889,7 +893,9 @@ public void sessionFactoryClosed(SessionFactory factory) { serviceRegistry.getService( JndiService.class ) ); - LOG.debug("Instantiated session factory"); + if ( debugEnabled ) { + LOG.debug("Instantiated session factory"); + } if ( settings.isAutoCreateSchema() ) { new SchemaExport( metadata ) diff --git a/hibernate-core/src/main/java/org/hibernate/internal/SessionImpl.java b/hibernate-core/src/main/java/org/hibernate/internal/SessionImpl.java index 59e9dba423..63e24f69ec 100644 --- a/hibernate-core/src/main/java/org/hibernate/internal/SessionImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/internal/SessionImpl.java @@ -2574,13 +2574,14 @@ protected void performAnyNeededCrossReferenceSynchronizations() { return; } + final boolean debugEnabled = LOG.isDebugEnabled(); for ( Serializable pk : getPersistenceContext().getNaturalIdHelper().getCachedPkResolutions( entityPersister ) ) { final EntityKey entityKey = generateEntityKey( pk, entityPersister ); final Object entity = getPersistenceContext().getEntity( entityKey ); final EntityEntry entry = getPersistenceContext().getEntry( entity ); if ( entry == null ) { - if ( LOG.isDebugEnabled() ) { + if ( debugEnabled ) { LOG.debug( "Cached natural-id/pk resolution linked to null EntityEntry in persistence context : " + MessageHelper.infoString( entityPersister, pk, getFactory() ) diff --git a/hibernate-core/src/main/java/org/hibernate/loader/Loader.java b/hibernate-core/src/main/java/org/hibernate/loader/Loader.java index 1430604082..0b78c1bd63 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/Loader.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/Loader.java @@ -1346,16 +1346,16 @@ private void handleEmptyCollections( final SessionImplementor session) { if ( keys != null ) { + final boolean debugEnabled = LOG.isDebugEnabled(); // this is a collection initializer, so we must create a collection // for each of the passed-in keys, to account for the possibility // that the collection is empty and has no rows in the result set - CollectionPersister[] collectionPersisters = getCollectionPersisters(); for ( int j=0; j javaDescriptor, SqlTypeDescriptor sqlDe * {@inheritDoc} */ public final void bind(PreparedStatement st, J value, int index, WrapperOptions options) throws SQLException { + final boolean traceEnabled = LOG.isTraceEnabled(); if ( value == null ) { - if ( LOG.isTraceEnabled() ) { + if ( traceEnabled ) { LOG.trace( String.format( NULL_BIND_MSG_TEMPLATE, @@ -79,7 +80,7 @@ public final void bind(PreparedStatement st, J value, int index, WrapperOptions st.setNull( index, sqlDescriptor.getSqlType() ); } else { - if ( LOG.isTraceEnabled() ) { + if ( traceEnabled ) { LOG.trace( String.format( BIND_MSG_TEMPLATE, diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/sql/BasicExtractor.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/sql/BasicExtractor.java index 7f0f939db9..6db5dd1d19 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/descriptor/sql/BasicExtractor.java +++ b/hibernate-core/src/main/java/org/hibernate/type/descriptor/sql/BasicExtractor.java @@ -62,12 +62,15 @@ public SqlTypeDescriptor getSqlDescriptor() { @Override public J extract(ResultSet rs, String name, WrapperOptions options) throws SQLException { final J value = doExtract( rs, name, options ); + final boolean traceEnabled = LOG.isTraceEnabled(); if ( value == null || rs.wasNull() ) { - LOG.tracev( "Found [null] as column [{0}]", name ); + if ( traceEnabled ) { + LOG.tracev( "Found [null] as column [{0}]", name ); + } return null; } else { - if ( LOG.isTraceEnabled() ) { + if ( traceEnabled ) { LOG.tracev( "Found [{0}] as column [{1}]", getJavaDescriptor().extractLoggableRepresentation( value ), name ); } return value; @@ -93,12 +96,15 @@ public J extract(ResultSet rs, String name, WrapperOptions options) throws SQLEx @Override public J extract(CallableStatement statement, int index, WrapperOptions options) throws SQLException { final J value = doExtract( statement, index, options ); + final boolean traceEnabled = LOG.isTraceEnabled(); if ( value == null || statement.wasNull() ) { - LOG.tracev( "Found [null] as procedure output parameter [{0}]", index ); + if ( traceEnabled ) { + LOG.tracev( "Found [null] as procedure output parameter [{0}]", index ); + } return null; } else { - if ( LOG.isTraceEnabled() ) { + if ( traceEnabled ) { LOG.tracev( "Found [{0}] as procedure output parameter [{1}]", getJavaDescriptor().extractLoggableRepresentation( value ), index ); } return value; @@ -128,12 +134,15 @@ public J extract(CallableStatement statement, String[] paramNames, WrapperOption } final String paramName = paramNames[0]; final J value = doExtract( statement, paramName, options ); + final boolean traceEnabled = LOG.isTraceEnabled(); if ( value == null || statement.wasNull() ) { - LOG.tracev( "Found [null] as procedure output parameter [{0}]", paramName ); + if ( traceEnabled ) { + LOG.tracev( "Found [null] as procedure output parameter [{0}]", paramName ); + } return null; } else { - if ( LOG.isTraceEnabled() ) { + if ( traceEnabled ) { LOG.tracev( "Found [{0}] as procedure output parameter [{1}]", getJavaDescriptor().extractLoggableRepresentation( value ), paramName ); } return value; diff --git a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/ConcurrentWriteTest.java b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/ConcurrentWriteTest.java index 9b236fc368..0abcec7353 100644 --- a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/ConcurrentWriteTest.java +++ b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/ConcurrentWriteTest.java @@ -469,7 +469,7 @@ public Void call() throws Exception { contactExists(); thinkRandomTime(); ++completedIterations; - if ( log.isTraceEnabled() ) { + if ( trace ) { log.tracef( "Iteration completed {0}", completedIterations ); } } From 1d9f6201a06a01c6228b545f6544fbd18599a312 Mon Sep 17 00:00:00 2001 From: Steve Ebersole Date: Fri, 12 Apr 2013 09:04:12 -0500 Subject: [PATCH 51/54] HHH-7841 - Redesign Loader --- .../FormulaNotSupportedException.java | 42 +++++++++++++++++++ .../internal/metadata/MetadataTools.java | 34 +++++++++++---- 2 files changed, 68 insertions(+), 8 deletions(-) create mode 100644 hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/metadata/FormulaNotSupportedException.java diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/metadata/FormulaNotSupportedException.java b/hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/metadata/FormulaNotSupportedException.java new file mode 100644 index 0000000000..3bbd6e4a6b --- /dev/null +++ b/hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/metadata/FormulaNotSupportedException.java @@ -0,0 +1,42 @@ +/* + * 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.envers.configuration.internal.metadata; + +import org.hibernate.HibernateException; + +/** + * Exception indicating that a formula mapping was encountered where it is not currently supported + * + * @author Steve Ebersole + */ +public class FormulaNotSupportedException extends HibernateException { + private static final String MSG = "Formula mappings (aside from @DiscriminatorValue) are currently not supported"; + + /** + * Constructs a FormulaNotSupportedException using a standard message + */ + public FormulaNotSupportedException() { + super( MSG ); + } +} diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/metadata/MetadataTools.java b/hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/metadata/MetadataTools.java index 4b2c1058d8..5bc51020c2 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/metadata/MetadataTools.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/metadata/MetadataTools.java @@ -32,6 +32,7 @@ import org.hibernate.envers.internal.tools.StringTools; import org.hibernate.mapping.Column; import org.hibernate.mapping.Formula; +import org.hibernate.mapping.Selectable; /** * @author Adam Warski (adam at warski dot org) @@ -221,9 +222,13 @@ public static Element createJoin(Element parent, String tableName, return join_mapping; } - public static void addColumns(Element any_mapping, Iterator columns) { - while (columns.hasNext()) { - addColumn(any_mapping, columns.next()); + public static void addColumns(Element any_mapping, Iterator selectables) { + while ( selectables.hasNext() ) { + final Selectable selectable = (Selectable) selectables.next(); + if ( selectable.isFormula() ) { + throw new FormulaNotSupportedException(); + } + addColumn( any_mapping, (Column) selectable ); } } @@ -310,13 +315,26 @@ public static void addColumnsOrFormulas(Element element, Iterator columnIterator /** * An iterator over column names. */ - public static abstract class ColumnNameIterator implements Iterator { } + public static abstract class ColumnNameIterator implements Iterator { + } - public static ColumnNameIterator getColumnNameIterator(final Iterator columnIterator) { + public static ColumnNameIterator getColumnNameIterator(final Iterator selectableIterator) { return new ColumnNameIterator() { - public boolean hasNext() { return columnIterator.hasNext(); } - public String next() { return columnIterator.next().getName(); } - public void remove() { columnIterator.remove(); } + public boolean hasNext() { + return selectableIterator.hasNext(); + } + + public String next() { + final Selectable next = selectableIterator.next(); + if ( next.isFormula() ) { + throw new FormulaNotSupportedException(); + } + return ( (Column) next ).getName(); + } + + public void remove() { + selectableIterator.remove(); + } }; } From 8bca70e6a92462c8691d5738fb6860593bd1a36e Mon Sep 17 00:00:00 2001 From: Steve Ebersole Date: Fri, 12 Apr 2013 14:08:35 -0500 Subject: [PATCH 52/54] HHH-7841 - Redesign Loader --- .../internal/EntityLoadQueryBuilderImpl.java | 4 +- .../ResultSetProcessingContextImpl.java | 4 +- .../internal/ResultSetProcessorImpl.java | 15 ++- .../plan/internal/LoadPlanBuildingHelper.java | 2 +- ...ngleRootReturnLoadPlanBuilderStrategy.java | 4 +- .../plan/spi/AbstractCollectionReference.java | 22 +++- .../loader/plan/spi/AbstractFetchOwner.java | 35 +++++- .../loader/plan/spi/AbstractPlanNode.java | 4 + .../spi/AbstractSingularAttributeFetch.java | 11 ++ .../loader/plan/spi/CollectionFetch.java | 14 +++ .../loader/plan/spi/CollectionReturn.java | 13 +- .../plan/spi/CompositeElementGraph.java | 30 ++++- .../loader/plan/spi/CompositeFetch.java | 13 ++ .../loader/plan/spi/CompositeIndexGraph.java | 29 ++++- .../loader/plan/spi/CopyContext.java | 33 +++++ .../loader/plan/spi/CopyableFetch.java | 31 +++++ .../loader/plan/spi/CopyableReturn.java | 38 ++++++ .../loader/plan/spi/EntityElementGraph.java | 32 ++++- .../loader/plan/spi/EntityFetch.java | 24 +++- .../loader/plan/spi/EntityIndexGraph.java | 31 ++++- .../loader/plan/spi/EntityReference.java | 5 +- .../loader/plan/spi/EntityReturn.java | 15 ++- .../org/hibernate/loader/plan/spi/Fetch.java | 5 +- .../hibernate/loader/plan/spi/FetchOwner.java | 2 + .../plan/spi/FetchableCollectionElement.java | 32 +++++ .../plan/spi/FetchableCollectionIndex.java | 34 +++++ .../AbstractLoadPlanBuilderStrategy.java | 13 +- .../plan/spi/{ => build}/LoadPlanBuilder.java | 5 +- .../{ => build}/LoadPlanBuilderStrategy.java | 5 +- .../{ => build}/LoadPlanBuildingContext.java | 2 +- .../DelegatedLoadPlanVisitationStrategy.java | 118 ++++++++++++++++++ .../spi/visit/LoadPlanVisitationStrategy.java | 41 ++++++ .../LoadPlanVisitationStrategyAdapter.java | 29 ++--- .../plan/spi/visit/LoadPlanVisitor.java | 53 ++++++++ .../ReturnGraphVisitationStrategy.java} | 35 +++--- .../ReturnGraphVisitationStrategyAdapter.java | 92 ++++++++++++++ .../ReturnGraphVisitor.java} | 41 +++--- .../hibernate/loader/spi/LoadPlanAdvisor.java | 33 +++++ .../loader/spi/NoOpLoadPlanAdvisor.java | 38 ++++++ .../loader/spi/ResultSetProcessor.java | 3 + .../entity/AbstractEntityPersister.java | 7 -- ...tityAssociationResultSetProcessorTest.java | 5 +- ...yWithCollectionResultSetProcessorTest.java | 9 +- .../loader/SimpleResultSetProcessorTest.java | 4 +- .../loader/plan/spi/LoadPlanBuilderTest.java | 1 + .../jpa/HibernateEntityManagerFactory.java | 3 + .../internal/AbstractGraphNode.java} | 23 ++-- .../internal}/AttributeNodeImpl.java | 32 +++-- .../internal}/EntityGraphImpl.java | 13 +- .../internal}/SubgraphImpl.java | 4 +- .../org/hibernate/jpa/graph/package-info.java | 5 + .../graph/spi/AttributeNodeImplementor.java | 39 ++++++ .../spi/EntityGraphBasedLoadPlanAdvisor.java | 107 ++++++++++++++++ .../jpa/graph/spi/GraphNodeImplementor.java | 39 ++++++ .../internal/EntityManagerFactoryImpl.java | 15 ++- .../jpa/internal/EntityManagerImpl.java | 2 +- .../jpa/internal/metamodel/MetamodelImpl.java | 4 + 57 files changed, 1173 insertions(+), 129 deletions(-) create mode 100644 hibernate-core/src/main/java/org/hibernate/loader/plan/spi/CopyContext.java create mode 100644 hibernate-core/src/main/java/org/hibernate/loader/plan/spi/CopyableFetch.java create mode 100644 hibernate-core/src/main/java/org/hibernate/loader/plan/spi/CopyableReturn.java create mode 100644 hibernate-core/src/main/java/org/hibernate/loader/plan/spi/FetchableCollectionElement.java create mode 100644 hibernate-core/src/main/java/org/hibernate/loader/plan/spi/FetchableCollectionIndex.java rename hibernate-core/src/main/java/org/hibernate/loader/plan/spi/{ => build}/AbstractLoadPlanBuilderStrategy.java (97%) rename hibernate-core/src/main/java/org/hibernate/loader/plan/spi/{ => build}/LoadPlanBuilder.java (90%) rename hibernate-core/src/main/java/org/hibernate/loader/plan/spi/{ => build}/LoadPlanBuilderStrategy.java (87%) rename hibernate-core/src/main/java/org/hibernate/loader/plan/spi/{ => build}/LoadPlanBuildingContext.java (97%) create mode 100644 hibernate-core/src/main/java/org/hibernate/loader/plan/spi/visit/DelegatedLoadPlanVisitationStrategy.java create mode 100644 hibernate-core/src/main/java/org/hibernate/loader/plan/spi/visit/LoadPlanVisitationStrategy.java rename hibernate-core/src/main/java/org/hibernate/loader/plan/spi/{ => visit}/LoadPlanVisitationStrategyAdapter.java (64%) create mode 100644 hibernate-core/src/main/java/org/hibernate/loader/plan/spi/visit/LoadPlanVisitor.java rename hibernate-core/src/main/java/org/hibernate/loader/plan/spi/{LoadPlanVisitationStrategy.java => visit/ReturnGraphVisitationStrategy.java} (82%) create mode 100644 hibernate-core/src/main/java/org/hibernate/loader/plan/spi/visit/ReturnGraphVisitationStrategyAdapter.java rename hibernate-core/src/main/java/org/hibernate/loader/plan/spi/{LoadPlanVisitor.java => visit/ReturnGraphVisitor.java} (78%) create mode 100644 hibernate-core/src/main/java/org/hibernate/loader/spi/LoadPlanAdvisor.java create mode 100644 hibernate-core/src/main/java/org/hibernate/loader/spi/NoOpLoadPlanAdvisor.java rename hibernate-entitymanager/src/main/java/org/hibernate/jpa/{internal/graph/GraphNode.java => graph/internal/AbstractGraphNode.java} (87%) rename hibernate-entitymanager/src/main/java/org/hibernate/jpa/{internal/graph => graph/internal}/AttributeNodeImpl.java (91%) rename hibernate-entitymanager/src/main/java/org/hibernate/jpa/{internal/graph => graph/internal}/EntityGraphImpl.java (92%) rename hibernate-entitymanager/src/main/java/org/hibernate/jpa/{internal/graph => graph/internal}/SubgraphImpl.java (96%) create mode 100644 hibernate-entitymanager/src/main/java/org/hibernate/jpa/graph/package-info.java create mode 100644 hibernate-entitymanager/src/main/java/org/hibernate/jpa/graph/spi/AttributeNodeImplementor.java create mode 100644 hibernate-entitymanager/src/main/java/org/hibernate/jpa/graph/spi/EntityGraphBasedLoadPlanAdvisor.java create mode 100644 hibernate-entitymanager/src/main/java/org/hibernate/jpa/graph/spi/GraphNodeImplementor.java diff --git a/hibernate-core/src/main/java/org/hibernate/loader/internal/EntityLoadQueryBuilderImpl.java b/hibernate-core/src/main/java/org/hibernate/loader/internal/EntityLoadQueryBuilderImpl.java index be11977031..d2860cd95d 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/internal/EntityLoadQueryBuilderImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/internal/EntityLoadQueryBuilderImpl.java @@ -37,8 +37,8 @@ import org.hibernate.loader.plan.spi.EntityFetch; import org.hibernate.loader.plan.spi.EntityReturn; import org.hibernate.loader.plan.spi.LoadPlan; -import org.hibernate.loader.plan.spi.LoadPlanVisitationStrategyAdapter; -import org.hibernate.loader.plan.spi.LoadPlanVisitor; +import org.hibernate.loader.plan.spi.visit.LoadPlanVisitationStrategyAdapter; +import org.hibernate.loader.plan.spi.visit.LoadPlanVisitor; import org.hibernate.loader.plan.spi.Return; import org.hibernate.loader.spi.LoadQueryBuilder; import org.hibernate.persister.entity.OuterJoinLoadable; diff --git a/hibernate-core/src/main/java/org/hibernate/loader/internal/ResultSetProcessingContextImpl.java b/hibernate-core/src/main/java/org/hibernate/loader/internal/ResultSetProcessingContextImpl.java index a66e8acbc9..6899233b0b 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/internal/ResultSetProcessingContextImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/internal/ResultSetProcessingContextImpl.java @@ -57,8 +57,8 @@ import org.hibernate.loader.plan.spi.CollectionReturn; import org.hibernate.loader.plan.spi.EntityReference; import org.hibernate.loader.plan.spi.LoadPlan; -import org.hibernate.loader.plan.spi.LoadPlanVisitationStrategyAdapter; -import org.hibernate.loader.plan.spi.LoadPlanVisitor; +import org.hibernate.loader.plan.spi.visit.LoadPlanVisitationStrategyAdapter; +import org.hibernate.loader.plan.spi.visit.LoadPlanVisitor; import org.hibernate.loader.spi.AfterLoadAction; import org.hibernate.loader.spi.NamedParameterContext; import org.hibernate.loader.spi.ResultSetProcessingContext; diff --git a/hibernate-core/src/main/java/org/hibernate/loader/internal/ResultSetProcessorImpl.java b/hibernate-core/src/main/java/org/hibernate/loader/internal/ResultSetProcessorImpl.java index e9176048e6..0eea1dd1e5 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/internal/ResultSetProcessorImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/internal/ResultSetProcessorImpl.java @@ -41,10 +41,11 @@ import org.hibernate.loader.plan.spi.CollectionReturn; import org.hibernate.loader.plan.spi.EntityFetch; import org.hibernate.loader.plan.spi.LoadPlan; -import org.hibernate.loader.plan.spi.LoadPlanVisitationStrategyAdapter; -import org.hibernate.loader.plan.spi.LoadPlanVisitor; +import org.hibernate.loader.plan.spi.visit.LoadPlanVisitationStrategyAdapter; +import org.hibernate.loader.plan.spi.visit.LoadPlanVisitor; import org.hibernate.loader.plan.spi.Return; import org.hibernate.loader.spi.AfterLoadAction; +import org.hibernate.loader.spi.LoadPlanAdvisor; import org.hibernate.loader.spi.NamedParameterContext; import org.hibernate.loader.spi.ScrollableResultSetProcessor; import org.hibernate.loader.spi.ResultSetProcessor; @@ -58,12 +59,12 @@ public class ResultSetProcessorImpl implements ResultSetProcessor { private static final Logger LOG = Logger.getLogger( ResultSetProcessorImpl.class ); - private final LoadPlan loadPlan; + private final LoadPlan baseLoadPlan; private final boolean hadSubselectFetches; public ResultSetProcessorImpl(LoadPlan loadPlan) { - this.loadPlan = loadPlan; + this.baseLoadPlan = loadPlan; LocalVisitationStrategy strategy = new LocalVisitationStrategy(); LoadPlanVisitor.visit( loadPlan, strategy ); @@ -78,6 +79,7 @@ public ScrollableResultSetProcessor toOnDemandForm() { @Override public List extractResults( + LoadPlanAdvisor loadPlanAdvisor, ResultSet resultSet, final SessionImplementor session, QueryParameters queryParameters, @@ -87,7 +89,9 @@ public List extractResults( ResultTransformer forcedResultTransformer, List afterLoadActionList) throws SQLException { - handlePotentiallyEmptyCollectionRootReturns( queryParameters.getCollectionKeys(), resultSet, session ); + final LoadPlan loadPlan = loadPlanAdvisor.advise( this.baseLoadPlan ); + + handlePotentiallyEmptyCollectionRootReturns( loadPlan, queryParameters.getCollectionKeys(), resultSet, session ); final int maxRows; final RowSelection selection = queryParameters.getRowSelection(); @@ -163,6 +167,7 @@ public List extractResults( private void handlePotentiallyEmptyCollectionRootReturns( + LoadPlan loadPlan, Serializable[] collectionKeys, ResultSet resultSet, SessionImplementor session) { diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/internal/LoadPlanBuildingHelper.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/internal/LoadPlanBuildingHelper.java index 0c1cc20723..0c85b7a1c3 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/plan/internal/LoadPlanBuildingHelper.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/internal/LoadPlanBuildingHelper.java @@ -32,7 +32,7 @@ import org.hibernate.loader.plan.spi.CompositeFetch; import org.hibernate.loader.plan.spi.EntityFetch; import org.hibernate.loader.plan.spi.FetchOwner; -import org.hibernate.loader.plan.spi.LoadPlanBuildingContext; +import org.hibernate.loader.plan.spi.build.LoadPlanBuildingContext; import org.hibernate.persister.walking.spi.AssociationAttributeDefinition; import org.hibernate.persister.walking.spi.CollectionDefinition; import org.hibernate.persister.walking.spi.CompositionDefinition; diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/internal/SingleRootReturnLoadPlanBuilderStrategy.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/internal/SingleRootReturnLoadPlanBuilderStrategy.java index fd710aa7f6..474a108a56 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/plan/internal/SingleRootReturnLoadPlanBuilderStrategy.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/internal/SingleRootReturnLoadPlanBuilderStrategy.java @@ -34,11 +34,11 @@ import org.hibernate.loader.CollectionAliases; import org.hibernate.loader.EntityAliases; import org.hibernate.loader.PropertyPath; -import org.hibernate.loader.plan.spi.AbstractLoadPlanBuilderStrategy; +import org.hibernate.loader.plan.spi.build.AbstractLoadPlanBuilderStrategy; import org.hibernate.loader.plan.spi.CollectionReturn; import org.hibernate.loader.plan.spi.EntityReturn; import org.hibernate.loader.plan.spi.LoadPlan; -import org.hibernate.loader.plan.spi.LoadPlanBuilderStrategy; +import org.hibernate.loader.plan.spi.build.LoadPlanBuilderStrategy; import org.hibernate.loader.plan.spi.Return; import org.hibernate.persister.collection.CollectionPersister; import org.hibernate.persister.entity.EntityPersister; diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/AbstractCollectionReference.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/AbstractCollectionReference.java index 996f7106c2..6d413f8c23 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/AbstractCollectionReference.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/AbstractCollectionReference.java @@ -43,8 +43,8 @@ public abstract class AbstractCollectionReference extends AbstractPlanNode imple private final CollectionAliases collectionAliases; private final EntityAliases elementEntityAliases; - private final FetchOwner indexGraph; - private final FetchOwner elementGraph; + private final FetchableCollectionIndex indexGraph; + private final FetchableCollectionElement elementGraph; protected AbstractCollectionReference( SessionFactoryImplementor sessionFactory, @@ -67,7 +67,7 @@ protected AbstractCollectionReference( this.elementGraph = buildElementGraph( getCollectionPersister() ); } - private FetchOwner buildIndexGraph(CollectionPersister persister) { + private FetchableCollectionIndex buildIndexGraph(CollectionPersister persister) { if ( persister.hasIndex() ) { final Type type = persister.getIndexType(); if ( type.isAssociationType() ) { @@ -83,7 +83,7 @@ else if ( type.isComponentType() ) { return null; } - private FetchOwner buildElementGraph(CollectionPersister persister) { + private FetchableCollectionElement buildElementGraph(CollectionPersister persister) { final Type type = persister.getElementType(); if ( type.isAssociationType() ) { if ( type.isEntityType() ) { @@ -97,6 +97,20 @@ else if ( type.isComponentType() ) { return null; } + protected AbstractCollectionReference(AbstractCollectionReference original, CopyContext copyContext) { + super( original ); + this.alias = original.alias; + this.lockMode = original.lockMode; + this.collectionPersister = original.collectionPersister; + this.propertyPath = original.propertyPath; + + this.collectionAliases = original.collectionAliases; + this.elementEntityAliases = original.elementEntityAliases; + + this.indexGraph = original.indexGraph == null ? null : original.indexGraph.makeCopy( copyContext ); + this.elementGraph = original.elementGraph == null ? null : original.elementGraph.makeCopy( copyContext ); + } + @Override public PropertyPath getPropertyPath() { return propertyPath; diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/AbstractFetchOwner.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/AbstractFetchOwner.java index ce1d1aef82..393ae377aa 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/AbstractFetchOwner.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/AbstractFetchOwner.java @@ -24,14 +24,12 @@ package org.hibernate.loader.plan.spi; import java.util.ArrayList; +import java.util.Collections; import java.util.List; -import org.hibernate.AssertionFailure; import org.hibernate.HibernateException; import org.hibernate.LockMode; -import org.hibernate.engine.spi.EntityKey; import org.hibernate.engine.spi.SessionFactoryImplementor; -import org.hibernate.loader.spi.ResultSetProcessingContext; /** * @author Steve Ebersole @@ -45,10 +43,39 @@ public abstract class AbstractFetchOwner extends AbstractPlanNode implements Fet public AbstractFetchOwner(SessionFactoryImplementor factory, String alias, LockMode lockMode) { super( factory ); this.alias = alias; + this.lockMode = lockMode; + validate(); + } + + private void validate() { if ( alias == null ) { throw new HibernateException( "alias must be specified" ); } - this.lockMode = lockMode; + } + + /** + * A "copy" constructor. Used while making clones/copies of this. + * + * @param original + */ + protected AbstractFetchOwner(AbstractFetchOwner original, CopyContext copyContext) { + super( original ); + this.alias = original.alias; + this.lockMode = original.lockMode; + validate(); + + copyContext.getReturnGraphVisitationStrategy().startingFetches( original ); + if ( fetches == null || fetches.size() == 0 ) { + this.fetches = Collections.emptyList(); + } + else { + List fetchesCopy = new ArrayList(); + for ( Fetch fetch : fetches ) { + fetchesCopy.add( fetch.makeCopy( copyContext, this ) ); + } + this.fetches = fetchesCopy; + } + copyContext.getReturnGraphVisitationStrategy().finishingFetches( original ); } public String getAlias() { diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/AbstractPlanNode.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/AbstractPlanNode.java index eb789612a2..8dc122cae8 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/AbstractPlanNode.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/AbstractPlanNode.java @@ -37,6 +37,10 @@ public AbstractPlanNode(SessionFactoryImplementor sessionFactory) { this.sessionFactory = sessionFactory; } + public AbstractPlanNode(AbstractPlanNode original) { + this( original.sessionFactory() ); + } + protected SessionFactoryImplementor sessionFactory() { return sessionFactory; } diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/AbstractSingularAttributeFetch.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/AbstractSingularAttributeFetch.java index d3a376dd09..2a30a69224 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/AbstractSingularAttributeFetch.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/AbstractSingularAttributeFetch.java @@ -57,6 +57,17 @@ public AbstractSingularAttributeFetch( this.propertyPath = owner.getPropertyPath().append( ownerProperty ); } + public AbstractSingularAttributeFetch( + AbstractSingularAttributeFetch original, + CopyContext copyContext, + FetchOwner fetchOwnerCopy) { + super( original, copyContext ); + this.owner = fetchOwnerCopy; + this.ownerProperty = original.ownerProperty; + this.fetchStrategy = original.fetchStrategy; + this.propertyPath = original.propertyPath; + } + @Override public FetchOwner getOwner() { return owner; diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/CollectionFetch.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/CollectionFetch.java index ab4e012ece..ebecfefb23 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/CollectionFetch.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/CollectionFetch.java @@ -66,6 +66,12 @@ public CollectionFetch( fetchOwner.addFetch( this ); } + protected CollectionFetch(CollectionFetch original, CopyContext copyContext, FetchOwner fetchOwnerCopy) { + super( original, copyContext ); + this.fetchOwner = fetchOwnerCopy; + this.fetchStrategy = original.fetchStrategy; + } + @Override public FetchOwner getOwner() { return fetchOwner; @@ -90,4 +96,12 @@ public void hydrate(ResultSet resultSet, ResultSetProcessingContext context) thr public Object resolve(ResultSet resultSet, ResultSetProcessingContext context) throws SQLException { return null; //To change body of implemented methods use File | Settings | File Templates. } + + @Override + public CollectionFetch makeCopy(CopyContext copyContext, FetchOwner fetchOwnerCopy) { + copyContext.getReturnGraphVisitationStrategy().startingCollectionFetch( this ); + final CollectionFetch copy = new CollectionFetch( this, copyContext, fetchOwnerCopy ); + copyContext.getReturnGraphVisitationStrategy().finishingCollectionFetch( this ); + return copy; + } } diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/CollectionReturn.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/CollectionReturn.java index 13b27be1b1..b131334f7f 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/CollectionReturn.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/CollectionReturn.java @@ -36,7 +36,7 @@ /** * @author Steve Ebersole */ -public class CollectionReturn extends AbstractCollectionReference implements Return { +public class CollectionReturn extends AbstractCollectionReference implements Return, CopyableReturn { private final String ownerEntityName; private final String ownerProperty; @@ -61,6 +61,12 @@ public CollectionReturn( this.ownerProperty = ownerProperty; } + public CollectionReturn(CollectionReturn original, CopyContext copyContext) { + super( original, copyContext ); + this.ownerEntityName = original.ownerEntityName; + this.ownerProperty = original.ownerProperty; + } + /** * Returns the class owning the collection. * @@ -98,4 +104,9 @@ public Object read(ResultSet resultSet, ResultSetProcessingContext context) thro public String toString() { return "CollectionReturn(" + getCollectionPersister().getRole() + ")"; } + + @Override + public CollectionReturn makeCopy(CopyContext copyContext) { + return new CollectionReturn( this, copyContext ); + } } diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/CompositeElementGraph.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/CompositeElementGraph.java index 306b8eb83d..e07fbd1fa4 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/CompositeElementGraph.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/CompositeElementGraph.java @@ -1,6 +1,7 @@ package org.hibernate.loader.plan.spi; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import org.hibernate.HibernateException; @@ -8,6 +9,7 @@ import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.loader.PropertyPath; import org.hibernate.loader.plan.internal.LoadPlanBuildingHelper; +import org.hibernate.loader.plan.spi.build.LoadPlanBuildingContext; import org.hibernate.persister.collection.CollectionPersister; import org.hibernate.persister.entity.EntityPersister; import org.hibernate.persister.walking.spi.AssociationAttributeDefinition; @@ -16,12 +18,13 @@ /** * @author Steve Ebersole */ -public class CompositeElementGraph extends AbstractPlanNode implements FetchOwner { +public class CompositeElementGraph extends AbstractPlanNode implements FetchableCollectionElement { private final CollectionReference collectionReference; private final PropertyPath propertyPath; private final CollectionPersister collectionPersister; private List fetches; + public CompositeElementGraph( SessionFactoryImplementor sessionFactory, CollectionReference collectionReference, @@ -33,6 +36,26 @@ public CompositeElementGraph( this.propertyPath = collectionPath.append( "" ); } + public CompositeElementGraph(CompositeElementGraph original, CopyContext copyContext) { + super( original ); + this.collectionReference = original.collectionReference; + this.collectionPersister = original.collectionPersister; + this.propertyPath = original.propertyPath; + + copyContext.getReturnGraphVisitationStrategy().startingFetches( original ); + if ( fetches == null || fetches.size() == 0 ) { + this.fetches = Collections.emptyList(); + } + else { + List fetchesCopy = new ArrayList(); + for ( Fetch fetch : fetches ) { + fetchesCopy.add( fetch.makeCopy( copyContext, this ) ); + } + this.fetches = fetchesCopy; + } + copyContext.getReturnGraphVisitationStrategy().finishingFetches( original ); + } + @Override public void addFetch(Fetch fetch) { if ( fetches == null ) { @@ -89,4 +112,9 @@ public CompositeFetch buildCompositeFetch( LoadPlanBuildingContext loadPlanBuildingContext) { return LoadPlanBuildingHelper.buildStandardCompositeFetch( this, attributeDefinition, loadPlanBuildingContext ); } + + @Override + public CompositeElementGraph makeCopy(CopyContext copyContext) { + return new CompositeElementGraph( this, copyContext ); + } } diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/CompositeFetch.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/CompositeFetch.java index 01a6140c81..15081e7162 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/CompositeFetch.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/CompositeFetch.java @@ -31,6 +31,7 @@ import org.hibernate.engine.FetchStyle; import org.hibernate.engine.FetchTiming; import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.loader.plan.spi.build.LoadPlanBuildingContext; import org.hibernate.loader.spi.ResultSetProcessingContext; import org.hibernate.persister.entity.EntityPersister; import org.hibernate.persister.walking.spi.AssociationAttributeDefinition; @@ -50,6 +51,10 @@ public CompositeFetch( super( sessionFactory, alias, LockMode.NONE, owner, ownerProperty, FETCH_PLAN ); } + public CompositeFetch(CompositeFetch original, CopyContext copyContext, FetchOwner fetchOwnerCopy) { + super( original, copyContext, fetchOwnerCopy ); + } + @Override public EntityPersister retrieveFetchSourcePersister() { return getOwner().retrieveFetchSourcePersister(); @@ -86,4 +91,12 @@ public void hydrate(ResultSet resultSet, ResultSetProcessingContext context) thr public Object resolve(ResultSet resultSet, ResultSetProcessingContext context) throws SQLException { return null; //To change body of implemented methods use File | Settings | File Templates. } + + @Override + public CompositeFetch makeCopy(CopyContext copyContext, FetchOwner fetchOwnerCopy) { + copyContext.getReturnGraphVisitationStrategy().startingCompositeFetch( this ); + final CompositeFetch copy = new CompositeFetch( this, copyContext, fetchOwnerCopy ); + copyContext.getReturnGraphVisitationStrategy().finishingCompositeFetch( this ); + return copy; + } } diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/CompositeIndexGraph.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/CompositeIndexGraph.java index fce9033b72..793215c96d 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/CompositeIndexGraph.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/CompositeIndexGraph.java @@ -1,6 +1,7 @@ package org.hibernate.loader.plan.spi; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import org.hibernate.HibernateException; @@ -8,6 +9,7 @@ import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.loader.PropertyPath; import org.hibernate.loader.plan.internal.LoadPlanBuildingHelper; +import org.hibernate.loader.plan.spi.build.LoadPlanBuildingContext; import org.hibernate.persister.collection.CollectionPersister; import org.hibernate.persister.entity.EntityPersister; import org.hibernate.persister.walking.spi.AssociationAttributeDefinition; @@ -16,7 +18,7 @@ /** * @author Steve Ebersole */ -public class CompositeIndexGraph extends AbstractPlanNode implements FetchOwner { +public class CompositeIndexGraph extends AbstractPlanNode implements FetchableCollectionIndex { private final CollectionReference collectionReference; private final PropertyPath propertyPath; private final CollectionPersister collectionPersister; @@ -33,6 +35,26 @@ public CompositeIndexGraph( this.propertyPath = propertyPath.append( "" ); } + protected CompositeIndexGraph(CompositeIndexGraph original, CopyContext copyContext) { + super( original ); + this.collectionReference = original.collectionReference; + this.collectionPersister = original.collectionPersister; + this.propertyPath = original.propertyPath; + + copyContext.getReturnGraphVisitationStrategy().startingFetches( original ); + if ( fetches == null || fetches.size() == 0 ) { + this.fetches = Collections.emptyList(); + } + else { + List fetchesCopy = new ArrayList(); + for ( Fetch fetch : fetches ) { + fetchesCopy.add( fetch.makeCopy( copyContext, this ) ); + } + this.fetches = fetchesCopy; + } + copyContext.getReturnGraphVisitationStrategy().finishingFetches( original ); + } + @Override public void addFetch(Fetch fetch) { if ( fetches == null ) { @@ -89,4 +111,9 @@ public CompositeFetch buildCompositeFetch( LoadPlanBuildingContext loadPlanBuildingContext) { return LoadPlanBuildingHelper.buildStandardCompositeFetch( this, attributeDefinition, loadPlanBuildingContext ); } + + @Override + public CompositeIndexGraph makeCopy(CopyContext copyContext) { + return new CompositeIndexGraph( this, copyContext ); + } } diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/CopyContext.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/CopyContext.java new file mode 100644 index 0000000000..bfce0bfaa0 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/CopyContext.java @@ -0,0 +1,33 @@ +/* + * 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.loader.plan.spi; + +import org.hibernate.loader.plan.spi.visit.ReturnGraphVisitationStrategy; + +/** + * @author Steve Ebersole + */ +public interface CopyContext { + public ReturnGraphVisitationStrategy getReturnGraphVisitationStrategy(); +} diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/CopyableFetch.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/CopyableFetch.java new file mode 100644 index 0000000000..b5c11ba77d --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/CopyableFetch.java @@ -0,0 +1,31 @@ +/* + * 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.loader.plan.spi; + +/** + * @author Steve Ebersole + */ +public interface CopyableFetch { + public Fetch makeCopy(CopyContext copyContext, FetchOwner fetchOwnerCopy); +} diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/CopyableReturn.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/CopyableReturn.java new file mode 100644 index 0000000000..48ad99f3df --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/CopyableReturn.java @@ -0,0 +1,38 @@ +/* + * 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.loader.plan.spi; + +/** + * @author Steve Ebersole + */ +public interface CopyableReturn { + + /** + * Makes a deep copy. + * + * @return + */ + public CopyableReturn makeCopy(CopyContext copyContext); + +} diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/EntityElementGraph.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/EntityElementGraph.java index 7f55b638bf..d713a4b819 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/EntityElementGraph.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/EntityElementGraph.java @@ -1,6 +1,7 @@ package org.hibernate.loader.plan.spi; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import org.hibernate.LockMode; @@ -9,6 +10,7 @@ import org.hibernate.loader.EntityAliases; import org.hibernate.loader.PropertyPath; import org.hibernate.loader.plan.internal.LoadPlanBuildingHelper; +import org.hibernate.loader.plan.spi.build.LoadPlanBuildingContext; import org.hibernate.persister.collection.CollectionPersister; import org.hibernate.persister.entity.EntityPersister; import org.hibernate.persister.walking.spi.AssociationAttributeDefinition; @@ -18,7 +20,7 @@ /** * @author Steve Ebersole */ -public class EntityElementGraph extends AbstractPlanNode implements FetchOwner, EntityReference { +public class EntityElementGraph extends AbstractPlanNode implements FetchableCollectionElement, EntityReference { private final CollectionReference collectionReference; private final CollectionPersister collectionPersister; private final AssociationType elementType; @@ -42,6 +44,29 @@ public EntityElementGraph( this.propertyPath = collectionPath.append( "" ); } + public EntityElementGraph(EntityElementGraph original, CopyContext copyContext) { + super( original ); + + this.collectionReference = original.collectionReference; + this.collectionPersister = original.collectionReference.getCollectionPersister(); + this.elementType = original.elementType; + this.elementPersister = original.elementPersister; + this.propertyPath = original.propertyPath; + + copyContext.getReturnGraphVisitationStrategy().startingFetches( original ); + if ( fetches == null || fetches.size() == 0 ) { + this.fetches = Collections.emptyList(); + } + else { + List fetchesCopy = new ArrayList(); + for ( Fetch fetch : fetches ) { + fetchesCopy.add( fetch.makeCopy( copyContext, this ) ); + } + this.fetches = fetchesCopy; + } + copyContext.getReturnGraphVisitationStrategy().finishingFetches( original ); + } + @Override public String getAlias() { return null; @@ -139,6 +164,11 @@ public void injectIdentifierDescription(IdentifierDescription identifierDescript this.identifierDescription = identifierDescription; } + @Override + public EntityElementGraph makeCopy(CopyContext copyContext) { + return new EntityElementGraph( this, copyContext ); + } + @Override public String toString() { return "EntityElementGraph(collection=" + collectionPersister.getRole() + ", type=" + elementPersister.getEntityName() + ")"; diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/EntityFetch.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/EntityFetch.java index 54f7a61a7e..66ea3a19d2 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/EntityFetch.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/EntityFetch.java @@ -34,11 +34,11 @@ import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.loader.EntityAliases; import org.hibernate.loader.plan.internal.LoadPlanBuildingHelper; +import org.hibernate.loader.plan.spi.build.LoadPlanBuildingContext; import org.hibernate.loader.spi.ResultSetProcessingContext; import org.hibernate.persister.entity.EntityPersister; import org.hibernate.persister.walking.spi.AssociationAttributeDefinition; import org.hibernate.persister.walking.spi.CompositionDefinition; -import org.hibernate.type.AssociationType; import org.hibernate.type.EntityType; /** @@ -70,6 +70,20 @@ public EntityFetch( this.persister = sessionFactory.getEntityPersister( associationType.getAssociatedEntityName() ); } + /** + * Copy constructor. + * + * @param original The original fetch + * @param copyContext Access to contextual needs for the copy operation + */ + protected EntityFetch(EntityFetch original, CopyContext copyContext, FetchOwner fetchOwnerCopy) { + super( original, copyContext, fetchOwnerCopy ); + this.sqlTableAlias = original.sqlTableAlias; + this.entityAliases = original.entityAliases; + this.associationType = original.associationType; + this.persister = original.persister; + } + public EntityType getAssociationType() { return associationType; } @@ -262,4 +276,12 @@ public EntityKey resolveInIdentifier(ResultSet resultSet, ResultSetProcessingCon public String toString() { return "EntityFetch(" + getPropertyPath().getFullPath() + " -> " + persister.getEntityName() + ")"; } + + @Override + public EntityFetch makeCopy(CopyContext copyContext, FetchOwner fetchOwnerCopy) { + copyContext.getReturnGraphVisitationStrategy().startingEntityFetch( this ); + final EntityFetch copy = new EntityFetch( this, copyContext, fetchOwnerCopy ); + copyContext.getReturnGraphVisitationStrategy().finishingEntityFetch( this ); + return copy; + } } diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/EntityIndexGraph.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/EntityIndexGraph.java index 806567396c..fcbece5f6b 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/EntityIndexGraph.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/EntityIndexGraph.java @@ -24,6 +24,7 @@ package org.hibernate.loader.plan.spi; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import org.hibernate.LockMode; @@ -32,6 +33,7 @@ import org.hibernate.loader.EntityAliases; import org.hibernate.loader.PropertyPath; import org.hibernate.loader.plan.internal.LoadPlanBuildingHelper; +import org.hibernate.loader.plan.spi.build.LoadPlanBuildingContext; import org.hibernate.persister.collection.CollectionPersister; import org.hibernate.persister.entity.EntityPersister; import org.hibernate.persister.walking.spi.AssociationAttributeDefinition; @@ -41,7 +43,7 @@ /** * @author Steve Ebersole */ -public class EntityIndexGraph extends AbstractPlanNode implements FetchOwner, EntityReference { +public class EntityIndexGraph extends AbstractPlanNode implements FetchableCollectionIndex, EntityReference { private final CollectionReference collectionReference; private final CollectionPersister collectionPersister; private final AssociationType indexType; @@ -64,6 +66,28 @@ public EntityIndexGraph( this.propertyPath = collectionPath.append( "" ); // todo : do we want the part? } + public EntityIndexGraph(EntityIndexGraph original, CopyContext copyContext) { + super( original ); + this.collectionReference = original.collectionReference; + this.collectionPersister = original.collectionReference.getCollectionPersister(); + this.indexType = original.indexType; + this.indexPersister = original.indexPersister; + this.propertyPath = original.propertyPath; + + copyContext.getReturnGraphVisitationStrategy().startingFetches( original ); + if ( fetches == null || fetches.size() == 0 ) { + this.fetches = Collections.emptyList(); + } + else { + List fetchesCopy = new ArrayList(); + for ( Fetch fetch : fetches ) { + fetchesCopy.add( fetch.makeCopy( copyContext, this ) ); + } + this.fetches = fetchesCopy; + } + copyContext.getReturnGraphVisitationStrategy().finishingFetches( original ); + } + @Override public String getAlias() { return null; @@ -160,4 +184,9 @@ public CompositeFetch buildCompositeFetch( public void injectIdentifierDescription(IdentifierDescription identifierDescription) { this.identifierDescription = identifierDescription; } + + @Override + public EntityIndexGraph makeCopy(CopyContext copyContext) { + return new EntityIndexGraph( this, copyContext ); + } } diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/EntityReference.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/EntityReference.java index da0f1067a0..b6158cf681 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/EntityReference.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/EntityReference.java @@ -23,9 +23,7 @@ */ package org.hibernate.loader.plan.spi; -import org.hibernate.AssertionFailure; import org.hibernate.LockMode; -import org.hibernate.engine.spi.EntityKey; import org.hibernate.loader.EntityAliases; import org.hibernate.loader.spi.ResultSetProcessingContext; import org.hibernate.persister.entity.EntityPersister; @@ -35,7 +33,8 @@ * * @author Steve Ebersole */ -public interface EntityReference extends IdentifierDescriptionInjectable, ResultSetProcessingContext.EntityKeyResolutionContext { +public interface EntityReference + extends IdentifierDescriptionInjectable, ResultSetProcessingContext.EntityKeyResolutionContext { /** * Retrieve the alias associated with the persister (entity/collection). * diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/EntityReturn.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/EntityReturn.java index 682696a64c..b73f15f512 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/EntityReturn.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/EntityReturn.java @@ -34,6 +34,7 @@ import org.hibernate.loader.EntityAliases; import org.hibernate.loader.PropertyPath; import org.hibernate.loader.plan.internal.LoadPlanBuildingHelper; +import org.hibernate.loader.plan.spi.build.LoadPlanBuildingContext; import org.hibernate.loader.spi.ResultSetProcessingContext; import org.hibernate.persister.entity.EntityPersister; import org.hibernate.persister.walking.spi.AssociationAttributeDefinition; @@ -44,7 +45,7 @@ /** * @author Steve Ebersole */ -public class EntityReturn extends AbstractFetchOwner implements Return, EntityReference { +public class EntityReturn extends AbstractFetchOwner implements Return, EntityReference, CopyableReturn { private final EntityAliases entityAliases; private final String sqlTableAlias; @@ -69,6 +70,13 @@ public EntityReturn( this.persister = sessionFactory.getEntityPersister( entityName ); } + protected EntityReturn(EntityReturn original, CopyContext copyContext) { + super( original, copyContext ); + this.entityAliases = original.entityAliases; + this.sqlTableAlias = original.sqlTableAlias; + this.persister = original.persister; + } + @Override public String getAlias() { return super.getAlias(); @@ -205,4 +213,9 @@ public void injectIdentifierDescription(IdentifierDescription identifierDescript public String toString() { return "EntityReturn(" + persister.getEntityName() + ")"; } + + @Override + public EntityReturn makeCopy(CopyContext copyContext) { + return new EntityReturn( this, copyContext ); + } } diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/Fetch.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/Fetch.java index 7213e18336..ab344a17f2 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/Fetch.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/Fetch.java @@ -37,7 +37,7 @@ * * @author Steve Ebersole */ -public interface Fetch { +public interface Fetch extends CopyableFetch { /** * Obtain the owner of this fetch. * @@ -64,4 +64,7 @@ public interface Fetch { public void hydrate(ResultSet resultSet, ResultSetProcessingContext context) throws SQLException; public Object resolve(ResultSet resultSet, ResultSetProcessingContext context) throws SQLException; + + @Override + public Fetch makeCopy(CopyContext copyContext, FetchOwner fetchOwnerCopy); } diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/FetchOwner.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/FetchOwner.java index 94958f221d..ada44e90cc 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/FetchOwner.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/FetchOwner.java @@ -25,6 +25,7 @@ import org.hibernate.engine.FetchStrategy; import org.hibernate.loader.PropertyPath; +import org.hibernate.loader.plan.spi.build.LoadPlanBuildingContext; import org.hibernate.persister.entity.EntityPersister; import org.hibernate.persister.walking.spi.AssociationAttributeDefinition; import org.hibernate.persister.walking.spi.CompositionDefinition; @@ -91,4 +92,5 @@ public CompositeFetch buildCompositeFetch( CompositionDefinition attributeDefinition, LoadPlanBuildingContext loadPlanBuildingContext); + } diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/FetchableCollectionElement.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/FetchableCollectionElement.java new file mode 100644 index 0000000000..5b18a01029 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/FetchableCollectionElement.java @@ -0,0 +1,32 @@ +/* + * 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.loader.plan.spi; + +/** + * @author Steve Ebersole + */ +public interface FetchableCollectionElement extends FetchOwner, CopyableReturn { + @Override + public FetchableCollectionElement makeCopy(CopyContext copyContext); +} diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/FetchableCollectionIndex.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/FetchableCollectionIndex.java new file mode 100644 index 0000000000..7fe443bb2f --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/FetchableCollectionIndex.java @@ -0,0 +1,34 @@ +/* + * 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.loader.plan.spi; + +/** + * A collection index which can be a fetch owner. + * + * @author Steve Ebersole + */ +public interface FetchableCollectionIndex extends FetchOwner, CopyableReturn { + @Override + public FetchableCollectionIndex makeCopy(CopyContext copyContext); +} diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/AbstractLoadPlanBuilderStrategy.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/build/AbstractLoadPlanBuilderStrategy.java similarity index 97% rename from hibernate-core/src/main/java/org/hibernate/loader/plan/spi/AbstractLoadPlanBuilderStrategy.java rename to hibernate-core/src/main/java/org/hibernate/loader/plan/spi/build/AbstractLoadPlanBuilderStrategy.java index a1162cbe33..33a3ebd194 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/AbstractLoadPlanBuilderStrategy.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/build/AbstractLoadPlanBuilderStrategy.java @@ -21,7 +21,7 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.loader.plan.spi; +package org.hibernate.loader.plan.spi.build; import java.io.Serializable; import java.sql.ResultSet; @@ -48,6 +48,17 @@ import org.hibernate.loader.GeneratedCollectionAliases; import org.hibernate.loader.PropertyPath; import org.hibernate.loader.plan.internal.LoadPlanBuildingHelper; +import org.hibernate.loader.plan.spi.CollectionFetch; +import org.hibernate.loader.plan.spi.CollectionReference; +import org.hibernate.loader.plan.spi.CollectionReturn; +import org.hibernate.loader.plan.spi.CompositeFetch; +import org.hibernate.loader.plan.spi.EntityFetch; +import org.hibernate.loader.plan.spi.EntityReference; +import org.hibernate.loader.plan.spi.EntityReturn; +import org.hibernate.loader.plan.spi.Fetch; +import org.hibernate.loader.plan.spi.FetchOwner; +import org.hibernate.loader.plan.spi.IdentifierDescription; +import org.hibernate.loader.plan.spi.Return; import org.hibernate.loader.spi.ResultSetProcessingContext; import org.hibernate.persister.collection.CollectionPersister; import org.hibernate.persister.entity.EntityPersister; diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/LoadPlanBuilder.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/build/LoadPlanBuilder.java similarity index 90% rename from hibernate-core/src/main/java/org/hibernate/loader/plan/spi/LoadPlanBuilder.java rename to hibernate-core/src/main/java/org/hibernate/loader/plan/spi/build/LoadPlanBuilder.java index 61b7b41ab1..19d3499d0c 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/LoadPlanBuilder.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/build/LoadPlanBuilder.java @@ -21,14 +21,15 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.loader.plan.spi; +package org.hibernate.loader.plan.spi.build; +import org.hibernate.loader.plan.spi.LoadPlan; import org.hibernate.persister.collection.CollectionPersister; import org.hibernate.persister.entity.EntityPersister; import org.hibernate.persister.walking.spi.MetadataDrivenModelGraphVisitor; /** - * Coordinates building of a {@link LoadPlan} between the {@link org.hibernate.persister.walking.spi.MetadataDrivenModelGraphVisitor} and + * Coordinates building of a {@link org.hibernate.loader.plan.spi.LoadPlan} between the {@link org.hibernate.persister.walking.spi.MetadataDrivenModelGraphVisitor} and * {@link LoadPlanBuilderStrategy} * * @author Steve Ebersole diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/LoadPlanBuilderStrategy.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/build/LoadPlanBuilderStrategy.java similarity index 87% rename from hibernate-core/src/main/java/org/hibernate/loader/plan/spi/LoadPlanBuilderStrategy.java rename to hibernate-core/src/main/java/org/hibernate/loader/plan/spi/build/LoadPlanBuilderStrategy.java index 7c40540fbf..64bc8c486b 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/LoadPlanBuilderStrategy.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/build/LoadPlanBuilderStrategy.java @@ -21,12 +21,13 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.loader.plan.spi; +package org.hibernate.loader.plan.spi.build; +import org.hibernate.loader.plan.spi.LoadPlan; import org.hibernate.persister.walking.spi.AssociationVisitationStrategy; /** - * Specialized {@link org.hibernate.persister.walking.spi.AssociationVisitationStrategy} implementation for building {@link LoadPlan} instances. + * Specialized {@link org.hibernate.persister.walking.spi.AssociationVisitationStrategy} implementation for building {@link org.hibernate.loader.plan.spi.LoadPlan} instances. * * @author Steve Ebersole */ diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/LoadPlanBuildingContext.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/build/LoadPlanBuildingContext.java similarity index 97% rename from hibernate-core/src/main/java/org/hibernate/loader/plan/spi/LoadPlanBuildingContext.java rename to hibernate-core/src/main/java/org/hibernate/loader/plan/spi/build/LoadPlanBuildingContext.java index 152133f44c..2fa50a9fc1 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/LoadPlanBuildingContext.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/build/LoadPlanBuildingContext.java @@ -21,7 +21,7 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.loader.plan.spi; +package org.hibernate.loader.plan.spi.build; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.loader.CollectionAliases; diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/visit/DelegatedLoadPlanVisitationStrategy.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/visit/DelegatedLoadPlanVisitationStrategy.java new file mode 100644 index 0000000000..bfa7ff79e9 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/visit/DelegatedLoadPlanVisitationStrategy.java @@ -0,0 +1,118 @@ +/* + * 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.loader.plan.spi.visit; + +import org.hibernate.loader.plan.spi.CollectionFetch; +import org.hibernate.loader.plan.spi.CollectionReturn; +import org.hibernate.loader.plan.spi.CompositeFetch; +import org.hibernate.loader.plan.spi.EntityFetch; +import org.hibernate.loader.plan.spi.EntityReturn; +import org.hibernate.loader.plan.spi.FetchOwner; +import org.hibernate.loader.plan.spi.LoadPlan; +import org.hibernate.loader.plan.spi.Return; +import org.hibernate.loader.plan.spi.ScalarReturn; + +/** + * @author Steve Ebersole + */ +public class DelegatedLoadPlanVisitationStrategy implements LoadPlanVisitationStrategy { + private final ReturnGraphVisitationStrategy returnGraphVisitationStrategy; + + public DelegatedLoadPlanVisitationStrategy(ReturnGraphVisitationStrategy returnGraphVisitationStrategy) { + this.returnGraphVisitationStrategy = returnGraphVisitationStrategy; + } + + @Override + public void start(LoadPlan loadPlan) { + } + + @Override + public void finish(LoadPlan loadPlan) { + } + + @Override + public void startingRootReturn(Return rootReturn) { + returnGraphVisitationStrategy.startingRootReturn( rootReturn ); + } + + @Override + public void finishingRootReturn(Return rootReturn) { + returnGraphVisitationStrategy.finishingRootReturn( rootReturn ); + } + + @Override + public void handleScalarReturn(ScalarReturn scalarReturn) { + returnGraphVisitationStrategy.handleScalarReturn( scalarReturn ); + } + + @Override + public void handleEntityReturn(EntityReturn rootEntityReturn) { + returnGraphVisitationStrategy.handleEntityReturn( rootEntityReturn ); + } + + @Override + public void handleCollectionReturn(CollectionReturn rootCollectionReturn) { + returnGraphVisitationStrategy.handleCollectionReturn( rootCollectionReturn ); + } + + @Override + public void startingFetches(FetchOwner fetchOwner) { + returnGraphVisitationStrategy.startingFetches( fetchOwner ); + } + + @Override + public void finishingFetches(FetchOwner fetchOwner) { + returnGraphVisitationStrategy.finishingFetches( fetchOwner ); + } + + @Override + public void startingEntityFetch(EntityFetch fetch) { + returnGraphVisitationStrategy.startingEntityFetch( fetch ); + } + + @Override + public void finishingEntityFetch(EntityFetch fetch) { + returnGraphVisitationStrategy.finishingEntityFetch( fetch ); + } + + @Override + public void startingCollectionFetch(CollectionFetch fetch) { + returnGraphVisitationStrategy.startingCollectionFetch( fetch ); + } + + @Override + public void finishingCollectionFetch(CollectionFetch fetch) { + returnGraphVisitationStrategy.finishingCollectionFetch( fetch ); + } + + @Override + public void startingCompositeFetch(CompositeFetch fetch) { + returnGraphVisitationStrategy.startingCompositeFetch( fetch ); + } + + @Override + public void finishingCompositeFetch(CompositeFetch fetch) { + returnGraphVisitationStrategy.finishingCompositeFetch( fetch ); + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/visit/LoadPlanVisitationStrategy.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/visit/LoadPlanVisitationStrategy.java new file mode 100644 index 0000000000..9a0d08fd09 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/visit/LoadPlanVisitationStrategy.java @@ -0,0 +1,41 @@ +/* + * 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.loader.plan.spi.visit; + +import org.hibernate.loader.plan.spi.LoadPlan; + +/** + * @author Steve Ebersole + */ +public interface LoadPlanVisitationStrategy extends ReturnGraphVisitationStrategy { + /** + * Notification we are preparing to start visitation. + */ + public void start(LoadPlan loadPlan); + + /** + * Notification we are finished visitation. + */ + public void finish(LoadPlan loadPlan); +} diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/LoadPlanVisitationStrategyAdapter.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/visit/LoadPlanVisitationStrategyAdapter.java similarity index 64% rename from hibernate-core/src/main/java/org/hibernate/loader/plan/spi/LoadPlanVisitationStrategyAdapter.java rename to hibernate-core/src/main/java/org/hibernate/loader/plan/spi/visit/LoadPlanVisitationStrategyAdapter.java index 6734ef990c..ca85c40cc2 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/LoadPlanVisitationStrategyAdapter.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/visit/LoadPlanVisitationStrategyAdapter.java @@ -21,84 +21,81 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.loader.plan.spi; +package org.hibernate.loader.plan.spi.visit; + +import org.hibernate.loader.plan.spi.CollectionFetch; +import org.hibernate.loader.plan.spi.CollectionReturn; +import org.hibernate.loader.plan.spi.CompositeFetch; +import org.hibernate.loader.plan.spi.EntityFetch; +import org.hibernate.loader.plan.spi.EntityReturn; +import org.hibernate.loader.plan.spi.FetchOwner; +import org.hibernate.loader.plan.spi.LoadPlan; +import org.hibernate.loader.plan.spi.Return; +import org.hibernate.loader.plan.spi.ScalarReturn; /** * @author Steve Ebersole */ public class LoadPlanVisitationStrategyAdapter implements LoadPlanVisitationStrategy { + public static final LoadPlanVisitationStrategyAdapter INSTANCE = new LoadPlanVisitationStrategyAdapter(); + @Override public void start(LoadPlan loadPlan) { - //To change body of implemented methods use File | Settings | File Templates. } @Override public void finish(LoadPlan loadPlan) { - //To change body of implemented methods use File | Settings | File Templates. } @Override public void startingRootReturn(Return rootReturn) { - //To change body of implemented methods use File | Settings | File Templates. } @Override public void finishingRootReturn(Return rootReturn) { - //To change body of implemented methods use File | Settings | File Templates. } @Override public void handleScalarReturn(ScalarReturn scalarReturn) { - //To change body of implemented methods use File | Settings | File Templates. } @Override public void handleEntityReturn(EntityReturn rootEntityReturn) { - //To change body of implemented methods use File | Settings | File Templates. } @Override public void handleCollectionReturn(CollectionReturn rootCollectionReturn) { - //To change body of implemented methods use File | Settings | File Templates. } @Override public void startingFetches(FetchOwner fetchOwner) { - //To change body of implemented methods use File | Settings | File Templates. } @Override public void finishingFetches(FetchOwner fetchOwner) { - //To change body of implemented methods use File | Settings | File Templates. } @Override public void startingEntityFetch(EntityFetch entityFetch) { - //To change body of implemented methods use File | Settings | File Templates. } @Override public void finishingEntityFetch(EntityFetch entityFetch) { - //To change body of implemented methods use File | Settings | File Templates. } @Override public void startingCollectionFetch(CollectionFetch collectionFetch) { - //To change body of implemented methods use File | Settings | File Templates. } @Override public void finishingCollectionFetch(CollectionFetch collectionFetch) { - //To change body of implemented methods use File | Settings | File Templates. } @Override public void startingCompositeFetch(CompositeFetch fetch) { - //To change body of implemented methods use File | Settings | File Templates. } @Override public void finishingCompositeFetch(CompositeFetch fetch) { - //To change body of implemented methods use File | Settings | File Templates. } } diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/visit/LoadPlanVisitor.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/visit/LoadPlanVisitor.java new file mode 100644 index 0000000000..7f20addb60 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/visit/LoadPlanVisitor.java @@ -0,0 +1,53 @@ +/* + * 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.loader.plan.spi.visit; + +import org.hibernate.loader.plan.spi.LoadPlan; + +/** + * Visitor for processing {@link org.hibernate.loader.plan.spi.Return} graphs + * + * @author Steve Ebersole + */ +public class LoadPlanVisitor { + public static void visit(LoadPlan loadPlan, LoadPlanVisitationStrategy strategy) { + new LoadPlanVisitor( strategy ).visit( loadPlan ); + } + + private final LoadPlanVisitationStrategy strategy; + private final ReturnGraphVisitor returnGraphVisitor; + + public LoadPlanVisitor(LoadPlanVisitationStrategy strategy) { + this.strategy = strategy; + this.returnGraphVisitor = new ReturnGraphVisitor( strategy ); + } + + private void visit(LoadPlan loadPlan) { + strategy.start( loadPlan ); + + returnGraphVisitor.visit( loadPlan.getReturns() ); + + strategy.finish( loadPlan ); + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/LoadPlanVisitationStrategy.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/visit/ReturnGraphVisitationStrategy.java similarity index 82% rename from hibernate-core/src/main/java/org/hibernate/loader/plan/spi/LoadPlanVisitationStrategy.java rename to hibernate-core/src/main/java/org/hibernate/loader/plan/spi/visit/ReturnGraphVisitationStrategy.java index 976177ed33..02d78e5597 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/LoadPlanVisitationStrategy.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/visit/ReturnGraphVisitationStrategy.java @@ -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,26 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.loader.plan.spi; +package org.hibernate.loader.plan.spi.visit; + +import org.hibernate.loader.plan.spi.CollectionFetch; +import org.hibernate.loader.plan.spi.CollectionReturn; +import org.hibernate.loader.plan.spi.CompositeFetch; +import org.hibernate.loader.plan.spi.EntityFetch; +import org.hibernate.loader.plan.spi.EntityReturn; +import org.hibernate.loader.plan.spi.FetchOwner; +import org.hibernate.loader.plan.spi.Return; +import org.hibernate.loader.plan.spi.ScalarReturn; /** + * A strategy for visiting a root {@link Return} and fetches it defines. + * * @author Steve Ebersole */ -public interface LoadPlanVisitationStrategy { +public interface ReturnGraphVisitationStrategy { /** - * Notification we are preparing to start visitation. - */ - public void start(LoadPlan loadPlan); - - /** - * Notification we are finished visitation. - */ - public void finish(LoadPlan loadPlan); - - /** - * Notification that a new root return branch is being started. Will be followed by calls to one of the following - * based on the type of return:

    + * Notification that a new root return branch is being started. Will be followed by calls + * to one of the following based on the type of return:
      *
    • {@link #handleScalarReturn}
    • *
    • {@link #handleEntityReturn}
    • *
    • {@link #handleCollectionReturn}
    • @@ -57,8 +58,8 @@ public interface LoadPlanVisitationStrategy { public void finishingRootReturn(Return rootReturn); /** - * Notification that a scalar return is being processed. Will be surrounded by calls to {@link #startingRootReturn} - * and {@link #finishingRootReturn} + * Notification that a scalar return is being processed. Will be surrounded by calls to + * {@link #startingRootReturn} and {@link #finishingRootReturn} * * @param scalarReturn The scalar return */ diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/visit/ReturnGraphVisitationStrategyAdapter.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/visit/ReturnGraphVisitationStrategyAdapter.java new file mode 100644 index 0000000000..1432cc955d --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/visit/ReturnGraphVisitationStrategyAdapter.java @@ -0,0 +1,92 @@ +/* + * 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.loader.plan.spi.visit; + +import org.hibernate.loader.plan.spi.CollectionFetch; +import org.hibernate.loader.plan.spi.CollectionReturn; +import org.hibernate.loader.plan.spi.CompositeFetch; +import org.hibernate.loader.plan.spi.EntityFetch; +import org.hibernate.loader.plan.spi.EntityReturn; +import org.hibernate.loader.plan.spi.FetchOwner; +import org.hibernate.loader.plan.spi.Return; +import org.hibernate.loader.plan.spi.ScalarReturn; + +/** + * @author Steve Ebersole + */ +public class ReturnGraphVisitationStrategyAdapter implements ReturnGraphVisitationStrategy { + public static final ReturnGraphVisitationStrategyAdapter INSTANCE = new ReturnGraphVisitationStrategyAdapter(); + + @Override + public void startingRootReturn(Return rootReturn) { + } + + @Override + public void finishingRootReturn(Return rootReturn) { + } + + @Override + public void handleScalarReturn(ScalarReturn scalarReturn) { + } + + @Override + public void handleEntityReturn(EntityReturn rootEntityReturn) { + } + + @Override + public void handleCollectionReturn(CollectionReturn rootCollectionReturn) { + } + + @Override + public void startingFetches(FetchOwner fetchOwner) { + } + + @Override + public void finishingFetches(FetchOwner fetchOwner) { + } + + @Override + public void startingEntityFetch(EntityFetch entityFetch) { + } + + @Override + public void finishingEntityFetch(EntityFetch entityFetch) { + } + + @Override + public void startingCollectionFetch(CollectionFetch collectionFetch) { + } + + @Override + public void finishingCollectionFetch(CollectionFetch collectionFetch) { + } + + @Override + public void startingCompositeFetch(CompositeFetch fetch) { + } + + @Override + public void finishingCompositeFetch(CompositeFetch fetch) { + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/LoadPlanVisitor.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/visit/ReturnGraphVisitor.java similarity index 78% rename from hibernate-core/src/main/java/org/hibernate/loader/plan/spi/LoadPlanVisitor.java rename to hibernate-core/src/main/java/org/hibernate/loader/plan/spi/visit/ReturnGraphVisitor.java index 304ace31ec..85036e69f9 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/LoadPlanVisitor.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/spi/visit/ReturnGraphVisitor.java @@ -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,32 +21,40 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.loader.plan.spi; +package org.hibernate.loader.plan.spi.visit; + +import java.util.List; + +import org.hibernate.loader.plan.spi.CollectionFetch; +import org.hibernate.loader.plan.spi.CollectionReturn; +import org.hibernate.loader.plan.spi.CompositeFetch; +import org.hibernate.loader.plan.spi.EntityFetch; +import org.hibernate.loader.plan.spi.EntityReturn; +import org.hibernate.loader.plan.spi.Fetch; +import org.hibernate.loader.plan.spi.FetchOwner; +import org.hibernate.loader.plan.spi.Return; +import org.hibernate.loader.plan.spi.ScalarReturn; /** - * Visitor for processing {@link Return} graphs - * * @author Steve Ebersole */ -public class LoadPlanVisitor { - public static void visit(LoadPlan loadPlan, LoadPlanVisitationStrategy strategy) { - new LoadPlanVisitor( strategy ).visit( loadPlan ); - } +public class ReturnGraphVisitor { + private final ReturnGraphVisitationStrategy strategy; - private final LoadPlanVisitationStrategy strategy; - - public LoadPlanVisitor(LoadPlanVisitationStrategy strategy) { + public ReturnGraphVisitor(ReturnGraphVisitationStrategy strategy) { this.strategy = strategy; } - private void visit(LoadPlan loadPlan) { - strategy.start( loadPlan ); - - for ( Return rootReturn : loadPlan.getReturns() ) { + public void visit(Return... rootReturns) { + for ( Return rootReturn : rootReturns ) { visitRootReturn( rootReturn ); } + } - strategy.finish( loadPlan ); + public void visit(List rootReturns) { + for ( Return rootReturn : rootReturns ) { + visitRootReturn( rootReturn ); + } } private void visitRootReturn(Return rootReturn) { @@ -117,5 +125,4 @@ else if ( CompositeFetch.class.isInstance( fetch ) ) { ); } } - } diff --git a/hibernate-core/src/main/java/org/hibernate/loader/spi/LoadPlanAdvisor.java b/hibernate-core/src/main/java/org/hibernate/loader/spi/LoadPlanAdvisor.java new file mode 100644 index 0000000000..cb252206d9 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/loader/spi/LoadPlanAdvisor.java @@ -0,0 +1,33 @@ +/* + * 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.loader.spi; + +import org.hibernate.loader.plan.spi.LoadPlan; + +/** + * @author Steve Ebersole + */ +public interface LoadPlanAdvisor { + public LoadPlan advise(LoadPlan loadPlan); +} diff --git a/hibernate-core/src/main/java/org/hibernate/loader/spi/NoOpLoadPlanAdvisor.java b/hibernate-core/src/main/java/org/hibernate/loader/spi/NoOpLoadPlanAdvisor.java new file mode 100644 index 0000000000..8769d6c6ee --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/loader/spi/NoOpLoadPlanAdvisor.java @@ -0,0 +1,38 @@ +/* + * 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.loader.spi; + +import org.hibernate.loader.plan.spi.LoadPlan; + +/** + * @author Steve Ebersole + */ +public class NoOpLoadPlanAdvisor implements LoadPlanAdvisor { + public static final NoOpLoadPlanAdvisor INSTANCE = new NoOpLoadPlanAdvisor(); + + @Override + public LoadPlan advise(LoadPlan loadPlan) { + return loadPlan; + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/loader/spi/ResultSetProcessor.java b/hibernate-core/src/main/java/org/hibernate/loader/spi/ResultSetProcessor.java index 89c439dc94..c6ee085646 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/spi/ResultSetProcessor.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/spi/ResultSetProcessor.java @@ -48,17 +48,20 @@ public interface ResultSetProcessor { * * Semi-copy of {@link org.hibernate.loader.Loader#doQuery}, with focus on just the ResultSet processing bit. * + * @param loadPlanAdvisor A dynamic advisor on the load plan. * @param resultSet The result set being processed. * @param session The originating session * @param queryParameters The "parameters" used to build the query * @param returnProxies Can proxies be returned (not the same as can they be created!) * @param forcedResultTransformer My old "friend" ResultTransformer... + * @param afterLoadActions Actions to be performed after loading an entity. * * @return The extracted results list. * * @throws java.sql.SQLException Indicates a problem access the JDBC ResultSet */ public List extractResults( + LoadPlanAdvisor loadPlanAdvisor, ResultSet resultSet, SessionImplementor session, QueryParameters queryParameters, diff --git a/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java b/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java index aaee057cb5..249c141061 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java @@ -96,9 +96,6 @@ import org.hibernate.loader.entity.CascadeEntityLoader; import org.hibernate.loader.entity.EntityLoader; import org.hibernate.loader.entity.UniqueEntityLoader; -import org.hibernate.loader.plan.internal.SingleRootReturnLoadPlanBuilderStrategy; -import org.hibernate.loader.plan.spi.LoadPlan; -import org.hibernate.loader.plan.spi.LoadPlanBuilder; import org.hibernate.mapping.Column; import org.hibernate.mapping.Component; import org.hibernate.mapping.PersistentClass; @@ -130,10 +127,6 @@ import org.hibernate.sql.SimpleSelect; import org.hibernate.sql.Template; import org.hibernate.sql.Update; -import org.hibernate.sql.ordering.antlr.ColumnMapper; -import org.hibernate.sql.ordering.antlr.ColumnReference; -import org.hibernate.sql.ordering.antlr.FormulaReference; -import org.hibernate.sql.ordering.antlr.SqlValueReference; import org.hibernate.tuple.entity.EntityMetamodel; import org.hibernate.tuple.entity.EntityTuplizer; import org.hibernate.type.AssociationType; diff --git a/hibernate-core/src/test/java/org/hibernate/loader/EntityAssociationResultSetProcessorTest.java b/hibernate-core/src/test/java/org/hibernate/loader/EntityAssociationResultSetProcessorTest.java index f8eb3a0bcc..9f7b2fbfaf 100644 --- a/hibernate-core/src/test/java/org/hibernate/loader/EntityAssociationResultSetProcessorTest.java +++ b/hibernate-core/src/test/java/org/hibernate/loader/EntityAssociationResultSetProcessorTest.java @@ -48,8 +48,9 @@ import org.hibernate.loader.internal.ResultSetProcessorImpl; import org.hibernate.loader.plan.internal.SingleRootReturnLoadPlanBuilderStrategy; import org.hibernate.loader.plan.spi.LoadPlan; -import org.hibernate.loader.plan.spi.LoadPlanBuilder; +import org.hibernate.loader.plan.spi.build.LoadPlanBuilder; import org.hibernate.loader.spi.NamedParameterContext; +import org.hibernate.loader.spi.NoOpLoadPlanAdvisor; import org.hibernate.persister.entity.EntityPersister; import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; import org.hibernate.testing.junit4.ExtraAssertions; @@ -114,6 +115,7 @@ public void execute(Connection connection) throws SQLException { ResultSet resultSet = ps.executeQuery(); results.addAll( resultSetProcessor.extractResults( + NoOpLoadPlanAdvisor.INSTANCE, resultSet, (SessionImplementor) workSession, new QueryParameters(), @@ -207,6 +209,7 @@ public void execute(Connection connection) throws SQLException { ResultSet resultSet = ps.executeQuery(); results.addAll( resultSetProcessor.extractResults( + NoOpLoadPlanAdvisor.INSTANCE, resultSet, (SessionImplementor) workSession, new QueryParameters(), diff --git a/hibernate-core/src/test/java/org/hibernate/loader/EntityWithCollectionResultSetProcessorTest.java b/hibernate-core/src/test/java/org/hibernate/loader/EntityWithCollectionResultSetProcessorTest.java index d83804e815..2edca22f3e 100644 --- a/hibernate-core/src/test/java/org/hibernate/loader/EntityWithCollectionResultSetProcessorTest.java +++ b/hibernate-core/src/test/java/org/hibernate/loader/EntityWithCollectionResultSetProcessorTest.java @@ -31,14 +31,10 @@ import java.util.HashSet; import java.util.List; import java.util.Set; -import javax.persistence.CascadeType; import javax.persistence.ElementCollection; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.Id; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToOne; -import javax.persistence.OneToMany; import org.junit.Test; @@ -47,14 +43,14 @@ import org.hibernate.engine.spi.LoadQueryInfluencers; import org.hibernate.engine.spi.QueryParameters; import org.hibernate.engine.spi.SessionImplementor; -import org.hibernate.internal.util.collections.IdentitySet; import org.hibernate.jdbc.Work; import org.hibernate.loader.internal.EntityLoadQueryBuilderImpl; import org.hibernate.loader.internal.ResultSetProcessorImpl; import org.hibernate.loader.plan.internal.SingleRootReturnLoadPlanBuilderStrategy; import org.hibernate.loader.plan.spi.LoadPlan; -import org.hibernate.loader.plan.spi.LoadPlanBuilder; +import org.hibernate.loader.plan.spi.build.LoadPlanBuilder; import org.hibernate.loader.spi.NamedParameterContext; +import org.hibernate.loader.spi.NoOpLoadPlanAdvisor; import org.hibernate.persister.entity.EntityPersister; import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; import org.hibernate.testing.junit4.ExtraAssertions; @@ -120,6 +116,7 @@ public void execute(Connection connection) throws SQLException { ResultSet resultSet = ps.executeQuery(); results.addAll( resultSetProcessor.extractResults( + NoOpLoadPlanAdvisor.INSTANCE, resultSet, (SessionImplementor) workSession, new QueryParameters(), diff --git a/hibernate-core/src/test/java/org/hibernate/loader/SimpleResultSetProcessorTest.java b/hibernate-core/src/test/java/org/hibernate/loader/SimpleResultSetProcessorTest.java index b420e0ec29..80e400f193 100644 --- a/hibernate-core/src/test/java/org/hibernate/loader/SimpleResultSetProcessorTest.java +++ b/hibernate-core/src/test/java/org/hibernate/loader/SimpleResultSetProcessorTest.java @@ -42,8 +42,9 @@ import org.hibernate.loader.internal.ResultSetProcessorImpl; import org.hibernate.loader.plan.internal.SingleRootReturnLoadPlanBuilderStrategy; import org.hibernate.loader.plan.spi.LoadPlan; -import org.hibernate.loader.plan.spi.LoadPlanBuilder; +import org.hibernate.loader.plan.spi.build.LoadPlanBuilder; import org.hibernate.loader.spi.NamedParameterContext; +import org.hibernate.loader.spi.NoOpLoadPlanAdvisor; import org.hibernate.persister.entity.EntityPersister; import org.junit.Test; @@ -104,6 +105,7 @@ public void execute(Connection connection) throws SQLException { ResultSet resultSet = ps.executeQuery(); results.addAll( resultSetProcessor.extractResults( + NoOpLoadPlanAdvisor.INSTANCE, resultSet, (SessionImplementor) workSession, new QueryParameters(), diff --git a/hibernate-core/src/test/java/org/hibernate/loader/plan/spi/LoadPlanBuilderTest.java b/hibernate-core/src/test/java/org/hibernate/loader/plan/spi/LoadPlanBuilderTest.java index 43d51cb3f4..01ce77bf65 100644 --- a/hibernate-core/src/test/java/org/hibernate/loader/plan/spi/LoadPlanBuilderTest.java +++ b/hibernate-core/src/test/java/org/hibernate/loader/plan/spi/LoadPlanBuilderTest.java @@ -36,6 +36,7 @@ import org.hibernate.loader.internal.EntityLoadQueryBuilderImpl; import org.hibernate.loader.plan.internal.CascadeLoadPlanBuilderStrategy; import org.hibernate.loader.plan.internal.SingleRootReturnLoadPlanBuilderStrategy; +import org.hibernate.loader.plan.spi.build.LoadPlanBuilder; import org.hibernate.loader.spi.LoadQueryBuilder; import org.hibernate.persister.collection.CollectionPersister; import org.hibernate.persister.entity.EntityPersister; diff --git a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/HibernateEntityManagerFactory.java b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/HibernateEntityManagerFactory.java index 15121228e0..0e9e5c36dd 100755 --- a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/HibernateEntityManagerFactory.java +++ b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/HibernateEntityManagerFactory.java @@ -27,6 +27,7 @@ import java.io.Serializable; import org.hibernate.SessionFactory; +import org.hibernate.jpa.internal.metamodel.EntityTypeImpl; /** * Contract giving access to the underlying {@link org.hibernate.SessionFactory} from an {@link javax.persistence.EntityManagerFactory} @@ -40,4 +41,6 @@ public interface HibernateEntityManagerFactory extends EntityManagerFactory, Ser * @return The underlying Hibernate SessionFactory */ public SessionFactory getSessionFactory(); + + public EntityTypeImpl getEntityTypeByName(String entityName); } diff --git a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/graph/GraphNode.java b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/graph/internal/AbstractGraphNode.java similarity index 87% rename from hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/graph/GraphNode.java rename to hibernate-entitymanager/src/main/java/org/hibernate/jpa/graph/internal/AbstractGraphNode.java index 30d4bdfd9b..16e240c3aa 100644 --- a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/graph/GraphNode.java +++ b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/graph/internal/AbstractGraphNode.java @@ -21,7 +21,7 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.jpa.internal.graph; +package org.hibernate.jpa.graph.internal; import javax.persistence.AttributeNode; import javax.persistence.Subgraph; @@ -36,24 +36,27 @@ import org.hibernate.internal.util.collections.CollectionHelper; import org.hibernate.jpa.HibernateEntityManagerFactory; +import org.hibernate.jpa.graph.spi.GraphNodeImplementor; /** + * Base class for EntityGraph and Subgraph implementations. + * * @author Steve Ebersole */ -public abstract class GraphNode { - private static final Logger log = Logger.getLogger( GraphNode.class ); +public abstract class AbstractGraphNode implements GraphNodeImplementor { + private static final Logger log = Logger.getLogger( AbstractGraphNode.class ); private final HibernateEntityManagerFactory entityManagerFactory; private final boolean mutable; private Map> attributeNodeMap; - protected GraphNode(HibernateEntityManagerFactory entityManagerFactory, boolean mutable) { + protected AbstractGraphNode(HibernateEntityManagerFactory entityManagerFactory, boolean mutable) { this.entityManagerFactory = entityManagerFactory; this.mutable = mutable; } - protected GraphNode(GraphNode original, boolean mutable) { + protected AbstractGraphNode(AbstractGraphNode original, boolean mutable) { this.entityManagerFactory = original.entityManagerFactory; this.mutable = mutable; this.attributeNodeMap = makeSafeMapCopy( original.attributeNodeMap ); @@ -75,11 +78,13 @@ private static Map> makeSafeMapCopy(Map> attributeNodes() { + @Override + public List> attributeNodes() { if ( attributeNodeMap == null ) { return Collections.emptyList(); } @@ -105,8 +110,8 @@ private AttributeNodeImpl buildAttributeNode(String attributeName) { protected abstract Attribute resolveAttribute(String attributeName); - protected AttributeNodeImpl buildAttributeNode(Attribute attribute) { - return new AttributeNodeImpl( entityManagerFactory, attribute ); + protected AttributeNodeImpl buildAttributeNode(Attribute attribute) { + return new AttributeNodeImpl( entityManagerFactory, attribute ); } protected AttributeNodeImpl addAttributeNode(AttributeNodeImpl attributeNode) { diff --git a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/graph/AttributeNodeImpl.java b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/graph/internal/AttributeNodeImpl.java similarity index 91% rename from hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/graph/AttributeNodeImpl.java rename to hibernate-entitymanager/src/main/java/org/hibernate/jpa/graph/internal/AttributeNodeImpl.java index 90ec5ea2ff..55584cb426 100644 --- a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/graph/AttributeNodeImpl.java +++ b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/graph/internal/AttributeNodeImpl.java @@ -21,7 +21,7 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.jpa.internal.graph; +package org.hibernate.jpa.graph.internal; import javax.persistence.AttributeNode; import javax.persistence.Subgraph; @@ -34,6 +34,7 @@ import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.internal.util.collections.CollectionHelper; import org.hibernate.jpa.HibernateEntityManagerFactory; +import org.hibernate.jpa.graph.spi.AttributeNodeImplementor; import org.hibernate.jpa.internal.metamodel.Helper; import org.hibernate.jpa.internal.metamodel.PluralAttributeImpl; import org.hibernate.persister.collection.QueryableCollection; @@ -47,14 +48,14 @@ * * @author Steve Ebersole */ -public class AttributeNodeImpl implements AttributeNode { +public class AttributeNodeImpl implements AttributeNode, AttributeNodeImplementor { private final HibernateEntityManagerFactory entityManagerFactory; - private final Attribute attribute; + private final Attribute attribute; private Map subgraphMap; private Map keySubgraphMap; - public AttributeNodeImpl(HibernateEntityManagerFactory entityManagerFactory, Attribute attribute) { + public AttributeNodeImpl(HibernateEntityManagerFactory entityManagerFactory, Attribute attribute) { this.entityManagerFactory = entityManagerFactory; this.attribute = attribute; } @@ -64,7 +65,7 @@ public AttributeNodeImpl(HibernateEntityManagerFactory entityManagerFactory, Att */ private AttributeNodeImpl( HibernateEntityManagerFactory entityManagerFactory, - Attribute attribute, + Attribute attribute, Map subgraphMap, Map keySubgraphMap) { this.entityManagerFactory = entityManagerFactory; @@ -73,11 +74,17 @@ private AttributeNodeImpl( this.keySubgraphMap = keySubgraphMap; } - private SessionFactoryImplementor sessionFactory() { - return (SessionFactoryImplementor) entityManagerFactory.getSessionFactory(); + @Override + public HibernateEntityManagerFactory entityManagerFactory() { + return entityManagerFactory; } - public Attribute getAttribute() { + private SessionFactoryImplementor sessionFactory() { + return (SessionFactoryImplementor) entityManagerFactory().getSessionFactory(); + } + + @Override + public Attribute getAttribute() { return attribute; } @@ -102,11 +109,15 @@ public Map getKeySubgraphs() { @SuppressWarnings("unchecked") public Subgraph makeSubgraph() { - return (Subgraph) makeSubgraph( null ); + return (Subgraph) internalMakeSubgraph( null ); } @SuppressWarnings("unchecked") public Subgraph makeSubgraph(Class type) { + return (Subgraph) internalMakeSubgraph( type ); + } + + private Subgraph internalMakeSubgraph(Class type) { if ( attribute.getPersistentAttributeType() == Attribute.PersistentAttributeType.BASIC || attribute.getPersistentAttributeType() == Attribute.PersistentAttributeType.EMBEDDED ) { throw new IllegalArgumentException( @@ -239,7 +250,8 @@ public Subgraph makeKeySubgraph(Class type) { return subgraph; } - AttributeNodeImpl makeImmutableCopy() { + @Override + public AttributeNodeImpl makeImmutableCopy() { return new AttributeNodeImpl( this.entityManagerFactory, this.attribute, diff --git a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/graph/EntityGraphImpl.java b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/graph/internal/EntityGraphImpl.java similarity index 92% rename from hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/graph/EntityGraphImpl.java rename to hibernate-entitymanager/src/main/java/org/hibernate/jpa/graph/internal/EntityGraphImpl.java index afbf92cbe0..4189b9144d 100644 --- a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/graph/EntityGraphImpl.java +++ b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/graph/internal/EntityGraphImpl.java @@ -21,7 +21,7 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.jpa.internal.graph; +package org.hibernate.jpa.graph.internal; import javax.persistence.AttributeNode; import javax.persistence.EntityGraph; @@ -39,7 +39,7 @@ * * @author Steve Ebersole */ -public class EntityGraphImpl extends GraphNode implements EntityGraph { +public class EntityGraphImpl extends AbstractGraphNode implements EntityGraph { private final String name; private final EntityType entityType; @@ -63,6 +63,10 @@ private EntityGraphImpl(String name, EntityGraphImpl original, boolean mutabl this.entityType = original.entityType; } + public EntityType getEntityType() { + return entityType; + } + @Override public String getName() { return name; @@ -144,6 +148,11 @@ protected Attribute resolveAttribute(String attributeName) { return attribute; } + @SuppressWarnings("unchecked") + public boolean appliesTo(String entityName) { + return appliesTo( entityManagerFactory().getEntityTypeByName( entityName ) ); + } + public boolean appliesTo(EntityType entityType) { if ( this.entityType.equals( entityType ) ) { return true; diff --git a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/graph/SubgraphImpl.java b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/graph/internal/SubgraphImpl.java similarity index 96% rename from hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/graph/SubgraphImpl.java rename to hibernate-entitymanager/src/main/java/org/hibernate/jpa/graph/internal/SubgraphImpl.java index 0564355cd1..1f206ff32f 100644 --- a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/graph/SubgraphImpl.java +++ b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/graph/internal/SubgraphImpl.java @@ -21,7 +21,7 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.jpa.internal.graph; +package org.hibernate.jpa.graph.internal; import javax.persistence.AttributeNode; import javax.persistence.Subgraph; @@ -34,7 +34,7 @@ /** * @author Steve Ebersole */ -public class SubgraphImpl extends GraphNode implements Subgraph { +public class SubgraphImpl extends AbstractGraphNode implements Subgraph { private final ManagedType managedType; private final Class subclass; diff --git a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/graph/package-info.java b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/graph/package-info.java new file mode 100644 index 0000000000..0328c34949 --- /dev/null +++ b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/graph/package-info.java @@ -0,0 +1,5 @@ +/** + * Definition of the Hibernate support for the JPA {@link javax.persistence.EntityGraph} feature-set + * introduced in JPA 2.1 + */ +package org.hibernate.jpa.graph; diff --git a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/graph/spi/AttributeNodeImplementor.java b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/graph/spi/AttributeNodeImplementor.java new file mode 100644 index 0000000000..81079fd466 --- /dev/null +++ b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/graph/spi/AttributeNodeImplementor.java @@ -0,0 +1,39 @@ +/* + * 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.jpa.graph.spi; + +import javax.persistence.metamodel.Attribute; + +import org.hibernate.jpa.HibernateEntityManagerFactory; + +/** + * @author Steve Ebersole + */ +public interface AttributeNodeImplementor { + public HibernateEntityManagerFactory entityManagerFactory(); + + public Attribute getAttribute(); + + public AttributeNodeImplementor makeImmutableCopy(); +} diff --git a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/graph/spi/EntityGraphBasedLoadPlanAdvisor.java b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/graph/spi/EntityGraphBasedLoadPlanAdvisor.java new file mode 100644 index 0000000000..55d5f2aa36 --- /dev/null +++ b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/graph/spi/EntityGraphBasedLoadPlanAdvisor.java @@ -0,0 +1,107 @@ +/* + * 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.jpa.graph.spi; + +import java.util.List; + +import org.jboss.logging.Logger; + +import org.hibernate.jpa.graph.internal.EntityGraphImpl; +import org.hibernate.loader.plan.spi.EntityReturn; +import org.hibernate.loader.plan.spi.LoadPlan; +import org.hibernate.loader.plan.spi.Return; +import org.hibernate.loader.spi.LoadPlanAdvisor; + +/** + * @author Steve Ebersole + */ +public class EntityGraphBasedLoadPlanAdvisor implements LoadPlanAdvisor { + private static final Logger log = Logger.getLogger( EntityGraphBasedLoadPlanAdvisor.class ); + + private final EntityGraphImpl root; + + public EntityGraphBasedLoadPlanAdvisor(EntityGraphImpl root) { + if ( root == null ) { + throw new IllegalArgumentException( "EntityGraph cannot be null" ); + } + this.root = root; + } + + public LoadPlan advise(LoadPlan loadPlan) { + if ( root == null ) { + log.debug( "Skipping load plan advising: no entity graph was specified" ); + } + else { + // for now, lets assume that the graph and the load-plan returns have to match up + EntityReturn entityReturn = findRootEntityReturn( loadPlan ); + if ( entityReturn == null ) { + log.debug( "Skipping load plan advising: not able to find appropriate root entity return in load plan" ); + } + else { + final String entityName = entityReturn.getEntityPersister().getEntityName(); + if ( ! root.appliesTo( entityName ) ) { + log.debugf( + "Skipping load plan advising: entity types did not match : [%s] and [%s]", + root.getEntityType().getName(), + entityName + ); + } + else { + // ok to apply the advice + return applyAdvice( entityReturn ); + } + } + } + + // return the original load-plan + return loadPlan; + } + + private LoadPlan applyAdvice(final EntityReturn entityReturn) { +// final EntityReturn copy = entityReturn.makeCopy( ) + return null; + } + + private EntityReturn findRootEntityReturn(LoadPlan loadPlan) { + EntityReturn rootEntityReturn = null; + for ( Return rtn : loadPlan.getReturns() ) { + if ( ! EntityReturn.class.isInstance( rtn ) ) { + continue; + } + + if ( rootEntityReturn != null ) { + log.debug( "Multiple EntityReturns were found" ); + return null; + } + + rootEntityReturn = (EntityReturn) rtn; + } + + if ( rootEntityReturn == null ) { + log.debug( "Unable to find root entity return in load plan" ); + } + + return rootEntityReturn; + } +} diff --git a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/graph/spi/GraphNodeImplementor.java b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/graph/spi/GraphNodeImplementor.java new file mode 100644 index 0000000000..d93a86753e --- /dev/null +++ b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/graph/spi/GraphNodeImplementor.java @@ -0,0 +1,39 @@ +/* + * 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.jpa.graph.spi; + +import javax.persistence.AttributeNode; +import java.util.List; + +import org.hibernate.jpa.HibernateEntityManagerFactory; + +/** + * Extended contract for a "graph node" (entity-graph or sub-graph). + * + * @author Steve Ebersole + */ +public interface GraphNodeImplementor { + public HibernateEntityManagerFactory entityManagerFactory(); + public List> attributeNodes(); +} diff --git a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/EntityManagerFactoryImpl.java b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/EntityManagerFactoryImpl.java index fa0a1fcaab..a94c3228aa 100755 --- a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/EntityManagerFactoryImpl.java +++ b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/EntityManagerFactoryImpl.java @@ -34,7 +34,6 @@ import javax.persistence.SynchronizationType; import javax.persistence.criteria.CriteriaBuilder; import javax.persistence.metamodel.EntityType; -import javax.persistence.metamodel.ManagedType; import javax.persistence.metamodel.Metamodel; import javax.persistence.spi.LoadState; import javax.persistence.spi.PersistenceUnitTransactionType; @@ -70,7 +69,8 @@ import org.hibernate.jpa.HibernateQuery; import org.hibernate.jpa.boot.internal.SettingsImpl; import org.hibernate.jpa.criteria.CriteriaBuilderImpl; -import org.hibernate.jpa.internal.graph.EntityGraphImpl; +import org.hibernate.jpa.graph.internal.EntityGraphImpl; +import org.hibernate.jpa.internal.metamodel.EntityTypeImpl; import org.hibernate.jpa.internal.metamodel.MetamodelImpl; import org.hibernate.jpa.internal.util.PersistenceUtilHelper; import org.hibernate.mapping.PersistentClass; @@ -95,7 +95,7 @@ public class EntityManagerFactoryImpl implements HibernateEntityManagerFactory { private final transient boolean discardOnClose; private final transient Class sessionInterceptorClass; private final transient CriteriaBuilderImpl criteriaBuilder; - private final transient Metamodel metamodel; + private final transient MetamodelImpl metamodel; private final transient HibernatePersistenceUnitUtil util; private final transient Map properties; private final String entityManagerFactoryName; @@ -388,6 +388,15 @@ public SessionFactoryImpl getSessionFactory() { return sessionFactory; } + @Override + public EntityTypeImpl getEntityTypeByName(String entityName) { + final EntityTypeImpl entityType = metamodel.getEntityTypeByName( entityName ); + if ( entityType == null ) { + throw new IllegalArgumentException( "[" + entityName + "] did not refer to EntityType" ); + } + return entityType; + } + public String getEntityManagerFactoryName() { return entityManagerFactoryName; } diff --git a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/EntityManagerImpl.java b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/EntityManagerImpl.java index 96808f6a54..ecea98b71d 100755 --- a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/EntityManagerImpl.java +++ b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/EntityManagerImpl.java @@ -42,7 +42,7 @@ import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.engine.spi.SessionOwner; import org.hibernate.jpa.AvailableSettings; -import org.hibernate.jpa.internal.graph.EntityGraphImpl; +import org.hibernate.jpa.graph.internal.EntityGraphImpl; /** * Hibernate implementation of {@link javax.persistence.EntityManager}. diff --git a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/metamodel/MetamodelImpl.java b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/metamodel/MetamodelImpl.java index 5306889b97..6a7a5516a3 100755 --- a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/metamodel/MetamodelImpl.java +++ b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/internal/metamodel/MetamodelImpl.java @@ -229,4 +229,8 @@ public Set> getEntities() { public Set> getEmbeddables() { return new HashSet>( embeddables.values() ); } + + public EntityTypeImpl getEntityTypeByName(String entityName) { + return entityTypesByEntityName.get( entityName ); + } } From 4796553a3f44e2263f7af245a94e4bebd2d43680 Mon Sep 17 00:00:00 2001 From: Kristoffer Lundberg Date: Thu, 11 Apr 2013 20:10:10 +0200 Subject: [PATCH 53/54] HHH-8171 - SETORDINAL to support set of embeddables --- .../main/docbook/devguide/en-US/Envers.xml | 11 +++++ .../envers/configuration/EnversSettings.java | 5 +++ .../internal/AuditEntitiesConfiguration.java | 9 ++++ .../metadata/CollectionMetadataGenerator.java | 36 +++++++++++----- .../relation/AbstractCollectionMapper.java | 37 ++++++++++++++-- .../relation/BasicCollectionMapper.java | 8 ++-- .../mapper/relation/ListCollectionMapper.java | 2 +- .../mapper/relation/MapCollectionMapper.java | 2 +- .../relation/SortedSetCollectionMapper.java | 9 ++-- .../collection/embeddable/EmbeddableSet.java | 42 ++++++++++++++++--- 10 files changed, 132 insertions(+), 29 deletions(-) diff --git a/documentation/src/main/docbook/devguide/en-US/Envers.xml b/documentation/src/main/docbook/devguide/en-US/Envers.xml index 1e03a0d1f7..ccc4ef9a78 100644 --- a/documentation/src/main/docbook/devguide/en-US/Envers.xml +++ b/documentation/src/main/docbook/devguide/en-US/Envers.xml @@ -315,6 +315,17 @@ For example: a property called "age", will by default get modified flag with column name "age_MOD". + + + org.hibernate.envers.embeddable_set_ordinal_field_name + + + SETORDINAL + + + The name of the column used for storing the ordinal of the change in sets of embeddables. + + diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/configuration/EnversSettings.java b/hibernate-envers/src/main/java/org/hibernate/envers/configuration/EnversSettings.java index 8b8d889156..4db8f4b6a4 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/configuration/EnversSettings.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/configuration/EnversSettings.java @@ -99,4 +99,9 @@ public interface EnversSettings { * Defaults to {@literal REVEND_TSTMP}. */ public static final String AUDIT_STRATEGY_VALIDITY_REVEND_TIMESTAMP_FIELD_NAME = "org.hibernate.envers.audit_strategy_validity_revend_timestamp_field_name"; + + /** + * The name of the column used for storing the ordinal of the change in sets of embeddables. Defaults to {@literal SETORDINAL}. + */ + public static final String EMBEDDABLE_SET_ORDINAL_FIELD_NAME = "org.hibernate.envers.embeddable_set_ordinal_field_name"; } diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/AuditEntitiesConfiguration.java b/hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/AuditEntitiesConfiguration.java index ac8ca6d5f6..39ea2d7e05 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/AuditEntitiesConfiguration.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/AuditEntitiesConfiguration.java @@ -59,6 +59,8 @@ public class AuditEntitiesConfiguration { private final boolean revisionEndTimestampEnabled; private final String revisionEndTimestampFieldName; + + private final String embeddableSetOrdinalPropertyName; public AuditEntitiesConfiguration(Properties properties, String revisionInfoEntityName) { this.revisionInfoEntityName = revisionInfoEntityName; @@ -100,6 +102,9 @@ public AuditEntitiesConfiguration(Properties properties, String revisionInfoEnti revisionNumberPath = originalIdPropName + "." + revisionFieldName + ".id"; revisionPropBasePath = originalIdPropName + "." + revisionFieldName + "."; + + embeddableSetOrdinalPropertyName = ConfigurationHelper.getString( + EnversSettings.EMBEDDABLE_SET_ORDINAL_FIELD_NAME, properties, "SETORDINAL" ); } public String getOriginalIdPropName() { @@ -167,4 +172,8 @@ public String getAuditStrategyName() { public String getRevisionEndFieldName() { return revisionEndFieldName; } + + public String getEmbeddableSetOrdinalPropertyName() { + return embeddableSetOrdinalPropertyName; + } } diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/metadata/CollectionMetadataGenerator.java b/hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/metadata/CollectionMetadataGenerator.java index ef2f1ccfd5..9ded90137c 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/metadata/CollectionMetadataGenerator.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/metadata/CollectionMetadataGenerator.java @@ -88,6 +88,7 @@ import org.hibernate.mapping.OneToMany; import org.hibernate.mapping.PersistentClass; import org.hibernate.mapping.Property; +import org.hibernate.mapping.SimpleValue; import org.hibernate.mapping.Table; import org.hibernate.mapping.Value; import org.hibernate.type.BagType; @@ -506,6 +507,22 @@ private MiddleComponentData addValueToMiddleTable(Value value, Element xmlMappin ); } + // Add an additional column holding a number to make each entry unique within the set, + // since embeddable properties can be null + if ( propertyValue.getCollectionType() instanceof SetType ) { + final String auditedEmbeddableSetOrdinalPropertyName = mainGenerator.getVerEntCfg() + .getEmbeddableSetOrdinalPropertyName(); + final String auditedEmbeddableSetOrdinalPropertyType = "integer"; + + final SimpleValue simpleValue = new SimpleValue( component.getMappings(), component.getTable() ); + simpleValue.setTypeName( auditedEmbeddableSetOrdinalPropertyType ); + + final Element idProperty = MetadataTools.addProperty( xmlMapping, + auditedEmbeddableSetOrdinalPropertyName, auditedEmbeddableSetOrdinalPropertyType, true, true ); + MetadataTools.addColumn( idProperty, auditedEmbeddableSetOrdinalPropertyName, null, 0, 0, null, null, + null, false ); + } + return new MiddleComponentData( componentMapper, 0 ); } else { // Last but one parameter: collection components are always insertable @@ -529,14 +546,13 @@ private void addMapper(CommonCollectionMapperData commonCollectionMapperData, Mi Type type = propertyValue.getType(); boolean embeddableElementType = isEmbeddableElementType(); if (type instanceof SortedSetType) { - currentMapper.addComposite(propertyAuditingData.getPropertyData(), - new SortedSetCollectionMapper(commonCollectionMapperData, - TreeSet.class, SortedSetProxy.class, elementComponentData, propertyValue.getComparator(), - embeddableElementType)); + currentMapper.addComposite( propertyAuditingData.getPropertyData(), new SortedSetCollectionMapper( + commonCollectionMapperData, TreeSet.class, SortedSetProxy.class, elementComponentData, + propertyValue.getComparator(), embeddableElementType, embeddableElementType ) ); } else if (type instanceof SetType) { - currentMapper.addComposite(propertyAuditingData.getPropertyData(), - new BasicCollectionMapper(commonCollectionMapperData, - HashSet.class, SetProxy.class, elementComponentData, embeddableElementType)); + currentMapper.addComposite( propertyAuditingData.getPropertyData(), new BasicCollectionMapper( + commonCollectionMapperData, HashSet.class, SetProxy.class, elementComponentData, + embeddableElementType, embeddableElementType ) ); } else if (type instanceof SortedMapType) { // Indexed collection, so indexComponentData is not null. currentMapper.addComposite(propertyAuditingData.getPropertyData(), @@ -549,9 +565,9 @@ private void addMapper(CommonCollectionMapperData commonCollectionMapperData, Mi new MapCollectionMapper(commonCollectionMapperData, HashMap.class, MapProxy.class, elementComponentData, indexComponentData, embeddableElementType)); } else if (type instanceof BagType) { - currentMapper.addComposite(propertyAuditingData.getPropertyData(), - new BasicCollectionMapper(commonCollectionMapperData, - ArrayList.class, ListProxy.class, elementComponentData, embeddableElementType)); + currentMapper.addComposite( propertyAuditingData.getPropertyData(), new BasicCollectionMapper( + commonCollectionMapperData, ArrayList.class, ListProxy.class, elementComponentData, + embeddableElementType, embeddableElementType ) ); } else if (type instanceof ListType) { // Indexed collection, so indexComponentData is not null. currentMapper.addComposite(propertyAuditingData.getPropertyData(), diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/AbstractCollectionMapper.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/AbstractCollectionMapper.java index 8fa96a4113..c7e125fe35 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/AbstractCollectionMapper.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/AbstractCollectionMapper.java @@ -55,15 +55,17 @@ public abstract class AbstractCollectionMapper implements PropertyMapper { protected final CommonCollectionMapperData commonCollectionMapperData; protected final Class collectionClass; + protected final boolean ordinalInId; protected final boolean revisionTypeInId; private final Constructor proxyConstructor; - protected AbstractCollectionMapper(CommonCollectionMapperData commonCollectionMapperData, - Class collectionClass, Class proxyClass, - boolean revisionTypeInId) { + protected AbstractCollectionMapper(CommonCollectionMapperData commonCollectionMapperData, + Class collectionClass, Class proxyClass, boolean ordinalInId, + boolean revisionTypeInId) { this.commonCollectionMapperData = commonCollectionMapperData; this.collectionClass = collectionClass; + this.ordinalInId = ordinalInId; this.revisionTypeInId = revisionTypeInId; try { @@ -84,11 +86,38 @@ protected AbstractCollectionMapper(CommonCollectionMapperData commonCollectionMa */ protected abstract void mapToMapFromObject(SessionImplementor session, Map idData, Map data, Object changed); + /** + * Creates a Map for the id. + * + *

      + * The ordinal parameter represents the iteration ordinal of the current element, used to add a synthetic id when + * dealing with embeddables since embeddable fields can't be contained within the primary key since they might be + * nullable. + *

      + * + * @param ordinal + * The element iteration ordinal. + * + * @return A Map for holding the ID information. + */ + protected Map createIdMap(int ordinal) { + final HashMap idMap = new HashMap(); + + if ( ordinalInId ) { + idMap.put( this.commonCollectionMapperData.getVerEntCfg().getEmbeddableSetOrdinalPropertyName(), + Integer.valueOf( ordinal ) ); + } + + return idMap; + } + private void addCollectionChanges(SessionImplementor session, List collectionChanges, Set changed, RevisionType revisionType, Serializable id) { + int ordinal = 0; + for (Object changedObj : changed) { Map entityData = new HashMap(); - Map originalId = new HashMap(); + Map originalId = createIdMap( ordinal++ ); entityData.put(commonCollectionMapperData.getVerEntCfg().getOriginalIdPropName(), originalId); collectionChanges.add(new PersistentCollectionChangeData( diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/BasicCollectionMapper.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/BasicCollectionMapper.java index 49a2db0ed9..7de41ea043 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/BasicCollectionMapper.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/BasicCollectionMapper.java @@ -41,10 +41,10 @@ public class BasicCollectionMapper extends AbstractCollectionMapper implements PropertyMapper { protected final MiddleComponentData elementComponentData; - public BasicCollectionMapper(CommonCollectionMapperData commonCollectionMapperData, - Class collectionClass, Class proxyClass, - MiddleComponentData elementComponentData, boolean revisionTypeInId) { - super(commonCollectionMapperData, collectionClass, proxyClass, revisionTypeInId); + public BasicCollectionMapper(CommonCollectionMapperData commonCollectionMapperData, + Class collectionClass, Class proxyClass, + MiddleComponentData elementComponentData, boolean ordinalInId, boolean revisionTypeInId) { + super( commonCollectionMapperData, collectionClass, proxyClass, ordinalInId, revisionTypeInId ); this.elementComponentData = elementComponentData; } diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/ListCollectionMapper.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/ListCollectionMapper.java index 26d6ce3398..112077117d 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/ListCollectionMapper.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/ListCollectionMapper.java @@ -49,7 +49,7 @@ public final class ListCollectionMapper extends AbstractCollectionMapper i public ListCollectionMapper(CommonCollectionMapperData commonCollectionMapperData, MiddleComponentData elementComponentData, MiddleComponentData indexComponentData, boolean revisionTypeInId) { - super(commonCollectionMapperData, List.class, ListProxy.class, revisionTypeInId); + super( commonCollectionMapperData, List.class, ListProxy.class, false, revisionTypeInId ); this.elementComponentData = elementComponentData; this.indexComponentData = indexComponentData; } diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/MapCollectionMapper.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/MapCollectionMapper.java index a2f6d46ea4..ae8a90bb0c 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/MapCollectionMapper.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/MapCollectionMapper.java @@ -46,7 +46,7 @@ public MapCollectionMapper(CommonCollectionMapperData commonCollectionMapperData Class collectionClass, Class proxyClass, MiddleComponentData elementComponentData, MiddleComponentData indexComponentData, boolean revisionTypeInId) { - super(commonCollectionMapperData, collectionClass, proxyClass, revisionTypeInId); + super( commonCollectionMapperData, collectionClass, proxyClass, false, revisionTypeInId ); this.elementComponentData = elementComponentData; this.indexComponentData = indexComponentData; } diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/SortedSetCollectionMapper.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/SortedSetCollectionMapper.java index 66efdf3736..e37bd744f6 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/SortedSetCollectionMapper.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/SortedSetCollectionMapper.java @@ -38,10 +38,11 @@ public final class SortedSetCollectionMapper extends BasicCollectionMapper collectionClass, Class proxyClass, - MiddleComponentData elementComponentData, Comparator comparator, - boolean revisionTypeInId) { - super(commonCollectionMapperData, collectionClass, proxyClass, elementComponentData, revisionTypeInId); + Class collectionClass, Class proxyClass, + MiddleComponentData elementComponentData, Comparator comparator, boolean ordinalInId, + boolean revisionTypeInId) { + super( commonCollectionMapperData, collectionClass, proxyClass, elementComponentData, ordinalInId, + revisionTypeInId ); this.comparator = comparator; } diff --git a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/collection/embeddable/EmbeddableSet.java b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/collection/embeddable/EmbeddableSet.java index 32c93332db..a41ae215c7 100644 --- a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/collection/embeddable/EmbeddableSet.java +++ b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/collection/embeddable/EmbeddableSet.java @@ -50,6 +50,8 @@ public class EmbeddableSet extends BaseEnversJPAFunctionalTestCase { private final Component4 c4_2 = new Component4( "c42", "c42_value2", "c42_description" ); private final Component3 c3_1 = new Component3( "c31", c4_1, c4_2 ); private final Component3 c3_2 = new Component3( "c32", c4_1, c4_2 ); + private final Component3 c3_3 = new Component3( "c33", c4_1, c4_2 ); + private final Component3 c3_4 = new Component3( "c34", c4_1, c4_2 ); @Override protected Class[] getAnnotatedClasses() { @@ -63,9 +65,10 @@ public void initData() { EmbeddableSetEntity ese1 = new EmbeddableSetEntity(); - // Revision 1 (ese1: initially 1 element in both collections) + // Revision 1 (ese1: initially 2 elements) em.getTransaction().begin(); ese1.getComponentSet().add( c3_1 ); + ese1.getComponentSet().add( c3_3 ); em.persist( ese1 ); em.getTransaction().commit(); @@ -93,6 +96,29 @@ public void initData() { ese1.getComponentSet().remove( c3_2 ); em.getTransaction().commit(); + // Revision 5 (ese1: adding two elements) + em.getTransaction().begin(); + ese1 = em.find( EmbeddableSetEntity.class, ese1.getId() ); + ese1.getComponentSet().add( c3_2 ); + ese1.getComponentSet().add( c3_4 ); + em.getTransaction().commit(); + + // Revision 6 (ese1: removing two elements) + em.getTransaction().begin(); + ese1 = em.find( EmbeddableSetEntity.class, ese1.getId() ); + ese1.getComponentSet().remove( c3_2 ); + ese1.getComponentSet().remove( c3_4 ); + em.getTransaction().commit(); + + // Revision 7 (ese1: removing and adding two elements) + em.getTransaction().begin(); + ese1 = em.find( EmbeddableSetEntity.class, ese1.getId() ); + ese1.getComponentSet().remove( c3_1 ); + ese1.getComponentSet().remove( c3_3 ); + ese1.getComponentSet().add( c3_2 ); + ese1.getComponentSet().add( c3_4 ); + em.getTransaction().commit(); + ese1_id = ese1.getId(); em.close(); @@ -100,7 +126,7 @@ public void initData() { @Test public void testRevisionsCounts() { - assertEquals( Arrays.asList( 1, 2, 3 ), getAuditReader().getRevisions( EmbeddableSetEntity.class, ese1_id ) ); + assertEquals( Arrays.asList( 1, 2, 3, 4, 5, 6 ), getAuditReader().getRevisions( EmbeddableSetEntity.class, ese1_id ) ); } @Test @@ -108,9 +134,15 @@ public void testHistoryOfEse1() { EmbeddableSetEntity rev1 = getAuditReader().find( EmbeddableSetEntity.class, ese1_id, 1 ); EmbeddableSetEntity rev2 = getAuditReader().find( EmbeddableSetEntity.class, ese1_id, 2 ); EmbeddableSetEntity rev3 = getAuditReader().find( EmbeddableSetEntity.class, ese1_id, 3 ); + EmbeddableSetEntity rev4 = getAuditReader().find( EmbeddableSetEntity.class, ese1_id, 4 ); + EmbeddableSetEntity rev5 = getAuditReader().find( EmbeddableSetEntity.class, ese1_id, 5 ); + EmbeddableSetEntity rev6 = getAuditReader().find( EmbeddableSetEntity.class, ese1_id, 6 ); - assertEquals( Collections.singleton( c3_1 ), rev1.getComponentSet() ); - assertEquals( TestTools.makeSet( c3_1, c3_2 ), rev2.getComponentSet() ); - assertEquals( TestTools.makeSet( c3_1 ), rev3.getComponentSet() ); + assertEquals( TestTools.makeSet( c3_1, c3_3 ), rev1.getComponentSet() ); + assertEquals( TestTools.makeSet( c3_1, c3_2, c3_3 ), rev2.getComponentSet() ); + assertEquals( TestTools.makeSet( c3_1, c3_3 ), rev3.getComponentSet() ); + assertEquals( TestTools.makeSet( c3_1, c3_2, c3_3, c3_4 ), rev4.getComponentSet() ); + assertEquals( TestTools.makeSet( c3_1, c3_3 ), rev5.getComponentSet() ); + assertEquals( TestTools.makeSet( c3_2, c3_4 ), rev6.getComponentSet() ); } } \ No newline at end of file From f2b9ab8278aa724a5be6ce612c2699f17bb79c9c Mon Sep 17 00:00:00 2001 From: Lukasz Antoniak Date: Sun, 14 Apr 2013 22:25:46 +0200 Subject: [PATCH 54/54] HHH-8171 - Cleanup --- .../main/docbook/devguide/en-US/Envers.xml | 2 +- .../envers/configuration/EnversSettings.java | 2 +- .../internal/AuditEntitiesConfiguration.java | 3 ++- .../metadata/CollectionMetadataGenerator.java | 25 ++++++++----------- .../relation/AbstractCollectionMapper.java | 23 +++++------------ .../relation/SortedSetCollectionMapper.java | 3 +-- .../collection/embeddable/EmbeddableSet.java | 23 +++++++++++------ 7 files changed, 36 insertions(+), 45 deletions(-) diff --git a/documentation/src/main/docbook/devguide/en-US/Envers.xml b/documentation/src/main/docbook/devguide/en-US/Envers.xml index ccc4ef9a78..acdba3762c 100644 --- a/documentation/src/main/docbook/devguide/en-US/Envers.xml +++ b/documentation/src/main/docbook/devguide/en-US/Envers.xml @@ -323,7 +323,7 @@ SETORDINAL - The name of the column used for storing the ordinal of the change in sets of embeddables. + Name of column used for storing ordinal of the change in sets of embeddable elements. diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/configuration/EnversSettings.java b/hibernate-envers/src/main/java/org/hibernate/envers/configuration/EnversSettings.java index 4db8f4b6a4..a2eb5c7e76 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/configuration/EnversSettings.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/configuration/EnversSettings.java @@ -101,7 +101,7 @@ public interface EnversSettings { public static final String AUDIT_STRATEGY_VALIDITY_REVEND_TIMESTAMP_FIELD_NAME = "org.hibernate.envers.audit_strategy_validity_revend_timestamp_field_name"; /** - * The name of the column used for storing the ordinal of the change in sets of embeddables. Defaults to {@literal SETORDINAL}. + * Name of column used for storing ordinal of the change in sets of embeddable elements. Defaults to {@literal SETORDINAL}. */ public static final String EMBEDDABLE_SET_ORDINAL_FIELD_NAME = "org.hibernate.envers.embeddable_set_ordinal_field_name"; } diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/AuditEntitiesConfiguration.java b/hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/AuditEntitiesConfiguration.java index 39ea2d7e05..1460ec3b4a 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/AuditEntitiesConfiguration.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/AuditEntitiesConfiguration.java @@ -104,7 +104,8 @@ public AuditEntitiesConfiguration(Properties properties, String revisionInfoEnti revisionPropBasePath = originalIdPropName + "." + revisionFieldName + "."; embeddableSetOrdinalPropertyName = ConfigurationHelper.getString( - EnversSettings.EMBEDDABLE_SET_ORDINAL_FIELD_NAME, properties, "SETORDINAL" ); + EnversSettings.EMBEDDABLE_SET_ORDINAL_FIELD_NAME, properties, "SETORDINAL" + ); } public String getOriginalIdPropName() { diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/metadata/CollectionMetadataGenerator.java b/hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/metadata/CollectionMetadataGenerator.java index 9ded90137c..8ed1b9db3f 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/metadata/CollectionMetadataGenerator.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/configuration/internal/metadata/CollectionMetadataGenerator.java @@ -88,7 +88,6 @@ import org.hibernate.mapping.OneToMany; import org.hibernate.mapping.PersistentClass; import org.hibernate.mapping.Property; -import org.hibernate.mapping.SimpleValue; import org.hibernate.mapping.Table; import org.hibernate.mapping.Value; import org.hibernate.type.BagType; @@ -507,20 +506,16 @@ private MiddleComponentData addValueToMiddleTable(Value value, Element xmlMappin ); } - // Add an additional column holding a number to make each entry unique within the set, - // since embeddable properties can be null - if ( propertyValue.getCollectionType() instanceof SetType ) { - final String auditedEmbeddableSetOrdinalPropertyName = mainGenerator.getVerEntCfg() - .getEmbeddableSetOrdinalPropertyName(); - final String auditedEmbeddableSetOrdinalPropertyType = "integer"; - - final SimpleValue simpleValue = new SimpleValue( component.getMappings(), component.getTable() ); - simpleValue.setTypeName( auditedEmbeddableSetOrdinalPropertyType ); - - final Element idProperty = MetadataTools.addProperty( xmlMapping, - auditedEmbeddableSetOrdinalPropertyName, auditedEmbeddableSetOrdinalPropertyType, true, true ); - MetadataTools.addColumn( idProperty, auditedEmbeddableSetOrdinalPropertyName, null, 0, 0, null, null, - null, false ); + // Add an additional column holding a number to make each entry unique within the set. + // Embeddable properties may contain null values, so cannot be stored within composite primary key. + if ( propertyValue.isSet() ) { + final String setOrdinalPropertyName = mainGenerator.getVerEntCfg().getEmbeddableSetOrdinalPropertyName(); + final Element ordinalProperty = MetadataTools.addProperty( + xmlMapping, setOrdinalPropertyName, "integer", true, true + ); + MetadataTools.addColumn( + ordinalProperty, setOrdinalPropertyName, null, null, null, null, null, null, false + ); } return new MiddleComponentData( componentMapper, 0 ); diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/AbstractCollectionMapper.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/AbstractCollectionMapper.java index c7e125fe35..4f522c6be2 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/AbstractCollectionMapper.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/AbstractCollectionMapper.java @@ -87,27 +87,16 @@ protected AbstractCollectionMapper(CommonCollectionMapperData commonCollectionMa protected abstract void mapToMapFromObject(SessionImplementor session, Map idData, Map data, Object changed); /** - * Creates a Map for the id. - * - *

      - * The ordinal parameter represents the iteration ordinal of the current element, used to add a synthetic id when - * dealing with embeddables since embeddable fields can't be contained within the primary key since they might be - * nullable. - *

      - * - * @param ordinal - * The element iteration ordinal. - * - * @return A Map for holding the ID information. + * Creates map for storing identifier data. Ordinal parameter guarantees uniqueness of primary key. + * Composite primary key cannot contain embeddable properties since they might be nullable. + * @param ordinal Iteration ordinal. + * @return Map for holding identifier data. */ protected Map createIdMap(int ordinal) { - final HashMap idMap = new HashMap(); - + final Map idMap = new HashMap(); if ( ordinalInId ) { - idMap.put( this.commonCollectionMapperData.getVerEntCfg().getEmbeddableSetOrdinalPropertyName(), - Integer.valueOf( ordinal ) ); + idMap.put( commonCollectionMapperData.getVerEntCfg().getEmbeddableSetOrdinalPropertyName(), ordinal ); } - return idMap; } diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/SortedSetCollectionMapper.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/SortedSetCollectionMapper.java index e37bd744f6..38cf07c737 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/SortedSetCollectionMapper.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/SortedSetCollectionMapper.java @@ -41,8 +41,7 @@ public SortedSetCollectionMapper(CommonCollectionMapperData commonCollectionMapp Class collectionClass, Class proxyClass, MiddleComponentData elementComponentData, Comparator comparator, boolean ordinalInId, boolean revisionTypeInId) { - super( commonCollectionMapperData, collectionClass, proxyClass, elementComponentData, ordinalInId, - revisionTypeInId ); + super( commonCollectionMapperData, collectionClass, proxyClass, elementComponentData, ordinalInId, revisionTypeInId ); this.comparator = comparator; } diff --git a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/collection/embeddable/EmbeddableSet.java b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/collection/embeddable/EmbeddableSet.java index a41ae215c7..0243319e9b 100644 --- a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/collection/embeddable/EmbeddableSet.java +++ b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/collection/embeddable/EmbeddableSet.java @@ -24,7 +24,6 @@ package org.hibernate.envers.test.integration.collection.embeddable; import java.util.Arrays; -import java.util.Collections; import javax.persistence.EntityManager; import org.junit.Test; @@ -65,7 +64,7 @@ public void initData() { EmbeddableSetEntity ese1 = new EmbeddableSetEntity(); - // Revision 1 (ese1: initially 2 elements) + // Revision 1 (ese1: initially two elements) em.getTransaction().begin(); ese1.getComponentSet().add( c3_1 ); ese1.getComponentSet().add( c3_3 ); @@ -84,33 +83,33 @@ public void initData() { ese1.getComponentSet().add( c3_2 ); em.getTransaction().commit(); - // Revision 3 (ese1: adding one existing element) + // Revision (still 2) (ese1: adding one existing element) em.getTransaction().begin(); ese1 = em.find( EmbeddableSetEntity.class, ese1.getId() ); ese1.getComponentSet().add( c3_1 ); em.getTransaction().commit(); - // Revision 4 (ese1: removing one existing element) + // Revision 3 (ese1: removing one existing element) em.getTransaction().begin(); ese1 = em.find( EmbeddableSetEntity.class, ese1.getId() ); ese1.getComponentSet().remove( c3_2 ); em.getTransaction().commit(); - // Revision 5 (ese1: adding two elements) + // Revision 4 (ese1: adding two elements) em.getTransaction().begin(); ese1 = em.find( EmbeddableSetEntity.class, ese1.getId() ); ese1.getComponentSet().add( c3_2 ); ese1.getComponentSet().add( c3_4 ); em.getTransaction().commit(); - // Revision 6 (ese1: removing two elements) + // Revision 5 (ese1: removing two elements) em.getTransaction().begin(); ese1 = em.find( EmbeddableSetEntity.class, ese1.getId() ); ese1.getComponentSet().remove( c3_2 ); ese1.getComponentSet().remove( c3_4 ); em.getTransaction().commit(); - // Revision 7 (ese1: removing and adding two elements) + // Revision 6 (ese1: removing and adding two elements) em.getTransaction().begin(); ese1 = em.find( EmbeddableSetEntity.class, ese1.getId() ); ese1.getComponentSet().remove( c3_1 ); @@ -119,6 +118,12 @@ public void initData() { ese1.getComponentSet().add( c3_4 ); em.getTransaction().commit(); + // Revision 7 (ese1: adding one element) + em.getTransaction().begin(); + ese1 = em.find( EmbeddableSetEntity.class, ese1.getId() ); + ese1.getComponentSet().add( c3_1 ); + em.getTransaction().commit(); + ese1_id = ese1.getId(); em.close(); @@ -126,7 +131,7 @@ public void initData() { @Test public void testRevisionsCounts() { - assertEquals( Arrays.asList( 1, 2, 3, 4, 5, 6 ), getAuditReader().getRevisions( EmbeddableSetEntity.class, ese1_id ) ); + assertEquals( Arrays.asList( 1, 2, 3, 4, 5, 6, 7 ), getAuditReader().getRevisions( EmbeddableSetEntity.class, ese1_id ) ); } @Test @@ -137,6 +142,7 @@ public void testHistoryOfEse1() { EmbeddableSetEntity rev4 = getAuditReader().find( EmbeddableSetEntity.class, ese1_id, 4 ); EmbeddableSetEntity rev5 = getAuditReader().find( EmbeddableSetEntity.class, ese1_id, 5 ); EmbeddableSetEntity rev6 = getAuditReader().find( EmbeddableSetEntity.class, ese1_id, 6 ); + EmbeddableSetEntity rev7 = getAuditReader().find( EmbeddableSetEntity.class, ese1_id, 7 ); assertEquals( TestTools.makeSet( c3_1, c3_3 ), rev1.getComponentSet() ); assertEquals( TestTools.makeSet( c3_1, c3_2, c3_3 ), rev2.getComponentSet() ); @@ -144,5 +150,6 @@ public void testHistoryOfEse1() { assertEquals( TestTools.makeSet( c3_1, c3_2, c3_3, c3_4 ), rev4.getComponentSet() ); assertEquals( TestTools.makeSet( c3_1, c3_3 ), rev5.getComponentSet() ); assertEquals( TestTools.makeSet( c3_2, c3_4 ), rev6.getComponentSet() ); + assertEquals( TestTools.makeSet( c3_2, c3_4, c3_1 ), rev7.getComponentSet() ); } } \ No newline at end of file