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:
permissions:
contents: read
name: Hibernate ORM
name: ORM
# runs-on: ubuntu-latest
runs-on: [self-hosted, Linux, X64, OCI]
strategy:

View File

@ -119,6 +119,11 @@ xjc {
xjcBindingFile = file( 'src/main/xjb/hbm-mapping-bindings.xjb' )
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 {
xsdFile = file( 'src/main/resources/org/hibernate/xsd/mapping/mapping-3.2.0.xsd' )
xjcBindingFile = file( 'src/main/xjb/mapping-bindings.xjb' )

View File

@ -8,6 +8,8 @@ package org.hibernate.boot;
import java.io.InputStream;
import org.checkerframework.checker.nullness.qual.Nullable;
/**
* 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
*/
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.JAXBException;
import org.checkerframework.checker.nullness.qual.Nullable;
import static org.hibernate.engine.config.spi.StandardConverters.BOOLEAN;
@ -113,7 +114,7 @@ public class MappingBinder extends AbstractBinder<JaxbBindableMappingDescriptor>
public MappingBinder(
ResourceStreamLocator resourceStreamLocator,
Function<String, Object> settingsAccess) {
@Nullable Function<String, Object> settingsAccess) {
super( resourceStreamLocator == null ? MappingBinder.class.getClassLoader()::getResourceAsStream : resourceStreamLocator );
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 org.hibernate.boot.xsd.MappingXsdSupport;
import org.hibernate.boot.xsd.XsdHelper;
/**
* 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() ) ) {
final String specifiedVersion = originalAttribute.getValue();
if ( ! MappingXsdSupport.isValidJpaVersion( specifiedVersion ) ) {
if ( ! XsdHelper.isValidJpaVersion( specifiedVersion ) ) {
throw new BadVersionException( specifiedVersion );
}
@ -156,7 +157,7 @@ public class JpaOrmXmlEventReader extends EventReaderDelegate {
}
private Namespace mapNamespace(Namespace originalNamespace) {
if ( MappingXsdSupport.shouldBeMappedToLatestJpaDescriptor( originalNamespace.getNamespaceURI() ) ) {
if ( XsdHelper.shouldBeMappedToLatestJpaDescriptor( originalNamespace.getNamespaceURI() ) ) {
// this is a namespace "to map" so map it
return xmlEventFactory.createNamespace(
originalNamespace.getPrefix(),

View File

@ -6,19 +6,8 @@
*/
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.MappingXsdSupport;
@ -28,156 +17,11 @@ import org.hibernate.boot.xsd.MappingXsdSupport;
* @author Steve Ebersole
* @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 VERSION_ATTRIBUTE_NAME = "version";
private final XMLEventFactory xmlEventFactory;
public MappingEventReader(XMLEventReader reader, XMLEventFactory xmlEventFactory) {
super( reader );
this.xmlEventFactory = xmlEventFactory;
super( ROOT_ELEMENT_NAME, MappingXsdSupport.latestDescriptor(), reader, 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.
* Custom keys:
* 0: cfgXml
* 1: JPA 1.0
* 2: JPA 2.0
* 3: JPA 2.1
* 4: JPA 2.2 (default)
* 5: Jakarta Persistence 3.0
* 6: Jakarta Persistence 3.1
* 1: configurationXML
* 2: JPA 1.0
* 3: JPA 2.0
* 4: JPA 2.1
* 5: JPA 2.2 (default)
* 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() {
return getJPA31();
@ -64,6 +65,9 @@ public class ConfigXsdSupport {
case "3.1": {
return getJPA31();
}
case "3.2": {
return getJPA32();
}
default: {
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;
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 ) {
XsdDescriptor jpa10 = xsdCache[index];
if ( jpa10 == null ) {
@ -119,7 +139,7 @@ public class ConfigXsdSupport {
}
public static XsdDescriptor getJPA21() {
final int index = 3;
final int index = 4;
synchronized ( xsdCache ) {
XsdDescriptor jpa21 = xsdCache[index];
if ( jpa21 == null ) {
@ -135,7 +155,7 @@ public class ConfigXsdSupport {
}
public static XsdDescriptor getJPA22() {
final int index = 4;
final int index = 5;
synchronized ( xsdCache ) {
XsdDescriptor jpa22 = xsdCache[index];
if ( jpa22 == null ) {
@ -151,7 +171,7 @@ public class ConfigXsdSupport {
}
public static XsdDescriptor getJPA30() {
final int index = 5;
final int index = 6;
synchronized ( xsdCache ) {
XsdDescriptor jpa30 = xsdCache[index];
if ( jpa30 == null ) {
@ -167,7 +187,7 @@ public class ConfigXsdSupport {
}
public static XsdDescriptor getJPA31() {
final int index = 6;
final int index = 7;
synchronized ( xsdCache ) {
XsdDescriptor jpa31 = xsdCache[index];
if ( jpa31 == null ) {
@ -181,5 +201,21 @@ public class ConfigXsdSupport {
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;
}
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) {
switch ( version ) {
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"?>
<!--
Copyright (c) 2008, 2020 Oracle and/or its affiliates. All rights reserved.
This program and the accompanying materials are made available under the
terms of the Eclipse Public License v. 2.0 which is available at
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
-->
~ 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.
-->
<!-- persistence.xml schema -->
<xsd:schema targetNamespace="https://jakarta.ee/xml/ns/persistence"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:persistence="https://jakarta.ee/xml/ns/persistence"
elementFormDefault="qualified"
attributeFormDefault="unqualified"
version="3.0">
<xsd:schema
xmlns="http://www.hibernate.org/xsd/orm/configuration"
xmlns:persistence="http://www.hibernate.org/xsd/orm/configuration"
targetNamespace="http://www.hibernate.org/xsd/orm/configuration"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified"
version="3.2">
<xsd:annotation>
<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.
The file must be named "META-INF/persistence.xml" in the
persistence archive.
Persistence configuration files must indicate
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>
<persistence xmlns="http://www.hibernate.org/xsd/orm/configuration"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
version="3.2">
...
</persistence>
]]></xsd:documentation>
</xsd:annotation>
@ -186,7 +170,7 @@
<!-- **************************************************** -->
<xsd:element name="shared-cache-mode"
type="persistence:persistence-unit-caching-type"
type="persistence:persistence-unit-caching-type"
minOccurs="0">
<xsd:annotation>
<xsd:documentation>
@ -283,7 +267,7 @@
</xsd:element>
</xsd:sequence>
<xsd:attribute name="version" type="persistence:versionType"
fixed="3.0" use="required"/>
fixed="3.1" use="required"/>
</xsd:complexType>
</xsd:element>

View File

@ -1,4 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ 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.
-->
<!-- Jakarta Persistence API object/relational mapping file schema -->
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns="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;
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.envers.Audited;
import org.hibernate.envers.DefaultRevisionEntity;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.metamodel.RuntimeMetamodels;
import org.hibernate.metamodel.model.domain.EntityDomainType;
import org.hibernate.persister.entity.EntityPersister;
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.SessionFactory;
import org.hibernate.testing.orm.junit.SessionFactoryScope;
import org.hibernate.testing.orm.junit.Setting;
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.Matchers.is;
import static org.hamcrest.Matchers.notNullValue;
/**
@ -54,9 +48,6 @@ public class RuntimeModelSmokeTests {
final EntityPersister mappingType = runtimeMetamodels.getMappingMetamodel().findEntityDescriptor( FULL_NAME );
assertThat( mappingType, notNullValue() );
final EntityDomainType<?> jpaType = runtimeMetamodels.getJpaMetamodel().entity( SIMPLE_NAME );
assertThat( jpaType, notNullValue() );
}
@Entity( name = "SimpleEntity" )

View File

@ -30,16 +30,15 @@ dependencyResolutionManagement {
url( rootProject.property( "mavenMirror" ) )
}
mavenCentral()
if (System.getProperty('JPA_PREVIEW') != null) {
// Needed for the RC versions of Jakarta Persistence
maven {
url "https://jakarta.oss.sonatype.org/content/repositories/releases/"
}
// Needed for the SNAPSHOT versions of Jakarta Persistence
maven {
url "https://jakarta.oss.sonatype.org/content/repositories/snapshots/"
}
}
if (System.getProperty('JPA_PREVIEW') != null) { // Needed for the RC versions of Jakarta Persistence
maven {
url "https://jakarta.oss.sonatype.org/content/repositories/releases/"
}
// Needed for the SNAPSHOT versions of Jakarta Persistence
maven {
url "https://jakarta.oss.sonatype.org/content/repositories/snapshots/"
}
}
//Allow loading additional dependencies from a local path;
//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.
* 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'
apply from: rootProject.file( 'gradle/published-java-module.gradle' )
apply plugin: 'version-injection'
ext {
xjcTargetDir = file( "${buildDir}/generated/sources/xjc/main" )
xsdDir = file( "${projectDir}/src/main/xsd" )
java {
sourceCompatibility = jdks.versions.getBaseline( )
targetCompatibility = 17
}
//configurations {
// modelImplementation {
// extendsFrom implementation
// }
// modelAnnotationProcessor {
// extendsFrom annotationProcessor
// }
// testImplementation {
// extendsFrom modelImplementation
// }
//}
sourceSets {
quarkusOrmPanache {
java {
@ -64,10 +72,6 @@ dependencies {
api libs.byteBuddy
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"
quarkusHrPanacheImplementation "io.quarkus:quarkus-hibernate-reactive-panache:3.6.2"
jakartaDataImplementation "jakarta.data:jakarta.data-api:1.0.0"
@ -121,14 +125,14 @@ test.dependsOn quarkusHrPanacheTestTask
test.dependsOn quarkusOrmPanacheTestTask
sourceSets.main {
java.srcDir xjcTargetDir
java.srcDir xjcTargetDir
resources.srcDir xsdDir
}
compileTestJava {
options.compilerArgs += [
"-proc:none",
"-AsuppressJakartaDataMetamodel=true"
options.compilerArgs += [
"-proc:none",
"-AsuppressJakartaDataMetamodel=true"
]
}
@ -193,29 +197,29 @@ else {
task jaxb {
// configure Gradle up-to-date checking
inputs.dir( xsdDir ).withPropertyName("xsdDir" ).withPathSensitivity( PathSensitivity.RELATIVE )
outputs.dir( xjcTargetDir )
outputs.cacheIf { true }
// configure Gradle up-to-date checking
inputs.dir( xsdDir ).withPropertyName("xsdDir" ).withPathSensitivity( PathSensitivity.RELATIVE )
outputs.dir( xjcTargetDir )
outputs.cacheIf { true }
// perform actions
doLast {
xjcTargetDir.mkdirs()
// perform actions
doLast {
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(
destdir: ( xjcTargetDir as File ).absolutePath,
package: 'org.hibernate.processor.xml.jaxb',
extension: 'true'
) {
project.ant.arg line: '-no-header'
project.ant.arg line: '-npa'
schema( dir: xsdDir.path, includes: "*.xsd" )
}
}
ant.xjc(
destdir: ( xjcTargetDir as File ).absolutePath,
package: 'org.hibernate.processor.xml.jaxb',
extension: 'true'
) {
project.ant.arg line: '-no-header'
project.ant.arg line: '-npa'
schema( dir: xsdDir.path, includes: "*.xsd" )
}
}
}
tasks.sourcesJar.dependsOn jaxb
tasks.sourcesJar.dependsOn ':hibernate-core:generateHqlParser'
tasks.sourcesJar.dependsOn ':hibernate-core:generateSqlScriptParser'
tasks.compileJava.dependsOn jaxb

View File

@ -27,10 +27,13 @@ import javax.lang.model.util.Elements;
import javax.lang.model.util.Types;
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.util.AccessType;
import org.hibernate.processor.util.AccessTypeInformation;
import jakarta.persistence.AccessType;
import org.checkerframework.checker.nullness.qual.Nullable;
import static java.lang.Boolean.parseBoolean;
@ -412,7 +415,7 @@ public final class Context {
public void setUsesQuarkusOrm(boolean b) {
usesQuarkusOrm = b;
}
public boolean usesQuarkusOrm() {
return usesQuarkusOrm;
}
@ -420,7 +423,7 @@ public final class Context {
public void setUsesQuarkusReactive(boolean b) {
usesQuarkusReactive = b;
}
public boolean 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.Types;
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.Collection;
import java.util.HashMap;
@ -63,6 +83,8 @@ import java.util.Set;
import java.util.StringTokenizer;
import java.util.regex.Pattern;
import jakarta.persistence.AccessType;
import static java.beans.Introspector.decapitalize;
import static java.lang.Boolean.FALSE;
import static java.util.Collections.emptyList;
@ -154,7 +176,7 @@ public class AnnotationMetaEntity extends AnnotationMeta {
* The field or method call to obtain the session
*/
private String sessionGetter = "entityManager";
private final Map<String,String> memberTypes = new HashMap<>();
/**
@ -580,7 +602,7 @@ public class AnnotationMetaEntity extends AnnotationMeta {
}
return null;
}
private void setupSession() {
if ( element.getTypeParameters().isEmpty() ) {
jakartaDataRepository = hasAnnotation( element, JD_REPOSITORY );
@ -2537,7 +2559,6 @@ public class AnnotationMetaEntity extends AnnotationMeta {
return returnTypeName.equals( UNI_VOID )
|| returnTypeName.equals( UNI_BOOLEAN )
|| returnTypeName.equals( UNI_INTEGER );
}
else {
// non-reactive

View File

@ -10,6 +10,27 @@ package org.hibernate.processor.util;
* @author Hardy Ferentschik
*/
public enum AccessType {
PROPERTY,
FIELD
PROPERTY( jakarta.persistence.AccessType.PROPERTY ),
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;
import jakarta.persistence.AccessType;
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.SimpleTypeVisitor8;
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.HashSet;
import java.util.List;

View File

@ -23,6 +23,10 @@ import javax.xml.stream.XMLStreamException;
import javax.xml.validation.Schema;
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.util.NullnessUtil;
import org.hibernate.processor.xml.jaxb.ObjectFactory;

View File

@ -19,11 +19,31 @@ import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.function.Function;
import javax.lang.model.element.TypeElement;
import javax.lang.model.util.Elements;
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.util.AccessType;
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.PersistenceUnitMetadata;
import jakarta.persistence.AccessType;
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 SERIALIZATION_FILE_NAME = "Hibernate-Static-Metamodel-Generator.tmp";
private static final String PERSISTENCE_SCHEMA = "persistence_3_0.xsd";
private static final String ORM_SCHEMA = "orm_3_1.xsd";
private static final String PERSISTENCE_SCHEMA = "org/hibernate/xsd/cfg/persistence_3_0.xsd";
private final Context context;
private final List<EntityMappings> entityMappings;
private final List<JaxbEntityMappingsImpl> entityMappings;
private final XmlParserHelper xmlParserHelper;
private final ConfigurationBinder configurationBinder;
private final MappingBinder mappingBinder;
public JpaDescriptorParser(Context context) {
this.context = context;
this.entityMappings = new ArrayList<>();
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();
if ( context.doLazyXmlParsing() && mappingFilesUnchanged( mappingFileNames ) ) {
@ -78,22 +105,22 @@ public class JpaDescriptorParser {
determineAnnotationAccessTypes();
}
for ( EntityMappings mappings : entityMappings ) {
for ( JaxbEntityMappingsImpl mappings : entityMappings ) {
String defaultPackageName = mappings.getPackage();
parseEntities( mappings.getEntity(), defaultPackageName );
parseEmbeddable( mappings.getEmbeddable(), defaultPackageName );
parseMappedSuperClass( mappings.getMappedSuperclass(), defaultPackageName );
parseEntities( mappings.getEntities(), defaultPackageName );
parseEmbeddable( mappings.getEmbeddables(), defaultPackageName );
parseMappedSuperClass( mappings.getMappedSuperclasses(), defaultPackageName );
}
}
private Collection<String> determineMappingFileNames() {
Collection<String> mappingFileNames = new ArrayList<>();
Persistence persistence = getPersistence();
JaxbPersistenceImpl persistence = getPersistence();
if ( persistence != null ) {
// get mapping file names from persistence.xml
List<Persistence.PersistenceUnit> persistenceUnits = persistence.getPersistenceUnit();
for ( Persistence.PersistenceUnit unit : persistenceUnits ) {
List<JaxbPersistenceImpl.JaxbPersistenceUnitImpl> persistenceUnits = persistence.getPersistenceUnit();
for ( JaxbPersistenceImpl.JaxbPersistenceUnitImpl unit : persistenceUnits ) {
mappingFileNames.addAll( unit.getMappingFile() );
}
}
@ -107,19 +134,26 @@ public class JpaDescriptorParser {
return mappingFileNames;
}
private @Nullable Persistence getPersistence() {
Persistence persistence = null;
String persistenceXmlLocation = context.getPersistenceXmlLocation();
private @Nullable JaxbPersistenceImpl getPersistence() {
JaxbPersistenceImpl persistence = null;
final String persistenceXmlLocation = context.getPersistenceXmlLocation();
final InputStream stream = xmlParserHelper.getInputStreamForResource( persistenceXmlLocation );
if ( stream == null ) {
return null;
}
try {
Schema schema = xmlParserHelper.getSchema( PERSISTENCE_SCHEMA );
persistence = xmlParserHelper.getJaxbRoot( stream, Persistence.class, schema );
final Binding<JaxbPersistenceImpl> binding = configurationBinder.bind(
stream,
new Origin( SourceType.RESOURCE, persistenceXmlLocation )
);
persistence = binding.getRoot();
}
catch (XmlParsingException e) {
catch (MappingException e) {
throw e;
}
catch (Exception e) {
context.logMessage(
Diagnostic.Kind.WARNING, "Unable to parse persistence.xml: " + e.getMessage()
);
@ -137,26 +171,31 @@ public class JpaDescriptorParser {
}
private void loadEntityMappings(Collection<String> mappingFileNames) {
final ResourceStreamLocatorImpl resourceStreamLocator = new ResourceStreamLocatorImpl( context );
for ( String mappingFile : mappingFileNames ) {
final InputStream stream = xmlParserHelper.getInputStreamForResource( mappingFile );
if ( stream == null ) {
final InputStream inputStream = resourceStreamLocator.locateResourceStream( mappingFile );
if ( inputStream == null ) {
// todo (jpa32) : log
continue;
}
try {
final Schema schema = xmlParserHelper.getSchema( ORM_SCHEMA );
final EntityMappings mapping = xmlParserHelper.getJaxbRoot( stream, EntityMappings.class, schema );
if ( mapping != null ) {
entityMappings.add( mapping );
final Binding<JaxbBindableMappingDescriptor> binding = mappingBinder.bind(
inputStream,
new Origin( SourceType.RESOURCE, mappingFile )
);
if ( binding != null ) {
entityMappings.add( (JaxbEntityMappingsImpl) binding.getRoot() );
}
}
catch (XmlParsingException e) {
catch (Exception e) {
context.logMessage(
Diagnostic.Kind.WARNING, "Unable to parse " + mappingFile + ": " + e.getMessage()
);
}
finally {
try {
stream.close();
inputStream.close();
}
catch (IOException e) {
// eat it
@ -236,8 +275,8 @@ public class JpaDescriptorParser {
return new FileTimeStampChecker();
}
private void parseEntities(Collection<Entity> entities, String defaultPackageName) {
for ( Entity entity : entities ) {
private void parseEntities(List<JaxbEntityImpl> entities, String defaultPackageName) {
for ( JaxbEntityImpl entity : entities ) {
String fqcn = StringUtil.determineFullyQualifiedClassName( defaultPackageName, entity.getClazz() );
if ( !xmlMappedTypeExists( fqcn ) ) {
@ -262,9 +301,9 @@ public class JpaDescriptorParser {
}
private void parseEmbeddable(
Collection<org.hibernate.processor.xml.jaxb.Embeddable> embeddables,
List<JaxbEmbeddableImpl> embeddables,
String defaultPackageName) {
for ( org.hibernate.processor.xml.jaxb.Embeddable embeddable : embeddables ) {
for ( JaxbEmbeddableImpl embeddable : embeddables ) {
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
String pkg = StringUtil.packageNameFromFqcn( fqcn );
@ -289,9 +328,9 @@ public class JpaDescriptorParser {
}
private void parseMappedSuperClass(
Collection<org.hibernate.processor.xml.jaxb.MappedSuperclass> mappedSuperClasses,
List<JaxbMappedSuperclassImpl> mappedSuperClasses,
String defaultPackageName) {
for ( org.hibernate.processor.xml.jaxb.MappedSuperclass mappedSuperClass : mappedSuperClasses ) {
for ( JaxbMappedSuperclassImpl mappedSuperClass : mappedSuperClasses ) {
String fqcn = StringUtil.determineFullyQualifiedClassName(
defaultPackageName, mappedSuperClass.getClazz()
);
@ -306,8 +345,7 @@ public class JpaDescriptorParser {
continue;
}
XmlMetaEntity metaEntity = new XmlMetaEntity(
mappedSuperClass, pkg, getXmlMappedType( fqcn ), context
XmlMetaEntity metaEntity = new XmlMetaEntity( mappedSuperClass, pkg, getXmlMappedType( fqcn ), context
);
if ( context.containsMetaEntity( fqcn ) ) {
@ -330,71 +368,53 @@ public class JpaDescriptorParser {
return utils.getTypeElement( fullyQualifiedClassName );
}
private AccessType determineEntityAccessType(EntityMappings mappings) {
AccessType accessType = context.getPersistenceUnitDefaultAccessType();
final org.hibernate.processor.xml.jaxb.AccessType mappingsAccess = mappings.getAccess();
private AccessType determineEntityAccessType(JaxbEntityMappingsImpl mappings) {
final AccessType contextAccessType = context.getPersistenceUnitDefaultAccessType();
final AccessType mappingsAccess = mappings.getAccess();
if ( mappingsAccess != null ) {
accessType = mapXmlAccessTypeToJpaAccessType( mappingsAccess );
return mappingsAccess;
}
return accessType;
return contextAccessType;
}
private void determineXmlAccessTypes() {
for ( EntityMappings mappings : entityMappings ) {
for ( JaxbEntityMappingsImpl mappings : entityMappings ) {
String fqcn;
String packageName = mappings.getPackage();
AccessType defaultAccessType = determineEntityAccessType( mappings );
for ( Entity entity : mappings.getEntity() ) {
String name = entity.getClazz();
for ( JaxbEntityImpl entity : mappings.getEntities() ) {
final String name = entity.getClazz();
fqcn = StringUtil.determineFullyQualifiedClassName( packageName, name );
AccessType explicitAccessType = null;
org.hibernate.processor.xml.jaxb.AccessType type = entity.getAccess();
if ( type != null ) {
explicitAccessType = mapXmlAccessTypeToJpaAccessType( type );
}
AccessTypeInformation accessInfo = new AccessTypeInformation(
fqcn, explicitAccessType, defaultAccessType
);
final AccessType explicitAccessType = entity.getAccess();
final AccessTypeInformation accessInfo = new AccessTypeInformation( fqcn, explicitAccessType, defaultAccessType );
context.addAccessTypeInformation( fqcn, accessInfo );
}
for ( org.hibernate.processor.xml.jaxb.MappedSuperclass mappedSuperClass : mappings.getMappedSuperclass() ) {
String name = mappedSuperClass.getClazz();
for ( JaxbMappedSuperclassImpl mappedSuperClass : mappings.getMappedSuperclasses() ) {
final String name = mappedSuperClass.getClazz();
fqcn = StringUtil.determineFullyQualifiedClassName( packageName, name );
AccessType explicitAccessType = null;
org.hibernate.processor.xml.jaxb.AccessType type = mappedSuperClass.getAccess();
if ( type != null ) {
explicitAccessType = mapXmlAccessTypeToJpaAccessType( type );
}
AccessTypeInformation accessInfo = new AccessTypeInformation(
fqcn, explicitAccessType, defaultAccessType
);
final AccessType explicitAccessType = mappedSuperClass.getAccess();
final AccessTypeInformation accessInfo = new AccessTypeInformation( fqcn, explicitAccessType, defaultAccessType );
context.addAccessTypeInformation( fqcn, accessInfo );
}
for ( org.hibernate.processor.xml.jaxb.Embeddable embeddable : mappings.getEmbeddable() ) {
String name = embeddable.getClazz();
for ( JaxbEmbeddableImpl embeddable : mappings.getEmbeddables() ) {
final String name = embeddable.getClazz();
fqcn = StringUtil.determineFullyQualifiedClassName( packageName, name );
AccessType explicitAccessType = null;
org.hibernate.processor.xml.jaxb.AccessType type = embeddable.getAccess();
if ( type != null ) {
explicitAccessType = mapXmlAccessTypeToJpaAccessType( type );
}
AccessTypeInformation accessInfo = new AccessTypeInformation(
fqcn, explicitAccessType, defaultAccessType
);
final AccessType explicitAccessType = embeddable.getAccess();
final AccessTypeInformation accessInfo = new AccessTypeInformation( fqcn, explicitAccessType, defaultAccessType );
context.addAccessTypeInformation( fqcn, accessInfo );
}
}
}
private void determineAnnotationAccessTypes() {
for ( EntityMappings mappings : entityMappings ) {
for ( JaxbEntityMappingsImpl mappings : entityMappings ) {
String fqcn;
String packageName = mappings.getPackage();
for ( Entity entity : mappings.getEntity() ) {
for ( JaxbEntityImpl entity : mappings.getEntities() ) {
String name = entity.getClazz();
fqcn = StringUtil.determineFullyQualifiedClassName( packageName, name );
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();
fqcn = StringUtil.determineFullyQualifiedClassName( packageName, name );
TypeElement element = context.getTypeElementForFullyQualifiedName( fqcn );
@ -430,16 +450,16 @@ public class JpaDescriptorParser {
* </ul>
*/
private void determineDefaultAccessTypeAndMetaCompleteness() {
for ( EntityMappings mappings : entityMappings ) {
PersistenceUnitMetadata meta = mappings.getPersistenceUnitMetadata();
for ( JaxbEntityMappingsImpl mappings : entityMappings ) {
JaxbPersistenceUnitMetadataImpl meta = mappings.getPersistenceUnitMetadata();
if ( meta != null ) {
context.mappingDocumentFullyXmlConfigured( meta.getXmlMappingMetadataComplete() != null );
PersistenceUnitDefaults persistenceUnitDefaults = meta.getPersistenceUnitDefaults();
JaxbPersistenceUnitDefaultsImpl persistenceUnitDefaults = meta.getPersistenceUnitDefaults();
if ( persistenceUnitDefaults != null ) {
org.hibernate.processor.xml.jaxb.AccessType xmlAccessType = persistenceUnitDefaults.getAccess();
if ( xmlAccessType != null ) {
context.setPersistenceUnitDefaultAccessType( mapXmlAccessTypeToJpaAccessType( xmlAccessType ) );
final jakarta.persistence.AccessType xmlJpaAccessType = persistenceUnitDefaults.getAccess();
if ( xmlJpaAccessType != null ) {
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.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.ImportContextImpl;
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.OneToOne;
import jakarta.persistence.AccessType;
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 org.hibernate.processor.util.StringUtil.determineFullyQualifiedClassName;
import static org.hibernate.processor.util.TypeUtils.extractClosestRealTypeAsString;
@ -70,8 +100,8 @@ public class XmlMetaEntity implements Metamodel {
private final Context context;
private final boolean isMetaComplete;
private @Nullable Attributes attributes;
private @Nullable EmbeddableAttributes embeddableAttributes;
private @Nullable JaxbAttributesContainerImpl attributes;
private @Nullable JaxbEmbeddableAttributesContainerImpl embeddableAttributes;
private AccessTypeInformation accessTypeInfo;
/**
@ -87,20 +117,20 @@ public class XmlMetaEntity implements Metamodel {
*/
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.attributes = ormEntity.getAttributes();
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 );
// entities can be directly initialised
entity.init();
return entity;
}
XmlMetaEntity(MappedSuperclass mappedSuperclass, String defaultPackageName, TypeElement element, Context context) {
XmlMetaEntity(JaxbMappedSuperclassImpl mappedSuperclass, String defaultPackageName, TypeElement element, Context context) {
this(
mappedSuperclass.getClazz(),
defaultPackageName,
@ -112,7 +142,7 @@ public class XmlMetaEntity implements Metamodel {
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.attributes = null;
this.embeddableAttributes = embeddable.getAttributes();
@ -365,98 +395,98 @@ public class XmlMetaEntity implements Metamodel {
return null;
}
private void parseAttributes(Attributes attributes) {
private void parseAttributes(JaxbAttributesContainerImpl attributes) {
XmlMetaSingleAttribute attribute;
for ( Id id : attributes.getId() ) {
ElementKind elementKind = getElementKind( id.getAccess() );
String type = getType( id.getName(), null, elementKind );
for ( JaxbIdImpl id : attributes.getIdAttributes() ) {
final ElementKind elementKind = getElementKind( id.getAccess() );
final String type = getType( id.getName(), null, elementKind );
if ( type != null ) {
attribute = new XmlMetaSingleAttribute( this, id.getName(), type );
members.add( attribute );
}
}
if ( attributes.getEmbeddedId() != null ) {
EmbeddedId embeddedId = attributes.getEmbeddedId();
ElementKind elementKind = getElementKind( embeddedId.getAccess() );
String type = getType( embeddedId.getName(), null, elementKind );
if ( attributes.getEmbeddedIdAttribute() != null ) {
final JaxbEmbeddedIdImpl embeddedId = attributes.getEmbeddedIdAttribute();
final ElementKind elementKind = getElementKind( embeddedId.getAccess() );
final String type = getType( embeddedId.getName(), null, elementKind );
if ( type != null ) {
attribute = new XmlMetaSingleAttribute( this, embeddedId.getName(), type );
members.add( attribute );
}
}
for ( Basic basic : attributes.getBasic() ) {
for ( JaxbBasicImpl basic : attributes.getBasicAttributes() ) {
parseBasic( basic );
}
for ( ManyToOne manyToOne : attributes.getManyToOne() ) {
for ( JaxbManyToOneImpl manyToOne : attributes.getManyToOneAttributes() ) {
parseManyToOne( manyToOne );
}
for ( OneToOne oneToOne : attributes.getOneToOne() ) {
for ( JaxbOneToOneImpl oneToOne : attributes.getOneToOneAttributes() ) {
parseOneToOne( oneToOne );
}
for ( ManyToMany manyToMany : attributes.getManyToMany() ) {
for ( JaxbManyToManyImpl manyToMany : attributes.getManyToManyAttributes() ) {
if ( parseManyToMany( manyToMany ) ) {
break;
}
}
for ( OneToMany oneToMany : attributes.getOneToMany() ) {
for ( JaxbOneToManyImpl oneToMany : attributes.getOneToManyAttributes() ) {
if ( parseOneToMany( oneToMany ) ) {
break;
}
}
for ( ElementCollection collection : attributes.getElementCollection() ) {
for ( JaxbElementCollectionImpl collection : attributes.getElementCollectionAttributes() ) {
if ( parseElementCollection( collection ) ) {
break;
}
}
for ( Embedded embedded : attributes.getEmbedded() ) {
for ( JaxbEmbeddedImpl embedded : attributes.getEmbeddedAttributes() ) {
parseEmbedded( embedded );
}
}
private void parseEmbeddableAttributes(@Nullable EmbeddableAttributes attributes) {
private void parseEmbeddableAttributes(@Nullable JaxbEmbeddableAttributesContainerImpl attributes) {
if ( attributes == null ) {
return;
}
for ( Basic basic : attributes.getBasic() ) {
for ( JaxbBasicImpl basic : attributes.getBasicAttributes() ) {
parseBasic( basic );
}
for ( ManyToOne manyToOne : attributes.getManyToOne() ) {
for ( JaxbManyToOneImpl manyToOne : attributes.getManyToOneAttributes() ) {
parseManyToOne( manyToOne );
}
for ( OneToOne oneToOne : attributes.getOneToOne() ) {
for ( JaxbOneToOneImpl oneToOne : attributes.getOneToOneAttributes() ) {
parseOneToOne( oneToOne );
}
for ( ManyToMany manyToMany : attributes.getManyToMany() ) {
for ( JaxbManyToManyImpl manyToMany : attributes.getManyToManyAttributes() ) {
if ( parseManyToMany( manyToMany ) ) {
break;
}
}
for ( OneToMany oneToMany : attributes.getOneToMany() ) {
for ( JaxbOneToManyImpl oneToMany : attributes.getOneToManyAttributes() ) {
if ( parseOneToMany( oneToMany ) ) {
break;
}
}
for ( ElementCollection collection : attributes.getElementCollection() ) {
for ( JaxbElementCollectionImpl collection : attributes.getElementCollectionAttributes() ) {
if ( parseElementCollection( collection ) ) {
break;
}
}
}
private boolean parseElementCollection(ElementCollection collection) {
private boolean parseElementCollection(JaxbElementCollectionImpl collection) {
@Nullable String @Nullable[] types;
XmlMetaCollection metaCollection;
ElementKind elementKind = getElementKind( collection.getAccess() );
@ -486,7 +516,7 @@ public class XmlMetaEntity implements Metamodel {
return false;
}
private void parseEmbedded(Embedded embedded) {
private void parseEmbedded(JaxbEmbeddedImpl embedded) {
XmlMetaSingleAttribute attribute;
ElementKind elementKind = getElementKind( embedded.getAccess() );
String type = getType( embedded.getName(), null, elementKind );
@ -504,7 +534,7 @@ public class XmlMetaEntity implements Metamodel {
return explicitTargetClass;
}
private @Nullable String determineExplicitMapKeyClass(MapKeyClass mapKeyClass) {
private @Nullable String determineExplicitMapKeyClass(JaxbMapKeyClassImpl mapKeyClass) {
String explicitMapKey = null;
if ( mapKeyClass != null ) {
explicitMapKey = determineFullyQualifiedClassName( defaultPackageName, mapKeyClass.getClazz() );
@ -512,7 +542,7 @@ public class XmlMetaEntity implements Metamodel {
return explicitMapKey;
}
private boolean parseOneToMany(OneToMany oneToMany) {
private boolean parseOneToMany(JaxbOneToManyImpl oneToMany) {
@Nullable String @Nullable [] types;
XmlMetaCollection metaCollection;
ElementKind elementKind = getElementKind( oneToMany.getAccess() );
@ -540,7 +570,7 @@ public class XmlMetaEntity implements Metamodel {
return false;
}
private boolean parseManyToMany(ManyToMany manyToMany) {
private boolean parseManyToMany(JaxbManyToManyImpl manyToMany) {
@Nullable String @Nullable [] types;
XmlMetaCollection metaCollection;
ElementKind elementKind = getElementKind( manyToMany.getAccess() );
@ -570,7 +600,7 @@ public class XmlMetaEntity implements Metamodel {
return false;
}
private void parseOneToOne(OneToOne oneToOne) {
private void parseOneToOne(JaxbOneToOneImpl oneToOne) {
XmlMetaSingleAttribute attribute;
ElementKind elementKind = getElementKind( oneToOne.getAccess() );
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;
ElementKind elementKind = getElementKind( manyToOne.getAccess() );
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;
ElementKind elementKind = getElementKind( basic.getAccess() );
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 ( accessType == null ) {
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>.
-->
<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"
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">
<mapping-file>/org/hibernate/processor/test/xmlonly/xmlonly.xml</mapping-file>
</persistence-unit>