Merge remote-tracking branch 'upstream/main' into wip/6.0_merge

This commit is contained in:
Andrea Boriero 2021-10-14 18:45:09 +02:00
commit 7b5e8de7bf
9 changed files with 275 additions and 21 deletions

View File

@ -54,7 +54,7 @@ public final class JPAXMLOverriddenMetadataProvider implements MetadataProvider
public JPAXMLOverriddenMetadataProvider(BootstrapContext bootstrapContext) {
this.classLoaderAccess = bootstrapContext.getClassLoaderAccess();
this.xmlContext = new XMLContext( classLoaderAccess );
this.xmlContext = new XMLContext( bootstrapContext );
this.xmlMappingEnabled = bootstrapContext.getMetadataBuildingOptions().isXmlMappingEnabled();
}

View File

@ -15,7 +15,7 @@ import jakarta.persistence.AccessType;
import jakarta.persistence.AttributeConverter;
import org.hibernate.AnnotationException;
import org.hibernate.boot.AttributeConverterInfo;
import org.hibernate.boot.internal.ClassmateContext;
import org.hibernate.boot.jaxb.mapping.spi.JaxbConverter;
import org.hibernate.boot.jaxb.mapping.spi.JaxbEntity;
import org.hibernate.boot.jaxb.mapping.spi.JaxbEntityListener;
@ -25,10 +25,11 @@ import org.hibernate.boot.jaxb.mapping.spi.JaxbMappedSuperclass;
import org.hibernate.boot.jaxb.mapping.spi.JaxbPersistenceUnitDefaults;
import org.hibernate.boot.jaxb.mapping.spi.JaxbPersistenceUnitMetadata;
import org.hibernate.boot.jaxb.mapping.spi.ManagedType;
import org.hibernate.boot.model.convert.internal.ClassBasedConverterDescriptor;
import org.hibernate.boot.model.convert.spi.ConverterDescriptor;
import org.hibernate.boot.registry.classloading.spi.ClassLoadingException;
import org.hibernate.boot.spi.BootstrapContext;
import org.hibernate.boot.spi.ClassLoaderAccess;
import org.hibernate.cfg.AttributeConverterDefinition;
import org.hibernate.cfg.annotations.reflection.AttributeConverterDefinitionCollector;
import org.hibernate.internal.CoreLogging;
import org.hibernate.internal.CoreMessageLogger;
@ -44,6 +45,7 @@ public class XMLContext implements Serializable {
private static final CoreMessageLogger LOG = CoreLogging.messageLogger( XMLContext.class );
private final ClassLoaderAccess classLoaderAccess;
private final ClassmateContext classmateContext;
private Default globalDefaults;
private final Map<String, ManagedType> managedTypeOverride = new HashMap<>();
@ -53,16 +55,9 @@ public class XMLContext implements Serializable {
private final List<String> defaultEntityListeners = new ArrayList<>();
private boolean hasContext = false;
/**
* @deprecated Use {@link #XMLContext(BootstrapContext)} instead.
*/
@Deprecated
public XMLContext(ClassLoaderAccess classLoaderAccess) {
this.classLoaderAccess = classLoaderAccess;
}
public XMLContext(BootstrapContext bootstrapContext) {
this.classLoaderAccess = bootstrapContext.getClassLoaderAccess();
this.classmateContext = bootstrapContext.getClassmateContext();
}
/**
@ -107,7 +102,7 @@ public class XMLContext implements Serializable {
entityMappingDefault.setAccess( entityMappings.getAccess() );
defaultElements.add( entityMappings );
setLocalAttributeConverterDefinitions( entityMappings.getConverter() );
setLocalAttributeConverterDefinitions( entityMappings.getConverter(), packageName );
addClass( entityMappings.getEntity(), packageName, entityMappingDefault, addedClasses );
@ -168,17 +163,17 @@ public class XMLContext implements Serializable {
}
@SuppressWarnings("unchecked")
private void setLocalAttributeConverterDefinitions(List<JaxbConverter> converterElements) {
private void setLocalAttributeConverterDefinitions(List<JaxbConverter> converterElements, String packageName) {
for ( JaxbConverter converterElement : converterElements ) {
final String className = converterElement.getClazz();
final boolean autoApply = Boolean.TRUE.equals( converterElement.isAutoApply() );
try {
final Class<? extends AttributeConverter> attributeConverterClass = classLoaderAccess.classForName(
className
buildSafeClassName( className, packageName )
);
attributeConverterInfoList.add(
new AttributeConverterDefinition( attributeConverterClass.newInstance(), autoApply )
converterDescriptors.add(
new ClassBasedConverterDescriptor( attributeConverterClass, autoApply, classmateContext )
);
}
catch (ClassLoadingException e) {
@ -227,13 +222,13 @@ public class XMLContext implements Serializable {
return hasContext;
}
private List<AttributeConverterInfo> attributeConverterInfoList = new ArrayList<>();
private List<ConverterDescriptor> converterDescriptors = new ArrayList<>();
public void applyDiscoveredAttributeConverters(AttributeConverterDefinitionCollector collector) {
for ( AttributeConverterInfo info : attributeConverterInfoList ) {
collector.addAttributeConverter( info );
for ( ConverterDescriptor descriptor : converterDescriptors ) {
collector.addAttributeConverter( descriptor );
}
attributeConverterInfoList.clear();
converterDescriptors.clear();
}
public static class Default implements Serializable {

View File

@ -0,0 +1,37 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.orm.test.cdi.converters;
import java.util.Objects;
import org.hibernate.annotations.Immutable;
@Immutable
public class MyData {
public final String value;
public MyData(String value) {
this.value = value;
}
@Override
public boolean equals(Object o) {
if ( this == o ) {
return true;
}
if ( o == null || getClass() != o.getClass() ) {
return false;
}
MyData myData = (MyData) o;
return value.equals( myData.value );
}
@Override
public int hashCode() {
return Objects.hash( value );
}
}

View File

@ -0,0 +1,36 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.orm.test.cdi.converters;
import jakarta.persistence.AttributeConverter;
public class OrmXmlConverterBean implements AttributeConverter<MyData,String> {
private final MonitorBean monitor;
@jakarta.inject.Inject
public OrmXmlConverterBean(MonitorBean monitor) {
this.monitor = monitor;
}
@Override
public String convertToDatabaseColumn(MyData attribute) {
monitor.toDbCalled();
if ( attribute == null ) {
return null;
}
return attribute.value;
}
@Override
public MyData convertToEntityAttribute(String dbData) {
monitor.fromDbCalled();
if ( dbData == null ) {
return null;
}
return new MyData( dbData );
}
}

View File

@ -0,0 +1,47 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.orm.test.cdi.converters;
// This entity is mapped using an orm.xml file
public class TheOrmXmlEntity {
private Integer id;
private String name;
private MyData data;
public TheOrmXmlEntity() {
}
public TheOrmXmlEntity(Integer id, String name, MyData data) {
this.id = id;
this.name = name;
this.data = data;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public MyData getData() {
return data;
}
public void setData(MyData data) {
this.data = data;
}
}

View File

@ -16,8 +16,12 @@ import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.orm.test.cdi.converters.MyData;
import org.hibernate.orm.test.cdi.converters.OrmXmlConverterBean;
import org.hibernate.orm.test.cdi.converters.TheOrmXmlEntity;
import org.hibernate.tool.schema.Action;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.junit4.BaseUnitTestCase;
import org.hibernate.orm.test.cdi.converters.ConverterBean;
import org.hibernate.orm.test.cdi.converters.MonitorBean;
@ -34,7 +38,7 @@ import static org.junit.Assert.assertTrue;
*/
public class CdiHostedConverterTest extends BaseUnitTestCase {
@Test
public void testIt() {
public void testAnnotations() {
MonitorBean.reset();
final SeContainerInitializer cdiInitializer = SeContainerInitializer.newInstance()
@ -99,4 +103,72 @@ public class CdiHostedConverterTest extends BaseUnitTestCase {
}
}
}
@Test
@TestForIssue(jiraKey = "HHH-14881\n")
public void testOrmXml() {
MonitorBean.reset();
final SeContainerInitializer cdiInitializer = SeContainerInitializer.newInstance()
.disableDiscovery()
.addBeanClasses( MonitorBean.class, OrmXmlConverterBean.class );
try ( final SeContainer cdiContainer = cdiInitializer.initialize() ) {
BootstrapServiceRegistry bsr = new BootstrapServiceRegistryBuilder().build();
final StandardServiceRegistry ssr = new StandardServiceRegistryBuilder( bsr )
.applySetting( AvailableSettings.HBM2DDL_AUTO, Action.CREATE_DROP )
.applySetting( AvailableSettings.CDI_BEAN_MANAGER, cdiContainer.getBeanManager() )
.build();
final SessionFactoryImplementor sessionFactory;
try {
sessionFactory = (SessionFactoryImplementor) new MetadataSources( ssr )
.addResource( "org/hibernate/test/cdi/converters/orm.xml" )
.buildMetadata()
.getSessionFactoryBuilder()
.build();
}
catch ( Exception e ) {
StandardServiceRegistryBuilder.destroy( ssr );
throw e;
}
// The CDI bean should have been built immediately...
assertTrue( MonitorBean.wasInstantiated() );
assertEquals( 0, MonitorBean.currentFromDbCount() );
assertEquals( 0, MonitorBean.currentToDbCount() );
try {
inTransaction(
sessionFactory,
session -> session.persist( new TheOrmXmlEntity( 1, "me", new MyData( "foo" ) ) )
);
assertEquals( 0, MonitorBean.currentFromDbCount() );
assertEquals( 1, MonitorBean.currentToDbCount() );
inTransaction(
sessionFactory,
session -> {
TheOrmXmlEntity it = session.find( TheOrmXmlEntity.class, 1 );
assertNotNull( it );
}
);
assertEquals( 1, MonitorBean.currentFromDbCount() );
assertEquals( 1, MonitorBean.currentToDbCount() );
}
finally {
inTransaction(
sessionFactory,
session -> {
session.createQuery( "delete TheOrmXmlEntity" ).executeUpdate();
}
);
sessionFactory.close();
}
}
}
}

View File

@ -219,6 +219,41 @@ public class AttributeConverterTest extends BaseUnitTestCase {
}
}
@Test
@TestForIssue(jiraKey = "HHH-14881")
public void testBasicOrmXmlConverterWithOrmXmlPackage() {
final StandardServiceRegistry ssr = new StandardServiceRegistryBuilder().build();
try {
MetadataImplementor metadata = (MetadataImplementor) new MetadataSources( ssr )
.addAnnotatedClass( Tester.class )
.addURL( ConfigHelper.findAsResource( "org/hibernate/test/converter/package.xml" ) )
.getMetadataBuilder()
.build();
PersistentClass tester = metadata.getEntityBinding( Tester.class.getName() );
Property nameProp = tester.getProperty( "name" );
SimpleValue nameValue = (SimpleValue) nameProp.getValue();
Type type = nameValue.getType();
assertNotNull( type );
if ( !AttributeConverterTypeAdapter.class.isInstance( type ) ) {
fail( "AttributeConverter not applied" );
}
final AttributeConverterTypeAdapter typeAdapter = (AttributeConverterTypeAdapter) type;
assertThat( typeAdapter.getDomainJtd().getJavaTypeClass(), equalTo( String.class ) );
assertThat( typeAdapter.getRelationalJtd().getJavaTypeClass(), equalTo( Clob.class ) );
final JdbcType sqlTypeDescriptor = typeAdapter.getJdbcTypeDescriptor();
assertThat( sqlTypeDescriptor.getJdbcTypeCode(), is( Types.CLOB ) );
}
finally {
StandardServiceRegistryBuilder.destroy( ssr );
}
}
@Test
public void testBasicConverterDisableApplication() {
final StandardServiceRegistry ssr = new StandardServiceRegistryBuilder().build();

View File

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Hibernate, Relational Persistence for Idiomatic Java
~
~ License: GNU Lesser General Public License (LGPL), version 2.1 or later.
~ See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
-->
<entity-mappings xmlns="http://xmlns.jcp.org/xml/ns/persistence/orm"
version="2.1">
<entity class="org.hibernate.orm.test.cdi.converters.TheOrmXmlEntity">
<attributes>
<id name="id" />
<basic name="name" />
<basic name="myData" />
</attributes>
</entity>
<converter class="org.hibernate.orm.test.cdi.converters.OrmXmlConverterBean" auto-apply="true"/>
</entity-mappings>

View File

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Hibernate, Relational Persistence for Idiomatic Java
~
~ License: GNU Lesser General Public License (LGPL), version 2.1 or later.
~ See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
-->
<entity-mappings xmlns="http://xmlns.jcp.org/xml/ns/persistence/orm"
version="2.1">
<package>org.hibernate.test.converter</package>
<converter class="org.hibernate.orm.test.mapping.converted.converter.StringClobConverter" auto-apply="true"/>
</entity-mappings>