HHH-8247 Implement XML binding of NamedEntityGraph
This commit is contained in:
parent
19da1ad211
commit
21444339ec
|
@ -25,6 +25,8 @@ package org.hibernate.cfg.annotations;
|
|||
|
||||
import javax.persistence.NamedEntityGraph;
|
||||
|
||||
import org.hibernate.internal.util.StringHelper;
|
||||
|
||||
/**
|
||||
* Models the definition of a {@link NamedEntityGraph} annotation
|
||||
*
|
||||
|
@ -34,15 +36,17 @@ public class NamedEntityGraphDefinition {
|
|||
private final NamedEntityGraph annotation;
|
||||
private final String jpaEntityName;
|
||||
private final String entityName;
|
||||
private final String name;
|
||||
|
||||
public NamedEntityGraphDefinition(NamedEntityGraph annotation, String jpaEntityName, String entityName) {
|
||||
this.annotation = annotation;
|
||||
this.jpaEntityName = jpaEntityName;
|
||||
this.entityName = entityName;
|
||||
this.name = StringHelper.isEmpty( annotation.name() ) ? jpaEntityName : annotation.name();
|
||||
}
|
||||
|
||||
public String getRegisteredName() {
|
||||
return jpaEntityName;
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getJpaEntityName() {
|
||||
|
|
|
@ -88,11 +88,16 @@ import javax.persistence.MapKeyJoinColumns;
|
|||
import javax.persistence.MapKeyTemporal;
|
||||
import javax.persistence.MappedSuperclass;
|
||||
import javax.persistence.MapsId;
|
||||
import javax.persistence.NamedAttributeNode;
|
||||
import javax.persistence.NamedEntityGraph;
|
||||
import javax.persistence.NamedEntityGraphs;
|
||||
import javax.persistence.NamedNativeQueries;
|
||||
import javax.persistence.NamedNativeQuery;
|
||||
import javax.persistence.NamedQueries;
|
||||
import javax.persistence.NamedQuery;
|
||||
import javax.persistence.NamedStoredProcedureQueries;
|
||||
import javax.persistence.NamedStoredProcedureQuery;
|
||||
import javax.persistence.NamedSubgraph;
|
||||
import javax.persistence.OneToMany;
|
||||
import javax.persistence.OneToOne;
|
||||
import javax.persistence.OrderBy;
|
||||
|
@ -179,10 +184,14 @@ public class JPAOverriddenAnnotationReader implements AnnotationReader {
|
|||
annotationToXml.put( DiscriminatorColumn.class, "discriminator-column" );
|
||||
annotationToXml.put( SequenceGenerator.class, "sequence-generator" );
|
||||
annotationToXml.put( TableGenerator.class, "table-generator" );
|
||||
annotationToXml.put( NamedEntityGraph.class, "named-entity-graph" );
|
||||
annotationToXml.put( NamedEntityGraphs.class, "named-entity-graph" );
|
||||
annotationToXml.put( NamedQuery.class, "named-query" );
|
||||
annotationToXml.put( NamedQueries.class, "named-query" );
|
||||
annotationToXml.put( NamedNativeQuery.class, "named-native-query" );
|
||||
annotationToXml.put( NamedNativeQueries.class, "named-native-query" );
|
||||
annotationToXml.put( NamedStoredProcedureQuery.class, "named-stored-procedure-query" );
|
||||
annotationToXml.put( NamedStoredProcedureQueries.class, "named-stored-procedure-query" );
|
||||
annotationToXml.put( SqlResultSetMapping.class, "sql-result-set-mapping" );
|
||||
annotationToXml.put( SqlResultSetMappings.class, "sql-result-set-mapping" );
|
||||
annotationToXml.put( ExcludeDefaultListeners.class, "exclude-default-listeners" );
|
||||
|
@ -360,6 +369,8 @@ public class JPAOverriddenAnnotationReader implements AnnotationReader {
|
|||
addIfNotNull( annotationList, getTableGenerator( tree, defaults ) );
|
||||
addIfNotNull( annotationList, getNamedQueries( tree, defaults ) );
|
||||
addIfNotNull( annotationList, getNamedNativeQueries( tree, defaults ) );
|
||||
addIfNotNull( annotationList, getNamedStoredProcedureQueries( tree, defaults ) );
|
||||
addIfNotNull( annotationList, getNamedEntityGraphs( tree, defaults ) );
|
||||
addIfNotNull( annotationList, getSqlResultSetMappings( tree, defaults ) );
|
||||
addIfNotNull( annotationList, getExcludeDefaultListeners( tree, defaults ) );
|
||||
addIfNotNull( annotationList, getExcludeSuperclassListeners( tree, defaults ) );
|
||||
|
@ -1746,6 +1757,64 @@ public class JPAOverriddenAnnotationReader implements AnnotationReader {
|
|||
}
|
||||
}
|
||||
|
||||
public static List<NamedEntityGraph> buildNamedEntityGraph(Element element, XMLContext.Default defaults) {
|
||||
if ( element == null ) {
|
||||
return new ArrayList<NamedEntityGraph>();
|
||||
}
|
||||
List<NamedEntityGraph> namedEntityGraphList = new ArrayList<NamedEntityGraph>();
|
||||
List<Element> namedEntityGraphElements = element.elements( "named-entity-graph" );
|
||||
for ( Element subElement : namedEntityGraphElements ) {
|
||||
AnnotationDescriptor ann = new AnnotationDescriptor( NamedEntityGraph.class );
|
||||
copyStringAttribute( ann, subElement, "name", false );
|
||||
copyBooleanAttribute( ann, subElement, "include-all-attributes" );
|
||||
bindNamedAttributeNodes( subElement, ann );
|
||||
|
||||
List<Element> subgraphNodes = subElement.elements( "subgraph" );
|
||||
bindNamedSubgraph( defaults, ann, subgraphNodes );
|
||||
List<Element> subclassSubgraphNodes = subElement.elements( "subclass-subgraph" );
|
||||
bindNamedSubgraph( defaults, ann, subclassSubgraphNodes );
|
||||
namedEntityGraphList.add( (NamedEntityGraph) AnnotationFactory.create( ann ) );
|
||||
}
|
||||
//TODO
|
||||
return namedEntityGraphList;
|
||||
}
|
||||
|
||||
private static void bindNamedSubgraph(XMLContext.Default defaults, AnnotationDescriptor ann, List<Element> subgraphNodes) {
|
||||
List<NamedSubgraph> annSubgraphNodes = new ArrayList<NamedSubgraph>( );
|
||||
for(Element subgraphNode : subgraphNodes){
|
||||
AnnotationDescriptor annSubgraphNode = new AnnotationDescriptor( NamedSubgraph.class );
|
||||
copyStringAttribute( annSubgraphNode, subgraphNode, "name", true );
|
||||
String clazzName = subgraphNode.attributeValue( "class" );
|
||||
Class clazz;
|
||||
try {
|
||||
clazz = ReflectHelper.classForName(
|
||||
XMLContext.buildSafeClassName( clazzName, defaults ),
|
||||
JPAOverriddenAnnotationReader.class
|
||||
);
|
||||
}
|
||||
catch ( ClassNotFoundException e ) {
|
||||
throw new AnnotationException( "Unable to find entity-class: " + clazzName, e );
|
||||
}
|
||||
annSubgraphNode.setValue( "type", clazz );
|
||||
bindNamedAttributeNodes(subgraphNode, annSubgraphNode);
|
||||
annSubgraphNodes.add( (NamedSubgraph) AnnotationFactory.create( annSubgraphNode ) );
|
||||
}
|
||||
ann.setValue( "subgraphs", annSubgraphNodes.toArray( new NamedSubgraph[annSubgraphNodes.size()] ) );
|
||||
}
|
||||
|
||||
private static void bindNamedAttributeNodes(Element subElement, AnnotationDescriptor ann) {
|
||||
List<Element> namedAttributeNodes = subElement.elements("named-attribute-node");
|
||||
List<NamedAttributeNode> annNamedAttributeNodes = new ArrayList<NamedAttributeNode>( );
|
||||
for(Element namedAttributeNode : namedAttributeNodes){
|
||||
AnnotationDescriptor annNamedAttributeNode = new AnnotationDescriptor( NamedAttributeNode.class );
|
||||
copyStringAttribute( annNamedAttributeNode, namedAttributeNode, "value", true );
|
||||
copyStringAttribute( annNamedAttributeNode, namedAttributeNode, "subgraph", false );
|
||||
copyStringAttribute( annNamedAttributeNode, namedAttributeNode, "key-subgraph", false );
|
||||
annNamedAttributeNodes.add( (NamedAttributeNode) AnnotationFactory.create( annNamedAttributeNode ) );
|
||||
}
|
||||
ann.setValue( "attributeNodes", annNamedAttributeNodes.toArray( new NamedAttributeNode[annNamedAttributeNodes.size()] ) );
|
||||
}
|
||||
|
||||
public static List<NamedStoredProcedureQuery> buildNamedStoreProcedureQueries(Element element, XMLContext.Default defaults) {
|
||||
if ( element == null ) {
|
||||
return new ArrayList<NamedStoredProcedureQuery>();
|
||||
|
@ -1820,7 +1889,7 @@ public class JPAOverriddenAnnotationReader implements AnnotationReader {
|
|||
buildQueryHints( elements, ann );
|
||||
namedStoredProcedureQueries.add( (NamedStoredProcedureQuery) AnnotationFactory.create( ann ) );
|
||||
}
|
||||
return namedStoredProcedureElements;
|
||||
return namedStoredProcedureQueries;
|
||||
|
||||
}
|
||||
|
||||
|
@ -1953,6 +2022,84 @@ public class JPAOverriddenAnnotationReader implements AnnotationReader {
|
|||
}
|
||||
}
|
||||
|
||||
private NamedEntityGraphs getNamedEntityGraphs(Element tree, XMLContext.Default defaults) {
|
||||
List<NamedEntityGraph> queries = buildNamedEntityGraph( tree, defaults );
|
||||
if ( defaults.canUseJavaAnnotations() ) {
|
||||
NamedEntityGraph annotation = getJavaAnnotation( NamedEntityGraph.class );
|
||||
addNamedEntityGraphIfNeeded( annotation, queries );
|
||||
NamedEntityGraphs annotations = getJavaAnnotation( NamedEntityGraphs.class );
|
||||
if ( annotations != null ) {
|
||||
for ( NamedEntityGraph current : annotations.value() ) {
|
||||
addNamedEntityGraphIfNeeded( current, queries );
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( queries.size() > 0 ) {
|
||||
AnnotationDescriptor ad = new AnnotationDescriptor( NamedEntityGraphs.class );
|
||||
ad.setValue( "value", queries.toArray( new NamedEntityGraph[queries.size()] ) );
|
||||
return AnnotationFactory.create( ad );
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private void addNamedEntityGraphIfNeeded(NamedEntityGraph annotation, List<NamedEntityGraph> queries) {
|
||||
if ( annotation != null ) {
|
||||
String queryName = annotation.name();
|
||||
boolean present = false;
|
||||
for ( NamedEntityGraph current : queries ) {
|
||||
if ( current.name().equals( queryName ) ) {
|
||||
present = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( !present ) {
|
||||
queries.add( annotation );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private NamedStoredProcedureQueries getNamedStoredProcedureQueries(Element tree, XMLContext.Default defaults) {
|
||||
List<NamedStoredProcedureQuery> queries = buildNamedStoreProcedureQueries( tree, defaults );
|
||||
if ( defaults.canUseJavaAnnotations() ) {
|
||||
NamedStoredProcedureQuery annotation = getJavaAnnotation( NamedStoredProcedureQuery.class );
|
||||
addNamedStoredProcedureQueryIfNeeded( annotation, queries );
|
||||
NamedStoredProcedureQueries annotations = getJavaAnnotation( NamedStoredProcedureQueries.class );
|
||||
if ( annotations != null ) {
|
||||
for ( NamedStoredProcedureQuery current : annotations.value() ) {
|
||||
addNamedStoredProcedureQueryIfNeeded( current, queries );
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( queries.size() > 0 ) {
|
||||
AnnotationDescriptor ad = new AnnotationDescriptor( NamedStoredProcedureQueries.class );
|
||||
ad.setValue( "value", queries.toArray( new NamedStoredProcedureQuery[queries.size()] ) );
|
||||
return AnnotationFactory.create( ad );
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private void addNamedStoredProcedureQueryIfNeeded(NamedStoredProcedureQuery annotation, List<NamedStoredProcedureQuery> queries) {
|
||||
if ( annotation != null ) {
|
||||
String queryName = annotation.name();
|
||||
boolean present = false;
|
||||
for ( NamedStoredProcedureQuery current : queries ) {
|
||||
if ( current.name().equals( queryName ) ) {
|
||||
present = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( !present ) {
|
||||
queries.add( annotation );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private NamedNativeQueries getNamedNativeQueries(Element tree, XMLContext.Default defaults) {
|
||||
List<NamedNativeQuery> queries = (List<NamedNativeQuery>) buildNamedQueries( tree, true, defaults );
|
||||
if ( defaults.canUseJavaAnnotations() ) {
|
||||
|
|
|
@ -34,12 +34,7 @@ import static junit.framework.Assert.assertNotNull;
|
|||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class BasicNamedEntityGraphTest extends BaseEntityManagerFunctionalTestCase {
|
||||
@Override
|
||||
protected Class<?>[] getAnnotatedClasses() {
|
||||
return new Class[] { Person.class };
|
||||
}
|
||||
|
||||
public abstract class AbstractNamedEntityGraphTest extends BaseEntityManagerFunctionalTestCase {
|
||||
@Test
|
||||
public void testIt() {
|
||||
EntityGraph graph = getOrCreateEntityManager().getEntityGraph( "Person" );
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2013, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.jpa.test.graphs.named.basic;
|
||||
|
||||
/**
|
||||
* @author Strong Liu <stliu@hibernate.org>
|
||||
*/
|
||||
public class BasicAnnNamedEntityGraphTest extends AbstractNamedEntityGraphTest{
|
||||
@Override
|
||||
protected Class<?>[] getAnnotatedClasses() {
|
||||
return new Class[] { Person.class };
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2013, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.jpa.test.graphs.named.basic;
|
||||
|
||||
/**
|
||||
* @author Strong Liu <stliu@hibernate.org>
|
||||
*/
|
||||
public class BasicOrmNamedEntityGraphTest extends AbstractNamedEntityGraphTest{
|
||||
@Override
|
||||
public String[] getEjb3DD() {
|
||||
return new String[]{"org/hibernate/jpa/test/graphs/named/basic/orm.xml"};
|
||||
}
|
||||
}
|
|
@ -31,8 +31,8 @@ import javax.persistence.NamedEntityGraph;
|
|||
* @author Steve Ebersole
|
||||
*/
|
||||
@Entity(name = "Person")
|
||||
@NamedEntityGraph()
|
||||
@NamedEntityGraph
|
||||
public class Person {
|
||||
@Id
|
||||
private Long id;
|
||||
public Long id;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<entity-mappings xmlns="http://xmlns.jcp.org/xml/ns/persistence/orm"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
version="2.1"
|
||||
>
|
||||
<package>org.hibernate.jpa.test.graphs.named.basic</package>
|
||||
<entity class="Person" metadata-complete="true" access="FIELD">
|
||||
<named-entity-graph/>
|
||||
<attributes>
|
||||
<id name="id">
|
||||
<column name="fld_id"/>
|
||||
</id>
|
||||
</attributes>
|
||||
</entity>
|
||||
</entity-mappings>
|
Loading…
Reference in New Issue