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