HHH-14530 Allow adding pre-parsed XML mappings to MetadataSources

Signed-off-by: Yoann Rodière <yoann@hibernate.org>
This commit is contained in:
Yoann Rodière 2021-03-22 16:36:46 +01:00
parent 571af7bc9e
commit ebb30aa178
6 changed files with 228 additions and 0 deletions

View File

@ -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
*

View File

@ -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

View File

@ -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 <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
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;
}
}
}

View File

@ -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 <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
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;
}
}
}

View File

@ -0,0 +1,22 @@
<?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://java.sun.com/xml/ns/persistence/orm"
version="2.0">
<entity class="org.hibernate.test.annotations.xml.ejb3.PreParsedOrmXmlTest$NonAnnotatedEntity" name="NonAnnotated">
<attributes>
<id name="id">
<generated-value strategy="IDENTITY"/>
</id>
<basic name="name">
<column name="thename"/>
</basic>
</attributes>
</entity>
</entity-mappings>

View File

@ -0,0 +1,18 @@
<?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>.
-->
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="org.hibernate.test.annotations.xml.hbm.PreParsedHbmXmlTest$NonAnnotatedEntity" table="NonAnnotated">
<id name="id">
<generator class="identity"/>
</id>
<property name="name" column="thename"/>
</class>
</hibernate-mapping>