HHH-18060 - HbXmlTransformer work
* non-aggregated composite id * extends
This commit is contained in:
parent
4d0422fe05
commit
d25f028222
|
@ -22,9 +22,11 @@ import org.hibernate.HibernateException;
|
||||||
import org.hibernate.Internal;
|
import org.hibernate.Internal;
|
||||||
import org.hibernate.boot.archive.spi.InputStreamAccess;
|
import org.hibernate.boot.archive.spi.InputStreamAccess;
|
||||||
import org.hibernate.boot.internal.MetadataBuilderImpl;
|
import org.hibernate.boot.internal.MetadataBuilderImpl;
|
||||||
|
import org.hibernate.boot.jaxb.hbm.spi.JaxbHbmHibernateMapping;
|
||||||
import org.hibernate.boot.jaxb.internal.XmlSources;
|
import org.hibernate.boot.jaxb.internal.XmlSources;
|
||||||
import org.hibernate.boot.jaxb.spi.JaxbBindableMappingDescriptor;
|
import org.hibernate.boot.jaxb.mapping.spi.JaxbEntityMappingsImpl;
|
||||||
import org.hibernate.boot.jaxb.spi.Binding;
|
import org.hibernate.boot.jaxb.spi.Binding;
|
||||||
|
import org.hibernate.boot.jaxb.spi.JaxbBindableMappingDescriptor;
|
||||||
import org.hibernate.boot.jaxb.spi.XmlSource;
|
import org.hibernate.boot.jaxb.spi.XmlSource;
|
||||||
import org.hibernate.boot.registry.BootstrapServiceRegistry;
|
import org.hibernate.boot.registry.BootstrapServiceRegistry;
|
||||||
import org.hibernate.boot.registry.BootstrapServiceRegistryBuilder;
|
import org.hibernate.boot.registry.BootstrapServiceRegistryBuilder;
|
||||||
|
@ -37,6 +39,8 @@ import org.hibernate.internal.CoreMessageLogger;
|
||||||
import org.hibernate.service.ServiceRegistry;
|
import org.hibernate.service.ServiceRegistry;
|
||||||
import org.hibernate.type.SerializationException;
|
import org.hibernate.type.SerializationException;
|
||||||
|
|
||||||
|
import static org.hibernate.internal.util.collections.CollectionHelper.arrayList;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Entry point for working with sources of O/R mapping metadata, either
|
* Entry point for working with sources of O/R mapping metadata, either
|
||||||
* in the form of annotated classes, or as XML mapping documents.
|
* in the form of annotated classes, or as XML mapping documents.
|
||||||
|
@ -65,7 +69,9 @@ public class MetadataSources implements Serializable {
|
||||||
|
|
||||||
private XmlMappingBinderAccess xmlMappingBinderAccess;
|
private XmlMappingBinderAccess xmlMappingBinderAccess;
|
||||||
|
|
||||||
private List<Binding<JaxbBindableMappingDescriptor>> xmlBindings;
|
private List<Binding<JaxbEntityMappingsImpl>> mappingXmlBindings;
|
||||||
|
private List<Binding<JaxbHbmHibernateMapping>> hbmXmlBindings;
|
||||||
|
|
||||||
private LinkedHashSet<Class<?>> annotatedClasses;
|
private LinkedHashSet<Class<?>> annotatedClasses;
|
||||||
private LinkedHashSet<String> annotatedClassNames;
|
private LinkedHashSet<String> annotatedClassNames;
|
||||||
private LinkedHashSet<String> annotatedPackages;
|
private LinkedHashSet<String> annotatedPackages;
|
||||||
|
@ -121,8 +127,36 @@ public class MetadataSources implements Serializable {
|
||||||
return xmlMappingBinderAccess;
|
return xmlMappingBinderAccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated Prefer {@linkplain #getMappingXmlBindings()} and/or {@linkplain #getHbmXmlBindings()}
|
||||||
|
*/
|
||||||
|
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||||
|
@Deprecated(since = "7.0")
|
||||||
public List<Binding<JaxbBindableMappingDescriptor>> getXmlBindings() {
|
public List<Binding<JaxbBindableMappingDescriptor>> getXmlBindings() {
|
||||||
return xmlBindings == null ? Collections.emptyList() : xmlBindings;
|
if ( mappingXmlBindings == null && hbmXmlBindings == null ) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( hbmXmlBindings == null ) {
|
||||||
|
return (List) mappingXmlBindings;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( mappingXmlBindings == null ) {
|
||||||
|
return (List) hbmXmlBindings;
|
||||||
|
}
|
||||||
|
|
||||||
|
final ArrayList<Binding<JaxbBindableMappingDescriptor>> combined = arrayList( mappingXmlBindings.size() + hbmXmlBindings.size() );
|
||||||
|
combined.addAll( (List) mappingXmlBindings );
|
||||||
|
combined.addAll( (List) hbmXmlBindings );
|
||||||
|
return combined;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Binding<JaxbEntityMappingsImpl>> getMappingXmlBindings() {
|
||||||
|
return mappingXmlBindings == null ? Collections.emptyList() : mappingXmlBindings;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Binding<JaxbHbmHibernateMapping>> getHbmXmlBindings() {
|
||||||
|
return hbmXmlBindings == null ? Collections.emptyList() : hbmXmlBindings;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Collection<String> getAnnotatedPackages() {
|
public Collection<String> getAnnotatedPackages() {
|
||||||
|
@ -329,7 +363,7 @@ public class MetadataSources implements Serializable {
|
||||||
public MetadataSources addResource(String name) {
|
public MetadataSources addResource(String name) {
|
||||||
final XmlSource xmlSource = XmlSources.fromResource( name, classLoaderService );
|
final XmlSource xmlSource = XmlSources.fromResource( name, classLoaderService );
|
||||||
final XmlMappingBinderAccess binderAccess = getXmlMappingBinderAccess();
|
final XmlMappingBinderAccess binderAccess = getXmlMappingBinderAccess();
|
||||||
getXmlBindingsForWrite().add( xmlSource.doBind( binderAccess.getMappingBinder() ) );
|
addXmlBinding( xmlSource.doBind( binderAccess.getMappingBinder() ) );
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -359,7 +393,7 @@ public class MetadataSources implements Serializable {
|
||||||
public MetadataSources addFile(File file) {
|
public MetadataSources addFile(File file) {
|
||||||
final XmlSource xmlSource = XmlSources.fromFile( file );
|
final XmlSource xmlSource = XmlSources.fromFile( file );
|
||||||
final XmlMappingBinderAccess binderAccess = getXmlMappingBinderAccess();
|
final XmlMappingBinderAccess binderAccess = getXmlMappingBinderAccess();
|
||||||
getXmlBindingsForWrite().add( xmlSource.doBind( binderAccess.getMappingBinder() ) );
|
addXmlBinding( xmlSource.doBind( binderAccess.getMappingBinder() ) );
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -372,8 +406,45 @@ public class MetadataSources implements Serializable {
|
||||||
* @return this (for method chaining purposes)
|
* @return this (for method chaining purposes)
|
||||||
*/
|
*/
|
||||||
public MetadataSources addXmlBinding(Binding<?> binding) {
|
public MetadataSources addXmlBinding(Binding<?> binding) {
|
||||||
|
if ( binding.getRoot() instanceof JaxbEntityMappingsImpl ) {
|
||||||
//noinspection unchecked
|
//noinspection unchecked
|
||||||
getXmlBindingsForWrite().add( (Binding<JaxbBindableMappingDescriptor>) binding );
|
return addMappingXmlBinding( (Binding<JaxbEntityMappingsImpl>) binding );
|
||||||
|
}
|
||||||
|
else if ( binding.getRoot() instanceof JaxbHbmHibernateMapping ) {
|
||||||
|
//noinspection unchecked
|
||||||
|
return addHbmXmlBinding( (Binding<JaxbHbmHibernateMapping>) binding );
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new UnsupportedOperationException( "Unknown type of binding : " + binding.getRoot() );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a {@linkplain Binding binding} for {@linkplain JaxbEntityMappingsImpl mapping.xsd} document
|
||||||
|
*
|
||||||
|
* @param binding The binding
|
||||||
|
*
|
||||||
|
* @return this (for method chaining purposes)
|
||||||
|
*/
|
||||||
|
public MetadataSources addMappingXmlBinding(Binding<JaxbEntityMappingsImpl> binding) {
|
||||||
|
if ( mappingXmlBindings == null ) {
|
||||||
|
mappingXmlBindings = new ArrayList<>();
|
||||||
|
}
|
||||||
|
mappingXmlBindings.add( binding );
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a {@linkplain Binding binding} for {@linkplain JaxbHbmHibernateMapping hbm.xsd} document
|
||||||
|
*
|
||||||
|
* @param binding The binding
|
||||||
|
*
|
||||||
|
* @return this (for method chaining purposes)
|
||||||
|
*/
|
||||||
|
public MetadataSources addHbmXmlBinding(Binding<JaxbHbmHibernateMapping> binding) {
|
||||||
|
if ( hbmXmlBindings == null ) {
|
||||||
|
hbmXmlBindings = new ArrayList<>();
|
||||||
|
}
|
||||||
|
hbmXmlBindings.add( binding );
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -444,7 +515,7 @@ public class MetadataSources implements Serializable {
|
||||||
public MetadataSources addCacheableFile(File file, File cacheDirectory) {
|
public MetadataSources addCacheableFile(File file, File cacheDirectory) {
|
||||||
final XmlSource xmlSource = XmlSources.fromCacheableFile( file, cacheDirectory );
|
final XmlSource xmlSource = XmlSources.fromCacheableFile( file, cacheDirectory );
|
||||||
final XmlMappingBinderAccess binderAccess = getXmlMappingBinderAccess();
|
final XmlMappingBinderAccess binderAccess = getXmlMappingBinderAccess();
|
||||||
getXmlBindingsForWrite().add( xmlSource.doBind( binderAccess.getMappingBinder() ) );
|
addXmlBinding( xmlSource.doBind( binderAccess.getMappingBinder() ) );
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -464,7 +535,7 @@ public class MetadataSources implements Serializable {
|
||||||
public MetadataSources addCacheableFileStrictly(File file) throws SerializationException {
|
public MetadataSources addCacheableFileStrictly(File file) throws SerializationException {
|
||||||
final XmlSource xmlSource = XmlSources.fromCacheableFile( file, true );
|
final XmlSource xmlSource = XmlSources.fromCacheableFile( file, true );
|
||||||
final XmlMappingBinderAccess binderAccess = getXmlMappingBinderAccess();
|
final XmlMappingBinderAccess binderAccess = getXmlMappingBinderAccess();
|
||||||
getXmlBindingsForWrite().add( xmlSource.doBind( binderAccess.getMappingBinder() ) );
|
addXmlBinding( xmlSource.doBind( binderAccess.getMappingBinder() ) );
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -484,7 +555,7 @@ public class MetadataSources implements Serializable {
|
||||||
public MetadataSources addCacheableFileStrictly(File file, File cacheDir) throws SerializationException {
|
public MetadataSources addCacheableFileStrictly(File file, File cacheDir) throws SerializationException {
|
||||||
final XmlSource xmlSource = XmlSources.fromCacheableFile( file, cacheDir, true );
|
final XmlSource xmlSource = XmlSources.fromCacheableFile( file, cacheDir, true );
|
||||||
final XmlMappingBinderAccess binderAccess = getXmlMappingBinderAccess();
|
final XmlMappingBinderAccess binderAccess = getXmlMappingBinderAccess();
|
||||||
getXmlBindingsForWrite().add( xmlSource.doBind( binderAccess.getMappingBinder() ) );
|
addXmlBinding( xmlSource.doBind( binderAccess.getMappingBinder() ) );
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -498,7 +569,7 @@ public class MetadataSources implements Serializable {
|
||||||
public MetadataSources addInputStream(InputStreamAccess xmlInputStreamAccess) {
|
public MetadataSources addInputStream(InputStreamAccess xmlInputStreamAccess) {
|
||||||
final XmlSource xmlSource = XmlSources.fromStream( xmlInputStreamAccess );
|
final XmlSource xmlSource = XmlSources.fromStream( xmlInputStreamAccess );
|
||||||
final XmlMappingBinderAccess binderAccess = getXmlMappingBinderAccess();
|
final XmlMappingBinderAccess binderAccess = getXmlMappingBinderAccess();
|
||||||
getXmlBindingsForWrite().add( xmlSource.doBind( binderAccess.getMappingBinder() ) );
|
addXmlBinding( xmlSource.doBind( binderAccess.getMappingBinder() ) );
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -512,7 +583,7 @@ public class MetadataSources implements Serializable {
|
||||||
public MetadataSources addInputStream(InputStream xmlInputStream) {
|
public MetadataSources addInputStream(InputStream xmlInputStream) {
|
||||||
final XmlSource xmlSource = XmlSources.fromStream( xmlInputStream );
|
final XmlSource xmlSource = XmlSources.fromStream( xmlInputStream );
|
||||||
final XmlMappingBinderAccess binderAccess = getXmlMappingBinderAccess();
|
final XmlMappingBinderAccess binderAccess = getXmlMappingBinderAccess();
|
||||||
getXmlBindingsForWrite().add( xmlSource.doBind( binderAccess.getMappingBinder() ) );
|
addXmlBinding( xmlSource.doBind( binderAccess.getMappingBinder() ) );
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -526,7 +597,7 @@ public class MetadataSources implements Serializable {
|
||||||
public MetadataSources addURL(URL url) {
|
public MetadataSources addURL(URL url) {
|
||||||
final XmlSource xmlSource = XmlSources.fromUrl( url );
|
final XmlSource xmlSource = XmlSources.fromUrl( url );
|
||||||
final XmlMappingBinderAccess binderAccess = getXmlMappingBinderAccess();
|
final XmlMappingBinderAccess binderAccess = getXmlMappingBinderAccess();
|
||||||
getXmlBindingsForWrite().add( xmlSource.doBind( binderAccess.getMappingBinder() ) );
|
addXmlBinding( xmlSource.doBind( binderAccess.getMappingBinder() ) );
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -544,18 +615,11 @@ public class MetadataSources implements Serializable {
|
||||||
final XmlMappingBinderAccess binderAccess = getXmlMappingBinderAccess();
|
final XmlMappingBinderAccess binderAccess = getXmlMappingBinderAccess();
|
||||||
XmlSources.fromJar(
|
XmlSources.fromJar(
|
||||||
jar,
|
jar,
|
||||||
xmlSource -> getXmlBindingsForWrite().add( xmlSource.doBind( binderAccess.getMappingBinder() ) )
|
xmlSource -> addXmlBinding( xmlSource.doBind( binderAccess.getMappingBinder() ) )
|
||||||
);
|
);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<Binding<JaxbBindableMappingDescriptor>> getXmlBindingsForWrite() {
|
|
||||||
if ( xmlBindings == null ) {
|
|
||||||
xmlBindings = new ArrayList<>();
|
|
||||||
}
|
|
||||||
return xmlBindings;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read all {@code .hbm.xml} mapping documents from a directory tree.
|
* Read all {@code .hbm.xml} mapping documents from a directory tree.
|
||||||
* <p>
|
* <p>
|
||||||
|
|
|
@ -83,6 +83,7 @@ import org.hibernate.boot.jaxb.hbm.spi.JaxbHbmRootEntityType;
|
||||||
import org.hibernate.boot.jaxb.hbm.spi.JaxbHbmSecondaryTableType;
|
import org.hibernate.boot.jaxb.hbm.spi.JaxbHbmSecondaryTableType;
|
||||||
import org.hibernate.boot.jaxb.hbm.spi.JaxbHbmSetType;
|
import org.hibernate.boot.jaxb.hbm.spi.JaxbHbmSetType;
|
||||||
import org.hibernate.boot.jaxb.hbm.spi.JaxbHbmSimpleIdType;
|
import org.hibernate.boot.jaxb.hbm.spi.JaxbHbmSimpleIdType;
|
||||||
|
import org.hibernate.boot.jaxb.hbm.spi.JaxbHbmSubclassEntityBaseDefinition;
|
||||||
import org.hibernate.boot.jaxb.hbm.spi.JaxbHbmSynchronizeType;
|
import org.hibernate.boot.jaxb.hbm.spi.JaxbHbmSynchronizeType;
|
||||||
import org.hibernate.boot.jaxb.hbm.spi.JaxbHbmTimestampAttributeType;
|
import org.hibernate.boot.jaxb.hbm.spi.JaxbHbmTimestampAttributeType;
|
||||||
import org.hibernate.boot.jaxb.hbm.spi.JaxbHbmUnionSubclassEntityType;
|
import org.hibernate.boot.jaxb.hbm.spi.JaxbHbmUnionSubclassEntityType;
|
||||||
|
@ -155,6 +156,7 @@ import org.hibernate.boot.jaxb.mapping.spi.JaxbTableImpl;
|
||||||
import org.hibernate.boot.jaxb.mapping.spi.JaxbTransientImpl;
|
import org.hibernate.boot.jaxb.mapping.spi.JaxbTransientImpl;
|
||||||
import org.hibernate.boot.jaxb.mapping.spi.JaxbUserTypeImpl;
|
import org.hibernate.boot.jaxb.mapping.spi.JaxbUserTypeImpl;
|
||||||
import org.hibernate.boot.jaxb.mapping.spi.JaxbVersionImpl;
|
import org.hibernate.boot.jaxb.mapping.spi.JaxbVersionImpl;
|
||||||
|
import org.hibernate.boot.jaxb.spi.Binding;
|
||||||
import org.hibernate.internal.util.StringHelper;
|
import org.hibernate.internal.util.StringHelper;
|
||||||
import org.hibernate.internal.util.collections.CollectionHelper;
|
import org.hibernate.internal.util.collections.CollectionHelper;
|
||||||
|
|
||||||
|
@ -170,54 +172,65 @@ import jakarta.xml.bind.JAXBException;
|
||||||
import jakarta.xml.bind.Marshaller;
|
import jakarta.xml.bind.Marshaller;
|
||||||
|
|
||||||
import static org.hibernate.boot.jaxb.hbm.transform.HbmTransformationLogging.TRANSFORMATION_LOGGER;
|
import static org.hibernate.boot.jaxb.hbm.transform.HbmTransformationLogging.TRANSFORMATION_LOGGER;
|
||||||
import static org.hibernate.internal.util.StringHelper.coalesce;
|
|
||||||
import static org.hibernate.internal.util.StringHelper.isNotEmpty;
|
import static org.hibernate.internal.util.StringHelper.isNotEmpty;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Transforms a JAXB binding of a hbm.xml file into a unified orm.xml representation
|
* Transforms {@code hbm.xml} {@linkplain JaxbHbmHibernateMapping JAXB} bindings into
|
||||||
|
* {@code mapping.xml} {@linkplain JaxbEntityMappingsImpl JAXB} bindings
|
||||||
*
|
*
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
* @author Brett Meyer
|
* @author Brett Meyer
|
||||||
*
|
|
||||||
* @implNote This transformation happens on the JAXB model level creating
|
|
||||||
* a {@link JaxbEntityMappingsImpl} "copy" of the {@link JaxbHbmHibernateMapping}
|
|
||||||
* representation
|
|
||||||
*/
|
*/
|
||||||
public class HbmXmlTransformer {
|
public class HbmXmlTransformer {
|
||||||
/**
|
/**
|
||||||
* Main entry into hbm.xml transformation
|
* Transforms a list of {@code hbm.xml} JAXB bindings into a list of {@code mapping.xml} JAXB bindings
|
||||||
*
|
*
|
||||||
* @param hbmXmlMapping The hbm.xml mapping to be transformed
|
* @param hbmXmlBindings The list of {@code hbm.xml} JAXB bindings
|
||||||
* @param origin The origin of the hbm.xml mapping
|
* @param unsupportedFeatureHandling How to handle {@code hbm.xml} features we don't transform
|
||||||
* @return The transformed representation
|
*
|
||||||
|
* @return The list of {@code mapping.xml} JAXB bindings
|
||||||
*/
|
*/
|
||||||
public static JaxbEntityMappingsImpl transform(JaxbHbmHibernateMapping hbmXmlMapping, Origin origin, Options options) {
|
public static List<Binding<JaxbEntityMappingsImpl>> transform(
|
||||||
return new HbmXmlTransformer( hbmXmlMapping, origin, options ).doTransform();
|
List<Binding<JaxbHbmHibernateMapping>> hbmXmlBindings,
|
||||||
|
UnsupportedFeatureHandling unsupportedFeatureHandling) {
|
||||||
|
final TransformationState transformationState = new TransformationState( hbmXmlBindings );
|
||||||
|
TransformationPreprocessor.preprocessHbmXml( hbmXmlBindings, transformationState );
|
||||||
|
|
||||||
|
for ( int i = 0; i < hbmXmlBindings.size(); i++ ) {
|
||||||
|
final Binding<JaxbHbmHibernateMapping> hbmJaxbBinding = hbmXmlBindings.get( i );
|
||||||
|
final Binding<JaxbEntityMappingsImpl> mappingJaxbBinding = transformationState.getMappingBindings().get( i );
|
||||||
|
final HbmXmlTransformer hbmXmlTransformer = new HbmXmlTransformer(
|
||||||
|
hbmJaxbBinding,
|
||||||
|
mappingJaxbBinding,
|
||||||
|
transformationState,
|
||||||
|
unsupportedFeatureHandling
|
||||||
|
);
|
||||||
|
hbmXmlTransformer.doTransform();
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface Options {
|
return transformationState.getMappingBindings();
|
||||||
UnsupportedFeatureHandling unsupportedFeatureHandling();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private final Origin origin;
|
private final Origin origin;
|
||||||
private final JaxbHbmHibernateMapping hbmXmlMapping;
|
private final JaxbHbmHibernateMapping hbmXmlMapping;
|
||||||
private final JaxbEntityMappingsImpl ormRoot;
|
private final JaxbEntityMappingsImpl ormRoot;
|
||||||
|
private final TransformationState transformationState;
|
||||||
|
private final UnsupportedFeatureHandling unsupportedFeatureHandling;
|
||||||
|
|
||||||
private final Options options;
|
|
||||||
|
|
||||||
public HbmXmlTransformer(JaxbHbmHibernateMapping hbmXmlMapping, Origin origin, Options options) {
|
|
||||||
this.origin = origin;
|
|
||||||
this.hbmXmlMapping = hbmXmlMapping;
|
|
||||||
this.options = options;
|
|
||||||
|
|
||||||
this.ormRoot = new JaxbEntityMappingsImpl();
|
|
||||||
this.ormRoot.setDescription(
|
|
||||||
"mapping.xml document auto-generated from legacy hbm.xml format via transformation - " + origin.getName()
|
|
||||||
);
|
|
||||||
|
|
||||||
|
private HbmXmlTransformer(
|
||||||
|
Binding<JaxbHbmHibernateMapping> hbmJaxbBinding,
|
||||||
|
Binding<JaxbEntityMappingsImpl> mappingJaxbBinding,
|
||||||
|
TransformationState transformationState,
|
||||||
|
UnsupportedFeatureHandling unsupportedFeatureHandling) {
|
||||||
|
this.origin = hbmJaxbBinding.getOrigin();
|
||||||
|
this.hbmXmlMapping = hbmJaxbBinding.getRoot();
|
||||||
|
this.ormRoot = mappingJaxbBinding.getRoot();
|
||||||
|
this.transformationState = transformationState;
|
||||||
|
this.unsupportedFeatureHandling = unsupportedFeatureHandling;
|
||||||
}
|
}
|
||||||
|
|
||||||
private JaxbEntityMappingsImpl doTransform() {
|
private void doTransform() {
|
||||||
TRANSFORMATION_LOGGER.tracef(
|
TRANSFORMATION_LOGGER.tracef(
|
||||||
"Starting hbm.xml transformation - `%s`",
|
"Starting hbm.xml transformation - `%s`",
|
||||||
origin
|
origin
|
||||||
|
@ -247,7 +260,6 @@ public class HbmXmlTransformer {
|
||||||
if ( TRANSFORMATION_LOGGER.isDebugEnabled() ) {
|
if ( TRANSFORMATION_LOGGER.isDebugEnabled() ) {
|
||||||
dumpTransformed( origin, ormRoot );
|
dumpTransformed( origin, ormRoot );
|
||||||
}
|
}
|
||||||
return ormRoot;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void dumpTransformed(Origin origin, JaxbEntityMappingsImpl ormRoot) {
|
private static void dumpTransformed(Origin origin, JaxbEntityMappingsImpl ormRoot) {
|
||||||
|
@ -293,7 +305,7 @@ public class HbmXmlTransformer {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleUnsupported(PickHandler pickHandler, String message, Object... messageArgs) {
|
private void handleUnsupported(PickHandler pickHandler, String message, Object... messageArgs) {
|
||||||
switch ( options.unsupportedFeatureHandling() ) {
|
switch ( unsupportedFeatureHandling ) {
|
||||||
case ERROR -> throw new UnsupportedOperationException(
|
case ERROR -> throw new UnsupportedOperationException(
|
||||||
String.format(
|
String.format(
|
||||||
Locale.ROOT,
|
Locale.ROOT,
|
||||||
|
@ -807,32 +819,28 @@ public class HbmXmlTransformer {
|
||||||
// 2) ?? Have abstract hbm class mappings become MappedSuperclass mappings ??
|
// 2) ?? Have abstract hbm class mappings become MappedSuperclass mappings ??
|
||||||
|
|
||||||
for ( JaxbHbmRootEntityType hbmClass : hbmXmlMapping.getClazz() ) {
|
for ( JaxbHbmRootEntityType hbmClass : hbmXmlMapping.getClazz() ) {
|
||||||
final JaxbEntityImpl entity = new JaxbEntityImpl();
|
final JaxbEntityImpl entity = transformationState.getEntityXref().get( hbmClass );
|
||||||
ormRoot.getEntities().add( entity );
|
|
||||||
transferRootEntity( hbmClass, entity );
|
transferRootEntity( hbmClass, entity );
|
||||||
}
|
}
|
||||||
|
|
||||||
for ( JaxbHbmDiscriminatorSubclassEntityType hbmSubclass : hbmXmlMapping.getSubclass() ) {
|
for ( JaxbHbmDiscriminatorSubclassEntityType hbmSubclass : hbmXmlMapping.getSubclass() ) {
|
||||||
final JaxbEntityImpl entity = new JaxbEntityImpl();
|
final JaxbEntityImpl entity = transformationState.getEntityXref().get( hbmSubclass );
|
||||||
ormRoot.getEntities().add( entity );
|
|
||||||
transferDiscriminatorSubclass( hbmSubclass, entity );
|
transferDiscriminatorSubclass( hbmSubclass, entity );
|
||||||
}
|
}
|
||||||
|
|
||||||
for ( JaxbHbmJoinedSubclassEntityType hbmSubclass : hbmXmlMapping.getJoinedSubclass() ) {
|
for ( JaxbHbmJoinedSubclassEntityType hbmSubclass : hbmXmlMapping.getJoinedSubclass() ) {
|
||||||
final JaxbEntityImpl entity = new JaxbEntityImpl();
|
final JaxbEntityImpl entity = transformationState.getEntityXref().get( hbmSubclass );
|
||||||
ormRoot.getEntities().add( entity );
|
|
||||||
transferJoinedSubclass( hbmSubclass, entity );
|
transferJoinedSubclass( hbmSubclass, entity );
|
||||||
}
|
}
|
||||||
|
|
||||||
for ( JaxbHbmUnionSubclassEntityType hbmSubclass : hbmXmlMapping.getUnionSubclass() ) {
|
for ( JaxbHbmUnionSubclassEntityType hbmSubclass : hbmXmlMapping.getUnionSubclass() ) {
|
||||||
final JaxbEntityImpl entity = new JaxbEntityImpl();
|
final JaxbEntityImpl entity = transformationState.getEntityXref().get( hbmSubclass );
|
||||||
ormRoot.getEntities().add( entity );
|
|
||||||
transferUnionSubclass( hbmSubclass, entity );
|
transferUnionSubclass( hbmSubclass, entity );
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private String extractEntityName(EntityInfo entityInfo) {
|
private static String extractEntityName(EntityInfo entityInfo) {
|
||||||
if ( entityInfo.getEntityName() != null ) {
|
if ( entityInfo.getEntityName() != null ) {
|
||||||
return entityInfo.getEntityName();
|
return entityInfo.getEntityName();
|
||||||
}
|
}
|
||||||
|
@ -901,12 +909,12 @@ public class HbmXmlTransformer {
|
||||||
entity.setSqlRestriction( hbmClass.getWhere() );
|
entity.setSqlRestriction( hbmClass.getWhere() );
|
||||||
|
|
||||||
if ( !hbmClass.getTuplizer().isEmpty() ) {
|
if ( !hbmClass.getTuplizer().isEmpty() ) {
|
||||||
if ( options.unsupportedFeatureHandling() == UnsupportedFeatureHandling.ERROR ) {
|
if ( unsupportedFeatureHandling == UnsupportedFeatureHandling.ERROR ) {
|
||||||
throw new MappingException( "HBM transformation: Tuplizer not supported", origin );
|
throw new MappingException( "HBM transformation: Tuplizer not supported", origin );
|
||||||
}
|
}
|
||||||
|
|
||||||
TRANSFORMATION_LOGGER.logf(
|
TRANSFORMATION_LOGGER.logf(
|
||||||
options.unsupportedFeatureHandling() == UnsupportedFeatureHandling.WARN
|
unsupportedFeatureHandling == UnsupportedFeatureHandling.WARN
|
||||||
? Logger.Level.WARN
|
? Logger.Level.WARN
|
||||||
: Logger.Level.DEBUG,
|
: Logger.Level.DEBUG,
|
||||||
"Transformation of <tuplizer/> is not supported - `%s`",
|
"Transformation of <tuplizer/> is not supported - `%s`",
|
||||||
|
@ -950,26 +958,17 @@ public class HbmXmlTransformer {
|
||||||
}
|
}
|
||||||
|
|
||||||
for ( JaxbHbmJoinedSubclassEntityType hbmSubclass : hbmClass.getJoinedSubclass() ) {
|
for ( JaxbHbmJoinedSubclassEntityType hbmSubclass : hbmClass.getJoinedSubclass() ) {
|
||||||
entity.setInheritance( new JaxbInheritanceImpl() );
|
final JaxbEntityImpl subclassEntity = transformationState.getEntityXref().get( hbmSubclass );
|
||||||
entity.getInheritance().setStrategy( InheritanceType.JOINED );
|
|
||||||
|
|
||||||
final JaxbEntityImpl subclassEntity = new JaxbEntityImpl();
|
|
||||||
ormRoot.getEntities().add( subclassEntity );
|
|
||||||
transferJoinedSubclass( hbmSubclass, subclassEntity );
|
transferJoinedSubclass( hbmSubclass, subclassEntity );
|
||||||
}
|
}
|
||||||
|
|
||||||
for (JaxbHbmUnionSubclassEntityType hbmSubclass : hbmClass.getUnionSubclass() ) {
|
for (JaxbHbmUnionSubclassEntityType hbmSubclass : hbmClass.getUnionSubclass() ) {
|
||||||
entity.setInheritance( new JaxbInheritanceImpl() );
|
final JaxbEntityImpl subclassEntity = transformationState.getEntityXref().get( hbmSubclass );
|
||||||
entity.getInheritance().setStrategy( InheritanceType.TABLE_PER_CLASS );
|
|
||||||
|
|
||||||
final JaxbEntityImpl subclassEntity = new JaxbEntityImpl();
|
|
||||||
ormRoot.getEntities().add( subclassEntity );
|
|
||||||
transferUnionSubclass( hbmSubclass, subclassEntity );
|
transferUnionSubclass( hbmSubclass, subclassEntity );
|
||||||
}
|
}
|
||||||
|
|
||||||
for ( JaxbHbmDiscriminatorSubclassEntityType hbmSubclass : hbmClass.getSubclass() ) {
|
for ( JaxbHbmDiscriminatorSubclassEntityType hbmSubclass : hbmClass.getSubclass() ) {
|
||||||
final JaxbEntityImpl subclassEntity = new JaxbEntityImpl();
|
final JaxbEntityImpl subclassEntity = transformationState.getEntityXref().get( hbmSubclass );
|
||||||
ormRoot.getEntities().add( subclassEntity );
|
|
||||||
transferDiscriminatorSubclass( hbmSubclass, subclassEntity );
|
transferDiscriminatorSubclass( hbmSubclass, subclassEntity );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1023,6 +1022,19 @@ public class HbmXmlTransformer {
|
||||||
transfer( hbmClass::getEntityName, entity::setName );
|
transfer( hbmClass::getEntityName, entity::setName );
|
||||||
transfer( hbmClass::getName, entity::setClazz );
|
transfer( hbmClass::getName, entity::setClazz );
|
||||||
|
|
||||||
|
if ( StringHelper.isEmpty( entity.getExtends() ) ) {
|
||||||
|
if ( hbmClass instanceof JaxbHbmSubclassEntityBaseDefinition hbmSubclass ) {
|
||||||
|
if ( StringHelper.isNotEmpty( hbmSubclass.getExtends() ) ) {
|
||||||
|
entity.setExtends( TransformationState.requireEntityReferenceName(
|
||||||
|
hbmSubclass.getExtends(),
|
||||||
|
hbmXmlMapping,
|
||||||
|
transformationState.getEntityMap(),
|
||||||
|
origin
|
||||||
|
) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ( hbmClass instanceof Discriminatable discriminatable ) {
|
if ( hbmClass instanceof Discriminatable discriminatable ) {
|
||||||
transfer( discriminatable::getDiscriminatorValue, entity::setDiscriminatorValue );
|
transfer( discriminatable::getDiscriminatorValue, entity::setDiscriminatorValue );
|
||||||
}
|
}
|
||||||
|
@ -1081,6 +1093,13 @@ public class HbmXmlTransformer {
|
||||||
transferBaseEntityInformation( hbmSubclass, subclassEntity );
|
transferBaseEntityInformation( hbmSubclass, subclassEntity );
|
||||||
|
|
||||||
transferEntityElementAttributes( hbmSubclass, subclassEntity );
|
transferEntityElementAttributes( hbmSubclass, subclassEntity );
|
||||||
|
|
||||||
|
if ( !hbmSubclass.getSubclass().isEmpty() ) {
|
||||||
|
for ( JaxbHbmDiscriminatorSubclassEntityType nestedHbmSubclass : hbmSubclass.getSubclass() ) {
|
||||||
|
final JaxbEntityImpl nestedSubclassEntity = transformationState.getEntityXref().get( nestedHbmSubclass );
|
||||||
|
transferDiscriminatorSubclass( nestedHbmSubclass, nestedSubclassEntity );
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void transferJoinedSubclass(JaxbHbmJoinedSubclassEntityType hbmSubclass, JaxbEntityImpl subclassEntity) {
|
private void transferJoinedSubclass(JaxbHbmJoinedSubclassEntityType hbmSubclass, JaxbEntityImpl subclassEntity) {
|
||||||
|
@ -1113,11 +1132,8 @@ public class HbmXmlTransformer {
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !hbmSubclass.getJoinedSubclass().isEmpty() ) {
|
if ( !hbmSubclass.getJoinedSubclass().isEmpty() ) {
|
||||||
subclassEntity.setInheritance( new JaxbInheritanceImpl() );
|
|
||||||
subclassEntity.getInheritance().setStrategy( InheritanceType.JOINED );
|
|
||||||
for ( JaxbHbmJoinedSubclassEntityType nestedHbmSubclass : hbmSubclass.getJoinedSubclass() ) {
|
for ( JaxbHbmJoinedSubclassEntityType nestedHbmSubclass : hbmSubclass.getJoinedSubclass() ) {
|
||||||
final JaxbEntityImpl nestedSubclassEntity = new JaxbEntityImpl();
|
final JaxbEntityImpl nestedSubclassEntity = transformationState.getEntityXref().get( nestedHbmSubclass );
|
||||||
ormRoot.getEntities().add( nestedSubclassEntity );
|
|
||||||
transferJoinedSubclass( nestedHbmSubclass, nestedSubclassEntity );
|
transferJoinedSubclass( nestedHbmSubclass, nestedSubclassEntity );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1284,7 +1300,15 @@ public class HbmXmlTransformer {
|
||||||
attributes.getEmbeddedAttributes().add( transformEmbedded( jaxbEmbeddable, hbmComponent ) );
|
attributes.getEmbeddedAttributes().add( transformEmbedded( jaxbEmbeddable, hbmComponent ) );
|
||||||
}
|
}
|
||||||
else if ( hbmAttributeMapping instanceof JaxbHbmPropertiesType hbmProperties ) {
|
else if ( hbmAttributeMapping instanceof JaxbHbmPropertiesType hbmProperties ) {
|
||||||
transferAttributes( hbmProperties.getAttributes(), attributes );
|
// while we could simply "unwrap" the <properties/> itself and inline the attributes,
|
||||||
|
// <properties/> is most often used to create a target for property-ref mappings - that
|
||||||
|
// we could not support without a new sort of annotation - e.g.
|
||||||
|
//
|
||||||
|
// @interface PropertyGroup {
|
||||||
|
// String name();
|
||||||
|
// String[] propertyNames();
|
||||||
|
// }
|
||||||
|
handleUnsupported( "<properties/> mappings not supported for transformation [name=%s]", hbmProperties.getName() );
|
||||||
}
|
}
|
||||||
else if ( hbmAttributeMapping instanceof JaxbHbmDynamicComponentType ) {
|
else if ( hbmAttributeMapping instanceof JaxbHbmDynamicComponentType ) {
|
||||||
final String name = ( (JaxbHbmDynamicComponentType) hbmAttributeMapping ).getName();
|
final String name = ( (JaxbHbmDynamicComponentType) hbmAttributeMapping ).getName();
|
||||||
|
@ -2401,11 +2425,8 @@ public class HbmXmlTransformer {
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !hbmSubclass.getUnionSubclass().isEmpty() ) {
|
if ( !hbmSubclass.getUnionSubclass().isEmpty() ) {
|
||||||
subclassEntity.setInheritance( new JaxbInheritanceImpl() );
|
|
||||||
subclassEntity.getInheritance().setStrategy( InheritanceType.TABLE_PER_CLASS );
|
|
||||||
for ( JaxbHbmUnionSubclassEntityType nestedHbmSubclass : hbmSubclass.getUnionSubclass() ) {
|
for ( JaxbHbmUnionSubclassEntityType nestedHbmSubclass : hbmSubclass.getUnionSubclass() ) {
|
||||||
final JaxbEntityImpl nestedSubclassEntity = new JaxbEntityImpl();
|
final JaxbEntityImpl nestedSubclassEntity = transformationState.getEntityXref().get( nestedHbmSubclass );
|
||||||
ormRoot.getEntities().add( nestedSubclassEntity );
|
|
||||||
transferUnionSubclass( nestedHbmSubclass, nestedSubclassEntity );
|
transferUnionSubclass( nestedHbmSubclass, nestedSubclassEntity );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,368 @@
|
||||||
|
/*
|
||||||
|
* 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.boot.jaxb.hbm.transform;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.hibernate.boot.MappingException;
|
||||||
|
import org.hibernate.boot.jaxb.Origin;
|
||||||
|
import org.hibernate.boot.jaxb.hbm.spi.EntityInfo;
|
||||||
|
import org.hibernate.boot.jaxb.hbm.spi.JaxbHbmDiscriminatorSubclassEntityType;
|
||||||
|
import org.hibernate.boot.jaxb.hbm.spi.JaxbHbmEntityBaseDefinition;
|
||||||
|
import org.hibernate.boot.jaxb.hbm.spi.JaxbHbmHibernateMapping;
|
||||||
|
import org.hibernate.boot.jaxb.hbm.spi.JaxbHbmJoinedSubclassEntityType;
|
||||||
|
import org.hibernate.boot.jaxb.hbm.spi.JaxbHbmSubclassEntityBaseDefinition;
|
||||||
|
import org.hibernate.boot.jaxb.hbm.spi.JaxbHbmUnionSubclassEntityType;
|
||||||
|
import org.hibernate.boot.jaxb.mapping.spi.JaxbEntityImpl;
|
||||||
|
import org.hibernate.boot.jaxb.mapping.spi.JaxbEntityMappingsImpl;
|
||||||
|
import org.hibernate.boot.jaxb.mapping.spi.JaxbInheritanceImpl;
|
||||||
|
import org.hibernate.boot.jaxb.spi.Binding;
|
||||||
|
import org.hibernate.internal.util.StringHelper;
|
||||||
|
import org.hibernate.internal.util.collections.CollectionHelper;
|
||||||
|
|
||||||
|
import jakarta.persistence.InheritanceType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
public class TransformationPreprocessor {
|
||||||
|
static void preprocessHbmXml(
|
||||||
|
List<Binding<JaxbHbmHibernateMapping>> hbmXmlBindings,
|
||||||
|
TransformationState transformationState) {
|
||||||
|
final EntityMappingConsumer entityMappingConsumer = new EntityMappingConsumer( transformationState );
|
||||||
|
final Map<String, JaxbEntityImpl> rootClassesMap = new HashMap<>();
|
||||||
|
|
||||||
|
processStructuredHierarchies( hbmXmlBindings, rootClassesMap, entityMappingConsumer );
|
||||||
|
processSeparatedHierarchies( hbmXmlBindings, rootClassesMap, entityMappingConsumer );
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void processStructuredHierarchies(
|
||||||
|
Collection<Binding<JaxbHbmHibernateMapping>> hbmXmlBindings,
|
||||||
|
Map<String, JaxbEntityImpl> rootClassesMap,
|
||||||
|
EntityMappingConsumer entityMappingConsumer) {
|
||||||
|
hbmXmlBindings.forEach( (hbmBinding) -> {
|
||||||
|
processStructuredHierarchies( rootClassesMap, entityMappingConsumer, hbmBinding );
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void processStructuredHierarchies(
|
||||||
|
Map<String, JaxbEntityImpl> rootClassesMap,
|
||||||
|
EntityMappingConsumer entityMappingConsumer,
|
||||||
|
Binding<JaxbHbmHibernateMapping> hbmBinding) {
|
||||||
|
final JaxbHbmHibernateMapping hibernateMapping = hbmBinding.getRoot();
|
||||||
|
hibernateMapping.getClazz().forEach( (hbmRoot) -> {
|
||||||
|
final JaxbEntityImpl rootJaxbEntity = makeJaxbEntity( hbmRoot, hibernateMapping );
|
||||||
|
final String entityName = determineEntityName( hbmRoot, hibernateMapping );
|
||||||
|
|
||||||
|
entityMappingConsumer.accept( hbmBinding, entityName, hbmRoot, rootJaxbEntity );
|
||||||
|
rootClassesMap.put( entityName, rootJaxbEntity );
|
||||||
|
|
||||||
|
if ( CollectionHelper.isNotEmpty( hbmRoot.getSubclass() ) ) {
|
||||||
|
applyInheritanceStrategy( entityName, rootJaxbEntity, InheritanceType.SINGLE_TABLE );
|
||||||
|
processStructuredDiscriminatorSubclasses(
|
||||||
|
hbmRoot.getSubclass(),
|
||||||
|
entityName,
|
||||||
|
hbmBinding,
|
||||||
|
entityMappingConsumer
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( CollectionHelper.isNotEmpty( hbmRoot.getJoinedSubclass() ) ) {
|
||||||
|
applyInheritanceStrategy( entityName, rootJaxbEntity, InheritanceType.JOINED );
|
||||||
|
processStructuredJoinedSubclasses(
|
||||||
|
hbmRoot.getJoinedSubclass(),
|
||||||
|
entityName,
|
||||||
|
hbmBinding,
|
||||||
|
entityMappingConsumer
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( CollectionHelper.isNotEmpty( hbmRoot.getUnionSubclass() ) ) {
|
||||||
|
applyInheritanceStrategy( entityName, rootJaxbEntity, InheritanceType.TABLE_PER_CLASS );
|
||||||
|
processStructuredUnionSubclasses(
|
||||||
|
hbmRoot.getUnionSubclass(),
|
||||||
|
entityName,
|
||||||
|
hbmBinding,
|
||||||
|
entityMappingConsumer
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void applyInheritanceStrategy(String entityName, JaxbEntityImpl rootJaxbEntity, InheritanceType strategy) {
|
||||||
|
final JaxbInheritanceImpl existing = rootJaxbEntity.getInheritance();
|
||||||
|
if ( existing != null ) {
|
||||||
|
if ( existing.getStrategy() != null && existing.getStrategy() != strategy ) {
|
||||||
|
throw new IllegalStateException( String.format(
|
||||||
|
Locale.ROOT,
|
||||||
|
"Root entity `%s` defined a mix of inheritance strategies; at least %s and %s",
|
||||||
|
entityName,
|
||||||
|
strategy,
|
||||||
|
existing.getStrategy()
|
||||||
|
) );
|
||||||
|
}
|
||||||
|
existing.setStrategy( strategy );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
final JaxbInheritanceImpl created = new JaxbInheritanceImpl();
|
||||||
|
created.setStrategy( strategy );
|
||||||
|
rootJaxbEntity.setInheritance( created );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void processStructuredDiscriminatorSubclasses(
|
||||||
|
List<JaxbHbmDiscriminatorSubclassEntityType> hbmSubclasses,
|
||||||
|
String superEntityName,
|
||||||
|
Binding<JaxbHbmHibernateMapping> hbmBinding,
|
||||||
|
EntityMappingConsumer entityMappingConsumer) {
|
||||||
|
hbmSubclasses.forEach( (hbmSubclass) -> {
|
||||||
|
final JaxbEntityImpl subclassJaxbEntity = makeJaxbEntity( hbmSubclass, hbmBinding.getRoot() );
|
||||||
|
final String subclassEntityName = determineEntityName( hbmSubclass, hbmBinding.getRoot() );
|
||||||
|
entityMappingConsumer.accept( hbmBinding, subclassEntityName, hbmSubclass, subclassJaxbEntity );
|
||||||
|
|
||||||
|
subclassJaxbEntity.setExtends( superEntityName );
|
||||||
|
|
||||||
|
if ( CollectionHelper.isNotEmpty( hbmSubclass.getSubclass() ) ) {
|
||||||
|
processStructuredDiscriminatorSubclasses(
|
||||||
|
hbmSubclass.getSubclass(),
|
||||||
|
subclassEntityName,
|
||||||
|
hbmBinding,
|
||||||
|
entityMappingConsumer
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void processStructuredJoinedSubclasses(
|
||||||
|
List<JaxbHbmJoinedSubclassEntityType> hbmSubclasses,
|
||||||
|
String superEntityName,
|
||||||
|
Binding<JaxbHbmHibernateMapping> hbmBinding,
|
||||||
|
EntityMappingConsumer entityMappingConsumer) {
|
||||||
|
hbmSubclasses.forEach( (hbmSubclass) -> {
|
||||||
|
final JaxbEntityImpl subclassJaxbEntity = makeJaxbEntity( hbmSubclass, hbmBinding.getRoot() );
|
||||||
|
final String subclassEntityName = determineEntityName( hbmSubclass, hbmBinding.getRoot() );
|
||||||
|
entityMappingConsumer.accept( hbmBinding, subclassEntityName, hbmSubclass, subclassJaxbEntity );
|
||||||
|
|
||||||
|
subclassJaxbEntity.setExtends( superEntityName );
|
||||||
|
|
||||||
|
if ( CollectionHelper.isNotEmpty( hbmSubclass.getJoinedSubclass() ) ) {
|
||||||
|
processStructuredJoinedSubclasses(
|
||||||
|
hbmSubclass.getJoinedSubclass(),
|
||||||
|
subclassEntityName,
|
||||||
|
hbmBinding,
|
||||||
|
entityMappingConsumer
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void processStructuredUnionSubclasses(
|
||||||
|
List<JaxbHbmUnionSubclassEntityType> hbmSubclasses,
|
||||||
|
String superEntityName,
|
||||||
|
Binding<JaxbHbmHibernateMapping> hbmBinding,
|
||||||
|
EntityMappingConsumer entityMappingConsumer) {
|
||||||
|
hbmSubclasses.forEach( (hbmSubclass) -> {
|
||||||
|
final JaxbEntityImpl subclassJaxbEntity = makeJaxbEntity( hbmSubclass, hbmBinding.getRoot() );
|
||||||
|
final String subclassEntityName = determineEntityName( hbmSubclass, hbmBinding.getRoot() );
|
||||||
|
entityMappingConsumer.accept( hbmBinding, subclassEntityName, hbmSubclass, subclassJaxbEntity );
|
||||||
|
|
||||||
|
subclassJaxbEntity.setExtends( superEntityName );
|
||||||
|
|
||||||
|
if ( CollectionHelper.isNotEmpty( hbmSubclass.getUnionSubclass() ) ) {
|
||||||
|
processStructuredUnionSubclasses(
|
||||||
|
hbmSubclass.getUnionSubclass(),
|
||||||
|
subclassEntityName,
|
||||||
|
hbmBinding,
|
||||||
|
entityMappingConsumer
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void processSeparatedHierarchies(
|
||||||
|
Collection<Binding<JaxbHbmHibernateMapping>> hbmXmlBindings,
|
||||||
|
Map<String, JaxbEntityImpl> rootClassesMap,
|
||||||
|
EntityMappingConsumer entityMappingConsumer) {
|
||||||
|
hbmXmlBindings.forEach( (hbmBinding) -> {
|
||||||
|
processSeparatedHierarchies( rootClassesMap, entityMappingConsumer, hbmBinding );
|
||||||
|
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void processSeparatedHierarchies(
|
||||||
|
Map<String, JaxbEntityImpl> rootClassesMap,
|
||||||
|
EntityMappingConsumer entityMappingConsumer,
|
||||||
|
Binding<JaxbHbmHibernateMapping> hbmBinding) {
|
||||||
|
final JaxbHbmHibernateMapping hibernateMapping = hbmBinding.getRoot();
|
||||||
|
|
||||||
|
processTopLevelDiscriminatedSubclasses( rootClassesMap, entityMappingConsumer, hbmBinding, hibernateMapping );
|
||||||
|
processTopLevelJoinedSubclasses( rootClassesMap, entityMappingConsumer, hbmBinding, hibernateMapping );
|
||||||
|
processTopLevelUnionSubclasses( rootClassesMap, entityMappingConsumer, hbmBinding, hibernateMapping );
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void processTopLevelDiscriminatedSubclasses(
|
||||||
|
Map<String, JaxbEntityImpl> rootClassesMap,
|
||||||
|
EntityMappingConsumer entityMappingConsumer,
|
||||||
|
Binding<JaxbHbmHibernateMapping> hbmBinding,
|
||||||
|
JaxbHbmHibernateMapping hibernateMapping) {
|
||||||
|
hibernateMapping.getSubclass().forEach( (hbmSubclass) -> {
|
||||||
|
final String entityName = determineEntityName( hbmSubclass, hibernateMapping );
|
||||||
|
applyExtendedInheritanceStrategy(
|
||||||
|
entityName,
|
||||||
|
InheritanceType.SINGLE_TABLE,
|
||||||
|
hbmSubclass,
|
||||||
|
hibernateMapping,
|
||||||
|
rootClassesMap,
|
||||||
|
hbmBinding.getOrigin()
|
||||||
|
);
|
||||||
|
|
||||||
|
final JaxbEntityImpl jaxbEntity = makeJaxbEntity( hbmSubclass, hibernateMapping );
|
||||||
|
entityMappingConsumer.accept( hbmBinding, entityName, hbmSubclass, jaxbEntity );
|
||||||
|
|
||||||
|
if ( CollectionHelper.isNotEmpty( hbmSubclass.getSubclass() ) ) {
|
||||||
|
processStructuredDiscriminatorSubclasses(
|
||||||
|
hbmSubclass.getSubclass(),
|
||||||
|
entityName,
|
||||||
|
hbmBinding,
|
||||||
|
entityMappingConsumer
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void processTopLevelJoinedSubclasses(
|
||||||
|
Map<String, JaxbEntityImpl> rootClassesMap,
|
||||||
|
EntityMappingConsumer entityMappingConsumer,
|
||||||
|
Binding<JaxbHbmHibernateMapping> hbmBinding,
|
||||||
|
JaxbHbmHibernateMapping hibernateMapping) {
|
||||||
|
hibernateMapping.getJoinedSubclass().forEach( (hbmSubclass) -> {
|
||||||
|
final String entityName = determineEntityName( hbmSubclass, hibernateMapping );
|
||||||
|
applyExtendedInheritanceStrategy(
|
||||||
|
entityName,
|
||||||
|
InheritanceType.JOINED,
|
||||||
|
hbmSubclass,
|
||||||
|
hibernateMapping,
|
||||||
|
rootClassesMap,
|
||||||
|
hbmBinding.getOrigin()
|
||||||
|
);
|
||||||
|
|
||||||
|
final JaxbEntityImpl jaxbEntity = makeJaxbEntity( hbmSubclass, hibernateMapping );
|
||||||
|
entityMappingConsumer.accept( hbmBinding, entityName, hbmSubclass, jaxbEntity );
|
||||||
|
|
||||||
|
if ( CollectionHelper.isNotEmpty( hbmSubclass.getJoinedSubclass() ) ) {
|
||||||
|
processStructuredJoinedSubclasses(
|
||||||
|
hbmSubclass.getJoinedSubclass(),
|
||||||
|
entityName,
|
||||||
|
hbmBinding,
|
||||||
|
entityMappingConsumer
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void processTopLevelUnionSubclasses(
|
||||||
|
Map<String, JaxbEntityImpl> rootClassesMap,
|
||||||
|
EntityMappingConsumer entityMappingConsumer,
|
||||||
|
Binding<JaxbHbmHibernateMapping> hbmBinding,
|
||||||
|
JaxbHbmHibernateMapping hibernateMapping) {
|
||||||
|
hibernateMapping.getUnionSubclass().forEach( (hbmSubclass) -> {
|
||||||
|
final String entityName = determineEntityName( hbmSubclass, hibernateMapping );
|
||||||
|
applyExtendedInheritanceStrategy(
|
||||||
|
entityName,
|
||||||
|
InheritanceType.TABLE_PER_CLASS,
|
||||||
|
hbmSubclass,
|
||||||
|
hibernateMapping,
|
||||||
|
rootClassesMap,
|
||||||
|
hbmBinding.getOrigin()
|
||||||
|
);
|
||||||
|
|
||||||
|
final JaxbEntityImpl jaxbEntity = makeJaxbEntity( hbmSubclass, hibernateMapping );
|
||||||
|
entityMappingConsumer.accept( hbmBinding, entityName, hbmSubclass, jaxbEntity );
|
||||||
|
|
||||||
|
if ( CollectionHelper.isNotEmpty( hbmSubclass.getUnionSubclass() ) ) {
|
||||||
|
processStructuredUnionSubclasses(
|
||||||
|
hbmSubclass.getUnionSubclass(),
|
||||||
|
entityName,
|
||||||
|
hbmBinding,
|
||||||
|
entityMappingConsumer
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void applyExtendedInheritanceStrategy(
|
||||||
|
String entityName,
|
||||||
|
InheritanceType strategy,
|
||||||
|
JaxbHbmSubclassEntityBaseDefinition hbmSubclass,
|
||||||
|
JaxbHbmHibernateMapping hibernateMapping,
|
||||||
|
Map<String, JaxbEntityImpl> rootClassesMap,
|
||||||
|
Origin origin) {
|
||||||
|
if ( StringHelper.isEmpty( hbmSubclass.getExtends() ) ) {
|
||||||
|
throw new MappingException( "Separated inheritance mapping did not specify extends", origin );
|
||||||
|
}
|
||||||
|
|
||||||
|
// we only have something to do here if the extends names a root entity
|
||||||
|
final JaxbEntityImpl superRoot = TransformationState.resolveEntityReference(
|
||||||
|
hbmSubclass.getExtends(),
|
||||||
|
hibernateMapping,
|
||||||
|
rootClassesMap
|
||||||
|
);
|
||||||
|
|
||||||
|
if ( superRoot != null ) {
|
||||||
|
applyInheritanceStrategy( entityName, superRoot, strategy );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static JaxbEntityImpl makeJaxbEntity(
|
||||||
|
JaxbHbmEntityBaseDefinition hbmEntity,
|
||||||
|
JaxbHbmHibernateMapping hibernateMapping) {
|
||||||
|
final JaxbEntityImpl jaxbEntity = new JaxbEntityImpl();
|
||||||
|
if ( StringHelper.isNotEmpty( hbmEntity.getName() ) ) {
|
||||||
|
jaxbEntity.setClazz( StringHelper.qualifyConditionallyIfNot( hibernateMapping.getPackage(), hbmEntity.getName() ) );
|
||||||
|
}
|
||||||
|
if ( StringHelper.isNotEmpty( hbmEntity.getEntityName() ) ) {
|
||||||
|
jaxbEntity.setName( hbmEntity.getEntityName() );
|
||||||
|
}
|
||||||
|
return jaxbEntity;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String determineEntityName(EntityInfo entityInfo, JaxbHbmHibernateMapping hibernateMapping) {
|
||||||
|
if ( entityInfo.getEntityName() != null ) {
|
||||||
|
return entityInfo.getEntityName();
|
||||||
|
}
|
||||||
|
return StringHelper.qualifyConditionallyIfNot( hibernateMapping.getPackage(), entityInfo.getName() );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private record EntityMappingConsumer(TransformationState transformationState) {
|
||||||
|
|
||||||
|
public void accept(
|
||||||
|
Binding<JaxbHbmHibernateMapping> hbmBinding,
|
||||||
|
String registrationName,
|
||||||
|
JaxbHbmEntityBaseDefinition hbmEntity,
|
||||||
|
JaxbEntityImpl mappingEntity) {
|
||||||
|
final Binding<JaxbEntityMappingsImpl> mappingBinding = resolveMappingBinding( hbmBinding );
|
||||||
|
mappingBinding.getRoot().getEntities().add( mappingEntity );
|
||||||
|
transformationState.getEntityXref().put( hbmEntity, mappingEntity );
|
||||||
|
transformationState.getEntityMap().put( registrationName, mappingEntity );
|
||||||
|
}
|
||||||
|
|
||||||
|
private Binding<JaxbEntityMappingsImpl> resolveMappingBinding(Binding<JaxbHbmHibernateMapping> hbmBinding) {
|
||||||
|
for ( int i = 0; i < transformationState.getHbmBindings().size(); i++ ) {
|
||||||
|
if ( hbmBinding == transformationState.getHbmBindings().get( i ) ) {
|
||||||
|
return transformationState.getMappingBindings().get( i );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new IllegalStateException( "Could not resolve corresponding mapping binding : " + hbmBinding );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,137 @@
|
||||||
|
/*
|
||||||
|
* 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.boot.jaxb.hbm.transform;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.hibernate.boot.jaxb.Origin;
|
||||||
|
import org.hibernate.boot.jaxb.hbm.spi.JaxbHbmEntityBaseDefinition;
|
||||||
|
import org.hibernate.boot.jaxb.hbm.spi.JaxbHbmHibernateMapping;
|
||||||
|
import org.hibernate.boot.jaxb.mapping.spi.JaxbEntityImpl;
|
||||||
|
import org.hibernate.boot.jaxb.mapping.spi.JaxbEntityMappingsImpl;
|
||||||
|
import org.hibernate.boot.jaxb.spi.Binding;
|
||||||
|
import org.hibernate.internal.util.StringHelper;
|
||||||
|
import org.hibernate.internal.util.collections.CollectionHelper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
class TransformationState {
|
||||||
|
private final List<Binding<JaxbHbmHibernateMapping>> hbmBindings;
|
||||||
|
private final List<Binding<JaxbEntityMappingsImpl>> mappingBindings;
|
||||||
|
|
||||||
|
private final Map<String, JaxbEntityImpl> entityMap = new HashMap<>();
|
||||||
|
private final Map<JaxbHbmEntityBaseDefinition, JaxbEntityImpl> entityXref = new HashMap<>();
|
||||||
|
|
||||||
|
public TransformationState(List<Binding<JaxbHbmHibernateMapping>> hbmBindings) {
|
||||||
|
this.hbmBindings = hbmBindings;
|
||||||
|
this.mappingBindings = CollectionHelper.arrayList( hbmBindings.size() );
|
||||||
|
for ( Binding<JaxbHbmHibernateMapping> hbmBinding : this.hbmBindings ) {
|
||||||
|
final JaxbEntityMappingsImpl mappingRoot = new JaxbEntityMappingsImpl();
|
||||||
|
mappingRoot.setDescription( String.format(
|
||||||
|
Locale.ROOT,
|
||||||
|
"Generated by Hibernate HbmXmlTransformer from %s (%s)",
|
||||||
|
hbmBinding.getOrigin().getName(),
|
||||||
|
hbmBinding.getOrigin().getType()
|
||||||
|
) );
|
||||||
|
mappingBindings.add( new Binding<>( mappingRoot, hbmBinding.getOrigin() ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String resolveEntityReferenceName(
|
||||||
|
String referenceName,
|
||||||
|
JaxbHbmHibernateMapping hibernateMapping,
|
||||||
|
Map<String,JaxbEntityImpl> entityMap) {
|
||||||
|
|
||||||
|
// First try it as a direct key reference; this covers the case of:
|
||||||
|
// 1. entity-name
|
||||||
|
// 2. fully-qualified name
|
||||||
|
final JaxbEntityImpl byDirectName = entityMap.get( referenceName );
|
||||||
|
if ( byDirectName != null ) {
|
||||||
|
return referenceName;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Next, try as an implicitly qualified name
|
||||||
|
if ( StringHelper.isNotEmpty( hibernateMapping.getPackage() ) ) {
|
||||||
|
final String qualifiedName = StringHelper.qualify( hibernateMapping.getPackage(), referenceName );
|
||||||
|
final JaxbEntityImpl byQualifiedName = entityMap.get( qualifiedName );
|
||||||
|
if ( byQualifiedName != null ) {
|
||||||
|
return qualifiedName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String requireEntityReferenceName(
|
||||||
|
String referenceName,
|
||||||
|
JaxbHbmHibernateMapping hibernateMapping,
|
||||||
|
Map<String,JaxbEntityImpl> entityMap,
|
||||||
|
Origin origin) {
|
||||||
|
final String resolved = resolveEntityReferenceName( referenceName, hibernateMapping, entityMap );
|
||||||
|
if ( resolved == null ) {
|
||||||
|
throw new UnknownEntityReferenceException( referenceName, origin );
|
||||||
|
}
|
||||||
|
return resolved;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static JaxbEntityImpl resolveEntityReference(
|
||||||
|
String referenceName,
|
||||||
|
JaxbHbmHibernateMapping hibernateMapping,
|
||||||
|
Map<String,JaxbEntityImpl> entityMap) {
|
||||||
|
|
||||||
|
// First try it as a direct key reference; this covers the case of:
|
||||||
|
// 1. entity-name
|
||||||
|
// 2. fully-qualified name
|
||||||
|
final JaxbEntityImpl byDirectName = entityMap.get( referenceName );
|
||||||
|
if ( byDirectName != null ) {
|
||||||
|
return byDirectName;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Next, try as an implicitly qualified name
|
||||||
|
if ( StringHelper.isNotEmpty( hibernateMapping.getPackage() ) ) {
|
||||||
|
final String qualifiedName = StringHelper.qualify( hibernateMapping.getPackage(), referenceName );
|
||||||
|
final JaxbEntityImpl byQualifiedName = entityMap.get( qualifiedName );
|
||||||
|
if ( byQualifiedName != null ) {
|
||||||
|
return byQualifiedName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static JaxbEntityImpl requireEntityReference(
|
||||||
|
String referenceName,
|
||||||
|
JaxbHbmHibernateMapping hibernateMapping,
|
||||||
|
Map<String,JaxbEntityImpl> entityMap,
|
||||||
|
Origin origin) {
|
||||||
|
final JaxbEntityImpl resolved = resolveEntityReference( referenceName, hibernateMapping, entityMap );
|
||||||
|
if ( resolved == null ) {
|
||||||
|
throw new UnknownEntityReferenceException( referenceName, origin );
|
||||||
|
}
|
||||||
|
return resolved;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Binding<JaxbHbmHibernateMapping>> getHbmBindings() {
|
||||||
|
return hbmBindings;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Binding<JaxbEntityMappingsImpl>> getMappingBindings() {
|
||||||
|
return mappingBindings;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, JaxbEntityImpl> getEntityMap() {
|
||||||
|
return entityMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<JaxbHbmEntityBaseDefinition, JaxbEntityImpl> getEntityXref() {
|
||||||
|
return entityXref;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
/*
|
||||||
|
* 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.boot.jaxb.hbm.transform;
|
||||||
|
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
|
import org.hibernate.MappingException;
|
||||||
|
import org.hibernate.boot.jaxb.Origin;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* We encountered a reference to an entity by name which we cannot resolve
|
||||||
|
*
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
public class UnknownEntityReferenceException extends MappingException {
|
||||||
|
public UnknownEntityReferenceException(String name, Origin origin) {
|
||||||
|
super( String.format(
|
||||||
|
Locale.ROOT,
|
||||||
|
"Could not resolve entity name `%s` : %s (%s)",
|
||||||
|
name,
|
||||||
|
origin.getName(),
|
||||||
|
origin.getType()
|
||||||
|
) );
|
||||||
|
}
|
||||||
|
}
|
|
@ -15,22 +15,19 @@ import javax.xml.stream.events.StartElement;
|
||||||
import org.hibernate.Internal;
|
import org.hibernate.Internal;
|
||||||
import org.hibernate.boot.ResourceStreamLocator;
|
import org.hibernate.boot.ResourceStreamLocator;
|
||||||
import org.hibernate.boot.UnsupportedOrmXsdVersionException;
|
import org.hibernate.boot.UnsupportedOrmXsdVersionException;
|
||||||
import org.hibernate.boot.jaxb.JaxbLogger;
|
|
||||||
import org.hibernate.boot.jaxb.Origin;
|
import org.hibernate.boot.jaxb.Origin;
|
||||||
import org.hibernate.boot.jaxb.hbm.spi.JaxbHbmHibernateMapping;
|
import org.hibernate.boot.jaxb.hbm.spi.JaxbHbmHibernateMapping;
|
||||||
import org.hibernate.boot.jaxb.hbm.transform.HbmXmlTransformer;
|
|
||||||
import org.hibernate.boot.jaxb.hbm.transform.UnsupportedFeatureHandling;
|
import org.hibernate.boot.jaxb.hbm.transform.UnsupportedFeatureHandling;
|
||||||
import org.hibernate.boot.jaxb.internal.stax.HbmEventReader;
|
import org.hibernate.boot.jaxb.internal.stax.HbmEventReader;
|
||||||
import org.hibernate.boot.jaxb.internal.stax.JpaOrmXmlEventReader;
|
import org.hibernate.boot.jaxb.internal.stax.JpaOrmXmlEventReader;
|
||||||
import org.hibernate.boot.jaxb.internal.stax.MappingEventReader;
|
import org.hibernate.boot.jaxb.internal.stax.MappingEventReader;
|
||||||
import org.hibernate.boot.jaxb.mapping.spi.JaxbEntityMappingsImpl;
|
import org.hibernate.boot.jaxb.mapping.spi.JaxbEntityMappingsImpl;
|
||||||
import org.hibernate.boot.jaxb.spi.JaxbBindableMappingDescriptor;
|
|
||||||
import org.hibernate.boot.jaxb.spi.Binding;
|
import org.hibernate.boot.jaxb.spi.Binding;
|
||||||
|
import org.hibernate.boot.jaxb.spi.JaxbBindableMappingDescriptor;
|
||||||
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
|
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
|
||||||
import org.hibernate.boot.xsd.MappingXsdSupport;
|
import org.hibernate.boot.xsd.MappingXsdSupport;
|
||||||
import org.hibernate.cfg.AvailableSettings;
|
import org.hibernate.cfg.AvailableSettings;
|
||||||
import org.hibernate.engine.config.spi.ConfigurationService;
|
import org.hibernate.engine.config.spi.ConfigurationService;
|
||||||
import org.hibernate.internal.log.DeprecationLogger;
|
|
||||||
import org.hibernate.internal.util.config.ConfigurationException;
|
import org.hibernate.internal.util.config.ConfigurationException;
|
||||||
import org.hibernate.service.ServiceRegistry;
|
import org.hibernate.service.ServiceRegistry;
|
||||||
import org.hibernate.service.spi.ServiceRegistryImplementor;
|
import org.hibernate.service.spi.ServiceRegistryImplementor;
|
||||||
|
@ -62,8 +59,6 @@ public class MappingBinder extends AbstractBinder<JaxbBindableMappingDescriptor>
|
||||||
|
|
||||||
public interface Options {
|
public interface Options {
|
||||||
boolean validateMappings();
|
boolean validateMappings();
|
||||||
|
|
||||||
boolean transformHbmMappings();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final Options VALIDATING = new Options() {
|
public static final Options VALIDATING = new Options() {
|
||||||
|
@ -71,11 +66,6 @@ public class MappingBinder extends AbstractBinder<JaxbBindableMappingDescriptor>
|
||||||
public boolean validateMappings() {
|
public boolean validateMappings() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean transformHbmMappings() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
public static final Options NON_VALIDATING = new Options() {
|
public static final Options NON_VALIDATING = new Options() {
|
||||||
|
@ -83,11 +73,6 @@ public class MappingBinder extends AbstractBinder<JaxbBindableMappingDescriptor>
|
||||||
public boolean validateMappings() {
|
public boolean validateMappings() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean transformHbmMappings() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -131,15 +116,6 @@ public class MappingBinder extends AbstractBinder<JaxbBindableMappingDescriptor>
|
||||||
}
|
}
|
||||||
return BOOLEAN.convert( setting );
|
return BOOLEAN.convert( setting );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean transformHbmMappings() {
|
|
||||||
final Object setting = settingsAccess.apply( AvailableSettings.TRANSFORM_HBM_XML );
|
|
||||||
if ( setting == null ) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return BOOLEAN.convert( setting );
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
this.unsupportedHandlingAccess = () -> {
|
this.unsupportedHandlingAccess = () -> {
|
||||||
|
@ -178,11 +154,6 @@ public class MappingBinder extends AbstractBinder<JaxbBindableMappingDescriptor>
|
||||||
public boolean validateMappings() {
|
public boolean validateMappings() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean transformHbmMappings() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
unsupportedHandling
|
unsupportedHandling
|
||||||
);
|
);
|
||||||
|
@ -219,13 +190,6 @@ public class MappingBinder extends AbstractBinder<JaxbBindableMappingDescriptor>
|
||||||
origin
|
origin
|
||||||
);
|
);
|
||||||
|
|
||||||
if ( optionsAccess.get().transformHbmMappings() ) {
|
|
||||||
JaxbLogger.JAXB_LOGGER.tracef( "Performing on-the-fly hbm.xml -> mapping.xml transformation - %s ", origin );
|
|
||||||
//noinspection unchecked
|
|
||||||
return new Binding<>( (X) HbmXmlTransformer.transform( hbmBindings, origin, unsupportedHandlingAccess::get ), origin );
|
|
||||||
}
|
|
||||||
|
|
||||||
DeprecationLogger.DEPRECATION_LOGGER.logDeprecatedHbmXmlProcessing( origin.getType(), origin.getName() );
|
|
||||||
//noinspection unchecked
|
//noinspection unchecked
|
||||||
return new Binding<>( (X) hbmBindings, origin );
|
return new Binding<>( (X) hbmBindings, origin );
|
||||||
}
|
}
|
||||||
|
@ -241,6 +205,7 @@ public class MappingBinder extends AbstractBinder<JaxbBindableMappingDescriptor>
|
||||||
mappingJaxbContext(),
|
mappingJaxbContext(),
|
||||||
origin
|
origin
|
||||||
);
|
);
|
||||||
|
|
||||||
//noinspection unchecked
|
//noinspection unchecked
|
||||||
return new Binding<>( (X) bindingRoot, origin );
|
return new Binding<>( (X) bindingRoot, origin );
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,15 +16,27 @@ import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import org.hibernate.Internal;
|
import org.hibernate.Internal;
|
||||||
|
import org.hibernate.boot.BootLogging;
|
||||||
import org.hibernate.boot.MetadataSources;
|
import org.hibernate.boot.MetadataSources;
|
||||||
import org.hibernate.boot.jaxb.spi.JaxbBindableMappingDescriptor;
|
import org.hibernate.boot.jaxb.Origin;
|
||||||
|
import org.hibernate.boot.jaxb.hbm.spi.JaxbHbmHibernateMapping;
|
||||||
|
import org.hibernate.boot.jaxb.hbm.transform.HbmXmlTransformer;
|
||||||
|
import org.hibernate.boot.jaxb.hbm.transform.UnsupportedFeatureHandling;
|
||||||
|
import org.hibernate.boot.jaxb.mapping.spi.JaxbEntityMappingsImpl;
|
||||||
import org.hibernate.boot.jaxb.spi.Binding;
|
import org.hibernate.boot.jaxb.spi.Binding;
|
||||||
|
import org.hibernate.boot.jaxb.spi.JaxbBindableMappingDescriptor;
|
||||||
import org.hibernate.boot.model.convert.spi.ConverterDescriptor;
|
import org.hibernate.boot.model.convert.spi.ConverterDescriptor;
|
||||||
import org.hibernate.boot.model.process.spi.ManagedResources;
|
import org.hibernate.boot.model.process.spi.ManagedResources;
|
||||||
import org.hibernate.boot.spi.BootstrapContext;
|
import org.hibernate.boot.spi.BootstrapContext;
|
||||||
|
import org.hibernate.cfg.AvailableSettings;
|
||||||
|
import org.hibernate.cfg.MappingSettings;
|
||||||
|
import org.hibernate.engine.config.spi.ConfigurationService;
|
||||||
|
import org.hibernate.internal.log.DeprecationLogger;
|
||||||
|
|
||||||
import jakarta.persistence.AttributeConverter;
|
import jakarta.persistence.AttributeConverter;
|
||||||
|
|
||||||
|
import static org.hibernate.engine.config.spi.StandardConverters.BOOLEAN;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
|
@ -42,11 +54,53 @@ public class ManagedResourcesImpl implements ManagedResources {
|
||||||
impl.annotatedClassReferences.addAll( sources.getAnnotatedClasses() );
|
impl.annotatedClassReferences.addAll( sources.getAnnotatedClasses() );
|
||||||
impl.annotatedClassNames.addAll( sources.getAnnotatedClassNames() );
|
impl.annotatedClassNames.addAll( sources.getAnnotatedClassNames() );
|
||||||
impl.annotatedPackageNames.addAll( sources.getAnnotatedPackages() );
|
impl.annotatedPackageNames.addAll( sources.getAnnotatedPackages() );
|
||||||
impl.mappingFileBindings.addAll( sources.getXmlBindings() );
|
handleXmlMappings( sources, impl, bootstrapContext );
|
||||||
impl.extraQueryImports = sources.getExtraQueryImports();
|
impl.extraQueryImports = sources.getExtraQueryImports();
|
||||||
return impl;
|
return impl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||||
|
private static void handleXmlMappings(
|
||||||
|
MetadataSources sources,
|
||||||
|
ManagedResourcesImpl impl,
|
||||||
|
BootstrapContext bootstrapContext) {
|
||||||
|
impl.mappingFileBindings.addAll( (List) sources.getMappingXmlBindings() );
|
||||||
|
|
||||||
|
if ( !bootstrapContext.getMetadataBuildingOptions().isXmlMappingEnabled() ) {
|
||||||
|
BootLogging.BOOT_LOGGER.debugf(
|
||||||
|
"Ignoring %s XML mappings due to `%s`",
|
||||||
|
sources.getMappingXmlBindings().size(),
|
||||||
|
MappingSettings.XML_MAPPING_ENABLED
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final ConfigurationService configurationService = bootstrapContext.getServiceRegistry().getService( ConfigurationService.class );
|
||||||
|
// NOTE : the configurationService nullness checking is here for a few tests using mocks
|
||||||
|
final boolean transformHbm = configurationService != null
|
||||||
|
&& configurationService.getSetting( MappingSettings.TRANSFORM_HBM_XML, BOOLEAN,false );
|
||||||
|
|
||||||
|
if ( !transformHbm ) {
|
||||||
|
// we are not transforming hbm.xml to mapping.xml, so just add the hbm.xml bindings as-is
|
||||||
|
impl.mappingFileBindings.addAll( (List) sources.getHbmXmlBindings() );
|
||||||
|
for ( Binding<JaxbHbmHibernateMapping> hbmXmlBinding : sources.getHbmXmlBindings() ) {
|
||||||
|
final Origin origin = hbmXmlBinding.getOrigin();
|
||||||
|
DeprecationLogger.DEPRECATION_LOGGER.logDeprecatedHbmXmlProcessing( origin.getType(), origin.getName() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// do the transformations
|
||||||
|
final List<Binding<JaxbEntityMappingsImpl>> transformed = HbmXmlTransformer.transform(
|
||||||
|
sources.getHbmXmlBindings(),
|
||||||
|
UnsupportedFeatureHandling.fromSetting(
|
||||||
|
configurationService.getSettings().get( AvailableSettings.TRANSFORM_HBM_XML_FEATURE_HANDLING ),
|
||||||
|
UnsupportedFeatureHandling.ERROR
|
||||||
|
)
|
||||||
|
);
|
||||||
|
impl.mappingFileBindings.addAll( (List) transformed );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public ManagedResourcesImpl() {
|
public ManagedResourcesImpl() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -576,11 +576,6 @@ public class MetadataBuildingProcess {
|
||||||
public boolean validateMappings() {
|
public boolean validateMappings() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean transformHbmMappings() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,11 +9,15 @@ package org.hibernate.boot.model.source.internal.annotations;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.hibernate.boot.jaxb.Origin;
|
import org.hibernate.boot.jaxb.Origin;
|
||||||
import org.hibernate.boot.jaxb.SourceType;
|
import org.hibernate.boot.jaxb.SourceType;
|
||||||
|
import org.hibernate.boot.jaxb.hbm.spi.JaxbHbmHibernateMapping;
|
||||||
|
import org.hibernate.boot.jaxb.hbm.transform.HbmXmlTransformer;
|
||||||
|
import org.hibernate.boot.jaxb.hbm.transform.UnsupportedFeatureHandling;
|
||||||
import org.hibernate.boot.jaxb.internal.MappingBinder;
|
import org.hibernate.boot.jaxb.internal.MappingBinder;
|
||||||
import org.hibernate.boot.jaxb.mapping.spi.JaxbEntityMappingsImpl;
|
import org.hibernate.boot.jaxb.mapping.spi.JaxbEntityMappingsImpl;
|
||||||
import org.hibernate.boot.jaxb.spi.Binding;
|
import org.hibernate.boot.jaxb.spi.Binding;
|
||||||
|
@ -85,6 +89,7 @@ public class AdditionalManagedResourcesImpl implements ManagedResources {
|
||||||
|
|
||||||
public static class Builder {
|
public static class Builder {
|
||||||
private final MappingBinder mappingBinder;
|
private final MappingBinder mappingBinder;
|
||||||
|
private final boolean transformHbmMappings;
|
||||||
|
|
||||||
private List<Class<?>> classes;
|
private List<Class<?>> classes;
|
||||||
private List<ClassDetails> classDetails;
|
private List<ClassDetails> classDetails;
|
||||||
|
@ -92,35 +97,26 @@ public class AdditionalManagedResourcesImpl implements ManagedResources {
|
||||||
private Collection<Binding<JaxbBindableMappingDescriptor>> xmlMappings;
|
private Collection<Binding<JaxbBindableMappingDescriptor>> xmlMappings;
|
||||||
|
|
||||||
public Builder(boolean validateMappings, boolean transformHbmMappings) {
|
public Builder(boolean validateMappings, boolean transformHbmMappings) {
|
||||||
this( new MappingBinder.Options() {
|
this( transformHbmMappings, new MappingBinder.Options() {
|
||||||
@Override
|
@Override
|
||||||
public boolean validateMappings() {
|
public boolean validateMappings() {
|
||||||
return validateMappings;
|
return validateMappings;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean transformHbmMappings() {
|
|
||||||
return transformHbmMappings;
|
|
||||||
}
|
|
||||||
} );
|
} );
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder() {
|
public Builder() {
|
||||||
this( new MappingBinder.Options() {
|
this( false, new MappingBinder.Options() {
|
||||||
@Override
|
@Override
|
||||||
public boolean validateMappings() {
|
public boolean validateMappings() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean transformHbmMappings() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} );
|
} );
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder(MappingBinder.Options options) {
|
public Builder(boolean transformHbmMappings, MappingBinder.Options options) {
|
||||||
mappingBinder = new MappingBinder(
|
this.transformHbmMappings = transformHbmMappings;
|
||||||
|
this.mappingBinder = new MappingBinder(
|
||||||
(resourceName) -> Builder.class.getClassLoader().getResourceAsStream( resourceName ),
|
(resourceName) -> Builder.class.getClassLoader().getResourceAsStream( resourceName ),
|
||||||
options
|
options
|
||||||
);
|
);
|
||||||
|
@ -163,6 +159,28 @@ public class AdditionalManagedResourcesImpl implements ManagedResources {
|
||||||
}
|
}
|
||||||
|
|
||||||
public ManagedResources build() {
|
public ManagedResources build() {
|
||||||
|
if ( CollectionHelper.isNotEmpty( xmlMappings ) ) {
|
||||||
|
if ( transformHbmMappings ) {
|
||||||
|
final List<Binding<JaxbHbmHibernateMapping>> hbmBindings = new ArrayList<>();
|
||||||
|
final Iterator<Binding<JaxbBindableMappingDescriptor>> iterator = xmlMappings.iterator();
|
||||||
|
while ( iterator.hasNext() ) {
|
||||||
|
final Binding<JaxbBindableMappingDescriptor> xmlBinding = iterator.next();
|
||||||
|
if ( xmlBinding.getRoot() instanceof JaxbHbmHibernateMapping ) {
|
||||||
|
//noinspection rawtypes,unchecked
|
||||||
|
hbmBindings.add( (Binding) xmlBinding );
|
||||||
|
iterator.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( !hbmBindings.isEmpty() ) {
|
||||||
|
final List<Binding<JaxbEntityMappingsImpl>> transformed = HbmXmlTransformer.transform(
|
||||||
|
hbmBindings,
|
||||||
|
UnsupportedFeatureHandling.ERROR
|
||||||
|
);
|
||||||
|
//noinspection rawtypes,unchecked
|
||||||
|
xmlMappings.addAll( (List) transformed );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return new AdditionalManagedResourcesImpl( classes, classDetails, packageNames, xmlMappings );
|
return new AdditionalManagedResourcesImpl( classes, classDetails, packageNames, xmlMappings );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,7 @@ import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.hibernate.MappingException;
|
||||||
import org.hibernate.boot.internal.MetadataBuildingContextRootImpl;
|
import org.hibernate.boot.internal.MetadataBuildingContextRootImpl;
|
||||||
import org.hibernate.boot.jaxb.mapping.spi.JaxbEntityMappingsImpl;
|
import org.hibernate.boot.jaxb.mapping.spi.JaxbEntityMappingsImpl;
|
||||||
import org.hibernate.boot.model.convert.internal.ClassBasedConverterDescriptor;
|
import org.hibernate.boot.model.convert.internal.ClassBasedConverterDescriptor;
|
||||||
|
@ -229,6 +230,14 @@ public class AnnotationMetadataSourceProcessorImpl implements MetadataSourceProc
|
||||||
List<XClass> clazzHierarchy = new ArrayList<>();
|
List<XClass> clazzHierarchy = new ArrayList<>();
|
||||||
|
|
||||||
for ( ClassDetails clazz : classes ) {
|
for ( ClassDetails clazz : classes ) {
|
||||||
|
if ( clazz.isInterface() ) {
|
||||||
|
if ( clazz.hasDirectAnnotationUsage( Entity.class ) ) {
|
||||||
|
throw new MappingException( "Only classes (not interfaces) may be mapped as @Entity : " + clazz.getName() );
|
||||||
|
}
|
||||||
|
if ( clazz.hasDirectAnnotationUsage( MappedSuperclass.class ) ) {
|
||||||
|
throw new MappingException( "Only classes (not interfaces) may be mapped as @MappedSuperclass : " + clazz.getName() );
|
||||||
|
}
|
||||||
|
}
|
||||||
if ( clazz.hasDirectAnnotationUsage( MappedSuperclass.class ) ) {
|
if ( clazz.hasDirectAnnotationUsage( MappedSuperclass.class ) ) {
|
||||||
if ( debug ) {
|
if ( debug ) {
|
||||||
log.debugf(
|
log.debugf(
|
||||||
|
|
|
@ -10,6 +10,7 @@ import java.lang.reflect.Modifier;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
import org.hibernate.MappingException;
|
||||||
import org.hibernate.annotations.CacheConcurrencyStrategy;
|
import org.hibernate.annotations.CacheConcurrencyStrategy;
|
||||||
import org.hibernate.boot.jaxb.mapping.spi.JaxbAttributesContainer;
|
import org.hibernate.boot.jaxb.mapping.spi.JaxbAttributesContainer;
|
||||||
import org.hibernate.boot.jaxb.mapping.spi.JaxbAttributesContainerImpl;
|
import org.hibernate.boot.jaxb.mapping.spi.JaxbAttributesContainerImpl;
|
||||||
|
@ -59,7 +60,9 @@ import org.hibernate.property.access.spi.BuiltInPropertyAccessStrategies;
|
||||||
import jakarta.persistence.Access;
|
import jakarta.persistence.Access;
|
||||||
import jakarta.persistence.AccessType;
|
import jakarta.persistence.AccessType;
|
||||||
import jakarta.persistence.EmbeddedId;
|
import jakarta.persistence.EmbeddedId;
|
||||||
|
import jakarta.persistence.Entity;
|
||||||
import jakarta.persistence.Id;
|
import jakarta.persistence.Id;
|
||||||
|
import jakarta.persistence.MappedSuperclass;
|
||||||
|
|
||||||
import static org.hibernate.boot.models.xml.XmlProcessLogging.XML_PROCESS_LOGGER;
|
import static org.hibernate.boot.models.xml.XmlProcessLogging.XML_PROCESS_LOGGER;
|
||||||
import static org.hibernate.internal.util.NullnessHelper.coalesce;
|
import static org.hibernate.internal.util.NullnessHelper.coalesce;
|
||||||
|
@ -123,6 +126,9 @@ public class ManagedTypeProcessor {
|
||||||
defaultAccessTypeFromDefaultAccessor( xmlDocumentContext ),
|
defaultAccessTypeFromDefaultAccessor( xmlDocumentContext ),
|
||||||
AccessType.PROPERTY
|
AccessType.PROPERTY
|
||||||
);
|
);
|
||||||
|
if ( classDetails.isInterface() ) {
|
||||||
|
throw new MappingException( "Only classes (not interfaces) may be mapped as @Entity : " + classDetails.getName() );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
classDetails.clearMemberAnnotationUsages();
|
classDetails.clearMemberAnnotationUsages();
|
||||||
|
|
|
@ -351,10 +351,9 @@ public class EntityManagerFactoryBuilderImpl implements EntityManagerFactoryBuil
|
||||||
if ( classLoader == null ) {
|
if ( classLoader == null ) {
|
||||||
throw persistenceException( "Enhancement requires a temp class loader, but none was given." );
|
throw persistenceException( "Enhancement requires a temp class loader, but none was given." );
|
||||||
}
|
}
|
||||||
for ( Binding<JaxbBindableMappingDescriptor> binding : metadataSources.getXmlBindings() ) {
|
|
||||||
final JaxbBindableMappingDescriptor root = binding.getRoot();
|
for ( Binding<JaxbHbmHibernateMapping> binding : metadataSources.getHbmXmlBindings() ) {
|
||||||
if ( root instanceof JaxbHbmHibernateMapping ) {
|
final JaxbHbmHibernateMapping hibernateMapping = binding.getRoot();
|
||||||
final JaxbHbmHibernateMapping hibernateMapping = (JaxbHbmHibernateMapping) root;
|
|
||||||
final String packageName = hibernateMapping.getPackage();
|
final String packageName = hibernateMapping.getPackage();
|
||||||
for ( JaxbHbmRootEntityType clazz : hibernateMapping.getClazz() ) {
|
for ( JaxbHbmRootEntityType clazz : hibernateMapping.getClazz() ) {
|
||||||
final String className;
|
final String className;
|
||||||
|
@ -372,7 +371,6 @@ public class EntityManagerFactoryBuilderImpl implements EntityManagerFactoryBuil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
for ( String annotatedClassName : metadataSources.getAnnotatedClassNames() ) {
|
for ( String annotatedClassName : metadataSources.getAnnotatedClassNames() ) {
|
||||||
classTransformer.discoverTypes( classLoader, annotatedClassName );
|
classTransformer.discoverTypes( classLoader, annotatedClassName );
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,8 @@ import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.StringReader;
|
import java.io.StringReader;
|
||||||
import java.io.StringWriter;
|
import java.io.StringWriter;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import javax.xml.stream.XMLEventFactory;
|
import javax.xml.stream.XMLEventFactory;
|
||||||
import javax.xml.stream.XMLEventReader;
|
import javax.xml.stream.XMLEventReader;
|
||||||
|
@ -21,6 +23,7 @@ import org.hibernate.boot.jaxb.hbm.transform.HbmXmlTransformer;
|
||||||
import org.hibernate.boot.jaxb.hbm.transform.UnsupportedFeatureHandling;
|
import org.hibernate.boot.jaxb.hbm.transform.UnsupportedFeatureHandling;
|
||||||
import org.hibernate.boot.jaxb.internal.stax.HbmEventReader;
|
import org.hibernate.boot.jaxb.internal.stax.HbmEventReader;
|
||||||
import org.hibernate.boot.jaxb.mapping.spi.JaxbEntityMappingsImpl;
|
import org.hibernate.boot.jaxb.mapping.spi.JaxbEntityMappingsImpl;
|
||||||
|
import org.hibernate.boot.jaxb.spi.Binding;
|
||||||
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
|
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
|
||||||
import org.hibernate.boot.xsd.MappingXsdSupport;
|
import org.hibernate.boot.xsd.MappingXsdSupport;
|
||||||
import org.hibernate.orm.test.boot.jaxb.JaxbHelper;
|
import org.hibernate.orm.test.boot.jaxb.JaxbHelper;
|
||||||
|
@ -57,11 +60,12 @@ public class TransformationHelper {
|
||||||
assertThat( hbmMapping ).isNotNull();
|
assertThat( hbmMapping ).isNotNull();
|
||||||
assertThat( hbmMapping.getClazz() ).hasSize( 1 );
|
assertThat( hbmMapping.getClazz() ).hasSize( 1 );
|
||||||
|
|
||||||
return HbmXmlTransformer.transform(
|
final List<Binding<JaxbEntityMappingsImpl>> transformed = HbmXmlTransformer.transform(
|
||||||
hbmMapping,
|
Collections.singletonList( new Binding<>( hbmMapping, new Origin( SourceType.RESOURCE, resourceName ) ) ),
|
||||||
new Origin( SourceType.RESOURCE, resourceName ),
|
UnsupportedFeatureHandling.ERROR
|
||||||
() -> UnsupportedFeatureHandling.ERROR
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
return transformed.get(0).getRoot();
|
||||||
}
|
}
|
||||||
catch (JAXBException e) {
|
catch (JAXBException e) {
|
||||||
throw new RuntimeException( "Error during JAXB processing", e );
|
throw new RuntimeException( "Error during JAXB processing", e );
|
||||||
|
|
|
@ -8,6 +8,8 @@ package org.hibernate.orm.test.boot.jaxb.mapping;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
import javax.xml.stream.XMLEventFactory;
|
import javax.xml.stream.XMLEventFactory;
|
||||||
import javax.xml.stream.XMLEventReader;
|
import javax.xml.stream.XMLEventReader;
|
||||||
|
|
||||||
|
@ -19,6 +21,7 @@ import org.hibernate.boot.jaxb.hbm.transform.UnsupportedFeatureHandling;
|
||||||
import org.hibernate.boot.jaxb.internal.stax.HbmEventReader;
|
import org.hibernate.boot.jaxb.internal.stax.HbmEventReader;
|
||||||
import org.hibernate.boot.jaxb.mapping.spi.JaxbEntityImpl;
|
import org.hibernate.boot.jaxb.mapping.spi.JaxbEntityImpl;
|
||||||
import org.hibernate.boot.jaxb.mapping.spi.JaxbEntityMappingsImpl;
|
import org.hibernate.boot.jaxb.mapping.spi.JaxbEntityMappingsImpl;
|
||||||
|
import org.hibernate.boot.jaxb.spi.Binding;
|
||||||
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
|
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
|
||||||
import org.hibernate.boot.xsd.MappingXsdSupport;
|
import org.hibernate.boot.xsd.MappingXsdSupport;
|
||||||
import org.hibernate.orm.test.boot.jaxb.JaxbHelper;
|
import org.hibernate.orm.test.boot.jaxb.JaxbHelper;
|
||||||
|
@ -56,11 +59,11 @@ public class HbmTransformationJaxbTests {
|
||||||
assertThat( hbmMapping ).isNotNull();
|
assertThat( hbmMapping ).isNotNull();
|
||||||
assertThat( hbmMapping.getClazz() ).hasSize( 1 );
|
assertThat( hbmMapping.getClazz() ).hasSize( 1 );
|
||||||
|
|
||||||
final JaxbEntityMappingsImpl transformed = HbmXmlTransformer.transform(
|
final List<Binding<JaxbEntityMappingsImpl>> transformedBindingList = HbmXmlTransformer.transform(
|
||||||
hbmMapping,
|
Collections.singletonList( new Binding<>( hbmMapping, new Origin( SourceType.RESOURCE, resourceName ) ) ),
|
||||||
new Origin( SourceType.RESOURCE, resourceName ),
|
UnsupportedFeatureHandling.ERROR
|
||||||
() -> UnsupportedFeatureHandling.ERROR
|
|
||||||
);
|
);
|
||||||
|
final JaxbEntityMappingsImpl transformed = transformedBindingList.get( 0 ).getRoot();
|
||||||
|
|
||||||
assertThat( transformed ).isNotNull();
|
assertThat( transformed ).isNotNull();
|
||||||
assertThat( transformed.getEntities() ).hasSize( 1 );
|
assertThat( transformed.getEntities() ).hasSize( 1 );
|
||||||
|
|
|
@ -0,0 +1,73 @@
|
||||||
|
/*
|
||||||
|
* 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.boot.models.hbm._extends;
|
||||||
|
|
||||||
|
import org.hibernate.boot.jaxb.mapping.spi.JaxbEntityImpl;
|
||||||
|
import org.hibernate.boot.jaxb.mapping.spi.JaxbEntityMappingsImpl;
|
||||||
|
import org.hibernate.cfg.MappingSettings;
|
||||||
|
import org.hibernate.orm.test.boot.jaxb.hbm.TransformationHelper;
|
||||||
|
|
||||||
|
import org.hibernate.testing.orm.junit.ServiceRegistry;
|
||||||
|
import org.hibernate.testing.orm.junit.ServiceRegistryScope;
|
||||||
|
import org.hibernate.testing.orm.junit.Setting;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import jakarta.persistence.InheritanceType;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("JUnitMalformedDeclaration")
|
||||||
|
public class ExtendsTests {
|
||||||
|
@ServiceRegistry(settings = @Setting(name = MappingSettings.TRANSFORM_HBM_XML, value = "true"))
|
||||||
|
@Test
|
||||||
|
void testDiscriminatedStructured(ServiceRegistryScope registryScope) {
|
||||||
|
final JaxbEntityMappingsImpl transformed = TransformationHelper.transform(
|
||||||
|
"mappings/models/hbm/extends/discriminated-structured.xml",
|
||||||
|
registryScope.getRegistry()
|
||||||
|
);
|
||||||
|
verifyHierarchy( transformed, InheritanceType.SINGLE_TABLE );
|
||||||
|
}
|
||||||
|
|
||||||
|
@ServiceRegistry(settings = @Setting(name = MappingSettings.TRANSFORM_HBM_XML, value = "true"))
|
||||||
|
@Test
|
||||||
|
void testDiscriminatedSeparated(ServiceRegistryScope registryScope) {
|
||||||
|
final JaxbEntityMappingsImpl transformed = TransformationHelper.transform(
|
||||||
|
"mappings/models/hbm/extends/discriminated-separate.xml",
|
||||||
|
registryScope.getRegistry()
|
||||||
|
);
|
||||||
|
verifyHierarchy( transformed, InheritanceType.SINGLE_TABLE );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void verifyHierarchy(JaxbEntityMappingsImpl transformed, InheritanceType inheritanceType) {
|
||||||
|
assertThat( transformed ).isNotNull();
|
||||||
|
assertThat( transformed.getEntities() ).hasSize( 3 );
|
||||||
|
|
||||||
|
for ( JaxbEntityImpl jaxbEntity : transformed.getEntities() ) {
|
||||||
|
if ( "org.hibernate.test.hbm._extends.Root".equals( jaxbEntity.getClazz() ) ) {
|
||||||
|
assertThat( jaxbEntity.getInheritance() ).isNotNull();
|
||||||
|
assertThat( jaxbEntity.getInheritance().getStrategy() ).isEqualTo( inheritanceType );
|
||||||
|
assertThat( jaxbEntity.getExtends() ).isNull();
|
||||||
|
assertThat( jaxbEntity.getDiscriminatorColumn().getName() ).isEqualTo( "the_type" );
|
||||||
|
assertThat( jaxbEntity.getDiscriminatorValue() ).isEqualTo( "R" );
|
||||||
|
}
|
||||||
|
else if ( "org.hibernate.test.hbm._extends.Branch".equals( jaxbEntity.getName() ) ) {
|
||||||
|
assertThat( jaxbEntity.getInheritance() ).isNull();
|
||||||
|
assertThat( jaxbEntity.getDiscriminatorValue() ).isEqualTo( "B" );
|
||||||
|
assertThat( jaxbEntity.getExtends() ).isEqualTo( "org.hibernate.test.hbm._extends.Root" );
|
||||||
|
}
|
||||||
|
else if ( "org.hibernate.test.hbm._extends.Leaf".equals( jaxbEntity.getName() ) ) {
|
||||||
|
assertThat( jaxbEntity.getInheritance() ).isNull();
|
||||||
|
assertThat( jaxbEntity.getDiscriminatorValue() ).isEqualTo( "L" );
|
||||||
|
assertThat( jaxbEntity.getExtends() ).isEqualTo( "org.hibernate.test.hbm._extends.Branch" );
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,59 +0,0 @@
|
||||||
/*
|
|
||||||
* 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.boot.models.hbm.ecid;
|
|
||||||
|
|
||||||
import org.hibernate.cfg.MappingSettings;
|
|
||||||
import org.hibernate.orm.test.abstractembeddedcomponents.cid.AbstractCompositeIdTest;
|
|
||||||
import org.hibernate.orm.test.abstractembeddedcomponents.cid.MyInterfaceImpl;
|
|
||||||
|
|
||||||
import org.hibernate.testing.orm.junit.DomainModel;
|
|
||||||
import org.hibernate.testing.orm.junit.FailureExpected;
|
|
||||||
import org.hibernate.testing.orm.junit.ServiceRegistry;
|
|
||||||
import org.hibernate.testing.orm.junit.SessionFactory;
|
|
||||||
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
|
||||||
import org.hibernate.testing.orm.junit.Setting;
|
|
||||||
import org.junit.jupiter.api.AfterEach;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @see AbstractCompositeIdTest
|
|
||||||
*
|
|
||||||
* @author Steve Ebersole
|
|
||||||
*/
|
|
||||||
@SuppressWarnings("JUnitMalformedDeclaration")
|
|
||||||
@ServiceRegistry(settings = @Setting(name= MappingSettings.TRANSFORM_HBM_XML, value="true"))
|
|
||||||
@DomainModel( xmlMappings = "org/hibernate/orm/test/abstractembeddedcomponents/cid/Mappings.hbm.xml" )
|
|
||||||
@SessionFactory
|
|
||||||
@FailureExpected
|
|
||||||
public class EmbeddedCompositeIdentifierOnAbstractClassTests {
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testTransformedHbmXml(SessionFactoryScope scope) {
|
|
||||||
MyInterfaceImpl myInterface = new MyInterfaceImpl();
|
|
||||||
myInterface.setKey1( "key1" );
|
|
||||||
myInterface.setKey2( "key2" );
|
|
||||||
myInterface.setName( "test" );
|
|
||||||
|
|
||||||
scope.inTransaction(
|
|
||||||
session -> {
|
|
||||||
// test persistence
|
|
||||||
session.persist( myInterface );
|
|
||||||
session.flush();
|
|
||||||
|
|
||||||
// test loading
|
|
||||||
session.createQuery( "from MyInterface" ).list();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@AfterEach
|
|
||||||
void dropTestData(SessionFactoryScope scope) {
|
|
||||||
scope.inTransaction( (session) -> {
|
|
||||||
session.createMutationQuery( "delete MyInterface" ).executeUpdate();
|
|
||||||
} );
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,49 +0,0 @@
|
||||||
/*
|
|
||||||
* 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.boot.models.hbm.ecid;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Steve Ebersole
|
|
||||||
*/
|
|
||||||
public class Login {
|
|
||||||
private String system;
|
|
||||||
private String username;
|
|
||||||
private String email;
|
|
||||||
|
|
||||||
public Login() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public Login(String system, String username, String email) {
|
|
||||||
this.system = system;
|
|
||||||
this.username = username;
|
|
||||||
this.email = email;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getSystem() {
|
|
||||||
return system;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSystem(String system) {
|
|
||||||
this.system = system;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getUsername() {
|
|
||||||
return username;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setUsername(String username) {
|
|
||||||
this.username = username;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getEmail() {
|
|
||||||
return email;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setEmail(String email) {
|
|
||||||
this.email = email;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,40 +0,0 @@
|
||||||
/*
|
|
||||||
* 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.boot.models.hbm.ecid;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.hibernate.cfg.MappingSettings;
|
|
||||||
|
|
||||||
import org.hibernate.testing.orm.junit.DomainModel;
|
|
||||||
import org.hibernate.testing.orm.junit.ServiceRegistry;
|
|
||||||
import org.hibernate.testing.orm.junit.SessionFactory;
|
|
||||||
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
|
||||||
import org.hibernate.testing.orm.junit.Setting;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Steve Ebersole
|
|
||||||
*/
|
|
||||||
@SuppressWarnings("JUnitMalformedDeclaration")
|
|
||||||
@ServiceRegistry(settings = @Setting(name= MappingSettings.TRANSFORM_HBM_XML, value="true"))
|
|
||||||
@DomainModel(xmlMappings = "mappings/models/hbm/ecid/standard-ecid.hbm.xml")
|
|
||||||
@SessionFactory
|
|
||||||
public class StandardNonAggregatedIdTests {
|
|
||||||
@Test
|
|
||||||
void simpleTest(SessionFactoryScope scope) {
|
|
||||||
final Login login = new Login( "prod", "john", "john@doe.com" );
|
|
||||||
scope.inTransaction( (session) -> session.persist( login ) );
|
|
||||||
|
|
||||||
scope.inTransaction( (session) -> {
|
|
||||||
final List<Login> logins = session.createSelectionQuery( "from Login", Login.class ).list();
|
|
||||||
assertThat( logins ).hasSize( 1 );
|
|
||||||
} );
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
/*
|
||||||
|
* 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.boot.models.hbm.intf;
|
||||||
|
|
||||||
|
import jakarta.persistence.Entity;
|
||||||
|
import jakarta.persistence.Id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
@Entity
|
||||||
|
public interface IPerson {
|
||||||
|
@Id
|
||||||
|
Integer getId();
|
||||||
|
String getName();
|
||||||
|
void setName(String name);
|
||||||
|
}
|
|
@ -0,0 +1,59 @@
|
||||||
|
/*
|
||||||
|
* 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.boot.models.hbm.intf;
|
||||||
|
|
||||||
|
import org.hibernate.MappingException;
|
||||||
|
import org.hibernate.boot.Metadata;
|
||||||
|
import org.hibernate.boot.MetadataSources;
|
||||||
|
import org.hibernate.boot.registry.StandardServiceRegistry;
|
||||||
|
import org.hibernate.cfg.MappingSettings;
|
||||||
|
|
||||||
|
import org.hibernate.testing.orm.junit.ServiceRegistry;
|
||||||
|
import org.hibernate.testing.orm.junit.ServiceRegistryScope;
|
||||||
|
import org.hibernate.testing.orm.junit.Setting;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests for mapping interfaces as managed classes.
|
||||||
|
*
|
||||||
|
* @implNote This is something {@code hbm.xml} supported, and we want to make sure it fails in
|
||||||
|
* a consistent manner.
|
||||||
|
*
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("JUnitMalformedDeclaration")
|
||||||
|
public class InterfaceMappingTests {
|
||||||
|
@ServiceRegistry
|
||||||
|
@Test
|
||||||
|
void testInterfaceAsEntity(ServiceRegistryScope registryScope) {
|
||||||
|
try (StandardServiceRegistry serviceRegistry = registryScope.getRegistry()) {
|
||||||
|
final Metadata metadata = new MetadataSources( serviceRegistry )
|
||||||
|
.addAnnotatedClasses( IPerson.class, Person.class )
|
||||||
|
.buildMetadata();
|
||||||
|
}
|
||||||
|
catch (MappingException expected) {
|
||||||
|
assertThat( expected.getMessage() ).startsWith( "Only classes (not interfaces) may be mapped as @Entity :" );
|
||||||
|
assertThat( expected.getMessage() ).endsWith( IPerson.class.getName() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ServiceRegistry(settings = @Setting(name = MappingSettings.TRANSFORM_HBM_XML, value = "true"))
|
||||||
|
@Test
|
||||||
|
void testTransformedHbmXml(ServiceRegistryScope registryScope) {
|
||||||
|
try (StandardServiceRegistry serviceRegistry = registryScope.getRegistry()) {
|
||||||
|
final Metadata metadata = new MetadataSources( serviceRegistry )
|
||||||
|
.addResource( "mappings/models/hbm/intf/mapped-interface.hbm.xml" )
|
||||||
|
.buildMetadata();
|
||||||
|
}
|
||||||
|
catch (MappingException expected) {
|
||||||
|
assertThat( expected.getMessage() ).startsWith( "Only classes (not interfaces) may be mapped as @Entity :" );
|
||||||
|
assertThat( expected.getMessage() ).endsWith( IPerson.class.getName() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
/*
|
||||||
|
* 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.boot.models.hbm.intf;
|
||||||
|
|
||||||
|
import jakarta.persistence.Entity;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
@Entity
|
||||||
|
public class Person implements IPerson {
|
||||||
|
private Integer id;
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
public Person() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public Person(Integer id, String name) {
|
||||||
|
this.id = id;
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Integer getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
/*
|
||||||
|
* 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.boot.models.hbm.properties;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
public class Address {
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
/*
|
||||||
|
* 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.boot.models.hbm.properties;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests for {@code hbm.xml} {@code <properties/>} grouping element
|
||||||
|
*
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
public class PropertiesGroupingTests {
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
/*
|
||||||
|
* 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.boot.models.hbm.properties;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
public class Server {
|
||||||
|
}
|
|
@ -0,0 +1,160 @@
|
||||||
|
/*
|
||||||
|
* 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.boot.models.hbm.propertyref;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.hibernate.boot.InvalidMappingException;
|
||||||
|
import org.hibernate.boot.MetadataSources;
|
||||||
|
import org.hibernate.boot.registry.StandardServiceRegistry;
|
||||||
|
import org.hibernate.cfg.MappingSettings;
|
||||||
|
import org.hibernate.mapping.PersistentClass;
|
||||||
|
import org.hibernate.mapping.Property;
|
||||||
|
import org.hibernate.mapping.ToOne;
|
||||||
|
|
||||||
|
import org.hibernate.testing.orm.junit.DomainModel;
|
||||||
|
import org.hibernate.testing.orm.junit.DomainModelScope;
|
||||||
|
import org.hibernate.testing.orm.junit.ServiceRegistry;
|
||||||
|
import org.hibernate.testing.orm.junit.ServiceRegistryScope;
|
||||||
|
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||||
|
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||||
|
import org.hibernate.testing.orm.junit.Setting;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests for {@code hbm.xml} {@code <properties/>} grouping element
|
||||||
|
*
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("JUnitMalformedDeclaration")
|
||||||
|
public class GroupedPropertyRefTests {
|
||||||
|
@Test
|
||||||
|
@DomainModel(annotatedClasses = {Person.class, Account.class}, xmlMappings = "mappings/models/hbm/propertyref/properties.hbm.xml" )
|
||||||
|
@SessionFactory
|
||||||
|
void testHbmXml(DomainModelScope domainModelScope, SessionFactoryScope sessionFactoryScope) {
|
||||||
|
// baseline test for straight hbm.xml handling
|
||||||
|
try {
|
||||||
|
verify( domainModelScope, sessionFactoryScope );
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
sessionFactoryScope.inTransaction( (session) -> {
|
||||||
|
session.createMutationQuery( "delete GroupedPropertyRefTests$Account" ).executeUpdate();
|
||||||
|
session.createMutationQuery( "delete GroupedPropertyRefTests$Person" ).executeUpdate();
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void verify(DomainModelScope domainModelScope, SessionFactoryScope sessionFactoryScope) {
|
||||||
|
final PersistentClass accountMapping = domainModelScope.getEntityBinding( Account.class );
|
||||||
|
|
||||||
|
final Property ownerProperty = accountMapping.getProperty( "owner" );
|
||||||
|
final ToOne ownerPropertyValue = (ToOne) ownerProperty.getValue();
|
||||||
|
assertThat( ownerPropertyValue.getReferencedPropertyName() ).isEqualTo( "name" );
|
||||||
|
|
||||||
|
sessionFactoryScope.inTransaction( (session) -> {
|
||||||
|
final Person john = new Person( 1, "John", "Doe" );
|
||||||
|
final Account account = new Account( 1, "savings", john );
|
||||||
|
session.persist( john );
|
||||||
|
session.persist( account );
|
||||||
|
} );
|
||||||
|
|
||||||
|
sessionFactoryScope.inTransaction( (session) -> {
|
||||||
|
final List<Account> accounts = session.createSelectionQuery(
|
||||||
|
"from GroupedPropertyRefTests$Account a join fetch a.owner",
|
||||||
|
Account.class ).list();
|
||||||
|
assertThat( accounts ).hasSize( 1 );
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@ServiceRegistry(settings = @Setting(name= MappingSettings.TRANSFORM_HBM_XML, value="true"))
|
||||||
|
void testTransformed(ServiceRegistryScope registryScope) {
|
||||||
|
// test the transformation - should be an error as this is unsupported
|
||||||
|
try {
|
||||||
|
final StandardServiceRegistry serviceRegistry = registryScope.getRegistry();
|
||||||
|
final MetadataSources metadataSources = new MetadataSources( serviceRegistry );
|
||||||
|
metadataSources.addResource( "mappings/models/hbm/propertyref/properties.hbm.xml" );
|
||||||
|
}
|
||||||
|
catch (InvalidMappingException expected) {
|
||||||
|
assertThat( expected.getCause() ).isInstanceOf( UnsupportedOperationException.class );
|
||||||
|
assertThat( expected.getCause().getMessage() ).startsWith( "<properties/>" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Person {
|
||||||
|
private Integer id;
|
||||||
|
private String firstName;
|
||||||
|
private String lastName;
|
||||||
|
|
||||||
|
public Person() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public Person(Integer id, String firstName, String lastName) {
|
||||||
|
this.id = id;
|
||||||
|
this.firstName = firstName;
|
||||||
|
this.lastName = lastName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFirstName() {
|
||||||
|
return firstName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFirstName(String firstName) {
|
||||||
|
this.firstName = firstName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLastName() {
|
||||||
|
return lastName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLastName(String lastName) {
|
||||||
|
this.lastName = lastName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Account {
|
||||||
|
private Integer id;
|
||||||
|
private String name;
|
||||||
|
private Person owner;
|
||||||
|
|
||||||
|
public Account() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public Account(Integer id, String name, Person owner) {
|
||||||
|
this.id = id;
|
||||||
|
this.name = name;
|
||||||
|
this.owner = owner;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Person getOwner() {
|
||||||
|
return owner;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOwner(Person owner) {
|
||||||
|
this.owner = owner;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -12,6 +12,7 @@ import org.hibernate.boot.internal.MetadataBuilderImpl;
|
||||||
import org.hibernate.boot.model.process.spi.ManagedResources;
|
import org.hibernate.boot.model.process.spi.ManagedResources;
|
||||||
import org.hibernate.boot.model.source.internal.annotations.AdditionalManagedResourcesImpl;
|
import org.hibernate.boot.model.source.internal.annotations.AdditionalManagedResourcesImpl;
|
||||||
import org.hibernate.boot.registry.StandardServiceRegistry;
|
import org.hibernate.boot.registry.StandardServiceRegistry;
|
||||||
|
import org.hibernate.cfg.MappingSettings;
|
||||||
import org.hibernate.mapping.Column;
|
import org.hibernate.mapping.Column;
|
||||||
import org.hibernate.mapping.Property;
|
import org.hibernate.mapping.Property;
|
||||||
import org.hibernate.models.spi.ClassDetails;
|
import org.hibernate.models.spi.ClassDetails;
|
||||||
|
@ -22,6 +23,7 @@ import org.hibernate.testing.orm.junit.DomainModel;
|
||||||
import org.hibernate.testing.orm.junit.DomainModelScope;
|
import org.hibernate.testing.orm.junit.DomainModelScope;
|
||||||
import org.hibernate.testing.orm.junit.ServiceRegistry;
|
import org.hibernate.testing.orm.junit.ServiceRegistry;
|
||||||
import org.hibernate.testing.orm.junit.ServiceRegistryScope;
|
import org.hibernate.testing.orm.junit.ServiceRegistryScope;
|
||||||
|
import org.hibernate.testing.orm.junit.Setting;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
@ -59,7 +61,7 @@ public class ModelTests {
|
||||||
assertThat( transformerAnn.write() ).isEqualTo( "? * 100.00" );
|
assertThat( transformerAnn.write() ).isEqualTo( "? * 100.00" );
|
||||||
}
|
}
|
||||||
|
|
||||||
@ServiceRegistry
|
@ServiceRegistry(settings = @Setting(name = MappingSettings.TRANSFORM_HBM_XML, value = "true"))
|
||||||
@Test
|
@Test
|
||||||
void testHbmXml(ServiceRegistryScope scope) {
|
void testHbmXml(ServiceRegistryScope scope) {
|
||||||
final ManagedResources managedResources = new AdditionalManagedResourcesImpl.Builder( true, true )
|
final ManagedResources managedResources = new AdditionalManagedResourcesImpl.Builder( true, true )
|
||||||
|
|
|
@ -35,12 +35,18 @@ import org.hibernate.boot.registry.StandardServiceRegistry;
|
||||||
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
|
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
|
||||||
import org.hibernate.boot.registry.classloading.spi.ClassLoadingException;
|
import org.hibernate.boot.registry.classloading.spi.ClassLoadingException;
|
||||||
import org.hibernate.boot.spi.BootstrapContext;
|
import org.hibernate.boot.spi.BootstrapContext;
|
||||||
|
import org.hibernate.boot.spi.MetadataBuildingOptions;
|
||||||
import org.hibernate.boot.spi.XmlMappingBinderAccess;
|
import org.hibernate.boot.spi.XmlMappingBinderAccess;
|
||||||
|
import org.hibernate.cfg.Environment;
|
||||||
|
import org.hibernate.engine.config.internal.ConfigurationServiceInitiator;
|
||||||
|
import org.hibernate.engine.config.spi.ConfigurationService;
|
||||||
|
|
||||||
import org.hibernate.testing.TestForIssue;
|
import org.hibernate.testing.TestForIssue;
|
||||||
import org.hibernate.testing.orm.junit.Logger;
|
import org.hibernate.testing.orm.junit.Logger;
|
||||||
import org.hibernate.testing.orm.junit.MessageKeyInspection;
|
import org.hibernate.testing.orm.junit.MessageKeyInspection;
|
||||||
import org.hibernate.testing.orm.junit.MessageKeyWatcher;
|
import org.hibernate.testing.orm.junit.MessageKeyWatcher;
|
||||||
|
import org.hibernate.testing.orm.junit.ServiceRegistry;
|
||||||
|
import org.hibernate.testing.orm.junit.ServiceRegistryScope;
|
||||||
|
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
@ -70,6 +76,7 @@ public class ScanningCoordinatorTest {
|
||||||
private BootstrapContext bootstrapContext = Mockito.mock( BootstrapContext.class );
|
private BootstrapContext bootstrapContext = Mockito.mock( BootstrapContext.class );
|
||||||
private ClassmateContext classmateContext = new ClassmateContext();
|
private ClassmateContext classmateContext = new ClassmateContext();
|
||||||
private XmlMappingBinderAccess xmlMappingBinderAccess = Mockito.mock( XmlMappingBinderAccess.class );
|
private XmlMappingBinderAccess xmlMappingBinderAccess = Mockito.mock( XmlMappingBinderAccess.class );
|
||||||
|
private MetadataBuildingOptions metadataBuildingOptions = Mockito.mock( MetadataBuildingOptions.class );
|
||||||
|
|
||||||
private ScanEnvironment scanEnvironment = Mockito.mock( ScanEnvironment.class );
|
private ScanEnvironment scanEnvironment = Mockito.mock( ScanEnvironment.class );
|
||||||
private StandardServiceRegistry serviceRegistry = Mockito.mock( StandardServiceRegistry.class );
|
private StandardServiceRegistry serviceRegistry = Mockito.mock( StandardServiceRegistry.class );
|
||||||
|
@ -87,8 +94,12 @@ public class ScanningCoordinatorTest {
|
||||||
when( bootstrapContext.getScanEnvironment() ).thenReturn( scanEnvironment );
|
when( bootstrapContext.getScanEnvironment() ).thenReturn( scanEnvironment );
|
||||||
when( bootstrapContext.getClassmateContext() ).thenReturn( classmateContext );
|
when( bootstrapContext.getClassmateContext() ).thenReturn( classmateContext );
|
||||||
when( bootstrapContext.getServiceRegistry() ).thenReturn( serviceRegistry );
|
when( bootstrapContext.getServiceRegistry() ).thenReturn( serviceRegistry );
|
||||||
|
when( bootstrapContext.getMetadataBuildingOptions() ).thenReturn( metadataBuildingOptions );
|
||||||
|
|
||||||
when( serviceRegistry.requireService( ClassLoaderService.class ) ).thenReturn( classLoaderService );
|
when( serviceRegistry.requireService( ClassLoaderService.class ) ).thenReturn( classLoaderService );
|
||||||
|
|
||||||
|
when( metadataBuildingOptions.isXmlMappingEnabled() ).thenReturn( true );
|
||||||
|
|
||||||
when( scanEnvironment.getExplicitlyListedClassNames() ).thenReturn(
|
when( scanEnvironment.getExplicitlyListedClassNames() ).thenReturn(
|
||||||
Arrays.asList( "a.b.C" ) );
|
Arrays.asList( "a.b.C" ) );
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,8 @@ hibernate.connection.autocommit false
|
||||||
hibernate.connection.initial_pool_size 0
|
hibernate.connection.initial_pool_size 0
|
||||||
hibernate.connection.pool_size 5
|
hibernate.connection.pool_size 5
|
||||||
|
|
||||||
|
hibernate.transform_hbm_xml.enabled true
|
||||||
|
|
||||||
hibernate.show_sql true
|
hibernate.show_sql true
|
||||||
hibernate.format_sql true
|
hibernate.format_sql true
|
||||||
hibernate.highlight_sql true
|
hibernate.highlight_sql true
|
||||||
|
|
|
@ -1,22 +0,0 @@
|
||||||
<?xml version="1.0"?>
|
|
||||||
<!--
|
|
||||||
~ 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.orm.test.boot.models.hbm.ecid.Login" table="user_logins">
|
|
||||||
<composite-id>
|
|
||||||
<key-property name="system"/>
|
|
||||||
<key-property name="username"/>
|
|
||||||
</composite-id>
|
|
||||||
<property name="email"/>
|
|
||||||
</class>
|
|
||||||
|
|
||||||
</hibernate-mapping>
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<!--
|
||||||
|
~ 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 package="org.hibernate.test.hbm._extends">
|
||||||
|
<subclass entity-name="Leaf" discriminator-value="L" extends="Branch">
|
||||||
|
</subclass>
|
||||||
|
|
||||||
|
<subclass entity-name="Branch" discriminator-value="B" extends="Root">
|
||||||
|
</subclass>
|
||||||
|
|
||||||
|
<class entity-name="Root" discriminator-value="R">
|
||||||
|
<id/>
|
||||||
|
<discriminator column="the_type"/>
|
||||||
|
<property name="name"/>
|
||||||
|
</class>
|
||||||
|
</hibernate-mapping>
|
|
@ -0,0 +1,22 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<!--
|
||||||
|
~ 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 package="org.hibernate.test.hbm._extends">
|
||||||
|
<class entity-name="Root" discriminator-value="R">
|
||||||
|
<id/>
|
||||||
|
<discriminator column="the_type"/>
|
||||||
|
<property name="name"/>
|
||||||
|
<subclass entity-name="Branch" discriminator-value="B">
|
||||||
|
<subclass entity-name="Leaf" discriminator-value="L">
|
||||||
|
</subclass>
|
||||||
|
</subclass>
|
||||||
|
</class>
|
||||||
|
</hibernate-mapping>
|
|
@ -0,0 +1,20 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<!--
|
||||||
|
~ 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 package="org.hibernate.orm.test.boot.models.hbm.intf">
|
||||||
|
<class name="IPerson" abstract="true">
|
||||||
|
<id/>
|
||||||
|
<discriminator/>
|
||||||
|
<property name="name"/>
|
||||||
|
|
||||||
|
<subclass name="Person" discriminator-value="P"/>
|
||||||
|
</class>
|
||||||
|
</hibernate-mapping>
|
|
@ -0,0 +1,35 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<!--
|
||||||
|
~ 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="Address" table="addresses">
|
||||||
|
<id name="id"/>
|
||||||
|
<properties name="uniqueAddress">
|
||||||
|
<property name="addressType" column="ADDRESS_TYPE" type="string" insert="false" update="false" length="30"/>
|
||||||
|
<many-to-one name="server" column="SERVER_ID" class="Server" not-null="true"/>
|
||||||
|
</properties>
|
||||||
|
</class>
|
||||||
|
|
||||||
|
<class name="Server" table="servers">
|
||||||
|
<id name="id"/>
|
||||||
|
<property name="serverType" type="string" column="SERVER_TYPE" length="10" update="false" insert="false"/>
|
||||||
|
<many-to-one name="address"
|
||||||
|
class="Address"
|
||||||
|
property-ref="uniqueAddress"
|
||||||
|
cascade="all"
|
||||||
|
unique="true"
|
||||||
|
update="false"
|
||||||
|
insert="false">
|
||||||
|
<column name="address_type"/>
|
||||||
|
<column name="server_id"/>
|
||||||
|
</many-to-one>
|
||||||
|
</class>
|
||||||
|
</hibernate-mapping>
|
|
@ -0,0 +1,33 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<!--
|
||||||
|
~ 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
|
||||||
|
package="org.hibernate.orm.test.boot.models.hbm.propertyref"
|
||||||
|
default-access="field">
|
||||||
|
|
||||||
|
<class name="GroupedPropertyRefTests$Person" table="persons">
|
||||||
|
<id name="id"/>
|
||||||
|
<properties name="name">
|
||||||
|
<property name="firstName" column="fname"/>
|
||||||
|
<property name="lastName" column="lname"/>
|
||||||
|
</properties>
|
||||||
|
</class>
|
||||||
|
|
||||||
|
<class name="GroupedPropertyRefTests$Account" table="accounts">
|
||||||
|
<id name="id"/>
|
||||||
|
<property name="name"/>
|
||||||
|
<many-to-one name="owner" property-ref="name">
|
||||||
|
<column name="owner_name_first"/>
|
||||||
|
<column name="owner_name_last"/>
|
||||||
|
</many-to-one>
|
||||||
|
</class>
|
||||||
|
|
||||||
|
</hibernate-mapping>
|
|
@ -179,6 +179,15 @@ Hibernate can use the persistence-unit name for binding into JNDI as well, but `
|
||||||
must be explicitly set to true.
|
must be explicitly set to true.
|
||||||
|
|
||||||
|
|
||||||
|
[[hbm-transform]]
|
||||||
|
== hbm.xml Transformation
|
||||||
|
|
||||||
|
Previous versions of Hibernate performed transformations of `hbm.xml` files (with `` enabled)
|
||||||
|
one file at a time. This is now done across the entire set of `hbm.xml` files at once.
|
||||||
|
While most users will never see this change, it might impact integrations which tie-in to
|
||||||
|
XML processing.
|
||||||
|
|
||||||
|
|
||||||
[[todo]]
|
[[todo]]
|
||||||
== Todos (dev)
|
== Todos (dev)
|
||||||
|
|
||||||
|
|
|
@ -72,7 +72,7 @@ dependencyResolutionManagement {
|
||||||
def byteBuddyVersion = version "byteBuddy", "1.14.18"
|
def byteBuddyVersion = version "byteBuddy", "1.14.18"
|
||||||
def classmateVersion = version "classmate", "1.5.1"
|
def classmateVersion = version "classmate", "1.5.1"
|
||||||
def geolatteVersion = version "geolatte", "1.9.1"
|
def geolatteVersion = version "geolatte", "1.9.1"
|
||||||
def hibernateModelsVersion = version "hibernateModels", "0.8.4"
|
def hibernateModelsVersion = version "hibernateModels", "0.8.5"
|
||||||
def jandexVersion = version "jandex", "3.2.0"
|
def jandexVersion = version "jandex", "3.2.0"
|
||||||
def hcannVersion = version "hcann", "7.0.1.Final"
|
def hcannVersion = version "hcann", "7.0.1.Final"
|
||||||
def jacksonVersion = version "jackson", "2.17.0"
|
def jacksonVersion = version "jackson", "2.17.0"
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
/*
|
||||||
|
* 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.tooling.gradle.misc;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
import org.hibernate.boot.jaxb.Origin;
|
||||||
|
import org.hibernate.boot.jaxb.SourceType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
public class OriginImpl extends Origin {
|
||||||
|
private final File hbmXmlFile;
|
||||||
|
|
||||||
|
public OriginImpl(File hbmXmlFile) {
|
||||||
|
super( SourceType.FILE, hbmXmlFile.getAbsolutePath() );
|
||||||
|
this.hbmXmlFile = hbmXmlFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
public File getHbmXmlFile() {
|
||||||
|
return hbmXmlFile;
|
||||||
|
}
|
||||||
|
}
|
|
@ -9,9 +9,12 @@ package org.hibernate.orm.tooling.gradle.misc;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import org.gradle.api.file.DirectoryProperty;
|
import org.gradle.api.file.DirectoryProperty;
|
||||||
import org.gradle.api.provider.Property;
|
import org.gradle.api.provider.Property;
|
||||||
|
import org.gradle.api.tasks.CacheableTask;
|
||||||
import org.gradle.api.tasks.Input;
|
import org.gradle.api.tasks.Input;
|
||||||
import org.gradle.api.tasks.Nested;
|
import org.gradle.api.tasks.Nested;
|
||||||
import org.gradle.api.tasks.OutputDirectory;
|
import org.gradle.api.tasks.OutputDirectory;
|
||||||
|
@ -19,7 +22,6 @@ import org.gradle.api.tasks.SourceTask;
|
||||||
import org.gradle.api.tasks.TaskAction;
|
import org.gradle.api.tasks.TaskAction;
|
||||||
|
|
||||||
import org.hibernate.boot.jaxb.Origin;
|
import org.hibernate.boot.jaxb.Origin;
|
||||||
import org.hibernate.boot.jaxb.SourceType;
|
|
||||||
import org.hibernate.boot.jaxb.hbm.spi.JaxbHbmHibernateMapping;
|
import org.hibernate.boot.jaxb.hbm.spi.JaxbHbmHibernateMapping;
|
||||||
import org.hibernate.boot.jaxb.hbm.transform.HbmXmlTransformer;
|
import org.hibernate.boot.jaxb.hbm.transform.HbmXmlTransformer;
|
||||||
import org.hibernate.boot.jaxb.hbm.transform.UnsupportedFeatureHandling;
|
import org.hibernate.boot.jaxb.hbm.transform.UnsupportedFeatureHandling;
|
||||||
|
@ -53,6 +55,7 @@ import jakarta.xml.bind.Marshaller;
|
||||||
* replacing the original (destructive).
|
* replacing the original (destructive).
|
||||||
* @see org.hibernate.boot.jaxb.hbm.transform.HbmXmlTransformer
|
* @see org.hibernate.boot.jaxb.hbm.transform.HbmXmlTransformer
|
||||||
*/
|
*/
|
||||||
|
@CacheableTask
|
||||||
public abstract class TransformHbmXmlTask extends SourceTask {
|
public abstract class TransformHbmXmlTask extends SourceTask {
|
||||||
private final Property<TransformationNaming> renaming;
|
private final Property<TransformationNaming> renaming;
|
||||||
private final Property<UnsupportedFeatureHandling> unsupportedFeatures;
|
private final Property<UnsupportedFeatureHandling> unsupportedFeatures;
|
||||||
|
@ -127,15 +130,24 @@ public abstract class TransformHbmXmlTask extends SourceTask {
|
||||||
throw new RuntimeException( "Unable to create JAXB Marshaller", e );
|
throw new RuntimeException( "Unable to create JAXB Marshaller", e );
|
||||||
}
|
}
|
||||||
|
|
||||||
getSource().forEach( (hbmXmlFile) -> transformFile( mappingBinder, marshaller, hbmXmlFile ) );
|
final List<Binding<JaxbHbmHibernateMapping>> hbmBindings = new ArrayList<>();
|
||||||
}
|
getSource().forEach( (hbmXmlFile) -> {
|
||||||
|
final Origin origin = new OriginImpl( hbmXmlFile );
|
||||||
|
final Binding<JaxbHbmHibernateMapping> hbmBinding = bindMapping( mappingBinder, hbmXmlFile, origin );
|
||||||
|
hbmBindings.add( hbmBinding );
|
||||||
|
} );
|
||||||
|
|
||||||
private void transformFile(MappingBinder mappingBinder, Marshaller marshaller, File hbmXmlFile) {
|
final List<Binding<JaxbEntityMappingsImpl>> transformedBindings = HbmXmlTransformer.transform(
|
||||||
final Origin origin = new Origin( SourceType.FILE, hbmXmlFile.getAbsolutePath() );
|
hbmBindings,
|
||||||
final Binding<JaxbHbmHibernateMapping> binding = bindMapping( mappingBinder, hbmXmlFile, origin );
|
unsupportedFeatures.get()
|
||||||
if ( binding == null ) {
|
);
|
||||||
return;
|
|
||||||
}
|
for ( int i = 0; i < hbmBindings.size(); i++ ) {
|
||||||
|
final Binding<JaxbHbmHibernateMapping> hbmBinding = hbmBindings.get( i );
|
||||||
|
final Binding<JaxbEntityMappingsImpl> transformedBinding = transformedBindings.get( i );
|
||||||
|
|
||||||
|
final OriginImpl origin = (OriginImpl) hbmBinding.getOrigin();
|
||||||
|
final File hbmXmlFile = origin.getHbmXmlFile();
|
||||||
|
|
||||||
if ( deleteHbmFiles.getOrElse( false ) ) {
|
if ( deleteHbmFiles.getOrElse( false ) ) {
|
||||||
final boolean deleted = hbmXmlFile.delete();
|
final boolean deleted = hbmXmlFile.delete();
|
||||||
|
@ -144,16 +156,12 @@ public abstract class TransformHbmXmlTask extends SourceTask {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final HbmXmlTransformer.Options transformationOptions = unsupportedFeatures::get;
|
|
||||||
|
|
||||||
final JaxbEntityMappingsImpl transformed = HbmXmlTransformer.transform( binding.getRoot(), origin, transformationOptions );
|
|
||||||
|
|
||||||
final String copyName = determineCopyName( hbmXmlFile );
|
final String copyName = determineCopyName( hbmXmlFile );
|
||||||
final File copyFile = determineCopyFile( copyName, hbmXmlFile );
|
final File copyFile = determineCopyFile( copyName, hbmXmlFile );
|
||||||
//noinspection ResultOfMethodCallIgnored
|
//noinspection ResultOfMethodCallIgnored
|
||||||
copyFile.getParentFile().mkdirs();
|
copyFile.getParentFile().mkdirs();
|
||||||
try {
|
try {
|
||||||
marshaller.marshal( transformed, copyFile );
|
marshaller.marshal( transformedBinding.getRoot(), copyFile );
|
||||||
}
|
}
|
||||||
catch (JAXBException e) {
|
catch (JAXBException e) {
|
||||||
throw new RuntimeException(
|
throw new RuntimeException(
|
||||||
|
@ -162,6 +170,7 @@ public abstract class TransformHbmXmlTask extends SourceTask {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private Binding<JaxbHbmHibernateMapping> bindMapping(MappingBinder mappingBinder, File hbmXmlFile, Origin origin) {
|
private Binding<JaxbHbmHibernateMapping> bindMapping(MappingBinder mappingBinder, File hbmXmlFile, Origin origin) {
|
||||||
try ( final FileInputStream fileStream = new FileInputStream( hbmXmlFile ) ) {
|
try ( final FileInputStream fileStream = new FileInputStream( hbmXmlFile ) ) {
|
||||||
|
|
Loading…
Reference in New Issue