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.boot.archive.spi.InputStreamAccess;
|
||||
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.spi.JaxbBindableMappingDescriptor;
|
||||
import org.hibernate.boot.jaxb.mapping.spi.JaxbEntityMappingsImpl;
|
||||
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.registry.BootstrapServiceRegistry;
|
||||
import org.hibernate.boot.registry.BootstrapServiceRegistryBuilder;
|
||||
|
@ -37,6 +39,8 @@ import org.hibernate.internal.CoreMessageLogger;
|
|||
import org.hibernate.service.ServiceRegistry;
|
||||
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
|
||||
* in the form of annotated classes, or as XML mapping documents.
|
||||
|
@ -65,7 +69,9 @@ public class MetadataSources implements Serializable {
|
|||
|
||||
private XmlMappingBinderAccess xmlMappingBinderAccess;
|
||||
|
||||
private List<Binding<JaxbBindableMappingDescriptor>> xmlBindings;
|
||||
private List<Binding<JaxbEntityMappingsImpl>> mappingXmlBindings;
|
||||
private List<Binding<JaxbHbmHibernateMapping>> hbmXmlBindings;
|
||||
|
||||
private LinkedHashSet<Class<?>> annotatedClasses;
|
||||
private LinkedHashSet<String> annotatedClassNames;
|
||||
private LinkedHashSet<String> annotatedPackages;
|
||||
|
@ -121,8 +127,36 @@ public class MetadataSources implements Serializable {
|
|||
return xmlMappingBinderAccess;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Prefer {@linkplain #getMappingXmlBindings()} and/or {@linkplain #getHbmXmlBindings()}
|
||||
*/
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
@Deprecated(since = "7.0")
|
||||
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() {
|
||||
|
@ -329,7 +363,7 @@ public class MetadataSources implements Serializable {
|
|||
public MetadataSources addResource(String name) {
|
||||
final XmlSource xmlSource = XmlSources.fromResource( name, classLoaderService );
|
||||
final XmlMappingBinderAccess binderAccess = getXmlMappingBinderAccess();
|
||||
getXmlBindingsForWrite().add( xmlSource.doBind( binderAccess.getMappingBinder() ) );
|
||||
addXmlBinding( xmlSource.doBind( binderAccess.getMappingBinder() ) );
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -359,7 +393,7 @@ public class MetadataSources implements Serializable {
|
|||
public MetadataSources addFile(File file) {
|
||||
final XmlSource xmlSource = XmlSources.fromFile( file );
|
||||
final XmlMappingBinderAccess binderAccess = getXmlMappingBinderAccess();
|
||||
getXmlBindingsForWrite().add( xmlSource.doBind( binderAccess.getMappingBinder() ) );
|
||||
addXmlBinding( xmlSource.doBind( binderAccess.getMappingBinder() ) );
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -372,8 +406,45 @@ public class MetadataSources implements Serializable {
|
|||
* @return this (for method chaining purposes)
|
||||
*/
|
||||
public MetadataSources addXmlBinding(Binding<?> binding) {
|
||||
//noinspection unchecked
|
||||
getXmlBindingsForWrite().add( (Binding<JaxbBindableMappingDescriptor>) binding );
|
||||
if ( binding.getRoot() instanceof JaxbEntityMappingsImpl ) {
|
||||
//noinspection unchecked
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -444,7 +515,7 @@ public class MetadataSources implements Serializable {
|
|||
public MetadataSources addCacheableFile(File file, File cacheDirectory) {
|
||||
final XmlSource xmlSource = XmlSources.fromCacheableFile( file, cacheDirectory );
|
||||
final XmlMappingBinderAccess binderAccess = getXmlMappingBinderAccess();
|
||||
getXmlBindingsForWrite().add( xmlSource.doBind( binderAccess.getMappingBinder() ) );
|
||||
addXmlBinding( xmlSource.doBind( binderAccess.getMappingBinder() ) );
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -464,7 +535,7 @@ public class MetadataSources implements Serializable {
|
|||
public MetadataSources addCacheableFileStrictly(File file) throws SerializationException {
|
||||
final XmlSource xmlSource = XmlSources.fromCacheableFile( file, true );
|
||||
final XmlMappingBinderAccess binderAccess = getXmlMappingBinderAccess();
|
||||
getXmlBindingsForWrite().add( xmlSource.doBind( binderAccess.getMappingBinder() ) );
|
||||
addXmlBinding( xmlSource.doBind( binderAccess.getMappingBinder() ) );
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -484,7 +555,7 @@ public class MetadataSources implements Serializable {
|
|||
public MetadataSources addCacheableFileStrictly(File file, File cacheDir) throws SerializationException {
|
||||
final XmlSource xmlSource = XmlSources.fromCacheableFile( file, cacheDir, true );
|
||||
final XmlMappingBinderAccess binderAccess = getXmlMappingBinderAccess();
|
||||
getXmlBindingsForWrite().add( xmlSource.doBind( binderAccess.getMappingBinder() ) );
|
||||
addXmlBinding( xmlSource.doBind( binderAccess.getMappingBinder() ) );
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -498,7 +569,7 @@ public class MetadataSources implements Serializable {
|
|||
public MetadataSources addInputStream(InputStreamAccess xmlInputStreamAccess) {
|
||||
final XmlSource xmlSource = XmlSources.fromStream( xmlInputStreamAccess );
|
||||
final XmlMappingBinderAccess binderAccess = getXmlMappingBinderAccess();
|
||||
getXmlBindingsForWrite().add( xmlSource.doBind( binderAccess.getMappingBinder() ) );
|
||||
addXmlBinding( xmlSource.doBind( binderAccess.getMappingBinder() ) );
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -512,7 +583,7 @@ public class MetadataSources implements Serializable {
|
|||
public MetadataSources addInputStream(InputStream xmlInputStream) {
|
||||
final XmlSource xmlSource = XmlSources.fromStream( xmlInputStream );
|
||||
final XmlMappingBinderAccess binderAccess = getXmlMappingBinderAccess();
|
||||
getXmlBindingsForWrite().add( xmlSource.doBind( binderAccess.getMappingBinder() ) );
|
||||
addXmlBinding( xmlSource.doBind( binderAccess.getMappingBinder() ) );
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -526,7 +597,7 @@ public class MetadataSources implements Serializable {
|
|||
public MetadataSources addURL(URL url) {
|
||||
final XmlSource xmlSource = XmlSources.fromUrl( url );
|
||||
final XmlMappingBinderAccess binderAccess = getXmlMappingBinderAccess();
|
||||
getXmlBindingsForWrite().add( xmlSource.doBind( binderAccess.getMappingBinder() ) );
|
||||
addXmlBinding( xmlSource.doBind( binderAccess.getMappingBinder() ) );
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -544,18 +615,11 @@ public class MetadataSources implements Serializable {
|
|||
final XmlMappingBinderAccess binderAccess = getXmlMappingBinderAccess();
|
||||
XmlSources.fromJar(
|
||||
jar,
|
||||
xmlSource -> getXmlBindingsForWrite().add( xmlSource.doBind( binderAccess.getMappingBinder() ) )
|
||||
xmlSource -> addXmlBinding( xmlSource.doBind( binderAccess.getMappingBinder() ) )
|
||||
);
|
||||
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.
|
||||
* <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.JaxbHbmSetType;
|
||||
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.JaxbHbmTimestampAttributeType;
|
||||
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.JaxbUserTypeImpl;
|
||||
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.collections.CollectionHelper;
|
||||
|
||||
|
@ -170,54 +172,65 @@ import jakarta.xml.bind.JAXBException;
|
|||
import jakarta.xml.bind.Marshaller;
|
||||
|
||||
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;
|
||||
|
||||
/**
|
||||
* 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 Brett Meyer
|
||||
*
|
||||
* @implNote This transformation happens on the JAXB model level creating
|
||||
* a {@link JaxbEntityMappingsImpl} "copy" of the {@link JaxbHbmHibernateMapping}
|
||||
* representation
|
||||
*/
|
||||
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 origin The origin of the hbm.xml mapping
|
||||
* @return The transformed representation
|
||||
* @param hbmXmlBindings The list of {@code hbm.xml} JAXB bindings
|
||||
* @param unsupportedFeatureHandling How to handle {@code hbm.xml} features we don't transform
|
||||
*
|
||||
* @return The list of {@code mapping.xml} JAXB bindings
|
||||
*/
|
||||
public static JaxbEntityMappingsImpl transform(JaxbHbmHibernateMapping hbmXmlMapping, Origin origin, Options options) {
|
||||
return new HbmXmlTransformer( hbmXmlMapping, origin, options ).doTransform();
|
||||
}
|
||||
public static List<Binding<JaxbEntityMappingsImpl>> transform(
|
||||
List<Binding<JaxbHbmHibernateMapping>> hbmXmlBindings,
|
||||
UnsupportedFeatureHandling unsupportedFeatureHandling) {
|
||||
final TransformationState transformationState = new TransformationState( hbmXmlBindings );
|
||||
TransformationPreprocessor.preprocessHbmXml( hbmXmlBindings, transformationState );
|
||||
|
||||
public interface Options {
|
||||
UnsupportedFeatureHandling unsupportedFeatureHandling();
|
||||
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();
|
||||
}
|
||||
|
||||
return transformationState.getMappingBindings();
|
||||
}
|
||||
|
||||
private final Origin origin;
|
||||
private final JaxbHbmHibernateMapping hbmXmlMapping;
|
||||
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(
|
||||
"Starting hbm.xml transformation - `%s`",
|
||||
origin
|
||||
|
@ -247,7 +260,6 @@ public class HbmXmlTransformer {
|
|||
if ( TRANSFORMATION_LOGGER.isDebugEnabled() ) {
|
||||
dumpTransformed( origin, ormRoot );
|
||||
}
|
||||
return 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) {
|
||||
switch ( options.unsupportedFeatureHandling() ) {
|
||||
switch ( unsupportedFeatureHandling ) {
|
||||
case ERROR -> throw new UnsupportedOperationException(
|
||||
String.format(
|
||||
Locale.ROOT,
|
||||
|
@ -807,32 +819,28 @@ public class HbmXmlTransformer {
|
|||
// 2) ?? Have abstract hbm class mappings become MappedSuperclass mappings ??
|
||||
|
||||
for ( JaxbHbmRootEntityType hbmClass : hbmXmlMapping.getClazz() ) {
|
||||
final JaxbEntityImpl entity = new JaxbEntityImpl();
|
||||
ormRoot.getEntities().add( entity );
|
||||
final JaxbEntityImpl entity = transformationState.getEntityXref().get( hbmClass );
|
||||
transferRootEntity( hbmClass, entity );
|
||||
}
|
||||
|
||||
for ( JaxbHbmDiscriminatorSubclassEntityType hbmSubclass : hbmXmlMapping.getSubclass() ) {
|
||||
final JaxbEntityImpl entity = new JaxbEntityImpl();
|
||||
ormRoot.getEntities().add( entity );
|
||||
final JaxbEntityImpl entity = transformationState.getEntityXref().get( hbmSubclass );
|
||||
transferDiscriminatorSubclass( hbmSubclass, entity );
|
||||
}
|
||||
|
||||
for ( JaxbHbmJoinedSubclassEntityType hbmSubclass : hbmXmlMapping.getJoinedSubclass() ) {
|
||||
final JaxbEntityImpl entity = new JaxbEntityImpl();
|
||||
ormRoot.getEntities().add( entity );
|
||||
final JaxbEntityImpl entity = transformationState.getEntityXref().get( hbmSubclass );
|
||||
transferJoinedSubclass( hbmSubclass, entity );
|
||||
}
|
||||
|
||||
for ( JaxbHbmUnionSubclassEntityType hbmSubclass : hbmXmlMapping.getUnionSubclass() ) {
|
||||
final JaxbEntityImpl entity = new JaxbEntityImpl();
|
||||
ormRoot.getEntities().add( entity );
|
||||
final JaxbEntityImpl entity = transformationState.getEntityXref().get( hbmSubclass );
|
||||
transferUnionSubclass( hbmSubclass, entity );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private String extractEntityName(EntityInfo entityInfo) {
|
||||
private static String extractEntityName(EntityInfo entityInfo) {
|
||||
if ( entityInfo.getEntityName() != null ) {
|
||||
return entityInfo.getEntityName();
|
||||
}
|
||||
|
@ -901,12 +909,12 @@ public class HbmXmlTransformer {
|
|||
entity.setSqlRestriction( hbmClass.getWhere() );
|
||||
|
||||
if ( !hbmClass.getTuplizer().isEmpty() ) {
|
||||
if ( options.unsupportedFeatureHandling() == UnsupportedFeatureHandling.ERROR ) {
|
||||
if ( unsupportedFeatureHandling == UnsupportedFeatureHandling.ERROR ) {
|
||||
throw new MappingException( "HBM transformation: Tuplizer not supported", origin );
|
||||
}
|
||||
|
||||
TRANSFORMATION_LOGGER.logf(
|
||||
options.unsupportedFeatureHandling() == UnsupportedFeatureHandling.WARN
|
||||
unsupportedFeatureHandling == UnsupportedFeatureHandling.WARN
|
||||
? Logger.Level.WARN
|
||||
: Logger.Level.DEBUG,
|
||||
"Transformation of <tuplizer/> is not supported - `%s`",
|
||||
|
@ -950,26 +958,17 @@ public class HbmXmlTransformer {
|
|||
}
|
||||
|
||||
for ( JaxbHbmJoinedSubclassEntityType hbmSubclass : hbmClass.getJoinedSubclass() ) {
|
||||
entity.setInheritance( new JaxbInheritanceImpl() );
|
||||
entity.getInheritance().setStrategy( InheritanceType.JOINED );
|
||||
|
||||
final JaxbEntityImpl subclassEntity = new JaxbEntityImpl();
|
||||
ormRoot.getEntities().add( subclassEntity );
|
||||
final JaxbEntityImpl subclassEntity = transformationState.getEntityXref().get( hbmSubclass );
|
||||
transferJoinedSubclass( hbmSubclass, subclassEntity );
|
||||
}
|
||||
|
||||
for (JaxbHbmUnionSubclassEntityType hbmSubclass : hbmClass.getUnionSubclass() ) {
|
||||
entity.setInheritance( new JaxbInheritanceImpl() );
|
||||
entity.getInheritance().setStrategy( InheritanceType.TABLE_PER_CLASS );
|
||||
|
||||
final JaxbEntityImpl subclassEntity = new JaxbEntityImpl();
|
||||
ormRoot.getEntities().add( subclassEntity );
|
||||
final JaxbEntityImpl subclassEntity = transformationState.getEntityXref().get( hbmSubclass );
|
||||
transferUnionSubclass( hbmSubclass, subclassEntity );
|
||||
}
|
||||
|
||||
for ( JaxbHbmDiscriminatorSubclassEntityType hbmSubclass : hbmClass.getSubclass() ) {
|
||||
final JaxbEntityImpl subclassEntity = new JaxbEntityImpl();
|
||||
ormRoot.getEntities().add( subclassEntity );
|
||||
final JaxbEntityImpl subclassEntity = transformationState.getEntityXref().get( hbmSubclass );
|
||||
transferDiscriminatorSubclass( hbmSubclass, subclassEntity );
|
||||
}
|
||||
|
||||
|
@ -1023,6 +1022,19 @@ public class HbmXmlTransformer {
|
|||
transfer( hbmClass::getEntityName, entity::setName );
|
||||
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 ) {
|
||||
transfer( discriminatable::getDiscriminatorValue, entity::setDiscriminatorValue );
|
||||
}
|
||||
|
@ -1081,6 +1093,13 @@ public class HbmXmlTransformer {
|
|||
transferBaseEntityInformation( 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) {
|
||||
|
@ -1113,11 +1132,8 @@ public class HbmXmlTransformer {
|
|||
}
|
||||
|
||||
if ( !hbmSubclass.getJoinedSubclass().isEmpty() ) {
|
||||
subclassEntity.setInheritance( new JaxbInheritanceImpl() );
|
||||
subclassEntity.getInheritance().setStrategy( InheritanceType.JOINED );
|
||||
for ( JaxbHbmJoinedSubclassEntityType nestedHbmSubclass : hbmSubclass.getJoinedSubclass() ) {
|
||||
final JaxbEntityImpl nestedSubclassEntity = new JaxbEntityImpl();
|
||||
ormRoot.getEntities().add( nestedSubclassEntity );
|
||||
final JaxbEntityImpl nestedSubclassEntity = transformationState.getEntityXref().get( nestedHbmSubclass );
|
||||
transferJoinedSubclass( nestedHbmSubclass, nestedSubclassEntity );
|
||||
}
|
||||
}
|
||||
|
@ -1284,7 +1300,15 @@ public class HbmXmlTransformer {
|
|||
attributes.getEmbeddedAttributes().add( transformEmbedded( jaxbEmbeddable, hbmComponent ) );
|
||||
}
|
||||
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 ) {
|
||||
final String name = ( (JaxbHbmDynamicComponentType) hbmAttributeMapping ).getName();
|
||||
|
@ -2401,11 +2425,8 @@ public class HbmXmlTransformer {
|
|||
}
|
||||
|
||||
if ( !hbmSubclass.getUnionSubclass().isEmpty() ) {
|
||||
subclassEntity.setInheritance( new JaxbInheritanceImpl() );
|
||||
subclassEntity.getInheritance().setStrategy( InheritanceType.TABLE_PER_CLASS );
|
||||
for ( JaxbHbmUnionSubclassEntityType nestedHbmSubclass : hbmSubclass.getUnionSubclass() ) {
|
||||
final JaxbEntityImpl nestedSubclassEntity = new JaxbEntityImpl();
|
||||
ormRoot.getEntities().add( nestedSubclassEntity );
|
||||
final JaxbEntityImpl nestedSubclassEntity = transformationState.getEntityXref().get( nestedHbmSubclass );
|
||||
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.boot.ResourceStreamLocator;
|
||||
import org.hibernate.boot.UnsupportedOrmXsdVersionException;
|
||||
import org.hibernate.boot.jaxb.JaxbLogger;
|
||||
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.internal.stax.HbmEventReader;
|
||||
import org.hibernate.boot.jaxb.internal.stax.JpaOrmXmlEventReader;
|
||||
import org.hibernate.boot.jaxb.internal.stax.MappingEventReader;
|
||||
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.JaxbBindableMappingDescriptor;
|
||||
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
|
||||
import org.hibernate.boot.xsd.MappingXsdSupport;
|
||||
import org.hibernate.cfg.AvailableSettings;
|
||||
import org.hibernate.engine.config.spi.ConfigurationService;
|
||||
import org.hibernate.internal.log.DeprecationLogger;
|
||||
import org.hibernate.internal.util.config.ConfigurationException;
|
||||
import org.hibernate.service.ServiceRegistry;
|
||||
import org.hibernate.service.spi.ServiceRegistryImplementor;
|
||||
|
@ -62,8 +59,6 @@ public class MappingBinder extends AbstractBinder<JaxbBindableMappingDescriptor>
|
|||
|
||||
public interface Options {
|
||||
boolean validateMappings();
|
||||
|
||||
boolean transformHbmMappings();
|
||||
}
|
||||
|
||||
public static final Options VALIDATING = new Options() {
|
||||
|
@ -71,11 +66,6 @@ public class MappingBinder extends AbstractBinder<JaxbBindableMappingDescriptor>
|
|||
public boolean validateMappings() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean transformHbmMappings() {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
public static final Options NON_VALIDATING = new Options() {
|
||||
|
@ -83,11 +73,6 @@ public class MappingBinder extends AbstractBinder<JaxbBindableMappingDescriptor>
|
|||
public boolean validateMappings() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean transformHbmMappings() {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -131,15 +116,6 @@ public class MappingBinder extends AbstractBinder<JaxbBindableMappingDescriptor>
|
|||
}
|
||||
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 = () -> {
|
||||
|
@ -178,11 +154,6 @@ public class MappingBinder extends AbstractBinder<JaxbBindableMappingDescriptor>
|
|||
public boolean validateMappings() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean transformHbmMappings() {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
unsupportedHandling
|
||||
);
|
||||
|
@ -219,13 +190,6 @@ public class MappingBinder extends AbstractBinder<JaxbBindableMappingDescriptor>
|
|||
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
|
||||
return new Binding<>( (X) hbmBindings, origin );
|
||||
}
|
||||
|
@ -241,6 +205,7 @@ public class MappingBinder extends AbstractBinder<JaxbBindableMappingDescriptor>
|
|||
mappingJaxbContext(),
|
||||
origin
|
||||
);
|
||||
|
||||
//noinspection unchecked
|
||||
return new Binding<>( (X) bindingRoot, origin );
|
||||
}
|
||||
|
|
|
@ -16,15 +16,27 @@ import java.util.Map;
|
|||
import java.util.Set;
|
||||
|
||||
import org.hibernate.Internal;
|
||||
import org.hibernate.boot.BootLogging;
|
||||
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.JaxbBindableMappingDescriptor;
|
||||
import org.hibernate.boot.model.convert.spi.ConverterDescriptor;
|
||||
import org.hibernate.boot.model.process.spi.ManagedResources;
|
||||
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 static org.hibernate.engine.config.spi.StandardConverters.BOOLEAN;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
|
@ -42,11 +54,53 @@ public class ManagedResourcesImpl implements ManagedResources {
|
|||
impl.annotatedClassReferences.addAll( sources.getAnnotatedClasses() );
|
||||
impl.annotatedClassNames.addAll( sources.getAnnotatedClassNames() );
|
||||
impl.annotatedPackageNames.addAll( sources.getAnnotatedPackages() );
|
||||
impl.mappingFileBindings.addAll( sources.getXmlBindings() );
|
||||
handleXmlMappings( sources, impl, bootstrapContext );
|
||||
impl.extraQueryImports = sources.getExtraQueryImports();
|
||||
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() {
|
||||
}
|
||||
|
||||
|
|
|
@ -576,11 +576,6 @@ public class MetadataBuildingProcess {
|
|||
public boolean validateMappings() {
|
||||
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.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
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.transform.HbmXmlTransformer;
|
||||
import org.hibernate.boot.jaxb.hbm.transform.UnsupportedFeatureHandling;
|
||||
import org.hibernate.boot.jaxb.internal.MappingBinder;
|
||||
import org.hibernate.boot.jaxb.mapping.spi.JaxbEntityMappingsImpl;
|
||||
import org.hibernate.boot.jaxb.spi.Binding;
|
||||
|
@ -85,6 +89,7 @@ public class AdditionalManagedResourcesImpl implements ManagedResources {
|
|||
|
||||
public static class Builder {
|
||||
private final MappingBinder mappingBinder;
|
||||
private final boolean transformHbmMappings;
|
||||
|
||||
private List<Class<?>> classes;
|
||||
private List<ClassDetails> classDetails;
|
||||
|
@ -92,35 +97,26 @@ public class AdditionalManagedResourcesImpl implements ManagedResources {
|
|||
private Collection<Binding<JaxbBindableMappingDescriptor>> xmlMappings;
|
||||
|
||||
public Builder(boolean validateMappings, boolean transformHbmMappings) {
|
||||
this( new MappingBinder.Options() {
|
||||
this( transformHbmMappings, new MappingBinder.Options() {
|
||||
@Override
|
||||
public boolean validateMappings() {
|
||||
return validateMappings;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean transformHbmMappings() {
|
||||
return transformHbmMappings;
|
||||
}
|
||||
} );
|
||||
}
|
||||
|
||||
public Builder() {
|
||||
this( new MappingBinder.Options() {
|
||||
this( false, new MappingBinder.Options() {
|
||||
@Override
|
||||
public boolean validateMappings() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean transformHbmMappings() {
|
||||
return false;
|
||||
}
|
||||
} );
|
||||
}
|
||||
|
||||
public Builder(MappingBinder.Options options) {
|
||||
mappingBinder = new MappingBinder(
|
||||
public Builder(boolean transformHbmMappings, MappingBinder.Options options) {
|
||||
this.transformHbmMappings = transformHbmMappings;
|
||||
this.mappingBinder = new MappingBinder(
|
||||
(resourceName) -> Builder.class.getClassLoader().getResourceAsStream( resourceName ),
|
||||
options
|
||||
);
|
||||
|
@ -163,6 +159,28 @@ public class AdditionalManagedResourcesImpl implements ManagedResources {
|
|||
}
|
||||
|
||||
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 );
|
||||
}
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.hibernate.MappingException;
|
||||
import org.hibernate.boot.internal.MetadataBuildingContextRootImpl;
|
||||
import org.hibernate.boot.jaxb.mapping.spi.JaxbEntityMappingsImpl;
|
||||
import org.hibernate.boot.model.convert.internal.ClassBasedConverterDescriptor;
|
||||
|
@ -229,6 +230,14 @@ public class AnnotationMetadataSourceProcessorImpl implements MetadataSourceProc
|
|||
List<XClass> clazzHierarchy = new ArrayList<>();
|
||||
|
||||
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 ( debug ) {
|
||||
log.debugf(
|
||||
|
|
|
@ -10,6 +10,7 @@ import java.lang.reflect.Modifier;
|
|||
import java.util.List;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.hibernate.MappingException;
|
||||
import org.hibernate.annotations.CacheConcurrencyStrategy;
|
||||
import org.hibernate.boot.jaxb.mapping.spi.JaxbAttributesContainer;
|
||||
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.AccessType;
|
||||
import jakarta.persistence.EmbeddedId;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.MappedSuperclass;
|
||||
|
||||
import static org.hibernate.boot.models.xml.XmlProcessLogging.XML_PROCESS_LOGGER;
|
||||
import static org.hibernate.internal.util.NullnessHelper.coalesce;
|
||||
|
@ -123,6 +126,9 @@ public class ManagedTypeProcessor {
|
|||
defaultAccessTypeFromDefaultAccessor( xmlDocumentContext ),
|
||||
AccessType.PROPERTY
|
||||
);
|
||||
if ( classDetails.isInterface() ) {
|
||||
throw new MappingException( "Only classes (not interfaces) may be mapped as @Entity : " + classDetails.getName() );
|
||||
}
|
||||
}
|
||||
|
||||
classDetails.clearMemberAnnotationUsages();
|
||||
|
|
|
@ -351,25 +351,23 @@ public class EntityManagerFactoryBuilderImpl implements EntityManagerFactoryBuil
|
|||
if ( classLoader == null ) {
|
||||
throw persistenceException( "Enhancement requires a temp class loader, but none was given." );
|
||||
}
|
||||
for ( Binding<JaxbBindableMappingDescriptor> binding : metadataSources.getXmlBindings() ) {
|
||||
final JaxbBindableMappingDescriptor root = binding.getRoot();
|
||||
if ( root instanceof JaxbHbmHibernateMapping ) {
|
||||
final JaxbHbmHibernateMapping hibernateMapping = (JaxbHbmHibernateMapping) root;
|
||||
final String packageName = hibernateMapping.getPackage();
|
||||
for ( JaxbHbmRootEntityType clazz : hibernateMapping.getClazz() ) {
|
||||
final String className;
|
||||
if ( packageName == null || packageName.isEmpty() ) {
|
||||
className = clazz.getName();
|
||||
}
|
||||
else {
|
||||
className = packageName + '.' + clazz.getName();
|
||||
}
|
||||
try {
|
||||
classTransformer.discoverTypes( classLoader, className );
|
||||
}
|
||||
catch (EnhancementException ex) {
|
||||
LOG.enhancementDiscoveryFailed( className, ex );
|
||||
}
|
||||
|
||||
for ( Binding<JaxbHbmHibernateMapping> binding : metadataSources.getHbmXmlBindings() ) {
|
||||
final JaxbHbmHibernateMapping hibernateMapping = binding.getRoot();
|
||||
final String packageName = hibernateMapping.getPackage();
|
||||
for ( JaxbHbmRootEntityType clazz : hibernateMapping.getClazz() ) {
|
||||
final String className;
|
||||
if ( packageName == null || packageName.isEmpty() ) {
|
||||
className = clazz.getName();
|
||||
}
|
||||
else {
|
||||
className = packageName + '.' + clazz.getName();
|
||||
}
|
||||
try {
|
||||
classTransformer.discoverTypes( classLoader, className );
|
||||
}
|
||||
catch (EnhancementException ex) {
|
||||
LOG.enhancementDiscoveryFailed( className, ex );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,6 +10,8 @@ import java.io.IOException;
|
|||
import java.io.InputStream;
|
||||
import java.io.StringReader;
|
||||
import java.io.StringWriter;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import javax.xml.stream.XMLEventFactory;
|
||||
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.internal.stax.HbmEventReader;
|
||||
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.xsd.MappingXsdSupport;
|
||||
import org.hibernate.orm.test.boot.jaxb.JaxbHelper;
|
||||
|
@ -57,11 +60,12 @@ public class TransformationHelper {
|
|||
assertThat( hbmMapping ).isNotNull();
|
||||
assertThat( hbmMapping.getClazz() ).hasSize( 1 );
|
||||
|
||||
return HbmXmlTransformer.transform(
|
||||
hbmMapping,
|
||||
new Origin( SourceType.RESOURCE, resourceName ),
|
||||
() -> UnsupportedFeatureHandling.ERROR
|
||||
final List<Binding<JaxbEntityMappingsImpl>> transformed = HbmXmlTransformer.transform(
|
||||
Collections.singletonList( new Binding<>( hbmMapping, new Origin( SourceType.RESOURCE, resourceName ) ) ),
|
||||
UnsupportedFeatureHandling.ERROR
|
||||
);
|
||||
|
||||
return transformed.get(0).getRoot();
|
||||
}
|
||||
catch (JAXBException 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.InputStream;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import javax.xml.stream.XMLEventFactory;
|
||||
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.mapping.spi.JaxbEntityImpl;
|
||||
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.xsd.MappingXsdSupport;
|
||||
import org.hibernate.orm.test.boot.jaxb.JaxbHelper;
|
||||
|
@ -56,11 +59,11 @@ public class HbmTransformationJaxbTests {
|
|||
assertThat( hbmMapping ).isNotNull();
|
||||
assertThat( hbmMapping.getClazz() ).hasSize( 1 );
|
||||
|
||||
final JaxbEntityMappingsImpl transformed = HbmXmlTransformer.transform(
|
||||
hbmMapping,
|
||||
new Origin( SourceType.RESOURCE, resourceName ),
|
||||
() -> UnsupportedFeatureHandling.ERROR
|
||||
final List<Binding<JaxbEntityMappingsImpl>> transformedBindingList = HbmXmlTransformer.transform(
|
||||
Collections.singletonList( new Binding<>( hbmMapping, new Origin( SourceType.RESOURCE, resourceName ) ) ),
|
||||
UnsupportedFeatureHandling.ERROR
|
||||
);
|
||||
final JaxbEntityMappingsImpl transformed = transformedBindingList.get( 0 ).getRoot();
|
||||
|
||||
assertThat( transformed ).isNotNull();
|
||||
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.source.internal.annotations.AdditionalManagedResourcesImpl;
|
||||
import org.hibernate.boot.registry.StandardServiceRegistry;
|
||||
import org.hibernate.cfg.MappingSettings;
|
||||
import org.hibernate.mapping.Column;
|
||||
import org.hibernate.mapping.Property;
|
||||
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.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;
|
||||
|
@ -59,7 +61,7 @@ public class ModelTests {
|
|||
assertThat( transformerAnn.write() ).isEqualTo( "? * 100.00" );
|
||||
}
|
||||
|
||||
@ServiceRegistry
|
||||
@ServiceRegistry(settings = @Setting(name = MappingSettings.TRANSFORM_HBM_XML, value = "true"))
|
||||
@Test
|
||||
void testHbmXml(ServiceRegistryScope scope) {
|
||||
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.ClassLoadingException;
|
||||
import org.hibernate.boot.spi.BootstrapContext;
|
||||
import org.hibernate.boot.spi.MetadataBuildingOptions;
|
||||
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.orm.junit.Logger;
|
||||
import org.hibernate.testing.orm.junit.MessageKeyInspection;
|
||||
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.Test;
|
||||
|
@ -70,6 +76,7 @@ public class ScanningCoordinatorTest {
|
|||
private BootstrapContext bootstrapContext = Mockito.mock( BootstrapContext.class );
|
||||
private ClassmateContext classmateContext = new ClassmateContext();
|
||||
private XmlMappingBinderAccess xmlMappingBinderAccess = Mockito.mock( XmlMappingBinderAccess.class );
|
||||
private MetadataBuildingOptions metadataBuildingOptions = Mockito.mock( MetadataBuildingOptions.class );
|
||||
|
||||
private ScanEnvironment scanEnvironment = Mockito.mock( ScanEnvironment.class );
|
||||
private StandardServiceRegistry serviceRegistry = Mockito.mock( StandardServiceRegistry.class );
|
||||
|
@ -87,8 +94,12 @@ public class ScanningCoordinatorTest {
|
|||
when( bootstrapContext.getScanEnvironment() ).thenReturn( scanEnvironment );
|
||||
when( bootstrapContext.getClassmateContext() ).thenReturn( classmateContext );
|
||||
when( bootstrapContext.getServiceRegistry() ).thenReturn( serviceRegistry );
|
||||
when( bootstrapContext.getMetadataBuildingOptions() ).thenReturn( metadataBuildingOptions );
|
||||
|
||||
when( serviceRegistry.requireService( ClassLoaderService.class ) ).thenReturn( classLoaderService );
|
||||
|
||||
when( metadataBuildingOptions.isXmlMappingEnabled() ).thenReturn( true );
|
||||
|
||||
when( scanEnvironment.getExplicitlyListedClassNames() ).thenReturn(
|
||||
Arrays.asList( "a.b.C" ) );
|
||||
|
||||
|
|
|
@ -16,6 +16,8 @@ hibernate.connection.autocommit false
|
|||
hibernate.connection.initial_pool_size 0
|
||||
hibernate.connection.pool_size 5
|
||||
|
||||
hibernate.transform_hbm_xml.enabled true
|
||||
|
||||
hibernate.show_sql true
|
||||
hibernate.format_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.
|
||||
|
||||
|
||||
[[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]]
|
||||
== Todos (dev)
|
||||
|
||||
|
|
|
@ -72,7 +72,7 @@ dependencyResolutionManagement {
|
|||
def byteBuddyVersion = version "byteBuddy", "1.14.18"
|
||||
def classmateVersion = version "classmate", "1.5.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 hcannVersion = version "hcann", "7.0.1.Final"
|
||||
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.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.gradle.api.file.DirectoryProperty;
|
||||
import org.gradle.api.provider.Property;
|
||||
import org.gradle.api.tasks.CacheableTask;
|
||||
import org.gradle.api.tasks.Input;
|
||||
import org.gradle.api.tasks.Nested;
|
||||
import org.gradle.api.tasks.OutputDirectory;
|
||||
|
@ -19,7 +22,6 @@ import org.gradle.api.tasks.SourceTask;
|
|||
import org.gradle.api.tasks.TaskAction;
|
||||
|
||||
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.transform.HbmXmlTransformer;
|
||||
import org.hibernate.boot.jaxb.hbm.transform.UnsupportedFeatureHandling;
|
||||
|
@ -53,6 +55,7 @@ import jakarta.xml.bind.Marshaller;
|
|||
* replacing the original (destructive).
|
||||
* @see org.hibernate.boot.jaxb.hbm.transform.HbmXmlTransformer
|
||||
*/
|
||||
@CacheableTask
|
||||
public abstract class TransformHbmXmlTask extends SourceTask {
|
||||
private final Property<TransformationNaming> renaming;
|
||||
private final Property<UnsupportedFeatureHandling> unsupportedFeatures;
|
||||
|
@ -127,39 +130,45 @@ public abstract class TransformHbmXmlTask extends SourceTask {
|
|||
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 Origin origin = new Origin( SourceType.FILE, hbmXmlFile.getAbsolutePath() );
|
||||
final Binding<JaxbHbmHibernateMapping> binding = bindMapping( mappingBinder, hbmXmlFile, origin );
|
||||
if ( binding == null ) {
|
||||
return;
|
||||
}
|
||||
final List<Binding<JaxbEntityMappingsImpl>> transformedBindings = HbmXmlTransformer.transform(
|
||||
hbmBindings,
|
||||
unsupportedFeatures.get()
|
||||
);
|
||||
|
||||
if ( deleteHbmFiles.getOrElse( false ) ) {
|
||||
final boolean deleted = hbmXmlFile.delete();
|
||||
if ( !deleted ) {
|
||||
getProject().getLogger().warn( "Unable to delete hbm.xml file `{}`", hbmXmlFile.getAbsoluteFile() );
|
||||
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 ) ) {
|
||||
final boolean deleted = hbmXmlFile.delete();
|
||||
if ( !deleted ) {
|
||||
getProject().getLogger().warn( "Unable to delete hbm.xml file `{}`", hbmXmlFile.getAbsoluteFile() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final HbmXmlTransformer.Options transformationOptions = unsupportedFeatures::get;
|
||||
|
||||
final JaxbEntityMappingsImpl transformed = HbmXmlTransformer.transform( binding.getRoot(), origin, transformationOptions );
|
||||
|
||||
final String copyName = determineCopyName( hbmXmlFile );
|
||||
final File copyFile = determineCopyFile( copyName, hbmXmlFile );
|
||||
//noinspection ResultOfMethodCallIgnored
|
||||
copyFile.getParentFile().mkdirs();
|
||||
try {
|
||||
marshaller.marshal( transformed, copyFile );
|
||||
}
|
||||
catch (JAXBException e) {
|
||||
throw new RuntimeException(
|
||||
"Unable to marshall mapping JAXB representation to file `" + copyFile.getAbsolutePath() + "`",
|
||||
e
|
||||
);
|
||||
final String copyName = determineCopyName( hbmXmlFile );
|
||||
final File copyFile = determineCopyFile( copyName, hbmXmlFile );
|
||||
//noinspection ResultOfMethodCallIgnored
|
||||
copyFile.getParentFile().mkdirs();
|
||||
try {
|
||||
marshaller.marshal( transformedBinding.getRoot(), copyFile );
|
||||
}
|
||||
catch (JAXBException e) {
|
||||
throw new RuntimeException(
|
||||
"Unable to marshall mapping JAXB representation to file `" + copyFile.getAbsolutePath() + "`",
|
||||
e
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue