Skip to content

Commit 7b5e8de

Browse files
committed
Merge remote-tracking branch 'upstream/main' into wip/6.0_merge
2 parents 4323f9f + 97f75f2 commit 7b5e8de

File tree

9 files changed

+275
-21
lines changed

9 files changed

+275
-21
lines changed

hibernate-core/src/main/java/org/hibernate/cfg/annotations/reflection/internal/JPAXMLOverriddenMetadataProvider.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ public final class JPAXMLOverriddenMetadataProvider implements MetadataProvider
5454

5555
public JPAXMLOverriddenMetadataProvider(BootstrapContext bootstrapContext) {
5656
this.classLoaderAccess = bootstrapContext.getClassLoaderAccess();
57-
this.xmlContext = new XMLContext( classLoaderAccess );
57+
this.xmlContext = new XMLContext( bootstrapContext );
5858
this.xmlMappingEnabled = bootstrapContext.getMetadataBuildingOptions().isXmlMappingEnabled();
5959
}
6060

hibernate-core/src/main/java/org/hibernate/cfg/annotations/reflection/internal/XMLContext.java

+14-19
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
import jakarta.persistence.AttributeConverter;
1616

1717
import org.hibernate.AnnotationException;
18-
import org.hibernate.boot.AttributeConverterInfo;
18+
import org.hibernate.boot.internal.ClassmateContext;
1919
import org.hibernate.boot.jaxb.mapping.spi.JaxbConverter;
2020
import org.hibernate.boot.jaxb.mapping.spi.JaxbEntity;
2121
import org.hibernate.boot.jaxb.mapping.spi.JaxbEntityListener;
@@ -25,10 +25,11 @@
2525
import org.hibernate.boot.jaxb.mapping.spi.JaxbPersistenceUnitDefaults;
2626
import org.hibernate.boot.jaxb.mapping.spi.JaxbPersistenceUnitMetadata;
2727
import org.hibernate.boot.jaxb.mapping.spi.ManagedType;
28+
import org.hibernate.boot.model.convert.internal.ClassBasedConverterDescriptor;
29+
import org.hibernate.boot.model.convert.spi.ConverterDescriptor;
2830
import org.hibernate.boot.registry.classloading.spi.ClassLoadingException;
2931
import org.hibernate.boot.spi.BootstrapContext;
3032
import org.hibernate.boot.spi.ClassLoaderAccess;
31-
import org.hibernate.cfg.AttributeConverterDefinition;
3233
import org.hibernate.cfg.annotations.reflection.AttributeConverterDefinitionCollector;
3334
import org.hibernate.internal.CoreLogging;
3435
import org.hibernate.internal.CoreMessageLogger;
@@ -44,6 +45,7 @@ public class XMLContext implements Serializable {
4445
private static final CoreMessageLogger LOG = CoreLogging.messageLogger( XMLContext.class );
4546

4647
private final ClassLoaderAccess classLoaderAccess;
48+
private final ClassmateContext classmateContext;
4749

4850
private Default globalDefaults;
4951
private final Map<String, ManagedType> managedTypeOverride = new HashMap<>();
@@ -53,16 +55,9 @@ public class XMLContext implements Serializable {
5355
private final List<String> defaultEntityListeners = new ArrayList<>();
5456
private boolean hasContext = false;
5557

56-
/**
57-
* @deprecated Use {@link #XMLContext(BootstrapContext)} instead.
58-
*/
59-
@Deprecated
60-
public XMLContext(ClassLoaderAccess classLoaderAccess) {
61-
this.classLoaderAccess = classLoaderAccess;
62-
}
63-
6458
public XMLContext(BootstrapContext bootstrapContext) {
6559
this.classLoaderAccess = bootstrapContext.getClassLoaderAccess();
60+
this.classmateContext = bootstrapContext.getClassmateContext();
6661
}
6762

6863
/**
@@ -107,7 +102,7 @@ public List<String> addDocument(JaxbEntityMappings entityMappings) {
107102
entityMappingDefault.setAccess( entityMappings.getAccess() );
108103
defaultElements.add( entityMappings );
109104

110-
setLocalAttributeConverterDefinitions( entityMappings.getConverter() );
105+
setLocalAttributeConverterDefinitions( entityMappings.getConverter(), packageName );
111106

112107
addClass( entityMappings.getEntity(), packageName, entityMappingDefault, addedClasses );
113108

@@ -168,17 +163,17 @@ private List<String> addEntityListenerClasses(JaxbEntityListeners listeners, Str
168163
}
169164

170165
@SuppressWarnings("unchecked")
171-
private void setLocalAttributeConverterDefinitions(List<JaxbConverter> converterElements) {
166+
private void setLocalAttributeConverterDefinitions(List<JaxbConverter> converterElements, String packageName) {
172167
for ( JaxbConverter converterElement : converterElements ) {
173168
final String className = converterElement.getClazz();
174169
final boolean autoApply = Boolean.TRUE.equals( converterElement.isAutoApply() );
175170

176171
try {
177172
final Class<? extends AttributeConverter> attributeConverterClass = classLoaderAccess.classForName(
178-
className
173+
buildSafeClassName( className, packageName )
179174
);
180-
attributeConverterInfoList.add(
181-
new AttributeConverterDefinition( attributeConverterClass.newInstance(), autoApply )
175+
converterDescriptors.add(
176+
new ClassBasedConverterDescriptor( attributeConverterClass, autoApply, classmateContext )
182177
);
183178
}
184179
catch (ClassLoadingException e) {
@@ -227,13 +222,13 @@ public boolean hasContext() {
227222
return hasContext;
228223
}
229224

230-
private List<AttributeConverterInfo> attributeConverterInfoList = new ArrayList<>();
225+
private List<ConverterDescriptor> converterDescriptors = new ArrayList<>();
231226

232227
public void applyDiscoveredAttributeConverters(AttributeConverterDefinitionCollector collector) {
233-
for ( AttributeConverterInfo info : attributeConverterInfoList ) {
234-
collector.addAttributeConverter( info );
228+
for ( ConverterDescriptor descriptor : converterDescriptors ) {
229+
collector.addAttributeConverter( descriptor );
235230
}
236-
attributeConverterInfoList.clear();
231+
converterDescriptors.clear();
237232
}
238233

239234
public static class Default implements Serializable {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/*
2+
* Hibernate, Relational Persistence for Idiomatic Java
3+
*
4+
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
5+
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
6+
*/
7+
package org.hibernate.orm.test.cdi.converters;
8+
9+
import java.util.Objects;
10+
11+
import org.hibernate.annotations.Immutable;
12+
13+
@Immutable
14+
public class MyData {
15+
public final String value;
16+
17+
public MyData(String value) {
18+
this.value = value;
19+
}
20+
21+
@Override
22+
public boolean equals(Object o) {
23+
if ( this == o ) {
24+
return true;
25+
}
26+
if ( o == null || getClass() != o.getClass() ) {
27+
return false;
28+
}
29+
MyData myData = (MyData) o;
30+
return value.equals( myData.value );
31+
}
32+
33+
@Override
34+
public int hashCode() {
35+
return Objects.hash( value );
36+
}
37+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/*
2+
* Hibernate, Relational Persistence for Idiomatic Java
3+
*
4+
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
5+
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
6+
*/
7+
package org.hibernate.orm.test.cdi.converters;
8+
9+
import jakarta.persistence.AttributeConverter;
10+
11+
public class OrmXmlConverterBean implements AttributeConverter<MyData,String> {
12+
private final MonitorBean monitor;
13+
14+
@jakarta.inject.Inject
15+
public OrmXmlConverterBean(MonitorBean monitor) {
16+
this.monitor = monitor;
17+
}
18+
19+
@Override
20+
public String convertToDatabaseColumn(MyData attribute) {
21+
monitor.toDbCalled();
22+
if ( attribute == null ) {
23+
return null;
24+
}
25+
return attribute.value;
26+
}
27+
28+
@Override
29+
public MyData convertToEntityAttribute(String dbData) {
30+
monitor.fromDbCalled();
31+
if ( dbData == null ) {
32+
return null;
33+
}
34+
return new MyData( dbData );
35+
}
36+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/*
2+
* Hibernate, Relational Persistence for Idiomatic Java
3+
*
4+
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
5+
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
6+
*/
7+
package org.hibernate.orm.test.cdi.converters;
8+
9+
// This entity is mapped using an orm.xml file
10+
public class TheOrmXmlEntity {
11+
private Integer id;
12+
private String name;
13+
private MyData data;
14+
15+
public TheOrmXmlEntity() {
16+
}
17+
18+
public TheOrmXmlEntity(Integer id, String name, MyData data) {
19+
this.id = id;
20+
this.name = name;
21+
this.data = data;
22+
}
23+
24+
public Integer getId() {
25+
return id;
26+
}
27+
28+
public void setId(Integer id) {
29+
this.id = id;
30+
}
31+
32+
public String getName() {
33+
return name;
34+
}
35+
36+
public void setName(String name) {
37+
this.name = name;
38+
}
39+
40+
public MyData getData() {
41+
return data;
42+
}
43+
44+
public void setData(MyData data) {
45+
this.data = data;
46+
}
47+
}

hibernate-core/src/test/java/org/hibernate/orm/test/cdi/converters/standard/CdiHostedConverterTest.java

+73-1
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,12 @@
1616
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
1717
import org.hibernate.cfg.AvailableSettings;
1818
import org.hibernate.engine.spi.SessionFactoryImplementor;
19+
import org.hibernate.orm.test.cdi.converters.MyData;
20+
import org.hibernate.orm.test.cdi.converters.OrmXmlConverterBean;
21+
import org.hibernate.orm.test.cdi.converters.TheOrmXmlEntity;
1922
import org.hibernate.tool.schema.Action;
2023

24+
import org.hibernate.testing.TestForIssue;
2125
import org.hibernate.testing.junit4.BaseUnitTestCase;
2226
import org.hibernate.orm.test.cdi.converters.ConverterBean;
2327
import org.hibernate.orm.test.cdi.converters.MonitorBean;
@@ -34,7 +38,7 @@
3438
*/
3539
public class CdiHostedConverterTest extends BaseUnitTestCase {
3640
@Test
37-
public void testIt() {
41+
public void testAnnotations() {
3842
MonitorBean.reset();
3943

4044
final SeContainerInitializer cdiInitializer = SeContainerInitializer.newInstance()
@@ -99,4 +103,72 @@ public void testIt() {
99103
}
100104
}
101105
}
106+
107+
@Test
108+
@TestForIssue(jiraKey = "HHH-14881\n")
109+
public void testOrmXml() {
110+
MonitorBean.reset();
111+
112+
final SeContainerInitializer cdiInitializer = SeContainerInitializer.newInstance()
113+
.disableDiscovery()
114+
.addBeanClasses( MonitorBean.class, OrmXmlConverterBean.class );
115+
try ( final SeContainer cdiContainer = cdiInitializer.initialize() ) {
116+
BootstrapServiceRegistry bsr = new BootstrapServiceRegistryBuilder().build();
117+
118+
final StandardServiceRegistry ssr = new StandardServiceRegistryBuilder( bsr )
119+
.applySetting( AvailableSettings.HBM2DDL_AUTO, Action.CREATE_DROP )
120+
.applySetting( AvailableSettings.CDI_BEAN_MANAGER, cdiContainer.getBeanManager() )
121+
.build();
122+
123+
final SessionFactoryImplementor sessionFactory;
124+
125+
try {
126+
sessionFactory = (SessionFactoryImplementor) new MetadataSources( ssr )
127+
.addResource( "org/hibernate/test/cdi/converters/orm.xml" )
128+
.buildMetadata()
129+
.getSessionFactoryBuilder()
130+
.build();
131+
}
132+
catch ( Exception e ) {
133+
StandardServiceRegistryBuilder.destroy( ssr );
134+
throw e;
135+
}
136+
137+
// The CDI bean should have been built immediately...
138+
assertTrue( MonitorBean.wasInstantiated() );
139+
assertEquals( 0, MonitorBean.currentFromDbCount() );
140+
assertEquals( 0, MonitorBean.currentToDbCount() );
141+
142+
try {
143+
inTransaction(
144+
sessionFactory,
145+
session -> session.persist( new TheOrmXmlEntity( 1, "me", new MyData( "foo" ) ) )
146+
);
147+
148+
assertEquals( 0, MonitorBean.currentFromDbCount() );
149+
assertEquals( 1, MonitorBean.currentToDbCount() );
150+
151+
inTransaction(
152+
sessionFactory,
153+
session -> {
154+
TheOrmXmlEntity it = session.find( TheOrmXmlEntity.class, 1 );
155+
assertNotNull( it );
156+
}
157+
);
158+
159+
assertEquals( 1, MonitorBean.currentFromDbCount() );
160+
assertEquals( 1, MonitorBean.currentToDbCount() );
161+
}
162+
finally {
163+
inTransaction(
164+
sessionFactory,
165+
session -> {
166+
session.createQuery( "delete TheOrmXmlEntity" ).executeUpdate();
167+
}
168+
);
169+
170+
sessionFactory.close();
171+
}
172+
}
173+
}
102174
}

hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/AttributeConverterTest.java

+35
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,41 @@ public void testBasicOrmXmlConverterApplication() {
219219
}
220220
}
221221

222+
@Test
223+
@TestForIssue(jiraKey = "HHH-14881")
224+
public void testBasicOrmXmlConverterWithOrmXmlPackage() {
225+
final StandardServiceRegistry ssr = new StandardServiceRegistryBuilder().build();
226+
227+
try {
228+
MetadataImplementor metadata = (MetadataImplementor) new MetadataSources( ssr )
229+
.addAnnotatedClass( Tester.class )
230+
.addURL( ConfigHelper.findAsResource( "org/hibernate/test/converter/package.xml" ) )
231+
.getMetadataBuilder()
232+
.build();
233+
234+
PersistentClass tester = metadata.getEntityBinding( Tester.class.getName() );
235+
Property nameProp = tester.getProperty( "name" );
236+
SimpleValue nameValue = (SimpleValue) nameProp.getValue();
237+
Type type = nameValue.getType();
238+
assertNotNull( type );
239+
if ( !AttributeConverterTypeAdapter.class.isInstance( type ) ) {
240+
fail( "AttributeConverter not applied" );
241+
}
242+
243+
final AttributeConverterTypeAdapter typeAdapter = (AttributeConverterTypeAdapter) type;
244+
245+
assertThat( typeAdapter.getDomainJtd().getJavaTypeClass(), equalTo( String.class ) );
246+
assertThat( typeAdapter.getRelationalJtd().getJavaTypeClass(), equalTo( Clob.class ) );
247+
248+
final JdbcType sqlTypeDescriptor = typeAdapter.getJdbcTypeDescriptor();
249+
assertThat( sqlTypeDescriptor.getJdbcTypeCode(), is( Types.CLOB ) );
250+
}
251+
finally {
252+
StandardServiceRegistryBuilder.destroy( ssr );
253+
}
254+
}
255+
256+
222257
@Test
223258
public void testBasicConverterDisableApplication() {
224259
final StandardServiceRegistry ssr = new StandardServiceRegistryBuilder().build();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
3+
<!--
4+
~ Hibernate, Relational Persistence for Idiomatic Java
5+
~
6+
~ License: GNU Lesser General Public License (LGPL), version 2.1 or later.
7+
~ See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
8+
-->
9+
<entity-mappings xmlns="http://xmlns.jcp.org/xml/ns/persistence/orm"
10+
version="2.1">
11+
<entity class="org.hibernate.orm.test.cdi.converters.TheOrmXmlEntity">
12+
<attributes>
13+
<id name="id" />
14+
<basic name="name" />
15+
<basic name="myData" />
16+
</attributes>
17+
</entity>
18+
<converter class="org.hibernate.orm.test.cdi.converters.OrmXmlConverterBean" auto-apply="true"/>
19+
</entity-mappings>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
3+
<!--
4+
~ Hibernate, Relational Persistence for Idiomatic Java
5+
~
6+
~ License: GNU Lesser General Public License (LGPL), version 2.1 or later.
7+
~ See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
8+
-->
9+
<entity-mappings xmlns="http://xmlns.jcp.org/xml/ns/persistence/orm"
10+
version="2.1">
11+
<package>org.hibernate.test.converter</package>
12+
<converter class="org.hibernate.orm.test.mapping.converted.converter.StringClobConverter" auto-apply="true"/>
13+
</entity-mappings>

0 commit comments

Comments
 (0)