Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WINDUPRULE-379 EAP 7.2 Migration: Hibernate ORM 5.1 to Hibernate ORM … #365

Merged
merged 10 commits into from
Mar 6, 2019
52 changes: 34 additions & 18 deletions rules-reviewed/eap7/eap71/hibernate51-53.windup.xml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
<!--<rule id="hibernate51-53-00000">
refer to hibernate51-53.windup.groovy
</rule>-->
<rule id="hibernate51-53-00001">
<rule id="hibernate51-53-00001">
<when>
<javaclass references="{methods_param}({*}org.hibernate.engine.spi.SessionImplementor{*})">
<location>METHOD_CALL</location>
Expand All @@ -37,7 +37,7 @@
<matches pattern="(org.hibernate.usertype.UserVersionType.next|org.hibernate.type.VersionType.next|org.hibernate.type.SingleColumnType.set|org.hibernate.type.AbstractStandardBasicType.set|org.hibernate.type.Type.resolve|org.hibernate.usertype.UserVersionType.seed|org.hibernate.type.VersionType.seed|org.hibernate.collection.spi.PersistentCollection.setCurrentSession|org.hibernate.type.ProcedureParameterNamedBinder.nullSafeSet|org.hibernate.type.Type.nullSafeSet|org.hibernate.usertype.UserType.nullSafeSet|org.hibernate.usertype.CompositeUserType.nullSafeSet|org.hibernate.type.Type.beforeAssemble|org.hibernate.type.AbstractStandardBasicType.nullSafeGet|org.hibernate.type.Type.nullSafeGet|org.hibernate.type.SingleColumnType.nullSafeGet|org.hibernate.usertype.UserType.nullSafeGet|org.hibernate.usertype.CompositeUserType.nullSafeGet|org.hibernate.type.Type.replace|org.hibernate.usertype.CompositeUserType.replace|org.hibernate.usertype.UserCollectionType.replaceElements|org.hibernate.collection.spi.PersistentCollection.unsetSession|org.hibernate.type.Type.hydrate|org.hibernate.type.Type.semiResolve|org.hibernate.usertype.CompositeUserType.assemble|org.hibernate.type.Type.assemble|org.hibernate.usertype.UserCollectionType.instantiate|org.hibernate.usertype.CompositeUserType.disassemble|org.hibernate.type.Type.disassemble|org.hibernate.type.ProcedureParameterExtractionAware.extract|org.hibernate.type.Type.isDirty|org.hibernate.type.Type.isModified|org.hibernate.type.SingleColumnType.get|org.hibernate.type.AbstractStandardBasicType.get|org.hibernate.usertype.UserCollectionType.wrap)" />
</where>
</rule>
<!--https://issues.jboss.org/browse/WINDUPRULE-377 -->
<!--https://issues.jboss.org/browse/WINDUPRULE-377 and WUNDUPRULE-378-->
<rule id="hibernate51-53-00100">
<when>
<project>
Expand All @@ -60,25 +60,41 @@
<matches pattern="(hibernate-java8|hibernate-entitymanager)" />
</where>
</rule>
<!--https://issues.jboss.org/browse/WINDUPRULE-378
<rule id="hibernate51-53-00200">
<when>
</when>
<perform>
</perform>
</rule>
-->
<!--https://issues.jboss.org/browse/WINDUPRULE-379
<!--https://issues.jboss.org/browse/WINDUPRULE-379-->
<rule id="hibernate51-53-00300">
<when>
<javaclass references="org.hibernate.{className}">
PhilipCattanach marked this conversation as resolved.
Show resolved Hide resolved
<location>IMPORT</location>
</javaclass>
</when>
<perform>
<hint title="Hibernate 5.3 - Exception Handling" effort="1" category-id="mandatory">
<message> If the `SessionFactory` is built via Hibernate’s native bootstrapping and `org.hibernate.HibernateException` or a subclass is referenced by the application
then set `hibernate.native_exception_handling_51_compliance` configuration property to `true`.</message>
<link title="Red Hat JBoss EAP 7.2: Migrating from Hibernate ORM 5.1 to Hibernate ORM 5.3" href="https://access.redhat.com/documentation/en-us/red_hat_jboss_enterprise_application_platform/7.2/html-single/migration_guide/#exception_handling_changes_between_51_53"/>
<tag>hibernate</tag>
</hint>
</perform>
<where param="">
<matches pattern="" />
<where param="className">
<matches pattern="(boot.archive.spi.ArchiveException|envers.exception.AuditException|jdbc.BatchFailedException|cache.CacheException|CallbackException
|boot.registry.classloading.spi.ClassLoadingException|tool.schema.spi.CommandAcceptanceException|bytecode.enhance.spi.EnhancementException
|tuple.entity.EntityMetamodel.ValueGenerationStrategyException|event.service.spi.EventListenerRegistrationException|HibernateError
|id.IdentifierGenerationException|boot.model.naming.IllegalIdentifierException|tool.hbm2ddl.ImportScriptException
|boot.spi.InFlightMetadataCollector.DuplicateSecondaryTableException|InstantiationException|secure.spi.IntegrationException|JDBCException
|engine.jndi.JndiException|engine.jndi.JndiNameException|engine.transaction.jta.platform.spi.JtaPlatformException|LazyInitializationException
|resource.transaction.LocalSynchronizationException|dialect.lock.LockingStrategyException|MappingException|loader.MultipleBagFetchException
|procedure.NamedParametersNotSupportedException|result.NoMoreReturnsException|loader.custom.NonUniqueDiscoveredSqlAliasException
|NonUniqueObjectException|NonUniqueResultException|procedure.NoSuchParameterException|bytecode.spi.NotInstrumentedException
|service.NullServiceException|resource.transaction.NullSynchronizationException|procedure.ParameterMisuseException
|engine.query.ParameterRecognitionException|procedure.ParameterStrategyException|PersistentObjectException|property.access.spi.PropertyAccessBuildingException
|PropertyAccessException|property.access.spi.PropertyAccessSerializationException|PropertyValueException|QueryException
|loader.plan.spi.QuerySpaceUidNotRegisteredException|ResourceClosedException|tool.schema.extract.spi.SchemaExtractionException|tool.schema.spi.SchemaManagementException
|type.SerializationException|service.spi.ServiceException|SessionException|StaleStateException|boot.registry.selector.spi.StrategySelectionException
|context.TenantIdentifierMismatchException|jdbc.TooManyRowsAffectedException|TransactionException|resource.transaction.TransactionRequiredForJoinException
|TransientObjectException|TypeMismatchException|cache.spi.access.UnknownAccessTypeException|persister.spi.UnknownPersisterException|UnknownProfileException
|service.UnknownServiceException|service.UnknownUnwrapTypeException|UnresolvableObjectException|UnsupportedLockAttemptException|WrongClassException)"/>
</where>
</rule>
-->
<!--https://issues.jboss.org/browse/WINDUPRULE-380-->
<rule id="hibernate51-53-00400">
<when>
Expand Down Expand Up @@ -161,8 +177,8 @@
<perform>
<hint title="Hibernate 5.3 - SessionFactoryImplementor.getSecondLevelCacheRegionAccessStrategy(String regionName) method removed" category-id="mandatory" effort="1">
<message>
Depending on the type of region, the appropriate method should be used instead:
Depending on the type of region, the appropriate method should be used instead:

