From ebb30aa178a36af567ddd8bf4e0a6481b44ec82f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Yoann=20Rodi=C3=A8re?= Date: Mon, 22 Mar 2021 16:36:46 +0100 Subject: [PATCH] HHH-14530 Allow adding pre-parsed XML mappings to MetadataSources MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Yoann Rodière --- .../org/hibernate/boot/MetadataSources.java | 12 +++ .../java/org/hibernate/cfg/Configuration.java | 20 +++++ .../xml/ejb3/PreParsedOrmXmlTest.java | 78 +++++++++++++++++++ .../xml/hbm/PreParsedHbmXmlTest.java | 78 +++++++++++++++++++ .../annotations/xml/ejb3/pre-parsed-orm.xml | 22 ++++++ .../annotations/xml/hbm/pre-parsed-hbm.xml | 18 +++++ 6 files changed, 228 insertions(+) create mode 100644 hibernate-core/src/test/java/org/hibernate/test/annotations/xml/ejb3/PreParsedOrmXmlTest.java create mode 100644 hibernate-core/src/test/java/org/hibernate/test/annotations/xml/hbm/PreParsedHbmXmlTest.java create mode 100644 hibernate-core/src/test/resources/org/hibernate/test/annotations/xml/ejb3/pre-parsed-orm.xml create mode 100644 hibernate-core/src/test/resources/org/hibernate/test/annotations/xml/hbm/pre-parsed-hbm.xml diff --git a/hibernate-core/src/main/java/org/hibernate/boot/MetadataSources.java b/hibernate-core/src/main/java/org/hibernate/boot/MetadataSources.java index 5e86f504ad..932ac5c16c 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/MetadataSources.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/MetadataSources.java @@ -338,6 +338,18 @@ public class MetadataSources implements Serializable { return this; } + /** + * Add XML mapping bindings created from an arbitrary source by the {@link #getXmlMappingBinderAccess() binder}. + * + * @param binding The binding. + * + * @return this (for method chaining purposes) + */ + public MetadataSources addXmlBinding(Binding binding) { + getXmlBindingsForWrite().add( binding ); + return this; + } + /** * See {@link #addCacheableFile(java.io.File)} for description * 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 85b63d24a4..d6c4715f1a 100644 --- a/hibernate-core/src/main/java/org/hibernate/cfg/Configuration.java +++ b/hibernate-core/src/main/java/org/hibernate/cfg/Configuration.java @@ -29,6 +29,7 @@ import org.hibernate.boot.Metadata; import org.hibernate.boot.MetadataBuilder; import org.hibernate.boot.MetadataSources; import org.hibernate.boot.SessionFactoryBuilder; +import org.hibernate.boot.jaxb.spi.Binding; import org.hibernate.boot.model.TypeContributor; import org.hibernate.boot.model.naming.ImplicitNamingStrategy; import org.hibernate.boot.model.naming.ImplicitNamingStrategyJpaCompliantImpl; @@ -39,6 +40,7 @@ import org.hibernate.boot.registry.BootstrapServiceRegistry; import org.hibernate.boot.registry.BootstrapServiceRegistryBuilder; import org.hibernate.boot.registry.StandardServiceRegistry; import org.hibernate.boot.registry.StandardServiceRegistryBuilder; +import org.hibernate.boot.spi.XmlMappingBinderAccess; import org.hibernate.cfg.annotations.NamedEntityGraphDefinition; import org.hibernate.cfg.annotations.NamedProcedureCallDefinition; import org.hibernate.context.spi.CurrentTenantIdentifierResolver; @@ -364,6 +366,13 @@ public class Configuration { return this; } + /** + * @return An object capable of parsing XML mapping files that can then be passed to {@link #addXmlMapping(Binding)}. + */ + public XmlMappingBinderAccess getXmlMappingBinderAccess() { + return metadataSources.getXmlMappingBinderAccess(); + } + /** * @deprecated No longer supported. */ @@ -371,6 +380,17 @@ public class Configuration { public void add(XmlDocument metadataXml) { } + /** + * Read mappings that were parsed using {@link #getXmlMappingBinderAccess()}. + * + * @param binding the parsed mapping + * @return this (for method chaining purposes) + */ + public Configuration addXmlMapping(Binding binding) { + metadataSources.addXmlBinding( binding ); + return this; + } + /** * Add a cached mapping file. A cached file is a serialized representation * of the DOM structure of a particular mapping. It is saved from a previous diff --git a/hibernate-core/src/test/java/org/hibernate/test/annotations/xml/ejb3/PreParsedOrmXmlTest.java b/hibernate-core/src/test/java/org/hibernate/test/annotations/xml/ejb3/PreParsedOrmXmlTest.java new file mode 100644 index 0000000000..04640901d8 --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/test/annotations/xml/ejb3/PreParsedOrmXmlTest.java @@ -0,0 +1,78 @@ +/* + * 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 . + */ +package org.hibernate.test.annotations.xml.ejb3; + +import java.io.IOException; +import java.io.InputStream; +import java.io.UncheckedIOException; + +import org.hibernate.boot.jaxb.spi.Binding; +import org.hibernate.cfg.Configuration; + +import org.hibernate.testing.TestForIssue; +import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; +import org.junit.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +@TestForIssue(jiraKey = "HHH-14530") +public class PreParsedOrmXmlTest extends BaseCoreFunctionalTestCase { + + @Override + protected void addMappings(Configuration configuration) { + super.addMappings( configuration ); + try (InputStream xmlStream = Thread.currentThread().getContextClassLoader() + .getResourceAsStream( "org/hibernate/test/annotations/xml/ejb3/pre-parsed-orm.xml" )) { + Binding parsed = configuration.getXmlMappingBinderAccess().bind( xmlStream ); + configuration.addXmlMapping( parsed ); + } + catch (IOException e) { + throw new UncheckedIOException( e ); + } + } + + @Test + public void testPreParsedOrmXml() { + // Just check that the entity can be persisted, which means the mapping file was taken into account + NonAnnotatedEntity persistedEntity = new NonAnnotatedEntity( "someName" ); + inTransaction( s -> s.persist( persistedEntity ) ); + inTransaction( s -> { + NonAnnotatedEntity retrievedEntity = s.find( NonAnnotatedEntity.class, persistedEntity.getId() ); + assertThat( retrievedEntity ).extracting( NonAnnotatedEntity::getName ) + .isEqualTo( persistedEntity.getName() ); + } ); + } + + public static class NonAnnotatedEntity { + private long id; + + private String name; + + public NonAnnotatedEntity() { + } + + public NonAnnotatedEntity(String name) { + this.name = name; + } + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + } +} diff --git a/hibernate-core/src/test/java/org/hibernate/test/annotations/xml/hbm/PreParsedHbmXmlTest.java b/hibernate-core/src/test/java/org/hibernate/test/annotations/xml/hbm/PreParsedHbmXmlTest.java new file mode 100644 index 0000000000..441751aa61 --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/test/annotations/xml/hbm/PreParsedHbmXmlTest.java @@ -0,0 +1,78 @@ +/* + * 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 . + */ +package org.hibernate.test.annotations.xml.hbm; + +import java.io.IOException; +import java.io.InputStream; +import java.io.UncheckedIOException; + +import org.hibernate.boot.jaxb.spi.Binding; +import org.hibernate.cfg.Configuration; + +import org.hibernate.testing.TestForIssue; +import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; +import org.junit.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +@TestForIssue(jiraKey = "HHH-14530") +public class PreParsedHbmXmlTest extends BaseCoreFunctionalTestCase { + + @Override + protected void addMappings(Configuration configuration) { + super.addMappings( configuration ); + try (InputStream xmlStream = Thread.currentThread().getContextClassLoader() + .getResourceAsStream( "org/hibernate/test/annotations/xml/hbm/pre-parsed-hbm.xml" )) { + Binding parsed = configuration.getXmlMappingBinderAccess().bind( xmlStream ); + configuration.addXmlMapping( parsed ); + } + catch (IOException e) { + throw new UncheckedIOException( e ); + } + } + + @Test + public void testPreParsedHbmXml() { + // Just check that the entity can be persisted, which means the mapping file was taken into account + NonAnnotatedEntity persistedEntity = new NonAnnotatedEntity( "someName" ); + inTransaction( s -> s.persist( persistedEntity ) ); + inTransaction( s -> { + NonAnnotatedEntity retrievedEntity = s.find( NonAnnotatedEntity.class, persistedEntity.getId() ); + assertThat( retrievedEntity ).extracting( NonAnnotatedEntity::getName ) + .isEqualTo( persistedEntity.getName() ); + } ); + } + + public static class NonAnnotatedEntity { + private long id; + + private String name; + + public NonAnnotatedEntity() { + } + + public NonAnnotatedEntity(String name) { + this.name = name; + } + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + } +} diff --git a/hibernate-core/src/test/resources/org/hibernate/test/annotations/xml/ejb3/pre-parsed-orm.xml b/hibernate-core/src/test/resources/org/hibernate/test/annotations/xml/ejb3/pre-parsed-orm.xml new file mode 100644 index 0000000000..bc06432f18 --- /dev/null +++ b/hibernate-core/src/test/resources/org/hibernate/test/annotations/xml/ejb3/pre-parsed-orm.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/hibernate-core/src/test/resources/org/hibernate/test/annotations/xml/hbm/pre-parsed-hbm.xml b/hibernate-core/src/test/resources/org/hibernate/test/annotations/xml/hbm/pre-parsed-hbm.xml new file mode 100644 index 0000000000..8aca88a94f --- /dev/null +++ b/hibernate-core/src/test/resources/org/hibernate/test/annotations/xml/hbm/pre-parsed-hbm.xml @@ -0,0 +1,18 @@ + + + + + + + + + + +