HHH-17377 - Migrate to JPA 3.2
https://hibernate.atlassian.net/browse/HHH-17377 jpamodelgen
This commit is contained in:
parent
5781bdd30f
commit
f8865106c1
|
@ -31,7 +31,7 @@ jobs:
|
||||||
build:
|
build:
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
name: Hibernate ORM
|
name: ORM
|
||||||
# runs-on: ubuntu-latest
|
# runs-on: ubuntu-latest
|
||||||
runs-on: [self-hosted, Linux, X64, OCI]
|
runs-on: [self-hosted, Linux, X64, OCI]
|
||||||
strategy:
|
strategy:
|
||||||
|
|
|
@ -119,6 +119,11 @@ xjc {
|
||||||
xjcBindingFile = file( 'src/main/xjb/hbm-mapping-bindings.xjb' )
|
xjcBindingFile = file( 'src/main/xjb/hbm-mapping-bindings.xjb' )
|
||||||
xjcExtensions += ['inheritance', 'simplify']
|
xjcExtensions += ['inheritance', 'simplify']
|
||||||
}
|
}
|
||||||
|
configuration {
|
||||||
|
xsdFile = file( 'src/main/resources/org/hibernate/xsd/cfg/configuration-3.2.0.xsd' )
|
||||||
|
xjcBindingFile = file( 'src/main/xjb/configuration-bindings.xjb' )
|
||||||
|
xjcExtensions += ['inheritance', 'simplify']
|
||||||
|
}
|
||||||
mapping {
|
mapping {
|
||||||
xsdFile = file( 'src/main/resources/org/hibernate/xsd/mapping/mapping-3.2.0.xsd' )
|
xsdFile = file( 'src/main/resources/org/hibernate/xsd/mapping/mapping-3.2.0.xsd' )
|
||||||
xjcBindingFile = file( 'src/main/xjb/mapping-bindings.xjb' )
|
xjcBindingFile = file( 'src/main/xjb/mapping-bindings.xjb' )
|
||||||
|
|
|
@ -8,6 +8,8 @@ package org.hibernate.boot;
|
||||||
|
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
|
||||||
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Abstraction for locating class-path resources
|
* Abstraction for locating class-path resources
|
||||||
*
|
*
|
||||||
|
@ -25,5 +27,5 @@ public interface ResourceStreamLocator {
|
||||||
*
|
*
|
||||||
* @return The located resource's InputStream, or {@code null} if no match found
|
* @return The located resource's InputStream, or {@code null} if no match found
|
||||||
*/
|
*/
|
||||||
InputStream locateResourceStream(String resourceName);
|
@Nullable InputStream locateResourceStream(String resourceName);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,69 @@
|
||||||
|
/*
|
||||||
|
* 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.internal;
|
||||||
|
|
||||||
|
import javax.xml.stream.XMLEventFactory;
|
||||||
|
import javax.xml.stream.XMLEventReader;
|
||||||
|
import javax.xml.stream.events.StartElement;
|
||||||
|
|
||||||
|
import org.hibernate.Internal;
|
||||||
|
import org.hibernate.boot.ResourceStreamLocator;
|
||||||
|
import org.hibernate.boot.jaxb.Origin;
|
||||||
|
import org.hibernate.boot.jaxb.configuration.spi.JaxbPersistenceImpl;
|
||||||
|
import org.hibernate.boot.jaxb.internal.stax.ConfigurationEventReader;
|
||||||
|
import org.hibernate.boot.jaxb.spi.Binding;
|
||||||
|
import org.hibernate.boot.xsd.ConfigXsdSupport;
|
||||||
|
import org.hibernate.internal.util.config.ConfigurationException;
|
||||||
|
|
||||||
|
import jakarta.xml.bind.JAXBContext;
|
||||||
|
import jakarta.xml.bind.JAXBException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
public class ConfigurationBinder extends AbstractBinder<JaxbPersistenceImpl> {
|
||||||
|
private final XMLEventFactory xmlEventFactory = XMLEventFactory.newInstance();
|
||||||
|
private JAXBContext jaxbContext;
|
||||||
|
|
||||||
|
public ConfigurationBinder(ResourceStreamLocator resourceStreamLocator) {
|
||||||
|
super( resourceStreamLocator );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isValidationEnabled() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected <X extends JaxbPersistenceImpl> Binding<X> doBind(
|
||||||
|
XMLEventReader staxEventReader,
|
||||||
|
StartElement rootElementStartEvent,
|
||||||
|
Origin origin) {
|
||||||
|
final XMLEventReader reader = new ConfigurationEventReader( staxEventReader, xmlEventFactory );
|
||||||
|
final JaxbPersistenceImpl bindingRoot = jaxb(
|
||||||
|
reader,
|
||||||
|
ConfigXsdSupport.configurationXsd().getSchema(),
|
||||||
|
jaxbContext(),
|
||||||
|
origin
|
||||||
|
);
|
||||||
|
//noinspection unchecked
|
||||||
|
return new Binding<>( (X) bindingRoot, origin );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Internal
|
||||||
|
public JAXBContext jaxbContext() {
|
||||||
|
if ( jaxbContext == null ) {
|
||||||
|
try {
|
||||||
|
jaxbContext = JAXBContext.newInstance( JaxbPersistenceImpl.class );
|
||||||
|
}
|
||||||
|
catch (JAXBException e) {
|
||||||
|
throw new ConfigurationException( "Unable to build configuration.xml JAXBContext", e );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return jaxbContext;
|
||||||
|
}
|
||||||
|
}
|
|
@ -39,6 +39,7 @@ import org.jboss.logging.Logger;
|
||||||
|
|
||||||
import jakarta.xml.bind.JAXBContext;
|
import jakarta.xml.bind.JAXBContext;
|
||||||
import jakarta.xml.bind.JAXBException;
|
import jakarta.xml.bind.JAXBException;
|
||||||
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
import static org.hibernate.engine.config.spi.StandardConverters.BOOLEAN;
|
import static org.hibernate.engine.config.spi.StandardConverters.BOOLEAN;
|
||||||
|
|
||||||
|
@ -113,7 +114,7 @@ public class MappingBinder extends AbstractBinder<JaxbBindableMappingDescriptor>
|
||||||
|
|
||||||
public MappingBinder(
|
public MappingBinder(
|
||||||
ResourceStreamLocator resourceStreamLocator,
|
ResourceStreamLocator resourceStreamLocator,
|
||||||
Function<String, Object> settingsAccess) {
|
@Nullable Function<String, Object> settingsAccess) {
|
||||||
super( resourceStreamLocator == null ? MappingBinder.class.getClassLoader()::getResourceAsStream : resourceStreamLocator );
|
super( resourceStreamLocator == null ? MappingBinder.class.getClassLoader()::getResourceAsStream : resourceStreamLocator );
|
||||||
|
|
||||||
if ( settingsAccess == null ) {
|
if ( settingsAccess == null ) {
|
||||||
|
|
|
@ -0,0 +1,184 @@
|
||||||
|
/*
|
||||||
|
* 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.internal.stax;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import javax.xml.namespace.QName;
|
||||||
|
import javax.xml.stream.XMLEventFactory;
|
||||||
|
import javax.xml.stream.XMLEventReader;
|
||||||
|
import javax.xml.stream.XMLStreamException;
|
||||||
|
import javax.xml.stream.events.Attribute;
|
||||||
|
import javax.xml.stream.events.EndElement;
|
||||||
|
import javax.xml.stream.events.Namespace;
|
||||||
|
import javax.xml.stream.events.StartElement;
|
||||||
|
import javax.xml.stream.events.XMLEvent;
|
||||||
|
import javax.xml.stream.util.EventReaderDelegate;
|
||||||
|
|
||||||
|
import org.hibernate.boot.xsd.XsdDescriptor;
|
||||||
|
import org.hibernate.boot.xsd.XsdHelper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
public abstract class AbstractEventReader extends EventReaderDelegate {
|
||||||
|
private static final String VERSION_ATTRIBUTE_NAME = "version";
|
||||||
|
|
||||||
|
private final String rootElementName;
|
||||||
|
private final XsdDescriptor xsdDescriptor;
|
||||||
|
private final XMLEventFactory xmlEventFactory;
|
||||||
|
|
||||||
|
public AbstractEventReader(
|
||||||
|
String rootElementName,
|
||||||
|
XsdDescriptor xsdDescriptor,
|
||||||
|
XMLEventReader reader,
|
||||||
|
XMLEventFactory xmlEventFactory) {
|
||||||
|
super( reader );
|
||||||
|
this.rootElementName = rootElementName;
|
||||||
|
this.xsdDescriptor = xsdDescriptor;
|
||||||
|
this.xmlEventFactory = xmlEventFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public XMLEvent peek() throws XMLStreamException {
|
||||||
|
return wrap( super.peek() );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public XMLEvent nextEvent() throws XMLStreamException {
|
||||||
|
return wrap( super.nextEvent() );
|
||||||
|
}
|
||||||
|
|
||||||
|
private XMLEvent wrap(XMLEvent event) {
|
||||||
|
if ( event != null ) {
|
||||||
|
if ( event.isStartElement() ) {
|
||||||
|
return wrap( event.asStartElement() );
|
||||||
|
}
|
||||||
|
else if ( event.isEndElement() ) {
|
||||||
|
return wrap( event.asEndElement() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return event;
|
||||||
|
}
|
||||||
|
|
||||||
|
private StartElement wrap(StartElement startElement) {
|
||||||
|
final List<Attribute> newElementAttributeList = mapAttributes( startElement );
|
||||||
|
final List<Namespace> newNamespaceList = mapNamespaces( startElement );
|
||||||
|
|
||||||
|
// Transfer the location info from the incoming event to the event factory
|
||||||
|
// so that the event we ask it to generate for us has the same location info
|
||||||
|
xmlEventFactory.setLocation( startElement.getLocation() );
|
||||||
|
return xmlEventFactory.createStartElement(
|
||||||
|
new QName( xsdDescriptor.getNamespaceUri(), startElement.getName().getLocalPart() ),
|
||||||
|
newElementAttributeList.iterator(),
|
||||||
|
newNamespaceList.iterator()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Iterator<Attribute> existingXmlAttributesIterator(StartElement startElement) {
|
||||||
|
return startElement.getAttributes();
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<Attribute> mapAttributes(StartElement startElement) {
|
||||||
|
final List<Attribute> mappedAttributes = new ArrayList<>();
|
||||||
|
|
||||||
|
final Iterator<Attribute> existingAttributesIterator = existingXmlAttributesIterator( startElement );
|
||||||
|
while ( existingAttributesIterator.hasNext() ) {
|
||||||
|
final Attribute originalAttribute = existingAttributesIterator.next();
|
||||||
|
final Attribute attributeToUse = mapAttribute( startElement, originalAttribute );
|
||||||
|
mappedAttributes.add( attributeToUse );
|
||||||
|
}
|
||||||
|
|
||||||
|
return mappedAttributes;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Attribute mapAttribute(StartElement startElement, Attribute originalAttribute) {
|
||||||
|
// Here we look to see if this attribute is the JPA version attribute, and if so do the following:
|
||||||
|
// 1) validate its version attribute is valid per our "latest XSD"
|
||||||
|
// 2) update its version attribute to the latest version if not already
|
||||||
|
//
|
||||||
|
// NOTE : atm this is a very simple check using just the attribute's local name
|
||||||
|
// rather than checking its qualified name. It is possibly (though unlikely)
|
||||||
|
// that this could match on "other" version attributes in the same element
|
||||||
|
|
||||||
|
if ( rootElementName.equals( startElement.getName().getLocalPart() ) ) {
|
||||||
|
if ( VERSION_ATTRIBUTE_NAME.equals( originalAttribute.getName().getLocalPart() ) ) {
|
||||||
|
final String specifiedVersion = originalAttribute.getValue();
|
||||||
|
|
||||||
|
if ( !XsdHelper.isValidJpaVersion( specifiedVersion ) ) {
|
||||||
|
throw new BadVersionException( specifiedVersion );
|
||||||
|
}
|
||||||
|
|
||||||
|
return xmlEventFactory.createAttribute( VERSION_ATTRIBUTE_NAME, xsdDescriptor.getVersion() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return originalAttribute;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<Namespace> mapNamespaces(StartElement startElement) {
|
||||||
|
return mapNamespaces( existingXmlNamespacesIterator( startElement ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<Namespace> mapNamespaces(Iterator<Namespace> originalNamespaceIterator ) {
|
||||||
|
final List<Namespace> mappedNamespaces = new ArrayList<>();
|
||||||
|
|
||||||
|
while ( originalNamespaceIterator.hasNext() ) {
|
||||||
|
final Namespace originalNamespace = originalNamespaceIterator.next();
|
||||||
|
final Namespace mappedNamespace = mapNamespace( originalNamespace );
|
||||||
|
mappedNamespaces.add( mappedNamespace );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( mappedNamespaces.isEmpty() ) {
|
||||||
|
mappedNamespaces.add( xmlEventFactory.createNamespace( xsdDescriptor.getNamespaceUri() ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
return mappedNamespaces;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Iterator<Namespace> existingXmlNamespacesIterator(StartElement startElement) {
|
||||||
|
return startElement.getNamespaces();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Namespace mapNamespace(Namespace originalNamespace) {
|
||||||
|
if ( XsdHelper.shouldBeMappedToLatestJpaDescriptor( originalNamespace.getNamespaceURI() ) ) {
|
||||||
|
// this is a namespace "to map" so map it
|
||||||
|
return xmlEventFactory.createNamespace( originalNamespace.getPrefix(), xsdDescriptor.getNamespaceUri() );
|
||||||
|
}
|
||||||
|
|
||||||
|
return originalNamespace;
|
||||||
|
}
|
||||||
|
|
||||||
|
private XMLEvent wrap(EndElement endElement) {
|
||||||
|
final List<Namespace> targetNamespaces = mapNamespaces( existingXmlNamespacesIterator( endElement ) );
|
||||||
|
|
||||||
|
// Transfer the location info from the incoming event to the event factory
|
||||||
|
// so that the event we ask it to generate for us has the same location info
|
||||||
|
xmlEventFactory.setLocation( endElement.getLocation() );
|
||||||
|
return xmlEventFactory.createEndElement(
|
||||||
|
new QName( xsdDescriptor.getNamespaceUri(), endElement.getName().getLocalPart() ),
|
||||||
|
targetNamespaces.iterator()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Iterator<Namespace> existingXmlNamespacesIterator(EndElement endElement) {
|
||||||
|
return endElement.getNamespaces();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class BadVersionException extends RuntimeException {
|
||||||
|
private final String requestedVersion;
|
||||||
|
|
||||||
|
public BadVersionException(String requestedVersion) {
|
||||||
|
this.requestedVersion = requestedVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRequestedVersion() {
|
||||||
|
return requestedVersion;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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.boot.jaxb.internal.stax;
|
||||||
|
|
||||||
|
import javax.xml.stream.XMLEventFactory;
|
||||||
|
import javax.xml.stream.XMLEventReader;
|
||||||
|
|
||||||
|
import org.hibernate.boot.xsd.ConfigXsdSupport;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
public class ConfigurationEventReader extends AbstractEventReader {
|
||||||
|
private static final String ROOT_ELEMENT_NAME = "persistence";
|
||||||
|
|
||||||
|
public ConfigurationEventReader(XMLEventReader reader, XMLEventFactory xmlEventFactory) {
|
||||||
|
super(
|
||||||
|
ROOT_ELEMENT_NAME,
|
||||||
|
ConfigXsdSupport.configurationXsd(),
|
||||||
|
reader,
|
||||||
|
xmlEventFactory
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -21,6 +21,7 @@ import javax.xml.stream.events.XMLEvent;
|
||||||
import javax.xml.stream.util.EventReaderDelegate;
|
import javax.xml.stream.util.EventReaderDelegate;
|
||||||
|
|
||||||
import org.hibernate.boot.xsd.MappingXsdSupport;
|
import org.hibernate.boot.xsd.MappingXsdSupport;
|
||||||
|
import org.hibernate.boot.xsd.XsdHelper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* StAX EVentReader which handles a few oddities specific to JPA {@code orm.xml}
|
* StAX EVentReader which handles a few oddities specific to JPA {@code orm.xml}
|
||||||
|
@ -119,7 +120,7 @@ public class JpaOrmXmlEventReader extends EventReaderDelegate {
|
||||||
if ( VERSION_ATTRIBUTE_NAME.equals( originalAttribute.getName().getLocalPart() ) ) {
|
if ( VERSION_ATTRIBUTE_NAME.equals( originalAttribute.getName().getLocalPart() ) ) {
|
||||||
final String specifiedVersion = originalAttribute.getValue();
|
final String specifiedVersion = originalAttribute.getValue();
|
||||||
|
|
||||||
if ( ! MappingXsdSupport.isValidJpaVersion( specifiedVersion ) ) {
|
if ( ! XsdHelper.isValidJpaVersion( specifiedVersion ) ) {
|
||||||
throw new BadVersionException( specifiedVersion );
|
throw new BadVersionException( specifiedVersion );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -156,7 +157,7 @@ public class JpaOrmXmlEventReader extends EventReaderDelegate {
|
||||||
}
|
}
|
||||||
|
|
||||||
private Namespace mapNamespace(Namespace originalNamespace) {
|
private Namespace mapNamespace(Namespace originalNamespace) {
|
||||||
if ( MappingXsdSupport.shouldBeMappedToLatestJpaDescriptor( originalNamespace.getNamespaceURI() ) ) {
|
if ( XsdHelper.shouldBeMappedToLatestJpaDescriptor( originalNamespace.getNamespaceURI() ) ) {
|
||||||
// this is a namespace "to map" so map it
|
// this is a namespace "to map" so map it
|
||||||
return xmlEventFactory.createNamespace(
|
return xmlEventFactory.createNamespace(
|
||||||
originalNamespace.getPrefix(),
|
originalNamespace.getPrefix(),
|
||||||
|
|
|
@ -6,19 +6,8 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.boot.jaxb.internal.stax;
|
package org.hibernate.boot.jaxb.internal.stax;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.List;
|
|
||||||
import javax.xml.namespace.QName;
|
|
||||||
import javax.xml.stream.XMLEventFactory;
|
import javax.xml.stream.XMLEventFactory;
|
||||||
import javax.xml.stream.XMLEventReader;
|
import javax.xml.stream.XMLEventReader;
|
||||||
import javax.xml.stream.XMLStreamException;
|
|
||||||
import javax.xml.stream.events.Attribute;
|
|
||||||
import javax.xml.stream.events.EndElement;
|
|
||||||
import javax.xml.stream.events.Namespace;
|
|
||||||
import javax.xml.stream.events.StartElement;
|
|
||||||
import javax.xml.stream.events.XMLEvent;
|
|
||||||
import javax.xml.stream.util.EventReaderDelegate;
|
|
||||||
|
|
||||||
import org.hibernate.boot.xsd.MappingXsdSupport;
|
import org.hibernate.boot.xsd.MappingXsdSupport;
|
||||||
|
|
||||||
|
@ -28,156 +17,11 @@ import org.hibernate.boot.xsd.MappingXsdSupport;
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
* @author Hardy Ferentschik
|
* @author Hardy Ferentschik
|
||||||
*/
|
*/
|
||||||
public class MappingEventReader extends EventReaderDelegate {
|
public class MappingEventReader extends AbstractEventReader {
|
||||||
private static final String ROOT_ELEMENT_NAME = "entity-mappings";
|
private static final String ROOT_ELEMENT_NAME = "entity-mappings";
|
||||||
private static final String VERSION_ATTRIBUTE_NAME = "version";
|
|
||||||
|
|
||||||
private final XMLEventFactory xmlEventFactory;
|
|
||||||
|
|
||||||
public MappingEventReader(XMLEventReader reader, XMLEventFactory xmlEventFactory) {
|
public MappingEventReader(XMLEventReader reader, XMLEventFactory xmlEventFactory) {
|
||||||
super( reader );
|
super( ROOT_ELEMENT_NAME, MappingXsdSupport.latestDescriptor(), reader, xmlEventFactory );
|
||||||
this.xmlEventFactory = xmlEventFactory;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public XMLEvent peek() throws XMLStreamException {
|
|
||||||
return wrap( super.peek() );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public XMLEvent nextEvent() throws XMLStreamException {
|
|
||||||
return wrap( super.nextEvent() );
|
|
||||||
}
|
|
||||||
|
|
||||||
private XMLEvent wrap(XMLEvent event) {
|
|
||||||
if ( event != null ) {
|
|
||||||
if ( event.isStartElement() ) {
|
|
||||||
return wrap( event.asStartElement() );
|
|
||||||
}
|
|
||||||
else if ( event.isEndElement() ) {
|
|
||||||
return wrap( event.asEndElement() );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return event;
|
|
||||||
}
|
|
||||||
|
|
||||||
private StartElement wrap(StartElement startElement) {
|
|
||||||
final List<Attribute> newElementAttributeList = mapAttributes( startElement );
|
|
||||||
final List<Namespace> newNamespaceList = mapNamespaces( startElement );
|
|
||||||
|
|
||||||
// Transfer the location info from the incoming event to the event factory
|
|
||||||
// so that the event we ask it to generate for us has the same location info
|
|
||||||
xmlEventFactory.setLocation( startElement.getLocation() );
|
|
||||||
return xmlEventFactory.createStartElement(
|
|
||||||
new QName( MappingXsdSupport.latestDescriptor().getNamespaceUri(), startElement.getName().getLocalPart() ),
|
|
||||||
newElementAttributeList.iterator(),
|
|
||||||
newNamespaceList.iterator()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<Attribute> mapAttributes(StartElement startElement) {
|
|
||||||
final List<Attribute> mappedAttributes = new ArrayList<>();
|
|
||||||
|
|
||||||
final Iterator<Attribute> existingAttributesIterator = existingXmlAttributesIterator( startElement );
|
|
||||||
while ( existingAttributesIterator.hasNext() ) {
|
|
||||||
final Attribute originalAttribute = existingAttributesIterator.next();
|
|
||||||
final Attribute attributeToUse = mapAttribute( startElement, originalAttribute );
|
|
||||||
mappedAttributes.add( attributeToUse );
|
|
||||||
}
|
|
||||||
|
|
||||||
return mappedAttributes;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Iterator<Attribute> existingXmlAttributesIterator(StartElement startElement) {
|
|
||||||
return startElement.getAttributes();
|
|
||||||
}
|
|
||||||
|
|
||||||
private Attribute mapAttribute(StartElement startElement, Attribute originalAttribute) {
|
|
||||||
// Here we look to see if this attribute is the JPA version attribute, and if so do the following:
|
|
||||||
// 1) validate its version attribute is valid per our "latest XSD"
|
|
||||||
// 2) update its version attribute to the latest version if not already
|
|
||||||
//
|
|
||||||
// NOTE : atm this is a very simple check using just the attribute's local name
|
|
||||||
// rather than checking its qualified name. It is possibly (though unlikely)
|
|
||||||
// that this could match on "other" version attributes in the same element
|
|
||||||
|
|
||||||
if ( ROOT_ELEMENT_NAME.equals( startElement.getName().getLocalPart() ) ) {
|
|
||||||
if ( VERSION_ATTRIBUTE_NAME.equals( originalAttribute.getName().getLocalPart() ) ) {
|
|
||||||
final String specifiedVersion = originalAttribute.getValue();
|
|
||||||
|
|
||||||
if ( ! MappingXsdSupport.isValidJpaVersion( specifiedVersion ) ) {
|
|
||||||
throw new BadVersionException( specifiedVersion );
|
|
||||||
}
|
|
||||||
|
|
||||||
return xmlEventFactory.createAttribute( VERSION_ATTRIBUTE_NAME, MappingXsdSupport.latestDescriptor().getVersion() );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return originalAttribute;
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<Namespace> mapNamespaces(StartElement startElement) {
|
|
||||||
return mapNamespaces( existingXmlNamespacesIterator( startElement ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<Namespace> mapNamespaces(Iterator<Namespace> originalNamespaceIterator ) {
|
|
||||||
final List<Namespace> mappedNamespaces = new ArrayList<>();
|
|
||||||
|
|
||||||
while ( originalNamespaceIterator.hasNext() ) {
|
|
||||||
final Namespace originalNamespace = originalNamespaceIterator.next();
|
|
||||||
final Namespace mappedNamespace = mapNamespace( originalNamespace );
|
|
||||||
mappedNamespaces.add( mappedNamespace );
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( mappedNamespaces.isEmpty() ) {
|
|
||||||
mappedNamespaces.add( xmlEventFactory.createNamespace( MappingXsdSupport.latestDescriptor().getNamespaceUri() ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
return mappedNamespaces;
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
private Iterator<Namespace> existingXmlNamespacesIterator(StartElement startElement) {
|
|
||||||
return startElement.getNamespaces();
|
|
||||||
}
|
|
||||||
|
|
||||||
private Namespace mapNamespace(Namespace originalNamespace) {
|
|
||||||
if ( MappingXsdSupport.shouldBeMappedToLatestJpaDescriptor( originalNamespace.getNamespaceURI() ) ) {
|
|
||||||
// this is a namespace "to map" so map it
|
|
||||||
return xmlEventFactory.createNamespace(
|
|
||||||
originalNamespace.getPrefix(),
|
|
||||||
MappingXsdSupport.latestDescriptor().getNamespaceUri()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return originalNamespace;
|
|
||||||
}
|
|
||||||
|
|
||||||
private XMLEvent wrap(EndElement endElement) {
|
|
||||||
final List<Namespace> targetNamespaces = mapNamespaces( existingXmlNamespacesIterator( endElement ) );
|
|
||||||
|
|
||||||
// Transfer the location info from the incoming event to the event factory
|
|
||||||
// so that the event we ask it to generate for us has the same location info
|
|
||||||
xmlEventFactory.setLocation( endElement.getLocation() );
|
|
||||||
return xmlEventFactory.createEndElement(
|
|
||||||
new QName( MappingXsdSupport.latestDescriptor().getNamespaceUri(), endElement.getName().getLocalPart() ),
|
|
||||||
targetNamespaces.iterator()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
private Iterator<Namespace> existingXmlNamespacesIterator(EndElement endElement) {
|
|
||||||
return endElement.getNamespaces();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class BadVersionException extends RuntimeException {
|
|
||||||
private final String requestedVersion;
|
|
||||||
|
|
||||||
public BadVersionException(String requestedVersion) {
|
|
||||||
this.requestedVersion = requestedVersion;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getRequestedVersion() {
|
|
||||||
return requestedVersion;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,14 +26,15 @@ public class ConfigXsdSupport {
|
||||||
* Needs synchronization on any access.
|
* Needs synchronization on any access.
|
||||||
* Custom keys:
|
* Custom keys:
|
||||||
* 0: cfgXml
|
* 0: cfgXml
|
||||||
* 1: JPA 1.0
|
* 1: configurationXML
|
||||||
* 2: JPA 2.0
|
* 2: JPA 1.0
|
||||||
* 3: JPA 2.1
|
* 3: JPA 2.0
|
||||||
* 4: JPA 2.2 (default)
|
* 4: JPA 2.1
|
||||||
* 5: Jakarta Persistence 3.0
|
* 5: JPA 2.2 (default)
|
||||||
* 6: Jakarta Persistence 3.1
|
* 6: Jakarta Persistence 3.0
|
||||||
|
* 7: Jakarta Persistence 3.1
|
||||||
*/
|
*/
|
||||||
private static final XsdDescriptor[] xsdCache = new XsdDescriptor[7];
|
private static final XsdDescriptor[] xsdCache = new XsdDescriptor[8];
|
||||||
|
|
||||||
public XsdDescriptor latestJpaDescriptor() {
|
public XsdDescriptor latestJpaDescriptor() {
|
||||||
return getJPA31();
|
return getJPA31();
|
||||||
|
@ -64,6 +65,9 @@ public class ConfigXsdSupport {
|
||||||
case "3.1": {
|
case "3.1": {
|
||||||
return getJPA31();
|
return getJPA31();
|
||||||
}
|
}
|
||||||
|
case "3.2": {
|
||||||
|
return getJPA32();
|
||||||
|
}
|
||||||
default: {
|
default: {
|
||||||
throw new IllegalArgumentException( "Unrecognized JPA persistence.xml XSD version : `" + version + "`" );
|
throw new IllegalArgumentException( "Unrecognized JPA persistence.xml XSD version : `" + version + "`" );
|
||||||
}
|
}
|
||||||
|
@ -86,8 +90,24 @@ public class ConfigXsdSupport {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static XsdDescriptor getJPA10() {
|
public static XsdDescriptor configurationXsd() {
|
||||||
final int index = 1;
|
final int index = 1;
|
||||||
|
synchronized ( xsdCache ) {
|
||||||
|
XsdDescriptor cfgXml = xsdCache[index];
|
||||||
|
if ( cfgXml == null ) {
|
||||||
|
cfgXml = LocalXsdResolver.buildXsdDescriptor(
|
||||||
|
"org/hibernate/xsd/cfg/configuration-3.2.0.xsd",
|
||||||
|
"3.2.0" ,
|
||||||
|
"http://www.hibernate.org/xsd/orm/configuration"
|
||||||
|
);
|
||||||
|
xsdCache[index] = cfgXml;
|
||||||
|
}
|
||||||
|
return cfgXml;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static XsdDescriptor getJPA10() {
|
||||||
|
final int index = 2;
|
||||||
synchronized ( xsdCache ) {
|
synchronized ( xsdCache ) {
|
||||||
XsdDescriptor jpa10 = xsdCache[index];
|
XsdDescriptor jpa10 = xsdCache[index];
|
||||||
if ( jpa10 == null ) {
|
if ( jpa10 == null ) {
|
||||||
|
@ -119,7 +139,7 @@ public class ConfigXsdSupport {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static XsdDescriptor getJPA21() {
|
public static XsdDescriptor getJPA21() {
|
||||||
final int index = 3;
|
final int index = 4;
|
||||||
synchronized ( xsdCache ) {
|
synchronized ( xsdCache ) {
|
||||||
XsdDescriptor jpa21 = xsdCache[index];
|
XsdDescriptor jpa21 = xsdCache[index];
|
||||||
if ( jpa21 == null ) {
|
if ( jpa21 == null ) {
|
||||||
|
@ -135,7 +155,7 @@ public class ConfigXsdSupport {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static XsdDescriptor getJPA22() {
|
public static XsdDescriptor getJPA22() {
|
||||||
final int index = 4;
|
final int index = 5;
|
||||||
synchronized ( xsdCache ) {
|
synchronized ( xsdCache ) {
|
||||||
XsdDescriptor jpa22 = xsdCache[index];
|
XsdDescriptor jpa22 = xsdCache[index];
|
||||||
if ( jpa22 == null ) {
|
if ( jpa22 == null ) {
|
||||||
|
@ -151,7 +171,7 @@ public class ConfigXsdSupport {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static XsdDescriptor getJPA30() {
|
public static XsdDescriptor getJPA30() {
|
||||||
final int index = 5;
|
final int index = 6;
|
||||||
synchronized ( xsdCache ) {
|
synchronized ( xsdCache ) {
|
||||||
XsdDescriptor jpa30 = xsdCache[index];
|
XsdDescriptor jpa30 = xsdCache[index];
|
||||||
if ( jpa30 == null ) {
|
if ( jpa30 == null ) {
|
||||||
|
@ -167,7 +187,7 @@ public class ConfigXsdSupport {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static XsdDescriptor getJPA31() {
|
public static XsdDescriptor getJPA31() {
|
||||||
final int index = 6;
|
final int index = 7;
|
||||||
synchronized ( xsdCache ) {
|
synchronized ( xsdCache ) {
|
||||||
XsdDescriptor jpa31 = xsdCache[index];
|
XsdDescriptor jpa31 = xsdCache[index];
|
||||||
if ( jpa31 == null ) {
|
if ( jpa31 == null ) {
|
||||||
|
@ -181,5 +201,21 @@ public class ConfigXsdSupport {
|
||||||
return jpa31;
|
return jpa31;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static XsdDescriptor getJPA32() {
|
||||||
|
final int index = 8;
|
||||||
|
synchronized ( xsdCache ) {
|
||||||
|
XsdDescriptor jpa32 = xsdCache[index];
|
||||||
|
if ( jpa32 == null ) {
|
||||||
|
jpa32 = LocalXsdResolver.buildXsdDescriptor(
|
||||||
|
"org/hibernate/jpa/persistence_3_2.xsd",
|
||||||
|
"3.2",
|
||||||
|
"https://jakarta.ee/xml/ns/persistence"
|
||||||
|
);
|
||||||
|
xsdCache[index] = jpa32;
|
||||||
|
}
|
||||||
|
return jpa32;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -101,26 +101,6 @@ public class MappingXsdSupport {
|
||||||
return jpa32;
|
return jpa32;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean shouldBeMappedToLatestJpaDescriptor(String uri) {
|
|
||||||
// JPA 1.0 and 2.0 share the same namespace URI
|
|
||||||
return jpa10.getNamespaceUri().equals( uri );
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isValidJpaVersion(String version) {
|
|
||||||
switch ( version ) {
|
|
||||||
case "1.0":
|
|
||||||
case "2.0":
|
|
||||||
case "2.1":
|
|
||||||
case "2.2":
|
|
||||||
case "3.0":
|
|
||||||
case "3.1":
|
|
||||||
case "3.2":
|
|
||||||
return true;
|
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public XsdDescriptor jpaXsd(String version) {
|
public XsdDescriptor jpaXsd(String version) {
|
||||||
switch ( version ) {
|
switch ( version ) {
|
||||||
case "1.0": {
|
case "1.0": {
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
/*
|
||||||
|
* 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.xsd;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
public class XsdHelper {
|
||||||
|
public static boolean isValidJpaVersion(String version) {
|
||||||
|
return switch ( version ) {
|
||||||
|
case "1.0", "2.0", "2.1", "2.2", "3.0", "3.1", "3.2" -> true;
|
||||||
|
default -> false;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean shouldBeMappedToLatestJpaDescriptor(String uri) {
|
||||||
|
// JPA 1.0 and 2.0 share the same namespace URI
|
||||||
|
return MappingXsdSupport.jpa10.getNamespaceUri().equals( uri );
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,47 +1,31 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
Copyright (c) 2008, 2020 Oracle and/or its affiliates. All rights reserved.
|
~ Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
~
|
||||||
This program and the accompanying materials are made available under the
|
~ License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||||
terms of the Eclipse Public License v. 2.0 which is available at
|
~ See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html.
|
||||||
http://www.eclipse.org/legal/epl-2.0,
|
-->
|
||||||
or the Eclipse Distribution License v. 1.0 which is available at
|
|
||||||
http://www.eclipse.org/org/documents/edl-v10.php.
|
|
||||||
|
|
||||||
SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
|
|
||||||
|
|
||||||
-->
|
|
||||||
|
|
||||||
<!-- persistence.xml schema -->
|
<!-- persistence.xml schema -->
|
||||||
<xsd:schema targetNamespace="https://jakarta.ee/xml/ns/persistence"
|
<xsd:schema
|
||||||
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
xmlns="http://www.hibernate.org/xsd/orm/configuration"
|
||||||
xmlns:persistence="https://jakarta.ee/xml/ns/persistence"
|
xmlns:persistence="http://www.hibernate.org/xsd/orm/configuration"
|
||||||
elementFormDefault="qualified"
|
targetNamespace="http://www.hibernate.org/xsd/orm/configuration"
|
||||||
attributeFormDefault="unqualified"
|
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||||
version="3.0">
|
elementFormDefault="qualified"
|
||||||
|
version="3.2">
|
||||||
|
|
||||||
<xsd:annotation>
|
<xsd:annotation>
|
||||||
<xsd:documentation><![CDATA[
|
<xsd:documentation><![CDATA[
|
||||||
|
XSD which "extends" the JPA `persistence.xml` XSD adding support
|
||||||
|
for Hibernate specific features.
|
||||||
|
|
||||||
This is the XML Schema for the persistence configuration file.
|
<persistence xmlns="http://www.hibernate.org/xsd/orm/configuration"
|
||||||
The file must be named "META-INF/persistence.xml" in the
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
persistence archive.
|
version="3.2">
|
||||||
|
...
|
||||||
Persistence configuration files must indicate
|
</persistence>
|
||||||
the persistence schema by using the persistence namespace:
|
|
||||||
|
|
||||||
https://jakarta.ee/xml/ns/persistence
|
|
||||||
|
|
||||||
and indicate the version of the schema by
|
|
||||||
using the version element as shown below:
|
|
||||||
|
|
||||||
<persistence xmlns="https://jakarta.ee/xml/ns/persistence"
|
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
||||||
xsi:schemaLocation="https://jakarta.ee/xml/ns/persistence
|
|
||||||
https://jakarta.ee/xml/ns/persistence/persistence_3_0.xsd"
|
|
||||||
version="3.0">
|
|
||||||
...
|
|
||||||
</persistence>
|
|
||||||
|
|
||||||
]]></xsd:documentation>
|
]]></xsd:documentation>
|
||||||
</xsd:annotation>
|
</xsd:annotation>
|
||||||
|
@ -186,7 +170,7 @@
|
||||||
<!-- **************************************************** -->
|
<!-- **************************************************** -->
|
||||||
|
|
||||||
<xsd:element name="shared-cache-mode"
|
<xsd:element name="shared-cache-mode"
|
||||||
type="persistence:persistence-unit-caching-type"
|
type="persistence:persistence-unit-caching-type"
|
||||||
minOccurs="0">
|
minOccurs="0">
|
||||||
<xsd:annotation>
|
<xsd:annotation>
|
||||||
<xsd:documentation>
|
<xsd:documentation>
|
||||||
|
@ -283,7 +267,7 @@
|
||||||
</xsd:element>
|
</xsd:element>
|
||||||
</xsd:sequence>
|
</xsd:sequence>
|
||||||
<xsd:attribute name="version" type="persistence:versionType"
|
<xsd:attribute name="version" type="persistence:versionType"
|
||||||
fixed="3.0" use="required"/>
|
fixed="3.1" use="required"/>
|
||||||
</xsd:complexType>
|
</xsd:complexType>
|
||||||
</xsd:element>
|
</xsd:element>
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
~ Hibernate, Relational Persistence for Idiomatic Java
|
~ Hibernate, Relational Persistence for Idiomatic Java
|
||||||
~
|
~
|
||||||
|
@ -6,7 +7,6 @@
|
||||||
~ See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html.
|
~ See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<!-- Jakarta Persistence API object/relational mapping file schema -->
|
|
||||||
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||||
xmlns="http://www.hibernate.org/xsd/orm/mapping"
|
xmlns="http://www.hibernate.org/xsd/orm/mapping"
|
||||||
xmlns:orm="http://www.hibernate.org/xsd/orm/mapping"
|
xmlns:orm="http://www.hibernate.org/xsd/orm/mapping"
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
~ Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
~
|
||||||
|
~ License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||||
|
~ See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html.
|
||||||
|
-->
|
||||||
|
<bindings xmlns="https://jakarta.ee/xml/ns/jaxb"
|
||||||
|
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||||
|
version="3.0">
|
||||||
|
|
||||||
|
<bindings schemaLocation="../resources/org/hibernate/xsd/cfg/configuration-3.2.0.xsd" node="/xsd:schema">
|
||||||
|
<schemaBindings>
|
||||||
|
<package name="org.hibernate.boot.jaxb.configuration.spi" />
|
||||||
|
<nameXmlTransform>
|
||||||
|
<typeName prefix="Jaxb" suffix="Impl"/>
|
||||||
|
<elementName prefix="Jaxb" suffix="Impl"/>
|
||||||
|
<modelGroupName prefix="Jaxb" suffix="Impl"/>
|
||||||
|
<anonymousTypeName prefix="Jaxb" suffix="Impl"/>
|
||||||
|
</nameXmlTransform>
|
||||||
|
</schemaBindings>
|
||||||
|
</bindings>
|
||||||
|
|
||||||
|
</bindings>
|
|
@ -6,29 +6,23 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.orm.test.envers;
|
package org.hibernate.orm.test.envers;
|
||||||
|
|
||||||
import jakarta.persistence.Entity;
|
|
||||||
import jakarta.persistence.Id;
|
|
||||||
import jakarta.persistence.Table;
|
|
||||||
|
|
||||||
import org.hibernate.boot.spi.MetadataImplementor;
|
|
||||||
import org.hibernate.cfg.AvailableSettings;
|
import org.hibernate.cfg.AvailableSettings;
|
||||||
import org.hibernate.envers.Audited;
|
import org.hibernate.envers.Audited;
|
||||||
import org.hibernate.envers.DefaultRevisionEntity;
|
|
||||||
import org.hibernate.mapping.PersistentClass;
|
|
||||||
import org.hibernate.metamodel.RuntimeMetamodels;
|
import org.hibernate.metamodel.RuntimeMetamodels;
|
||||||
import org.hibernate.metamodel.model.domain.EntityDomainType;
|
|
||||||
import org.hibernate.persister.entity.EntityPersister;
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
|
|
||||||
import org.hibernate.testing.orm.junit.DomainModel;
|
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.ServiceRegistry;
|
||||||
import org.hibernate.testing.orm.junit.SessionFactory;
|
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||||
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||||
import org.hibernate.testing.orm.junit.Setting;
|
import org.hibernate.testing.orm.junit.Setting;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import jakarta.persistence.Entity;
|
||||||
|
import jakarta.persistence.Id;
|
||||||
|
import jakarta.persistence.Table;
|
||||||
|
|
||||||
import static org.hamcrest.MatcherAssert.assertThat;
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
import static org.hamcrest.Matchers.is;
|
|
||||||
import static org.hamcrest.Matchers.notNullValue;
|
import static org.hamcrest.Matchers.notNullValue;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -54,9 +48,6 @@ public class RuntimeModelSmokeTests {
|
||||||
|
|
||||||
final EntityPersister mappingType = runtimeMetamodels.getMappingMetamodel().findEntityDescriptor( FULL_NAME );
|
final EntityPersister mappingType = runtimeMetamodels.getMappingMetamodel().findEntityDescriptor( FULL_NAME );
|
||||||
assertThat( mappingType, notNullValue() );
|
assertThat( mappingType, notNullValue() );
|
||||||
|
|
||||||
final EntityDomainType<?> jpaType = runtimeMetamodels.getJpaMetamodel().entity( SIMPLE_NAME );
|
|
||||||
assertThat( jpaType, notNullValue() );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Entity( name = "SimpleEntity" )
|
@Entity( name = "SimpleEntity" )
|
||||||
|
|
|
@ -30,16 +30,15 @@ dependencyResolutionManagement {
|
||||||
url( rootProject.property( "mavenMirror" ) )
|
url( rootProject.property( "mavenMirror" ) )
|
||||||
}
|
}
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
if (System.getProperty('JPA_PREVIEW') != null) {
|
if (System.getProperty('JPA_PREVIEW') != null) { // Needed for the RC versions of Jakarta Persistence
|
||||||
// Needed for the RC versions of Jakarta Persistence
|
maven {
|
||||||
maven {
|
url "https://jakarta.oss.sonatype.org/content/repositories/releases/"
|
||||||
url "https://jakarta.oss.sonatype.org/content/repositories/releases/"
|
}
|
||||||
}
|
// Needed for the SNAPSHOT versions of Jakarta Persistence
|
||||||
// Needed for the SNAPSHOT versions of Jakarta Persistence
|
maven {
|
||||||
maven {
|
url "https://jakarta.oss.sonatype.org/content/repositories/snapshots/"
|
||||||
url "https://jakarta.oss.sonatype.org/content/repositories/snapshots/"
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
//Allow loading additional dependencies from a local path;
|
//Allow loading additional dependencies from a local path;
|
||||||
//useful to load JDBC drivers which can not be distributed in public.
|
//useful to load JDBC drivers which can not be distributed in public.
|
||||||
|
|
|
@ -4,20 +4,28 @@
|
||||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
* 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>.
|
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||||
*/
|
*/
|
||||||
plugins {
|
|
||||||
id 'org.hibernate.build.xjc-jakarta'
|
|
||||||
}
|
|
||||||
|
|
||||||
description = 'Hibernate compile-time tooling'
|
description = 'Hibernate compile-time tooling'
|
||||||
|
|
||||||
apply from: rootProject.file( 'gradle/published-java-module.gradle' )
|
apply from: rootProject.file( 'gradle/published-java-module.gradle' )
|
||||||
apply plugin: 'version-injection'
|
apply plugin: 'version-injection'
|
||||||
|
|
||||||
ext {
|
java {
|
||||||
xjcTargetDir = file( "${buildDir}/generated/sources/xjc/main" )
|
sourceCompatibility = jdks.versions.getBaseline( )
|
||||||
xsdDir = file( "${projectDir}/src/main/xsd" )
|
targetCompatibility = 17
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//configurations {
|
||||||
|
// modelImplementation {
|
||||||
|
// extendsFrom implementation
|
||||||
|
// }
|
||||||
|
// modelAnnotationProcessor {
|
||||||
|
// extendsFrom annotationProcessor
|
||||||
|
// }
|
||||||
|
// testImplementation {
|
||||||
|
// extendsFrom modelImplementation
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
sourceSets {
|
sourceSets {
|
||||||
quarkusOrmPanache {
|
quarkusOrmPanache {
|
||||||
java {
|
java {
|
||||||
|
@ -64,10 +72,6 @@ dependencies {
|
||||||
api libs.byteBuddy
|
api libs.byteBuddy
|
||||||
api libs.logging
|
api libs.logging
|
||||||
|
|
||||||
xjc jakartaLibs.xjc
|
|
||||||
xjc jakartaLibs.jaxb
|
|
||||||
xjc rootProject.fileTree(dir: 'patched-libs/jaxb2-basics', include: '*.jar')
|
|
||||||
|
|
||||||
quarkusOrmPanacheImplementation "io.quarkus:quarkus-hibernate-orm-panache:3.6.2"
|
quarkusOrmPanacheImplementation "io.quarkus:quarkus-hibernate-orm-panache:3.6.2"
|
||||||
quarkusHrPanacheImplementation "io.quarkus:quarkus-hibernate-reactive-panache:3.6.2"
|
quarkusHrPanacheImplementation "io.quarkus:quarkus-hibernate-reactive-panache:3.6.2"
|
||||||
jakartaDataImplementation "jakarta.data:jakarta.data-api:1.0.0"
|
jakartaDataImplementation "jakarta.data:jakarta.data-api:1.0.0"
|
||||||
|
@ -121,14 +125,14 @@ test.dependsOn quarkusHrPanacheTestTask
|
||||||
test.dependsOn quarkusOrmPanacheTestTask
|
test.dependsOn quarkusOrmPanacheTestTask
|
||||||
|
|
||||||
sourceSets.main {
|
sourceSets.main {
|
||||||
java.srcDir xjcTargetDir
|
java.srcDir xjcTargetDir
|
||||||
resources.srcDir xsdDir
|
resources.srcDir xsdDir
|
||||||
}
|
}
|
||||||
|
|
||||||
compileTestJava {
|
compileTestJava {
|
||||||
options.compilerArgs += [
|
options.compilerArgs += [
|
||||||
"-proc:none",
|
"-proc:none",
|
||||||
"-AsuppressJakartaDataMetamodel=true"
|
"-AsuppressJakartaDataMetamodel=true"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -193,29 +197,29 @@ else {
|
||||||
|
|
||||||
|
|
||||||
task jaxb {
|
task jaxb {
|
||||||
// configure Gradle up-to-date checking
|
// configure Gradle up-to-date checking
|
||||||
inputs.dir( xsdDir ).withPropertyName("xsdDir" ).withPathSensitivity( PathSensitivity.RELATIVE )
|
inputs.dir( xsdDir ).withPropertyName("xsdDir" ).withPathSensitivity( PathSensitivity.RELATIVE )
|
||||||
outputs.dir( xjcTargetDir )
|
outputs.dir( xjcTargetDir )
|
||||||
outputs.cacheIf { true }
|
outputs.cacheIf { true }
|
||||||
|
|
||||||
// perform actions
|
// perform actions
|
||||||
doLast {
|
doLast {
|
||||||
xjcTargetDir.mkdirs()
|
xjcTargetDir.mkdirs()
|
||||||
|
|
||||||
ant.taskdef(name: 'xjc', classname: 'org.jvnet.jaxb2_commons.xjc.XJC2Task', classpath: configurations.xjc.asPath)
|
ant.taskdef(name: 'xjc', classname: 'org.jvnet.jaxb2_commons.xjc.XJC2Task', classpath: configurations.xjc.asPath)
|
||||||
|
|
||||||
ant.xjc(
|
ant.xjc(
|
||||||
destdir: ( xjcTargetDir as File ).absolutePath,
|
destdir: ( xjcTargetDir as File ).absolutePath,
|
||||||
package: 'org.hibernate.processor.xml.jaxb',
|
package: 'org.hibernate.processor.xml.jaxb',
|
||||||
extension: 'true'
|
extension: 'true'
|
||||||
) {
|
) {
|
||||||
project.ant.arg line: '-no-header'
|
project.ant.arg line: '-no-header'
|
||||||
project.ant.arg line: '-npa'
|
project.ant.arg line: '-npa'
|
||||||
schema( dir: xsdDir.path, includes: "*.xsd" )
|
schema( dir: xsdDir.path, includes: "*.xsd" )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
tasks.sourcesJar.dependsOn jaxb
|
|
||||||
tasks.sourcesJar.dependsOn ':hibernate-core:generateHqlParser'
|
tasks.sourcesJar.dependsOn ':hibernate-core:generateHqlParser'
|
||||||
tasks.sourcesJar.dependsOn ':hibernate-core:generateSqlScriptParser'
|
tasks.sourcesJar.dependsOn ':hibernate-core:generateSqlScriptParser'
|
||||||
tasks.compileJava.dependsOn jaxb
|
tasks.compileJava.dependsOn jaxb
|
||||||
|
|
|
@ -27,10 +27,13 @@ import javax.lang.model.util.Elements;
|
||||||
import javax.lang.model.util.Types;
|
import javax.lang.model.util.Types;
|
||||||
import javax.tools.Diagnostic;
|
import javax.tools.Diagnostic;
|
||||||
|
|
||||||
|
import org.hibernate.jpamodelgen.model.Metamodel;
|
||||||
|
import org.hibernate.jpamodelgen.util.AccessTypeInformation;
|
||||||
import org.hibernate.processor.model.Metamodel;
|
import org.hibernate.processor.model.Metamodel;
|
||||||
import org.hibernate.processor.util.AccessType;
|
import org.hibernate.processor.util.AccessType;
|
||||||
import org.hibernate.processor.util.AccessTypeInformation;
|
import org.hibernate.processor.util.AccessTypeInformation;
|
||||||
|
|
||||||
|
import jakarta.persistence.AccessType;
|
||||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
import static java.lang.Boolean.parseBoolean;
|
import static java.lang.Boolean.parseBoolean;
|
||||||
|
@ -412,7 +415,7 @@ public final class Context {
|
||||||
public void setUsesQuarkusOrm(boolean b) {
|
public void setUsesQuarkusOrm(boolean b) {
|
||||||
usesQuarkusOrm = b;
|
usesQuarkusOrm = b;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean usesQuarkusOrm() {
|
public boolean usesQuarkusOrm() {
|
||||||
return usesQuarkusOrm;
|
return usesQuarkusOrm;
|
||||||
}
|
}
|
||||||
|
@ -420,7 +423,7 @@ public final class Context {
|
||||||
public void setUsesQuarkusReactive(boolean b) {
|
public void setUsesQuarkusReactive(boolean b) {
|
||||||
usesQuarkusReactive = b;
|
usesQuarkusReactive = b;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean usesQuarkusReactive() {
|
public boolean usesQuarkusReactive() {
|
||||||
return usesQuarkusReactive;
|
return usesQuarkusReactive;
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,6 +54,26 @@ import javax.lang.model.type.WildcardType;
|
||||||
import javax.lang.model.util.Elements;
|
import javax.lang.model.util.Elements;
|
||||||
import javax.lang.model.util.Types;
|
import javax.lang.model.util.Types;
|
||||||
import javax.tools.Diagnostic;
|
import javax.tools.Diagnostic;
|
||||||
|
|
||||||
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
import org.hibernate.jpamodelgen.Context;
|
||||||
|
import org.hibernate.jpamodelgen.ImportContextImpl;
|
||||||
|
import org.hibernate.jpamodelgen.ProcessLaterException;
|
||||||
|
import org.hibernate.jpamodelgen.model.ImportContext;
|
||||||
|
import org.hibernate.jpamodelgen.model.MetaAttribute;
|
||||||
|
import org.hibernate.jpamodelgen.model.Metamodel;
|
||||||
|
import org.hibernate.jpamodelgen.util.AccessTypeInformation;
|
||||||
|
import org.hibernate.jpamodelgen.util.Constants;
|
||||||
|
import org.hibernate.jpamodelgen.validation.ProcessorSessionFactory;
|
||||||
|
import org.hibernate.jpamodelgen.validation.Validation;
|
||||||
|
import org.hibernate.metamodel.model.domain.EntityDomainType;
|
||||||
|
import org.hibernate.query.criteria.JpaEntityJoin;
|
||||||
|
import org.hibernate.query.criteria.JpaRoot;
|
||||||
|
import org.hibernate.query.criteria.JpaSelection;
|
||||||
|
import org.hibernate.query.sqm.SqmExpressible;
|
||||||
|
import org.hibernate.query.sqm.tree.SqmStatement;
|
||||||
|
import org.hibernate.query.sqm.tree.expression.SqmParameter;
|
||||||
|
import org.hibernate.query.sqm.tree.select.SqmSelectStatement;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
@ -63,6 +83,8 @@ import java.util.Set;
|
||||||
import java.util.StringTokenizer;
|
import java.util.StringTokenizer;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import jakarta.persistence.AccessType;
|
||||||
|
|
||||||
import static java.beans.Introspector.decapitalize;
|
import static java.beans.Introspector.decapitalize;
|
||||||
import static java.lang.Boolean.FALSE;
|
import static java.lang.Boolean.FALSE;
|
||||||
import static java.util.Collections.emptyList;
|
import static java.util.Collections.emptyList;
|
||||||
|
@ -154,7 +176,7 @@ public class AnnotationMetaEntity extends AnnotationMeta {
|
||||||
* The field or method call to obtain the session
|
* The field or method call to obtain the session
|
||||||
*/
|
*/
|
||||||
private String sessionGetter = "entityManager";
|
private String sessionGetter = "entityManager";
|
||||||
|
|
||||||
private final Map<String,String> memberTypes = new HashMap<>();
|
private final Map<String,String> memberTypes = new HashMap<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -580,7 +602,7 @@ public class AnnotationMetaEntity extends AnnotationMeta {
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setupSession() {
|
private void setupSession() {
|
||||||
if ( element.getTypeParameters().isEmpty() ) {
|
if ( element.getTypeParameters().isEmpty() ) {
|
||||||
jakartaDataRepository = hasAnnotation( element, JD_REPOSITORY );
|
jakartaDataRepository = hasAnnotation( element, JD_REPOSITORY );
|
||||||
|
@ -2537,7 +2559,6 @@ public class AnnotationMetaEntity extends AnnotationMeta {
|
||||||
return returnTypeName.equals( UNI_VOID )
|
return returnTypeName.equals( UNI_VOID )
|
||||||
|| returnTypeName.equals( UNI_BOOLEAN )
|
|| returnTypeName.equals( UNI_BOOLEAN )
|
||||||
|| returnTypeName.equals( UNI_INTEGER );
|
|| returnTypeName.equals( UNI_INTEGER );
|
||||||
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// non-reactive
|
// non-reactive
|
||||||
|
|
|
@ -10,6 +10,27 @@ package org.hibernate.processor.util;
|
||||||
* @author Hardy Ferentschik
|
* @author Hardy Ferentschik
|
||||||
*/
|
*/
|
||||||
public enum AccessType {
|
public enum AccessType {
|
||||||
PROPERTY,
|
PROPERTY( jakarta.persistence.AccessType.PROPERTY ),
|
||||||
FIELD
|
FIELD( jakarta.persistence.AccessType.FIELD );
|
||||||
|
|
||||||
|
private final jakarta.persistence.AccessType jpaAccessType;
|
||||||
|
|
||||||
|
AccessType(jakarta.persistence.AccessType jpaAccessType) {
|
||||||
|
this.jpaAccessType = jpaAccessType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public jakarta.persistence.AccessType getJpaAccessType() {
|
||||||
|
return jpaAccessType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static AccessType fromJpaAccessType(jakarta.persistence.AccessType jpaAccessType) {
|
||||||
|
if ( jpaAccessType == jakarta.persistence.AccessType.FIELD ) {
|
||||||
|
return FIELD;
|
||||||
|
}
|
||||||
|
if ( jpaAccessType == jakarta.persistence.AccessType.PROPERTY ) {
|
||||||
|
return PROPERTY;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new IllegalArgumentException( "Unknown JPA AccessType - " + jpaAccessType.name() );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.processor.util;
|
package org.hibernate.processor.util;
|
||||||
|
|
||||||
|
import jakarta.persistence.AccessType;
|
||||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -31,6 +31,10 @@ import javax.lang.model.util.ElementFilter;
|
||||||
import javax.lang.model.util.Elements;
|
import javax.lang.model.util.Elements;
|
||||||
import javax.lang.model.util.SimpleTypeVisitor8;
|
import javax.lang.model.util.SimpleTypeVisitor8;
|
||||||
import javax.tools.Diagnostic;
|
import javax.tools.Diagnostic;
|
||||||
|
|
||||||
|
import jakarta.persistence.AccessType;
|
||||||
|
import org.hibernate.jpamodelgen.Context;
|
||||||
|
import org.hibernate.jpamodelgen.MetaModelGenerationException;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
|
@ -23,6 +23,10 @@ import javax.xml.stream.XMLStreamException;
|
||||||
import javax.xml.validation.Schema;
|
import javax.xml.validation.Schema;
|
||||||
import javax.xml.validation.SchemaFactory;
|
import javax.xml.validation.SchemaFactory;
|
||||||
|
|
||||||
|
import org.hibernate.boot.jaxb.cfg.spi.ObjectFactory;
|
||||||
|
|
||||||
|
import org.hibernate.jpamodelgen.Context;
|
||||||
|
import org.hibernate.jpamodelgen.util.NullnessUtil;
|
||||||
import org.hibernate.processor.Context;
|
import org.hibernate.processor.Context;
|
||||||
import org.hibernate.processor.util.NullnessUtil;
|
import org.hibernate.processor.util.NullnessUtil;
|
||||||
import org.hibernate.processor.xml.jaxb.ObjectFactory;
|
import org.hibernate.processor.xml.jaxb.ObjectFactory;
|
||||||
|
|
|
@ -19,11 +19,31 @@ import java.net.URL;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.function.Function;
|
||||||
import javax.lang.model.element.TypeElement;
|
import javax.lang.model.element.TypeElement;
|
||||||
import javax.lang.model.util.Elements;
|
import javax.lang.model.util.Elements;
|
||||||
import javax.tools.Diagnostic;
|
import javax.tools.Diagnostic;
|
||||||
import javax.xml.validation.Schema;
|
|
||||||
|
|
||||||
|
import org.hibernate.MappingException;
|
||||||
|
import org.hibernate.boot.jaxb.Origin;
|
||||||
|
import org.hibernate.boot.jaxb.SourceType;
|
||||||
|
import org.hibernate.boot.jaxb.configuration.spi.JaxbPersistenceImpl;
|
||||||
|
import org.hibernate.boot.jaxb.internal.ConfigurationBinder;
|
||||||
|
import org.hibernate.boot.jaxb.internal.MappingBinder;
|
||||||
|
import org.hibernate.boot.jaxb.mapping.spi.JaxbEmbeddableImpl;
|
||||||
|
import org.hibernate.boot.jaxb.mapping.spi.JaxbEntityImpl;
|
||||||
|
import org.hibernate.boot.jaxb.mapping.spi.JaxbEntityMappingsImpl;
|
||||||
|
import org.hibernate.boot.jaxb.mapping.spi.JaxbMappedSuperclassImpl;
|
||||||
|
import org.hibernate.boot.jaxb.mapping.spi.JaxbPersistenceUnitDefaultsImpl;
|
||||||
|
import org.hibernate.boot.jaxb.mapping.spi.JaxbPersistenceUnitMetadataImpl;
|
||||||
|
import org.hibernate.boot.jaxb.spi.Binding;
|
||||||
|
import org.hibernate.boot.jaxb.spi.JaxbBindableMappingDescriptor;
|
||||||
|
import org.hibernate.jpamodelgen.Context;
|
||||||
|
import org.hibernate.jpamodelgen.util.AccessTypeInformation;
|
||||||
|
import org.hibernate.jpamodelgen.util.FileTimeStampChecker;
|
||||||
|
import org.hibernate.jpamodelgen.util.StringUtil;
|
||||||
|
import org.hibernate.jpamodelgen.util.TypeUtils;
|
||||||
|
import org.hibernate.jpamodelgen.util.xml.XmlParserHelper;
|
||||||
import org.hibernate.processor.Context;
|
import org.hibernate.processor.Context;
|
||||||
import org.hibernate.processor.util.AccessType;
|
import org.hibernate.processor.util.AccessType;
|
||||||
import org.hibernate.processor.util.AccessTypeInformation;
|
import org.hibernate.processor.util.AccessTypeInformation;
|
||||||
|
@ -38,6 +58,7 @@ import org.hibernate.processor.xml.jaxb.Persistence;
|
||||||
import org.hibernate.processor.xml.jaxb.PersistenceUnitDefaults;
|
import org.hibernate.processor.xml.jaxb.PersistenceUnitDefaults;
|
||||||
import org.hibernate.processor.xml.jaxb.PersistenceUnitMetadata;
|
import org.hibernate.processor.xml.jaxb.PersistenceUnitMetadata;
|
||||||
|
|
||||||
|
import jakarta.persistence.AccessType;
|
||||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -49,20 +70,26 @@ public class JpaDescriptorParser {
|
||||||
private static final String DEFAULT_ORM_XML_LOCATION = "/META-INF/orm.xml";
|
private static final String DEFAULT_ORM_XML_LOCATION = "/META-INF/orm.xml";
|
||||||
private static final String SERIALIZATION_FILE_NAME = "Hibernate-Static-Metamodel-Generator.tmp";
|
private static final String SERIALIZATION_FILE_NAME = "Hibernate-Static-Metamodel-Generator.tmp";
|
||||||
|
|
||||||
private static final String PERSISTENCE_SCHEMA = "persistence_3_0.xsd";
|
private static final String PERSISTENCE_SCHEMA = "org/hibernate/xsd/cfg/persistence_3_0.xsd";
|
||||||
private static final String ORM_SCHEMA = "orm_3_1.xsd";
|
|
||||||
|
|
||||||
private final Context context;
|
private final Context context;
|
||||||
private final List<EntityMappings> entityMappings;
|
private final List<JaxbEntityMappingsImpl> entityMappings;
|
||||||
private final XmlParserHelper xmlParserHelper;
|
private final XmlParserHelper xmlParserHelper;
|
||||||
|
private final ConfigurationBinder configurationBinder;
|
||||||
|
private final MappingBinder mappingBinder;
|
||||||
|
|
||||||
public JpaDescriptorParser(Context context) {
|
public JpaDescriptorParser(Context context) {
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.entityMappings = new ArrayList<>();
|
this.entityMappings = new ArrayList<>();
|
||||||
this.xmlParserHelper = new XmlParserHelper( context );
|
this.xmlParserHelper = new XmlParserHelper( context );
|
||||||
|
|
||||||
|
final ResourceStreamLocatorImpl resourceStreamLocator = new ResourceStreamLocatorImpl( context );
|
||||||
|
this.configurationBinder = new ConfigurationBinder( resourceStreamLocator );
|
||||||
|
this.mappingBinder = new MappingBinder( resourceStreamLocator, (Function<String,Object>) null );
|
||||||
}
|
}
|
||||||
|
|
||||||
public void parseXml() {
|
public void parseMappingXml() {
|
||||||
Collection<String> mappingFileNames = determineMappingFileNames();
|
Collection<String> mappingFileNames = determineMappingFileNames();
|
||||||
|
|
||||||
if ( context.doLazyXmlParsing() && mappingFilesUnchanged( mappingFileNames ) ) {
|
if ( context.doLazyXmlParsing() && mappingFilesUnchanged( mappingFileNames ) ) {
|
||||||
|
@ -78,22 +105,22 @@ public class JpaDescriptorParser {
|
||||||
determineAnnotationAccessTypes();
|
determineAnnotationAccessTypes();
|
||||||
}
|
}
|
||||||
|
|
||||||
for ( EntityMappings mappings : entityMappings ) {
|
for ( JaxbEntityMappingsImpl mappings : entityMappings ) {
|
||||||
String defaultPackageName = mappings.getPackage();
|
String defaultPackageName = mappings.getPackage();
|
||||||
parseEntities( mappings.getEntity(), defaultPackageName );
|
parseEntities( mappings.getEntities(), defaultPackageName );
|
||||||
parseEmbeddable( mappings.getEmbeddable(), defaultPackageName );
|
parseEmbeddable( mappings.getEmbeddables(), defaultPackageName );
|
||||||
parseMappedSuperClass( mappings.getMappedSuperclass(), defaultPackageName );
|
parseMappedSuperClass( mappings.getMappedSuperclasses(), defaultPackageName );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Collection<String> determineMappingFileNames() {
|
private Collection<String> determineMappingFileNames() {
|
||||||
Collection<String> mappingFileNames = new ArrayList<>();
|
Collection<String> mappingFileNames = new ArrayList<>();
|
||||||
|
|
||||||
Persistence persistence = getPersistence();
|
JaxbPersistenceImpl persistence = getPersistence();
|
||||||
if ( persistence != null ) {
|
if ( persistence != null ) {
|
||||||
// get mapping file names from persistence.xml
|
// get mapping file names from persistence.xml
|
||||||
List<Persistence.PersistenceUnit> persistenceUnits = persistence.getPersistenceUnit();
|
List<JaxbPersistenceImpl.JaxbPersistenceUnitImpl> persistenceUnits = persistence.getPersistenceUnit();
|
||||||
for ( Persistence.PersistenceUnit unit : persistenceUnits ) {
|
for ( JaxbPersistenceImpl.JaxbPersistenceUnitImpl unit : persistenceUnits ) {
|
||||||
mappingFileNames.addAll( unit.getMappingFile() );
|
mappingFileNames.addAll( unit.getMappingFile() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -107,19 +134,26 @@ public class JpaDescriptorParser {
|
||||||
return mappingFileNames;
|
return mappingFileNames;
|
||||||
}
|
}
|
||||||
|
|
||||||
private @Nullable Persistence getPersistence() {
|
private @Nullable JaxbPersistenceImpl getPersistence() {
|
||||||
Persistence persistence = null;
|
JaxbPersistenceImpl persistence = null;
|
||||||
String persistenceXmlLocation = context.getPersistenceXmlLocation();
|
|
||||||
|
final String persistenceXmlLocation = context.getPersistenceXmlLocation();
|
||||||
final InputStream stream = xmlParserHelper.getInputStreamForResource( persistenceXmlLocation );
|
final InputStream stream = xmlParserHelper.getInputStreamForResource( persistenceXmlLocation );
|
||||||
if ( stream == null ) {
|
if ( stream == null ) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Schema schema = xmlParserHelper.getSchema( PERSISTENCE_SCHEMA );
|
final Binding<JaxbPersistenceImpl> binding = configurationBinder.bind(
|
||||||
persistence = xmlParserHelper.getJaxbRoot( stream, Persistence.class, schema );
|
stream,
|
||||||
|
new Origin( SourceType.RESOURCE, persistenceXmlLocation )
|
||||||
|
);
|
||||||
|
persistence = binding.getRoot();
|
||||||
}
|
}
|
||||||
catch (XmlParsingException e) {
|
catch (MappingException e) {
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
context.logMessage(
|
context.logMessage(
|
||||||
Diagnostic.Kind.WARNING, "Unable to parse persistence.xml: " + e.getMessage()
|
Diagnostic.Kind.WARNING, "Unable to parse persistence.xml: " + e.getMessage()
|
||||||
);
|
);
|
||||||
|
@ -137,26 +171,31 @@ public class JpaDescriptorParser {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void loadEntityMappings(Collection<String> mappingFileNames) {
|
private void loadEntityMappings(Collection<String> mappingFileNames) {
|
||||||
|
final ResourceStreamLocatorImpl resourceStreamLocator = new ResourceStreamLocatorImpl( context );
|
||||||
|
|
||||||
for ( String mappingFile : mappingFileNames ) {
|
for ( String mappingFile : mappingFileNames ) {
|
||||||
final InputStream stream = xmlParserHelper.getInputStreamForResource( mappingFile );
|
final InputStream inputStream = resourceStreamLocator.locateResourceStream( mappingFile );
|
||||||
if ( stream == null ) {
|
if ( inputStream == null ) {
|
||||||
|
// todo (jpa32) : log
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
final Schema schema = xmlParserHelper.getSchema( ORM_SCHEMA );
|
final Binding<JaxbBindableMappingDescriptor> binding = mappingBinder.bind(
|
||||||
final EntityMappings mapping = xmlParserHelper.getJaxbRoot( stream, EntityMappings.class, schema );
|
inputStream,
|
||||||
if ( mapping != null ) {
|
new Origin( SourceType.RESOURCE, mappingFile )
|
||||||
entityMappings.add( mapping );
|
);
|
||||||
|
if ( binding != null ) {
|
||||||
|
entityMappings.add( (JaxbEntityMappingsImpl) binding.getRoot() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (XmlParsingException e) {
|
catch (Exception e) {
|
||||||
context.logMessage(
|
context.logMessage(
|
||||||
Diagnostic.Kind.WARNING, "Unable to parse " + mappingFile + ": " + e.getMessage()
|
Diagnostic.Kind.WARNING, "Unable to parse " + mappingFile + ": " + e.getMessage()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
try {
|
try {
|
||||||
stream.close();
|
inputStream.close();
|
||||||
}
|
}
|
||||||
catch (IOException e) {
|
catch (IOException e) {
|
||||||
// eat it
|
// eat it
|
||||||
|
@ -236,8 +275,8 @@ public class JpaDescriptorParser {
|
||||||
return new FileTimeStampChecker();
|
return new FileTimeStampChecker();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseEntities(Collection<Entity> entities, String defaultPackageName) {
|
private void parseEntities(List<JaxbEntityImpl> entities, String defaultPackageName) {
|
||||||
for ( Entity entity : entities ) {
|
for ( JaxbEntityImpl entity : entities ) {
|
||||||
String fqcn = StringUtil.determineFullyQualifiedClassName( defaultPackageName, entity.getClazz() );
|
String fqcn = StringUtil.determineFullyQualifiedClassName( defaultPackageName, entity.getClazz() );
|
||||||
|
|
||||||
if ( !xmlMappedTypeExists( fqcn ) ) {
|
if ( !xmlMappedTypeExists( fqcn ) ) {
|
||||||
|
@ -262,9 +301,9 @@ public class JpaDescriptorParser {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseEmbeddable(
|
private void parseEmbeddable(
|
||||||
Collection<org.hibernate.processor.xml.jaxb.Embeddable> embeddables,
|
List<JaxbEmbeddableImpl> embeddables,
|
||||||
String defaultPackageName) {
|
String defaultPackageName) {
|
||||||
for ( org.hibernate.processor.xml.jaxb.Embeddable embeddable : embeddables ) {
|
for ( JaxbEmbeddableImpl embeddable : embeddables ) {
|
||||||
String fqcn = StringUtil.determineFullyQualifiedClassName( defaultPackageName, embeddable.getClazz() );
|
String fqcn = StringUtil.determineFullyQualifiedClassName( defaultPackageName, embeddable.getClazz() );
|
||||||
// we have to extract the package name from the fqcn. Maybe the entity was setting a fqcn directly
|
// we have to extract the package name from the fqcn. Maybe the entity was setting a fqcn directly
|
||||||
String pkg = StringUtil.packageNameFromFqcn( fqcn );
|
String pkg = StringUtil.packageNameFromFqcn( fqcn );
|
||||||
|
@ -289,9 +328,9 @@ public class JpaDescriptorParser {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseMappedSuperClass(
|
private void parseMappedSuperClass(
|
||||||
Collection<org.hibernate.processor.xml.jaxb.MappedSuperclass> mappedSuperClasses,
|
List<JaxbMappedSuperclassImpl> mappedSuperClasses,
|
||||||
String defaultPackageName) {
|
String defaultPackageName) {
|
||||||
for ( org.hibernate.processor.xml.jaxb.MappedSuperclass mappedSuperClass : mappedSuperClasses ) {
|
for ( JaxbMappedSuperclassImpl mappedSuperClass : mappedSuperClasses ) {
|
||||||
String fqcn = StringUtil.determineFullyQualifiedClassName(
|
String fqcn = StringUtil.determineFullyQualifiedClassName(
|
||||||
defaultPackageName, mappedSuperClass.getClazz()
|
defaultPackageName, mappedSuperClass.getClazz()
|
||||||
);
|
);
|
||||||
|
@ -306,8 +345,7 @@ public class JpaDescriptorParser {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
XmlMetaEntity metaEntity = new XmlMetaEntity(
|
XmlMetaEntity metaEntity = new XmlMetaEntity( mappedSuperClass, pkg, getXmlMappedType( fqcn ), context
|
||||||
mappedSuperClass, pkg, getXmlMappedType( fqcn ), context
|
|
||||||
);
|
);
|
||||||
|
|
||||||
if ( context.containsMetaEntity( fqcn ) ) {
|
if ( context.containsMetaEntity( fqcn ) ) {
|
||||||
|
@ -330,71 +368,53 @@ public class JpaDescriptorParser {
|
||||||
return utils.getTypeElement( fullyQualifiedClassName );
|
return utils.getTypeElement( fullyQualifiedClassName );
|
||||||
}
|
}
|
||||||
|
|
||||||
private AccessType determineEntityAccessType(EntityMappings mappings) {
|
private AccessType determineEntityAccessType(JaxbEntityMappingsImpl mappings) {
|
||||||
AccessType accessType = context.getPersistenceUnitDefaultAccessType();
|
final AccessType contextAccessType = context.getPersistenceUnitDefaultAccessType();
|
||||||
final org.hibernate.processor.xml.jaxb.AccessType mappingsAccess = mappings.getAccess();
|
final AccessType mappingsAccess = mappings.getAccess();
|
||||||
if ( mappingsAccess != null ) {
|
if ( mappingsAccess != null ) {
|
||||||
accessType = mapXmlAccessTypeToJpaAccessType( mappingsAccess );
|
return mappingsAccess;
|
||||||
}
|
}
|
||||||
return accessType;
|
return contextAccessType;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void determineXmlAccessTypes() {
|
private void determineXmlAccessTypes() {
|
||||||
for ( EntityMappings mappings : entityMappings ) {
|
for ( JaxbEntityMappingsImpl mappings : entityMappings ) {
|
||||||
String fqcn;
|
String fqcn;
|
||||||
String packageName = mappings.getPackage();
|
String packageName = mappings.getPackage();
|
||||||
AccessType defaultAccessType = determineEntityAccessType( mappings );
|
AccessType defaultAccessType = determineEntityAccessType( mappings );
|
||||||
|
|
||||||
for ( Entity entity : mappings.getEntity() ) {
|
for ( JaxbEntityImpl entity : mappings.getEntities() ) {
|
||||||
String name = entity.getClazz();
|
final String name = entity.getClazz();
|
||||||
fqcn = StringUtil.determineFullyQualifiedClassName( packageName, name );
|
fqcn = StringUtil.determineFullyQualifiedClassName( packageName, name );
|
||||||
AccessType explicitAccessType = null;
|
final AccessType explicitAccessType = entity.getAccess();
|
||||||
org.hibernate.processor.xml.jaxb.AccessType type = entity.getAccess();
|
final AccessTypeInformation accessInfo = new AccessTypeInformation( fqcn, explicitAccessType, defaultAccessType );
|
||||||
if ( type != null ) {
|
|
||||||
explicitAccessType = mapXmlAccessTypeToJpaAccessType( type );
|
|
||||||
}
|
|
||||||
AccessTypeInformation accessInfo = new AccessTypeInformation(
|
|
||||||
fqcn, explicitAccessType, defaultAccessType
|
|
||||||
);
|
|
||||||
context.addAccessTypeInformation( fqcn, accessInfo );
|
context.addAccessTypeInformation( fqcn, accessInfo );
|
||||||
}
|
}
|
||||||
|
|
||||||
for ( org.hibernate.processor.xml.jaxb.MappedSuperclass mappedSuperClass : mappings.getMappedSuperclass() ) {
|
for ( JaxbMappedSuperclassImpl mappedSuperClass : mappings.getMappedSuperclasses() ) {
|
||||||
String name = mappedSuperClass.getClazz();
|
final String name = mappedSuperClass.getClazz();
|
||||||
fqcn = StringUtil.determineFullyQualifiedClassName( packageName, name );
|
fqcn = StringUtil.determineFullyQualifiedClassName( packageName, name );
|
||||||
AccessType explicitAccessType = null;
|
final AccessType explicitAccessType = mappedSuperClass.getAccess();
|
||||||
org.hibernate.processor.xml.jaxb.AccessType type = mappedSuperClass.getAccess();
|
final AccessTypeInformation accessInfo = new AccessTypeInformation( fqcn, explicitAccessType, defaultAccessType );
|
||||||
if ( type != null ) {
|
|
||||||
explicitAccessType = mapXmlAccessTypeToJpaAccessType( type );
|
|
||||||
}
|
|
||||||
AccessTypeInformation accessInfo = new AccessTypeInformation(
|
|
||||||
fqcn, explicitAccessType, defaultAccessType
|
|
||||||
);
|
|
||||||
context.addAccessTypeInformation( fqcn, accessInfo );
|
context.addAccessTypeInformation( fqcn, accessInfo );
|
||||||
}
|
}
|
||||||
|
|
||||||
for ( org.hibernate.processor.xml.jaxb.Embeddable embeddable : mappings.getEmbeddable() ) {
|
for ( JaxbEmbeddableImpl embeddable : mappings.getEmbeddables() ) {
|
||||||
String name = embeddable.getClazz();
|
final String name = embeddable.getClazz();
|
||||||
fqcn = StringUtil.determineFullyQualifiedClassName( packageName, name );
|
fqcn = StringUtil.determineFullyQualifiedClassName( packageName, name );
|
||||||
AccessType explicitAccessType = null;
|
final AccessType explicitAccessType = embeddable.getAccess();
|
||||||
org.hibernate.processor.xml.jaxb.AccessType type = embeddable.getAccess();
|
final AccessTypeInformation accessInfo = new AccessTypeInformation( fqcn, explicitAccessType, defaultAccessType );
|
||||||
if ( type != null ) {
|
|
||||||
explicitAccessType = mapXmlAccessTypeToJpaAccessType( type );
|
|
||||||
}
|
|
||||||
AccessTypeInformation accessInfo = new AccessTypeInformation(
|
|
||||||
fqcn, explicitAccessType, defaultAccessType
|
|
||||||
);
|
|
||||||
context.addAccessTypeInformation( fqcn, accessInfo );
|
context.addAccessTypeInformation( fqcn, accessInfo );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void determineAnnotationAccessTypes() {
|
private void determineAnnotationAccessTypes() {
|
||||||
for ( EntityMappings mappings : entityMappings ) {
|
for ( JaxbEntityMappingsImpl mappings : entityMappings ) {
|
||||||
String fqcn;
|
String fqcn;
|
||||||
String packageName = mappings.getPackage();
|
String packageName = mappings.getPackage();
|
||||||
|
|
||||||
for ( Entity entity : mappings.getEntity() ) {
|
for ( JaxbEntityImpl entity : mappings.getEntities() ) {
|
||||||
String name = entity.getClazz();
|
String name = entity.getClazz();
|
||||||
fqcn = StringUtil.determineFullyQualifiedClassName( packageName, name );
|
fqcn = StringUtil.determineFullyQualifiedClassName( packageName, name );
|
||||||
TypeElement element = context.getTypeElementForFullyQualifiedName( fqcn );
|
TypeElement element = context.getTypeElementForFullyQualifiedName( fqcn );
|
||||||
|
@ -403,7 +423,7 @@ public class JpaDescriptorParser {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for ( org.hibernate.processor.xml.jaxb.MappedSuperclass mappedSuperClass : mappings.getMappedSuperclass() ) {
|
for ( JaxbMappedSuperclassImpl mappedSuperClass : mappings.getMappedSuperclasses() ) {
|
||||||
String name = mappedSuperClass.getClazz();
|
String name = mappedSuperClass.getClazz();
|
||||||
fqcn = StringUtil.determineFullyQualifiedClassName( packageName, name );
|
fqcn = StringUtil.determineFullyQualifiedClassName( packageName, name );
|
||||||
TypeElement element = context.getTypeElementForFullyQualifiedName( fqcn );
|
TypeElement element = context.getTypeElementForFullyQualifiedName( fqcn );
|
||||||
|
@ -430,16 +450,16 @@ public class JpaDescriptorParser {
|
||||||
* </ul>
|
* </ul>
|
||||||
*/
|
*/
|
||||||
private void determineDefaultAccessTypeAndMetaCompleteness() {
|
private void determineDefaultAccessTypeAndMetaCompleteness() {
|
||||||
for ( EntityMappings mappings : entityMappings ) {
|
for ( JaxbEntityMappingsImpl mappings : entityMappings ) {
|
||||||
PersistenceUnitMetadata meta = mappings.getPersistenceUnitMetadata();
|
JaxbPersistenceUnitMetadataImpl meta = mappings.getPersistenceUnitMetadata();
|
||||||
if ( meta != null ) {
|
if ( meta != null ) {
|
||||||
context.mappingDocumentFullyXmlConfigured( meta.getXmlMappingMetadataComplete() != null );
|
context.mappingDocumentFullyXmlConfigured( meta.getXmlMappingMetadataComplete() != null );
|
||||||
|
|
||||||
PersistenceUnitDefaults persistenceUnitDefaults = meta.getPersistenceUnitDefaults();
|
JaxbPersistenceUnitDefaultsImpl persistenceUnitDefaults = meta.getPersistenceUnitDefaults();
|
||||||
if ( persistenceUnitDefaults != null ) {
|
if ( persistenceUnitDefaults != null ) {
|
||||||
org.hibernate.processor.xml.jaxb.AccessType xmlAccessType = persistenceUnitDefaults.getAccess();
|
final jakarta.persistence.AccessType xmlJpaAccessType = persistenceUnitDefaults.getAccess();
|
||||||
if ( xmlAccessType != null ) {
|
if ( xmlJpaAccessType != null ) {
|
||||||
context.setPersistenceUnitDefaultAccessType( mapXmlAccessTypeToJpaAccessType( xmlAccessType ) );
|
context.setPersistenceUnitDefaultAccessType( xmlJpaAccessType );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -448,14 +468,4 @@ public class JpaDescriptorParser {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private AccessType mapXmlAccessTypeToJpaAccessType(org.hibernate.processor.xml.jaxb.AccessType xmlAccessType) {
|
|
||||||
switch ( xmlAccessType ) {
|
|
||||||
case FIELD:
|
|
||||||
return AccessType.FIELD;
|
|
||||||
case PROPERTY:
|
|
||||||
return AccessType.PROPERTY;
|
|
||||||
}
|
|
||||||
throw new IllegalArgumentException( "Unknown access type: " + xmlAccessType );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,32 @@ import javax.lang.model.type.ExecutableType;
|
||||||
import javax.lang.model.type.TypeMirror;
|
import javax.lang.model.type.TypeMirror;
|
||||||
import javax.tools.Diagnostic;
|
import javax.tools.Diagnostic;
|
||||||
|
|
||||||
|
import org.hibernate.boot.jaxb.mapping.spi.JaxbAttributesContainerImpl;
|
||||||
|
import org.hibernate.boot.jaxb.mapping.spi.JaxbBasicImpl;
|
||||||
|
import org.hibernate.boot.jaxb.mapping.spi.JaxbElementCollectionImpl;
|
||||||
|
import org.hibernate.boot.jaxb.mapping.spi.JaxbEmbeddableAttributesContainerImpl;
|
||||||
|
import org.hibernate.boot.jaxb.mapping.spi.JaxbEmbeddableImpl;
|
||||||
|
import org.hibernate.boot.jaxb.mapping.spi.JaxbEmbeddedIdImpl;
|
||||||
|
import org.hibernate.boot.jaxb.mapping.spi.JaxbEmbeddedImpl;
|
||||||
|
import org.hibernate.boot.jaxb.mapping.spi.JaxbEntityImpl;
|
||||||
|
import org.hibernate.boot.jaxb.mapping.spi.JaxbIdImpl;
|
||||||
|
import org.hibernate.boot.jaxb.mapping.spi.JaxbManyToManyImpl;
|
||||||
|
import org.hibernate.boot.jaxb.mapping.spi.JaxbManyToOneImpl;
|
||||||
|
import org.hibernate.boot.jaxb.mapping.spi.JaxbMapKeyClassImpl;
|
||||||
|
import org.hibernate.boot.jaxb.mapping.spi.JaxbMappedSuperclassImpl;
|
||||||
|
import org.hibernate.boot.jaxb.mapping.spi.JaxbOneToManyImpl;
|
||||||
|
import org.hibernate.boot.jaxb.mapping.spi.JaxbOneToOneImpl;
|
||||||
|
import org.hibernate.jpamodelgen.Context;
|
||||||
|
import org.hibernate.jpamodelgen.ImportContextImpl;
|
||||||
|
import org.hibernate.jpamodelgen.MetaModelGenerationException;
|
||||||
|
import org.hibernate.jpamodelgen.model.ImportContext;
|
||||||
|
import org.hibernate.jpamodelgen.model.MetaAttribute;
|
||||||
|
import org.hibernate.jpamodelgen.model.Metamodel;
|
||||||
|
import org.hibernate.jpamodelgen.util.AccessTypeInformation;
|
||||||
|
import org.hibernate.jpamodelgen.util.Constants;
|
||||||
|
import org.hibernate.jpamodelgen.util.NullnessUtil;
|
||||||
|
import org.hibernate.jpamodelgen.util.StringUtil;
|
||||||
|
import org.hibernate.jpamodelgen.util.TypeUtils;
|
||||||
import org.hibernate.processor.Context;
|
import org.hibernate.processor.Context;
|
||||||
import org.hibernate.processor.ImportContextImpl;
|
import org.hibernate.processor.ImportContextImpl;
|
||||||
import org.hibernate.processor.MetaModelGenerationException;
|
import org.hibernate.processor.MetaModelGenerationException;
|
||||||
|
@ -45,8 +71,12 @@ import org.hibernate.processor.xml.jaxb.MappedSuperclass;
|
||||||
import org.hibernate.processor.xml.jaxb.OneToMany;
|
import org.hibernate.processor.xml.jaxb.OneToMany;
|
||||||
import org.hibernate.processor.xml.jaxb.OneToOne;
|
import org.hibernate.processor.xml.jaxb.OneToOne;
|
||||||
|
|
||||||
|
import jakarta.persistence.AccessType;
|
||||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
|
import static jakarta.persistence.AccessType.FIELD;
|
||||||
|
import static org.hibernate.jpamodelgen.util.StringUtil.determineFullyQualifiedClassName;
|
||||||
|
import static org.hibernate.jpamodelgen.util.TypeUtils.getElementKindForAccessType;
|
||||||
import static java.util.Collections.emptyList;
|
import static java.util.Collections.emptyList;
|
||||||
import static org.hibernate.processor.util.StringUtil.determineFullyQualifiedClassName;
|
import static org.hibernate.processor.util.StringUtil.determineFullyQualifiedClassName;
|
||||||
import static org.hibernate.processor.util.TypeUtils.extractClosestRealTypeAsString;
|
import static org.hibernate.processor.util.TypeUtils.extractClosestRealTypeAsString;
|
||||||
|
@ -70,8 +100,8 @@ public class XmlMetaEntity implements Metamodel {
|
||||||
private final Context context;
|
private final Context context;
|
||||||
private final boolean isMetaComplete;
|
private final boolean isMetaComplete;
|
||||||
|
|
||||||
private @Nullable Attributes attributes;
|
private @Nullable JaxbAttributesContainerImpl attributes;
|
||||||
private @Nullable EmbeddableAttributes embeddableAttributes;
|
private @Nullable JaxbEmbeddableAttributesContainerImpl embeddableAttributes;
|
||||||
private AccessTypeInformation accessTypeInfo;
|
private AccessTypeInformation accessTypeInfo;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -87,20 +117,20 @@ public class XmlMetaEntity implements Metamodel {
|
||||||
*/
|
*/
|
||||||
private boolean initialized;
|
private boolean initialized;
|
||||||
|
|
||||||
XmlMetaEntity(Entity ormEntity, String defaultPackageName, TypeElement element, Context context) {
|
XmlMetaEntity(JaxbEntityImpl ormEntity, String defaultPackageName, TypeElement element, Context context) {
|
||||||
this( ormEntity.getClazz(), defaultPackageName, element, context, ormEntity.isMetadataComplete() );
|
this( ormEntity.getClazz(), defaultPackageName, element, context, ormEntity.isMetadataComplete() );
|
||||||
this.attributes = ormEntity.getAttributes();
|
this.attributes = ormEntity.getAttributes();
|
||||||
this.embeddableAttributes = null;
|
this.embeddableAttributes = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
static XmlMetaEntity create(Entity ormEntity, String defaultPackageName, TypeElement element, Context context) {
|
static XmlMetaEntity create(JaxbEntityImpl ormEntity, String defaultPackageName, TypeElement element, Context context) {
|
||||||
XmlMetaEntity entity = new XmlMetaEntity( ormEntity, defaultPackageName, element, context );
|
XmlMetaEntity entity = new XmlMetaEntity( ormEntity, defaultPackageName, element, context );
|
||||||
// entities can be directly initialised
|
// entities can be directly initialised
|
||||||
entity.init();
|
entity.init();
|
||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
XmlMetaEntity(MappedSuperclass mappedSuperclass, String defaultPackageName, TypeElement element, Context context) {
|
XmlMetaEntity(JaxbMappedSuperclassImpl mappedSuperclass, String defaultPackageName, TypeElement element, Context context) {
|
||||||
this(
|
this(
|
||||||
mappedSuperclass.getClazz(),
|
mappedSuperclass.getClazz(),
|
||||||
defaultPackageName,
|
defaultPackageName,
|
||||||
|
@ -112,7 +142,7 @@ public class XmlMetaEntity implements Metamodel {
|
||||||
this.embeddableAttributes = null;
|
this.embeddableAttributes = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
XmlMetaEntity(Embeddable embeddable, String defaultPackageName, TypeElement element, Context context) {
|
XmlMetaEntity(JaxbEmbeddableImpl embeddable, String defaultPackageName, TypeElement element, Context context) {
|
||||||
this( embeddable.getClazz(), defaultPackageName, element, context, embeddable.isMetadataComplete() );
|
this( embeddable.getClazz(), defaultPackageName, element, context, embeddable.isMetadataComplete() );
|
||||||
this.attributes = null;
|
this.attributes = null;
|
||||||
this.embeddableAttributes = embeddable.getAttributes();
|
this.embeddableAttributes = embeddable.getAttributes();
|
||||||
|
@ -365,98 +395,98 @@ public class XmlMetaEntity implements Metamodel {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseAttributes(Attributes attributes) {
|
private void parseAttributes(JaxbAttributesContainerImpl attributes) {
|
||||||
XmlMetaSingleAttribute attribute;
|
XmlMetaSingleAttribute attribute;
|
||||||
for ( Id id : attributes.getId() ) {
|
for ( JaxbIdImpl id : attributes.getIdAttributes() ) {
|
||||||
ElementKind elementKind = getElementKind( id.getAccess() );
|
final ElementKind elementKind = getElementKind( id.getAccess() );
|
||||||
String type = getType( id.getName(), null, elementKind );
|
final String type = getType( id.getName(), null, elementKind );
|
||||||
if ( type != null ) {
|
if ( type != null ) {
|
||||||
attribute = new XmlMetaSingleAttribute( this, id.getName(), type );
|
attribute = new XmlMetaSingleAttribute( this, id.getName(), type );
|
||||||
members.add( attribute );
|
members.add( attribute );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( attributes.getEmbeddedId() != null ) {
|
if ( attributes.getEmbeddedIdAttribute() != null ) {
|
||||||
EmbeddedId embeddedId = attributes.getEmbeddedId();
|
final JaxbEmbeddedIdImpl embeddedId = attributes.getEmbeddedIdAttribute();
|
||||||
ElementKind elementKind = getElementKind( embeddedId.getAccess() );
|
final ElementKind elementKind = getElementKind( embeddedId.getAccess() );
|
||||||
String type = getType( embeddedId.getName(), null, elementKind );
|
final String type = getType( embeddedId.getName(), null, elementKind );
|
||||||
if ( type != null ) {
|
if ( type != null ) {
|
||||||
attribute = new XmlMetaSingleAttribute( this, embeddedId.getName(), type );
|
attribute = new XmlMetaSingleAttribute( this, embeddedId.getName(), type );
|
||||||
members.add( attribute );
|
members.add( attribute );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for ( Basic basic : attributes.getBasic() ) {
|
for ( JaxbBasicImpl basic : attributes.getBasicAttributes() ) {
|
||||||
parseBasic( basic );
|
parseBasic( basic );
|
||||||
}
|
}
|
||||||
|
|
||||||
for ( ManyToOne manyToOne : attributes.getManyToOne() ) {
|
for ( JaxbManyToOneImpl manyToOne : attributes.getManyToOneAttributes() ) {
|
||||||
parseManyToOne( manyToOne );
|
parseManyToOne( manyToOne );
|
||||||
}
|
}
|
||||||
|
|
||||||
for ( OneToOne oneToOne : attributes.getOneToOne() ) {
|
for ( JaxbOneToOneImpl oneToOne : attributes.getOneToOneAttributes() ) {
|
||||||
parseOneToOne( oneToOne );
|
parseOneToOne( oneToOne );
|
||||||
}
|
}
|
||||||
|
|
||||||
for ( ManyToMany manyToMany : attributes.getManyToMany() ) {
|
for ( JaxbManyToManyImpl manyToMany : attributes.getManyToManyAttributes() ) {
|
||||||
if ( parseManyToMany( manyToMany ) ) {
|
if ( parseManyToMany( manyToMany ) ) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for ( OneToMany oneToMany : attributes.getOneToMany() ) {
|
for ( JaxbOneToManyImpl oneToMany : attributes.getOneToManyAttributes() ) {
|
||||||
if ( parseOneToMany( oneToMany ) ) {
|
if ( parseOneToMany( oneToMany ) ) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for ( ElementCollection collection : attributes.getElementCollection() ) {
|
for ( JaxbElementCollectionImpl collection : attributes.getElementCollectionAttributes() ) {
|
||||||
if ( parseElementCollection( collection ) ) {
|
if ( parseElementCollection( collection ) ) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for ( Embedded embedded : attributes.getEmbedded() ) {
|
for ( JaxbEmbeddedImpl embedded : attributes.getEmbeddedAttributes() ) {
|
||||||
parseEmbedded( embedded );
|
parseEmbedded( embedded );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseEmbeddableAttributes(@Nullable EmbeddableAttributes attributes) {
|
private void parseEmbeddableAttributes(@Nullable JaxbEmbeddableAttributesContainerImpl attributes) {
|
||||||
if ( attributes == null ) {
|
if ( attributes == null ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for ( Basic basic : attributes.getBasic() ) {
|
for ( JaxbBasicImpl basic : attributes.getBasicAttributes() ) {
|
||||||
parseBasic( basic );
|
parseBasic( basic );
|
||||||
}
|
}
|
||||||
|
|
||||||
for ( ManyToOne manyToOne : attributes.getManyToOne() ) {
|
for ( JaxbManyToOneImpl manyToOne : attributes.getManyToOneAttributes() ) {
|
||||||
parseManyToOne( manyToOne );
|
parseManyToOne( manyToOne );
|
||||||
}
|
}
|
||||||
|
|
||||||
for ( OneToOne oneToOne : attributes.getOneToOne() ) {
|
for ( JaxbOneToOneImpl oneToOne : attributes.getOneToOneAttributes() ) {
|
||||||
parseOneToOne( oneToOne );
|
parseOneToOne( oneToOne );
|
||||||
}
|
}
|
||||||
|
|
||||||
for ( ManyToMany manyToMany : attributes.getManyToMany() ) {
|
for ( JaxbManyToManyImpl manyToMany : attributes.getManyToManyAttributes() ) {
|
||||||
if ( parseManyToMany( manyToMany ) ) {
|
if ( parseManyToMany( manyToMany ) ) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for ( OneToMany oneToMany : attributes.getOneToMany() ) {
|
for ( JaxbOneToManyImpl oneToMany : attributes.getOneToManyAttributes() ) {
|
||||||
if ( parseOneToMany( oneToMany ) ) {
|
if ( parseOneToMany( oneToMany ) ) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for ( ElementCollection collection : attributes.getElementCollection() ) {
|
for ( JaxbElementCollectionImpl collection : attributes.getElementCollectionAttributes() ) {
|
||||||
if ( parseElementCollection( collection ) ) {
|
if ( parseElementCollection( collection ) ) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean parseElementCollection(ElementCollection collection) {
|
private boolean parseElementCollection(JaxbElementCollectionImpl collection) {
|
||||||
@Nullable String @Nullable[] types;
|
@Nullable String @Nullable[] types;
|
||||||
XmlMetaCollection metaCollection;
|
XmlMetaCollection metaCollection;
|
||||||
ElementKind elementKind = getElementKind( collection.getAccess() );
|
ElementKind elementKind = getElementKind( collection.getAccess() );
|
||||||
|
@ -486,7 +516,7 @@ public class XmlMetaEntity implements Metamodel {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseEmbedded(Embedded embedded) {
|
private void parseEmbedded(JaxbEmbeddedImpl embedded) {
|
||||||
XmlMetaSingleAttribute attribute;
|
XmlMetaSingleAttribute attribute;
|
||||||
ElementKind elementKind = getElementKind( embedded.getAccess() );
|
ElementKind elementKind = getElementKind( embedded.getAccess() );
|
||||||
String type = getType( embedded.getName(), null, elementKind );
|
String type = getType( embedded.getName(), null, elementKind );
|
||||||
|
@ -504,7 +534,7 @@ public class XmlMetaEntity implements Metamodel {
|
||||||
return explicitTargetClass;
|
return explicitTargetClass;
|
||||||
}
|
}
|
||||||
|
|
||||||
private @Nullable String determineExplicitMapKeyClass(MapKeyClass mapKeyClass) {
|
private @Nullable String determineExplicitMapKeyClass(JaxbMapKeyClassImpl mapKeyClass) {
|
||||||
String explicitMapKey = null;
|
String explicitMapKey = null;
|
||||||
if ( mapKeyClass != null ) {
|
if ( mapKeyClass != null ) {
|
||||||
explicitMapKey = determineFullyQualifiedClassName( defaultPackageName, mapKeyClass.getClazz() );
|
explicitMapKey = determineFullyQualifiedClassName( defaultPackageName, mapKeyClass.getClazz() );
|
||||||
|
@ -512,7 +542,7 @@ public class XmlMetaEntity implements Metamodel {
|
||||||
return explicitMapKey;
|
return explicitMapKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean parseOneToMany(OneToMany oneToMany) {
|
private boolean parseOneToMany(JaxbOneToManyImpl oneToMany) {
|
||||||
@Nullable String @Nullable [] types;
|
@Nullable String @Nullable [] types;
|
||||||
XmlMetaCollection metaCollection;
|
XmlMetaCollection metaCollection;
|
||||||
ElementKind elementKind = getElementKind( oneToMany.getAccess() );
|
ElementKind elementKind = getElementKind( oneToMany.getAccess() );
|
||||||
|
@ -540,7 +570,7 @@ public class XmlMetaEntity implements Metamodel {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean parseManyToMany(ManyToMany manyToMany) {
|
private boolean parseManyToMany(JaxbManyToManyImpl manyToMany) {
|
||||||
@Nullable String @Nullable [] types;
|
@Nullable String @Nullable [] types;
|
||||||
XmlMetaCollection metaCollection;
|
XmlMetaCollection metaCollection;
|
||||||
ElementKind elementKind = getElementKind( manyToMany.getAccess() );
|
ElementKind elementKind = getElementKind( manyToMany.getAccess() );
|
||||||
|
@ -570,7 +600,7 @@ public class XmlMetaEntity implements Metamodel {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseOneToOne(OneToOne oneToOne) {
|
private void parseOneToOne(JaxbOneToOneImpl oneToOne) {
|
||||||
XmlMetaSingleAttribute attribute;
|
XmlMetaSingleAttribute attribute;
|
||||||
ElementKind elementKind = getElementKind( oneToOne.getAccess() );
|
ElementKind elementKind = getElementKind( oneToOne.getAccess() );
|
||||||
String type = getType( oneToOne.getName(), oneToOne.getTargetEntity(), elementKind );
|
String type = getType( oneToOne.getName(), oneToOne.getTargetEntity(), elementKind );
|
||||||
|
@ -580,7 +610,7 @@ public class XmlMetaEntity implements Metamodel {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseManyToOne(ManyToOne manyToOne) {
|
private void parseManyToOne(JaxbManyToOneImpl manyToOne) {
|
||||||
XmlMetaSingleAttribute attribute;
|
XmlMetaSingleAttribute attribute;
|
||||||
ElementKind elementKind = getElementKind( manyToOne.getAccess() );
|
ElementKind elementKind = getElementKind( manyToOne.getAccess() );
|
||||||
String type = getType( manyToOne.getName(), manyToOne.getTargetEntity(), elementKind );
|
String type = getType( manyToOne.getName(), manyToOne.getTargetEntity(), elementKind );
|
||||||
|
@ -590,7 +620,7 @@ public class XmlMetaEntity implements Metamodel {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseBasic(Basic basic) {
|
private void parseBasic(JaxbBasicImpl basic) {
|
||||||
XmlMetaSingleAttribute attribute;
|
XmlMetaSingleAttribute attribute;
|
||||||
ElementKind elementKind = getElementKind( basic.getAccess() );
|
ElementKind elementKind = getElementKind( basic.getAccess() );
|
||||||
String type = getType( basic.getName(), null, elementKind );
|
String type = getType( basic.getName(), null, elementKind );
|
||||||
|
@ -614,7 +644,7 @@ public class XmlMetaEntity implements Metamodel {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private ElementKind getElementKind(org.hibernate.processor.xml.jaxb.AccessType accessType) {
|
private ElementKind getElementKind(AccessType accessType) {
|
||||||
// if no explicit access type was specified in xml we use the entity access type
|
// if no explicit access type was specified in xml we use the entity access type
|
||||||
if ( accessType == null ) {
|
if ( accessType == null ) {
|
||||||
return getElementKindForAccessType( accessTypeInfo.getAccessType() );
|
return getElementKindForAccessType( accessTypeInfo.getAccessType() );
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -6,9 +6,9 @@
|
||||||
~ See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
~ See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
|
<persistence xmlns="http://www.hibernate.org/xsd/orm/configuration"
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence persistence.xsd" version="2.0">
|
version="3.2">
|
||||||
<persistence-unit name="annotation-processor" transaction-type="JTA">
|
<persistence-unit name="annotation-processor" transaction-type="JTA">
|
||||||
<mapping-file>/org/hibernate/processor/test/xmlonly/xmlonly.xml</mapping-file>
|
<mapping-file>/org/hibernate/processor/test/xmlonly/xmlonly.xml</mapping-file>
|
||||||
</persistence-unit>
|
</persistence-unit>
|
||||||
|
|
Loading…
Reference in New Issue