* For an entity cache region, `org.hibernate.engine.spi.SessionFactoryImplementor.getMetamodel().entityPersister( entityName ).getCacheAccessStrategy()` should be used instead
* For a collection region, `org.hibernate.engine.spi.SessionFactoryImplementor.getMetamodel().collectionPersister( role ).getCacheAccessStrategy()` should be used instead
* For a natural ID region, `org.hibernate.engine.spi.SessionFactoryImplementor.getMetamodel().entityPersister( entityName ).getNaturalIdCacheAccessStrategy()` should be used instead
Expand Down Expand Up @@ -333,7 +349,7 @@
<perform>
<hint title="Hibernate 5.3 - SecondLevelCacheStatistics.getEntries() deprecated method" effort="1" category-id="optional">
<message>
A change to be aware of is accessing cache entries via `SecondLevelCacheStatistics.getEntries()`.
A change to be aware of is accessing cache entries via `SecondLevelCacheStatistics.getEntries()`.
This method has been deprecated, however the new caching SPI does not really require caching providers to support this.
As of Hibernate 5.3 these methods inherently return an empty Map (`Collections#emptyMap`).
This has always been something that providers did not implement "correctly" anyway.
Expand Down Expand Up @@ -406,6 +422,6 @@
<where param="className">
<matches pattern="(engine.query.spi.NamedParameterDescriptor|engine.query.spi.OrdinalParameterDescriptor|query.procedure.internal.ProcedureParameterImpl|query.internal.QueryParameterImpl|query.internal.QueryParameterNamedImpl)"/>
</where>
</rule>
</rule>
</rules>
</ruleset>
Original file line number Diff line number Diff line change
@@ -0,0 +1,221 @@
/*
* 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.boot.archive.internal;

import java.io.File;
import java.io.IOException;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.Enumeration;
import java.util.jar.JarFile;
import java.util.zip.ZipEntry;

import org.jboss.logging.Logger;

import org.hibernate.jpa.boot.archive.spi.AbstractArchiveDescriptor;
import org.hibernate.jpa.boot.archive.spi.ArchiveContext;
import org.hibernate.jpa.boot.archive.spi.ArchiveDescriptorFactory;
import org.hibernate.jpa.boot.archive.spi.ArchiveEntry;
import org.hibernate.boot.archive.spi.ArchiveException;
import org.hibernate.jpa.boot.internal.FileInputStreamAccess;
import org.hibernate.jpa.boot.spi.InputStreamAccess;
import org.hibernate.jpa.internal.EntityManagerMessageLogger;

/**
* Descriptor for exploded (directory) archives
*
* @author Steve Ebersole
*/
public class Hibernate515300300 extends AbstractArchiveDescriptor {
private static final EntityManagerMessageLogger LOG = Logger.getMessageLogger(
EntityManagerMessageLogger.class,
ExplodedArchiveDescriptor.class.getName()
);

/**
* Constructs an ExplodedArchiveDescriptor
*
* @param archiveDescriptorFactory The factory creating this
* @param archiveUrl The directory URL
* @param entryBasePrefix the base (within the url) that described the prefix for entries within the archive
*/
public Hibernate515300300(
ArchiveDescriptorFactory archiveDescriptorFactory,
URL archiveUrl,
String entryBasePrefix) {
super( archiveDescriptorFactory, archiveUrl, entryBasePrefix );
}

@Override
public void visitArchive(ArchiveContext context) {
final File rootDirectory = resolveRootDirectory();
if ( rootDirectory == null ) {
return;
}

if ( rootDirectory.isDirectory() ) {
processDirectory( rootDirectory, null, context );
}
else {
//assume zipped file
processZippedRoot( rootDirectory, context );
}
}

private File resolveRootDirectory() {
final File archiveUrlDirectory;
try {
final String filePart = getArchiveUrl().getFile();
if ( filePart != null && filePart.indexOf( ' ' ) != -1 ) {
//unescaped (from the container), keep as is
archiveUrlDirectory = new File( filePart );
}
else {
archiveUrlDirectory = new File( getArchiveUrl().toURI().getSchemeSpecificPart() );
}
}
catch (URISyntaxException e) {
LOG.malformedUrl( getArchiveUrl(), e );
return null;
}

if ( !archiveUrlDirectory.exists() ) {
LOG.explodedJarDoesNotExist( getArchiveUrl() );
return null;
}
if ( !archiveUrlDirectory.isDirectory() ) {
LOG.explodedJarNotDirectory( getArchiveUrl() );
return null;
}

final String entryBase = getEntryBasePrefix();
if ( entryBase != null && entryBase.length() > 0 && ! "/".equals( entryBase ) ) {
return new File( archiveUrlDirectory, entryBase );
}
else {
return archiveUrlDirectory;
}
}

private void processDirectory(
File directory,
String path,
ArchiveContext context) {
if ( directory == null ) {
return;
}

final File[] files = directory.listFiles();
if ( files == null ) {
return;
}

path = path == null ? "" : path + "/";
for ( final File localFile : files ) {
if ( !localFile.exists() ) {
// should never happen conceptually, but...
continue;
}

if ( localFile.isDirectory() ) {
processDirectory( localFile, path + localFile.getName(), context );
continue;
}

final String name = localFile.getAbsolutePath();
final String relativeName = path + localFile.getName();
final InputStreamAccess inputStreamAccess = new FileInputStreamAccess( name, localFile );

final ArchiveEntry entry = new ArchiveEntry() {
@Override
public String getName() {
return name;
}

@Override
public String getNameWithinArchive() {
return relativeName;
}

@Override
public InputStreamAccess getStreamAccess() {
return inputStreamAccess;
}
};

context.obtainArchiveEntryHandler( entry ).handleEntry( entry, context );
}
}

private void processZippedRoot(File rootFile, ArchiveContext context) {
try {
final JarFile jarFile = new JarFile(rootFile);
final Enumeration<? extends ZipEntry> entries = jarFile.entries();
while ( entries.hasMoreElements() ) {
final ZipEntry zipEntry = entries.nextElement();
if ( zipEntry.isDirectory() ) {
continue;
}

final String name = extractName( zipEntry );
final String relativeName = extractRelativeName( zipEntry );
final InputStreamAccess inputStreamAccess;
try {
inputStreamAccess = buildByteBasedInputStreamAccess( name, jarFile.getInputStream( zipEntry ) );
}
catch (IOException e) {
throw new ArchiveException(
String.format(
"Unable to access stream from jar file [%s] for entry [%s]",
jarFile.getName(),
zipEntry.getName()
)
);
}

final ArchiveEntry entry = new ArchiveEntry() {
@Override
public String getName() {
return name;
}

@Override
public String getNameWithinArchive() {
return relativeName;
}

@Override
public InputStreamAccess getStreamAccess() {
return inputStreamAccess;
}
};
context.obtainArchiveEntryHandler( entry ).handleEntry( entry, context );
}
}
catch (IOException e) {
throw new ArchiveException( "Error accessing jar file [" + rootFile.getAbsolutePath() + "]", e );
}
}

}
25 changes: 5 additions & 20 deletions rules-reviewed/eap7/eap71/tests/hibernate51-53.windup.test.xml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
<fail message="SessionImplementor hint not found." />
</perform>
</rule>
<!--https://issues.jboss.org/browse/WINDUPRULE-377 -->
<!--https://issues.jboss.org/browse/WINDUPRULE-377 and WINDUPRULE-378 -->
<rule id="hibernate51-53-00100-test">
<when>
<not>
Expand All @@ -34,34 +34,19 @@
<fail message="No reference to hibernate-java8 found in pom.xml (where hibernate-core not also referenced)" />
</perform>
</rule>
<!--https://issues.jboss.org/browse/WINDUPRULE-378-
<rule id="hibernate51-53-00200-test">
<when>
<not>
<iterable-filter size="1">
<hint-exists message="" />
</iterable-filter>
</not>
</when>
<perform>
<fail message="" />
</perform>
</rule>
-->
<!--https://issues.jboss.org/browse/WINDUPRULE-379-
<!--https://issues.jboss.org/browse/WINDUPRULE-379-->
<rule id="hibernate51-53-00300-test">
<when>
<not>
<iterable-filter size="5">
<hint-exists message="" />
<iterable-filter size="1">
<hint-exists message="If the `SessionFactory` is built via Hibernate’s native bootstrapping and `org.hibernate.HibernateException`*" />
</iterable-filter>
</not>
</when>
<perform>
<fail message="" />
<fail message="References to org.hibernate.HibernateException or subclasses not found" />
</perform>
</rule>
-->
<!--https://issues.jboss.org/browse/WINDUPRULE-380-->
<rule id="hibernate51-53-00400-test">
<when>
Expand Down