HHH-17377 - Migrate to JPA 3.2

https://hibernate.atlassian.net/browse/HHH-17377

jpamodelgen
This commit is contained in:
Steve Ebersole 2023-11-07 11:38:20 -06:00
parent 5781bdd30f
commit f8865106c1
29 changed files with 697 additions and 2751 deletions

View File

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

View File

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

View File

@ -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);
} }

View File

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

View File

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

View File

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

View File

@ -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
);
}
}

View File

@ -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(),

View File

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

View File

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

View File

@ -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": {

View File

@ -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 );
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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() );
}
} }

View File

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

View File

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

View File

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

View File

@ -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 );
}
} }

View File

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

View File

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