Merge remote-tracking branch 'upstream/main' into wip/6.0_merge
This commit is contained in:
commit
7b5e8de7bf
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
}
|
|
@ -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 );
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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>
|
|
@ -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>
|
Loading…
Reference in New Issue