HHH-6114 Implementing fetch profile parsing and binding as example for other global configurations
This commit is contained in:
parent
e1ba813122
commit
82ae20598b
|
@ -0,0 +1,89 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* Copyright (c) 2011, 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.metamodel.source.annotations.global;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.jboss.jandex.AnnotationInstance;
|
||||||
|
import org.jboss.jandex.Index;
|
||||||
|
|
||||||
|
import org.hibernate.MappingException;
|
||||||
|
import org.hibernate.annotations.FetchMode;
|
||||||
|
import org.hibernate.mapping.FetchProfile;
|
||||||
|
import org.hibernate.mapping.MetadataSource;
|
||||||
|
import org.hibernate.metamodel.source.annotations.HibernateDotNames;
|
||||||
|
import org.hibernate.metamodel.source.internal.MetadataImpl;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Binds fetch profiles found in annotations.
|
||||||
|
*
|
||||||
|
* @author Hardy Ferentschik
|
||||||
|
*/
|
||||||
|
public class FetchProfileBinder {
|
||||||
|
/**
|
||||||
|
* Binds all {@link org.hibernate.annotations.FetchProfiles} and {@link org.hibernate.annotations.FetchProfile} \
|
||||||
|
* annotations to the specified meta data instance.
|
||||||
|
*
|
||||||
|
* @param meta the global metadata
|
||||||
|
* @param index the annotation index repository
|
||||||
|
*/
|
||||||
|
// TODO how to handle fetch profiles defined in hbm and annotations. Which overrides which?
|
||||||
|
// TODO verify that association exists. See former VerifyFetchProfileReferenceSecondPass
|
||||||
|
public static void bindFetchProfiles(MetadataImpl meta, Index index) {
|
||||||
|
// check @FetchProfiles
|
||||||
|
List<AnnotationInstance> fetchProfilesAnnotations = index.getAnnotations( HibernateDotNames.FETCH_PROFILES );
|
||||||
|
for ( AnnotationInstance fetchProfilesAnnotation : fetchProfilesAnnotations ) {
|
||||||
|
AnnotationInstance fetchProfiles[] = fetchProfilesAnnotation.value().asNestedArray();
|
||||||
|
bindFetchProfileAnnotations( meta, Arrays.asList( fetchProfiles ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
// check @FetchProfile
|
||||||
|
List<AnnotationInstance> fetchProfileAnnotations = index.getAnnotations( HibernateDotNames.FETCH_PROFILE );
|
||||||
|
bindFetchProfileAnnotations( meta, fetchProfileAnnotations );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void bindFetchProfileAnnotations(MetadataImpl meta, List<AnnotationInstance> fetchProfileAnnotations) {
|
||||||
|
for ( AnnotationInstance fetchProfileAnnotation : fetchProfileAnnotations ) {
|
||||||
|
String name = fetchProfileAnnotation.value( "name" ).asString();
|
||||||
|
FetchProfile profile = meta.findOrCreateFetchProfile( name, MetadataSource.ANNOTATIONS );
|
||||||
|
|
||||||
|
AnnotationInstance overrides[] = fetchProfileAnnotation.value( "fetchOverrides" ).asNestedArray();
|
||||||
|
for ( AnnotationInstance overrideAnnotation : overrides ) {
|
||||||
|
FetchMode fetchMode = Enum.valueOf( FetchMode.class, overrideAnnotation.value( "mode" ).asEnum() );
|
||||||
|
if ( !fetchMode.equals( org.hibernate.annotations.FetchMode.JOIN ) ) {
|
||||||
|
throw new MappingException( "Only FetchMode.JOIN is currently supported" );
|
||||||
|
}
|
||||||
|
|
||||||
|
String entityClassName = overrideAnnotation.value( "entity" ).asClass().name().toString();
|
||||||
|
String associationName = overrideAnnotation.value( "association" ).asString();
|
||||||
|
profile.addFetch(
|
||||||
|
entityClassName, associationName, fetchMode.toString().toLowerCase()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* Copyright (c) 2011, 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.metamodel.source.annotations.global;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This package contains binders for global configuration annotations, for example {@link javax.persistence.SequenceGenerator},
|
||||||
|
* {@link javax.persistence.TableGenerator} or {@link org.hibernate.annotations.FetchProfile}.
|
||||||
|
* This type of annotations contains global configuration which can be bound w/o information of the mapped entities.
|
||||||
|
*/
|
|
@ -0,0 +1,122 @@
|
||||||
|
package org.hibernate.metamodel.source.annotations.global;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Iterator;
|
||||||
|
|
||||||
|
import org.jboss.jandex.Index;
|
||||||
|
import org.junit.After;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import org.hibernate.MappingException;
|
||||||
|
import org.hibernate.annotations.FetchMode;
|
||||||
|
import org.hibernate.annotations.FetchProfile;
|
||||||
|
import org.hibernate.annotations.FetchProfiles;
|
||||||
|
import org.hibernate.metamodel.source.MetadataSources;
|
||||||
|
import org.hibernate.metamodel.source.annotations.util.JandexHelper;
|
||||||
|
import org.hibernate.metamodel.source.internal.MetadataImpl;
|
||||||
|
import org.hibernate.service.classloading.spi.ClassLoaderService;
|
||||||
|
import org.hibernate.service.internal.BasicServiceRegistryImpl;
|
||||||
|
import org.hibernate.testing.junit4.BaseUnitTestCase;
|
||||||
|
|
||||||
|
import static junit.framework.Assert.fail;
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Hardy Ferentschik
|
||||||
|
*/
|
||||||
|
public class FetchProfileBinderTest extends BaseUnitTestCase {
|
||||||
|
|
||||||
|
private BasicServiceRegistryImpl serviceRegistry;
|
||||||
|
private ClassLoaderService service;
|
||||||
|
private MetadataImpl meta;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
serviceRegistry = new BasicServiceRegistryImpl( Collections.emptyMap() );
|
||||||
|
service = serviceRegistry.getService( ClassLoaderService.class );
|
||||||
|
meta = new MetadataImpl( new MetadataSources( serviceRegistry ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void tearDown() {
|
||||||
|
serviceRegistry.destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSingleFetchProfile() {
|
||||||
|
@FetchProfile(name = "foo", fetchOverrides = {
|
||||||
|
@FetchProfile.FetchOverride(entity = Foo.class, association = "bar", mode = FetchMode.JOIN)
|
||||||
|
})
|
||||||
|
class Foo {
|
||||||
|
}
|
||||||
|
Index index = JandexHelper.indexForClass( service, Foo.class );
|
||||||
|
|
||||||
|
FetchProfileBinder.bindFetchProfiles( meta, index );
|
||||||
|
|
||||||
|
Iterator<org.hibernate.mapping.FetchProfile> mappedFetchProfiles = meta.getFetchProfiles().iterator();
|
||||||
|
assertTrue( mappedFetchProfiles.hasNext() );
|
||||||
|
org.hibernate.mapping.FetchProfile profile = mappedFetchProfiles.next();
|
||||||
|
assertEquals( "Wrong fetch profile name", "foo", profile.getName() );
|
||||||
|
org.hibernate.mapping.FetchProfile.Fetch fetch = profile.getFetches().iterator().next();
|
||||||
|
assertEquals( "Wrong association name", "bar", fetch.getAssociation() );
|
||||||
|
assertEquals( "Wrong association type", Foo.class.getName(), fetch.getEntity() );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFetchProfiles() {
|
||||||
|
Index index = JandexHelper.indexForClass( service, FooBar.class );
|
||||||
|
FetchProfileBinder.bindFetchProfiles( meta, index );
|
||||||
|
|
||||||
|
Iterator<org.hibernate.mapping.FetchProfile> mappedFetchProfiles = meta.getFetchProfiles().iterator();
|
||||||
|
assertTrue( mappedFetchProfiles.hasNext() );
|
||||||
|
org.hibernate.mapping.FetchProfile profile = mappedFetchProfiles.next();
|
||||||
|
assertProfiles( profile );
|
||||||
|
|
||||||
|
assertTrue( mappedFetchProfiles.hasNext() );
|
||||||
|
profile = mappedFetchProfiles.next();
|
||||||
|
assertProfiles( profile );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void assertProfiles(org.hibernate.mapping.FetchProfile profile) {
|
||||||
|
if ( profile.getName().equals( "foobar" ) ) {
|
||||||
|
org.hibernate.mapping.FetchProfile.Fetch fetch = profile.getFetches().iterator().next();
|
||||||
|
assertEquals( "Wrong association name", "foobar", fetch.getAssociation() );
|
||||||
|
assertEquals( "Wrong association type", FooBar.class.getName(), fetch.getEntity() );
|
||||||
|
}
|
||||||
|
else if ( profile.getName().equals( "fubar" ) ) {
|
||||||
|
org.hibernate.mapping.FetchProfile.Fetch fetch = profile.getFetches().iterator().next();
|
||||||
|
assertEquals( "Wrong association name", "fubar", fetch.getAssociation() );
|
||||||
|
assertEquals( "Wrong association type", FooBar.class.getName(), fetch.getEntity() );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
fail( "Wrong fetch name:" + profile.getName() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = MappingException.class)
|
||||||
|
public void testNonJoinFetchThrowsException() {
|
||||||
|
@FetchProfile(name = "foo", fetchOverrides = {
|
||||||
|
@FetchProfile.FetchOverride(entity = Foo.class, association = "bar", mode = FetchMode.SELECT)
|
||||||
|
})
|
||||||
|
class Foo {
|
||||||
|
}
|
||||||
|
Index index = JandexHelper.indexForClass( service, Foo.class );
|
||||||
|
|
||||||
|
FetchProfileBinder.bindFetchProfiles( meta, index );
|
||||||
|
}
|
||||||
|
|
||||||
|
@FetchProfiles( {
|
||||||
|
@FetchProfile(name = "foobar", fetchOverrides = {
|
||||||
|
@FetchProfile.FetchOverride(entity = FooBar.class, association = "foobar", mode = FetchMode.JOIN)
|
||||||
|
}),
|
||||||
|
@FetchProfile(name = "fubar", fetchOverrides = {
|
||||||
|
@FetchProfile.FetchOverride(entity = FooBar.class, association = "fubar", mode = FetchMode.JOIN)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
class FooBar {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue