HHH-6132 @FetchProfiles should throw MappingException when invalid

entity or association used
This commit is contained in:
Brett Meyer 2014-03-25 14:12:07 -04:00
parent b6795294e6
commit 519acb2749
6 changed files with 132 additions and 81 deletions

View File

@ -34,9 +34,10 @@ import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
import org.hibernate.metamodel.source.internal.annotations.AnnotationBindingContext;
import org.hibernate.metamodel.source.internal.annotations.util.HibernateDotNames;
import org.hibernate.metamodel.source.internal.annotations.util.JandexHelper;
import org.hibernate.metamodel.spi.binding.EntityBinding;
import org.hibernate.metamodel.spi.binding.FetchProfile;
import org.hibernate.metamodel.spi.binding.FetchProfile.Fetch;
import org.hibernate.metamodel.spi.domain.Attribute;
import org.jboss.jandex.AnnotationInstance;
/**
@ -54,7 +55,6 @@ public class FetchProfileProcessor {
*
* @param bindingContext the context for annotation binding
*/
// TODO verify that association exists. See former VerifyFetchProfileReferenceSecondPass
public static void bind(AnnotationBindingContext bindingContext) {
Collection<AnnotationInstance> annotations = bindingContext.getJandexAccess()
@ -93,8 +93,19 @@ public class FetchProfileProcessor {
if ( !fetchMode.equals( org.hibernate.annotations.FetchMode.JOIN ) ) {
throw new MappingException( "Only FetchMode.JOIN is currently supported" );
}
final String entityName = JandexHelper.getValue( override, "entity", String.class, classLoaderService );
final String associationName = JandexHelper.getValue( override, "association", String.class, classLoaderService );
EntityBinding entityBinding = bindingContext.getMetadataCollector().getEntityBinding( entityName );
if ( entityBinding == null ) {
throw new MappingException( "FetchProfile " + name + " references an unknown entity: " + entityName );
}
Attribute attributeBinding = entityBinding.getAttributeContainer().locateAttribute( associationName );
if ( attributeBinding == null ) {
throw new MappingException( "FetchProfile " + name + " references an unknown association: " + associationName );
}
fetches.add( new Fetch( entityName, associationName, fetchMode.toString().toLowerCase() ) );
}
bindingContext.getMetadataCollector().addFetchProfile( new FetchProfile( name, fetches ) );

View File

@ -23,10 +23,24 @@
*/
package org.hibernate.metamodel.internal.source;
import java.util.List;
import javax.persistence.ElementCollection;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
/**
* @author Hardy Ferentschik
*/
@Entity
public class Foo {
@Id
@GeneratedValue
public long id;
@ElementCollection
public List<String> bars;
}

View File

@ -65,6 +65,7 @@ public class MetadataImplTest extends BaseUnitTestCase {
public void testAddingPackageName() {
MetadataSources sources = new MetadataSources( new StandardServiceRegistryBuilder().build() );
sources.addPackage( "org.hibernate.metamodel.internal.source" );
sources.addAnnotatedClass( Foo.class );
MetadataImpl metadata = (MetadataImpl) sources.buildMetadata();
assertFetchProfile( metadata );
@ -74,6 +75,7 @@ public class MetadataImplTest extends BaseUnitTestCase {
public void testAddingPackageNameWithTrailingDot() {
MetadataSources sources = new MetadataSources( new StandardServiceRegistryBuilder().build() );
sources.addPackage( "org.hibernate.metamodel.internal.source." );
sources.addAnnotatedClass( Foo.class );
MetadataImpl metadata = (MetadataImpl) sources.buildMetadata();
assertFetchProfile( metadata );

View File

@ -24,6 +24,12 @@
package org.hibernate.metamodel.internal.source.annotations.global;
import java.util.Iterator;
import java.util.List;
import javax.persistence.ElementCollection;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import org.hibernate.MappingException;
import org.hibernate.annotations.FetchMode;
@ -33,7 +39,6 @@ import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.boot.registry.internal.StandardServiceRegistryImpl;
import org.hibernate.metamodel.Metadata;
import org.hibernate.metamodel.MetadataSources;
import org.hibernate.testing.junit4.BaseUnitTestCase;
import org.junit.After;
import org.junit.Before;
@ -62,9 +67,16 @@ public class FetchProfileBinderTest extends BaseUnitTestCase {
@Test
public void testSingleFetchProfile() {
@FetchProfile(name = "foo", fetchOverrides = {
@FetchProfile.FetchOverride(entity = Foo.class, association = "bar", mode = FetchMode.JOIN)
@FetchProfile.FetchOverride(entity = Foo.class, association = "bars", mode = FetchMode.JOIN)
})
@Entity
class Foo {
@Id
@GeneratedValue
public long id;
@ElementCollection
public List<String> bars;
}
Metadata meta = new MetadataSources( serviceRegistry ).addAnnotatedClass( Foo.class ).buildMetadata();
@ -74,7 +86,7 @@ public class FetchProfileBinderTest extends BaseUnitTestCase {
org.hibernate.metamodel.spi.binding.FetchProfile profile = mappedFetchProfiles.next();
assertEquals( "Wrong fetch profile name", "foo", profile.getName() );
org.hibernate.metamodel.spi.binding.FetchProfile.Fetch fetch = profile.getFetches().iterator().next();
assertEquals( "Wrong association name", "bar", fetch.getAssociation() );
assertEquals( "Wrong association name", "bars", fetch.getAssociation() );
assertEquals( "Wrong association type", Foo.class.getName(), fetch.getEntity() );
}
@ -95,12 +107,12 @@ public class FetchProfileBinderTest extends BaseUnitTestCase {
private void assertProfiles(org.hibernate.metamodel.spi.binding.FetchProfile profile) {
if ( profile.getName().equals( "foobar" ) ) {
org.hibernate.metamodel.spi.binding.FetchProfile.Fetch fetch = profile.getFetches().iterator().next();
assertEquals( "Wrong association name", "foobar", fetch.getAssociation() );
assertEquals( "Wrong association name", "fubars", fetch.getAssociation() );
assertEquals( "Wrong association type", FooBar.class.getName(), fetch.getEntity() );
}
else if ( profile.getName().equals( "fubar" ) ) {
org.hibernate.metamodel.spi.binding.FetchProfile.Fetch fetch = profile.getFetches().iterator().next();
assertEquals( "Wrong association name", "fubar", fetch.getAssociation() );
assertEquals( "Wrong association name", "fubars", fetch.getAssociation() );
assertEquals( "Wrong association type", FooBar.class.getName(), fetch.getEntity() );
}
else {
@ -111,9 +123,16 @@ public class FetchProfileBinderTest extends BaseUnitTestCase {
@Test(expected = MappingException.class)
public void testNonJoinFetchThrowsException() {
@FetchProfile(name = "foo", fetchOverrides = {
@FetchProfile.FetchOverride(entity = Foo.class, association = "bar", mode = FetchMode.SELECT)
@FetchProfile.FetchOverride(entity = Foo.class, association = "bars", mode = FetchMode.SELECT)
})
@Entity
class Foo {
@Id
@GeneratedValue
public long id;
@ElementCollection
public List<String> bars;
}
new MetadataSources( serviceRegistry ).addAnnotatedClass( Foo.class ).buildMetadata();
@ -121,13 +140,20 @@ public class FetchProfileBinderTest extends BaseUnitTestCase {
@FetchProfiles( {
@FetchProfile(name = "foobar", fetchOverrides = {
@FetchProfile.FetchOverride(entity = FooBar.class, association = "foobar", mode = FetchMode.JOIN)
@FetchProfile.FetchOverride(entity = FooBar.class, association = "fubars", mode = FetchMode.JOIN)
}),
@FetchProfile(name = "fubar", fetchOverrides = {
@FetchProfile.FetchOverride(entity = FooBar.class, association = "fubar", mode = FetchMode.JOIN)
@FetchProfile.FetchOverride(entity = FooBar.class, association = "fubars", mode = FetchMode.JOIN)
})
})
@Entity
class FooBar {
@Id
@GeneratedValue
public long id;
@ElementCollection
public List<String> fubars;
}
}

View File

@ -22,7 +22,7 @@
* Boston, MA 02110-1301 USA
*/
@FetchProfile(name = "package-configured-profile", fetchOverrides = {
@FetchProfile.FetchOverride(entity = Foo.class, association = "bar", mode = FetchMode.JOIN)
@FetchProfile.FetchOverride(entity = Foo.class, association = "bars", mode = FetchMode.JOIN)
})
package org.hibernate.metamodel.internal.source;

View File

@ -23,28 +23,28 @@
*/
package org.hibernate.test.annotations.fetchprofile;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.io.InputStream;
import org.hibernate.MappingException;
import org.hibernate.boot.registry.BootstrapServiceRegistry;
import org.hibernate.boot.registry.BootstrapServiceRegistryBuilder;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.metamodel.MetadataSources;
import org.hibernate.service.spi.ServiceRegistryImplementor;
import org.hibernate.testing.FailureExpectedWithNewMetamodel;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.junit4.BaseUnitTestCase;
import org.jboss.logging.Logger;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.hibernate.MappingException;
import org.hibernate.cfg.Configuration;
import org.hibernate.cfg.Environment;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.testing.FailureExpectedWithNewMetamodel;
import org.hibernate.testing.ServiceRegistryBuilder;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.junit4.BaseUnitTestCase;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
/**
* Test case for HHH-4812
*
@ -54,28 +54,31 @@ import static org.junit.Assert.fail;
public class FetchProfileTest extends BaseUnitTestCase {
private static final Logger log = Logger.getLogger( FetchProfileTest.class );
private ServiceRegistry serviceRegistry;
private BootstrapServiceRegistry bootstrapServiceRegistry;
private StandardServiceRegistry serviceRegistry;
@Before
public void setUp() {
serviceRegistry = ServiceRegistryBuilder.buildServiceRegistry( Environment.getProperties() );
public void setUp() {
bootstrapServiceRegistry = new BootstrapServiceRegistryBuilder().build();
serviceRegistry = new StandardServiceRegistryBuilder( bootstrapServiceRegistry ).build();
}
@After
public void tearDown() {
if (serviceRegistry != null) ServiceRegistryBuilder.destroy(serviceRegistry);
public void tearDown() {
( (ServiceRegistryImplementor) serviceRegistry ).destroy();
( (ServiceRegistryImplementor) bootstrapServiceRegistry ).destroy();
}
@Test
public void testFetchProfileConfigured() {
Configuration config = new Configuration();
config.addAnnotatedClass( Customer.class );
config.addAnnotatedClass( Order.class );
config.addAnnotatedClass( SupportTickets.class );
config.addAnnotatedClass( Country.class );
SessionFactoryImplementor sessionImpl = ( SessionFactoryImplementor ) config.buildSessionFactory(
serviceRegistry
);
MetadataSources metadataSources = new MetadataSources( bootstrapServiceRegistry );
metadataSources.addAnnotatedClass( Customer.class );
metadataSources.addAnnotatedClass( Order.class );
metadataSources.addAnnotatedClass( SupportTickets.class );
metadataSources.addAnnotatedClass( Country.class );
SessionFactoryImplementor sessionImpl = ( SessionFactoryImplementor ) metadataSources
.getMetadataBuilder( serviceRegistry ).build().buildSessionFactory();
assertTrue(
"fetch profile not parsed properly",
@ -89,15 +92,14 @@ public class FetchProfileTest extends BaseUnitTestCase {
}
@Test
@FailureExpectedWithNewMetamodel
public void testWrongAssociationName() {
Configuration config = new Configuration();
config.addAnnotatedClass( Customer2.class );
config.addAnnotatedClass( Order.class );
config.addAnnotatedClass( Country.class );
MetadataSources metadataSources = new MetadataSources( bootstrapServiceRegistry );
metadataSources.addAnnotatedClass( Customer2.class );
metadataSources.addAnnotatedClass( Order.class );
metadataSources.addAnnotatedClass( Country.class );
try {
config.buildMappings();
metadataSources.buildMetadata();
fail();
}
catch ( MappingException e ) {
@ -106,15 +108,14 @@ public class FetchProfileTest extends BaseUnitTestCase {
}
@Test
@FailureExpectedWithNewMetamodel
public void testWrongClass() {
Configuration config = new Configuration();
config.addAnnotatedClass( Customer3.class );
config.addAnnotatedClass( Order.class );
config.addAnnotatedClass( Country.class );
MetadataSources metadataSources = new MetadataSources( bootstrapServiceRegistry );
metadataSources.addAnnotatedClass( Customer3.class );
metadataSources.addAnnotatedClass( Order.class );
metadataSources.addAnnotatedClass( Country.class );
try {
config.buildMappings();
metadataSources.buildMetadata();
fail();
}
catch ( MappingException e ) {
@ -123,15 +124,14 @@ public class FetchProfileTest extends BaseUnitTestCase {
}
@Test
@FailureExpectedWithNewMetamodel
public void testUnsupportedFetchMode() {
Configuration config = new Configuration();
config.addAnnotatedClass( Customer4.class );
config.addAnnotatedClass( Order.class );
config.addAnnotatedClass( Country.class );
MetadataSources metadataSources = new MetadataSources( bootstrapServiceRegistry );
metadataSources.addAnnotatedClass( Customer4.class );
metadataSources.addAnnotatedClass( Order.class );
metadataSources.addAnnotatedClass( Country.class );
try {
config.buildMappings();
metadataSources.buildMetadata();
fail();
}
catch ( MappingException e ) {
@ -142,17 +142,16 @@ public class FetchProfileTest extends BaseUnitTestCase {
@Test
@FailureExpectedWithNewMetamodel
public void testXmlOverride() {
Configuration config = new Configuration();
config.addAnnotatedClass( Customer5.class );
config.addAnnotatedClass( Order.class );
config.addAnnotatedClass( Country.class );
MetadataSources metadataSources = new MetadataSources( bootstrapServiceRegistry );
metadataSources.addAnnotatedClass( Customer5.class );
metadataSources.addAnnotatedClass( Order.class );
metadataSources.addAnnotatedClass( Country.class );
InputStream is = Thread.currentThread()
.getContextClassLoader()
.getResourceAsStream( "org/hibernate/test/annotations/fetchprofile/mappings.hbm.xml" );
config.addInputStream( is );
SessionFactoryImplementor sessionImpl = ( SessionFactoryImplementor ) config.buildSessionFactory(
serviceRegistry
);
metadataSources.addInputStream( is );
SessionFactoryImplementor sessionImpl = ( SessionFactoryImplementor ) metadataSources
.getMetadataBuilder( serviceRegistry ).build().buildSessionFactory();
assertTrue(
"fetch profile not parsed properly",
@ -161,12 +160,12 @@ public class FetchProfileTest extends BaseUnitTestCase {
sessionImpl.close();
// now the same with no xml
config = new Configuration();
config.addAnnotatedClass( Customer5.class );
config.addAnnotatedClass( Order.class );
config.addAnnotatedClass( Country.class );
metadataSources = new MetadataSources( bootstrapServiceRegistry );
metadataSources.addAnnotatedClass( Customer5.class );
metadataSources.addAnnotatedClass( Order.class );
metadataSources.addAnnotatedClass( Country.class );
try {
config.buildMappings();
metadataSources.buildMetadata();
fail();
}
catch ( MappingException e ) {
@ -176,15 +175,14 @@ public class FetchProfileTest extends BaseUnitTestCase {
@Test
public void testPackageConfiguredFetchProfile() {
Configuration config = new Configuration();
config.addAnnotatedClass( Customer.class );
config.addAnnotatedClass( Order.class );
config.addAnnotatedClass( SupportTickets.class );
config.addAnnotatedClass( Country.class );
config.addPackage( Customer.class.getPackage().getName() );
SessionFactoryImplementor sessionImpl = ( SessionFactoryImplementor ) config.buildSessionFactory(
serviceRegistry
);
MetadataSources metadataSources = new MetadataSources( bootstrapServiceRegistry );
metadataSources.addAnnotatedClass( Customer.class );
metadataSources.addAnnotatedClass( Order.class );
metadataSources.addAnnotatedClass( SupportTickets.class );
metadataSources.addAnnotatedClass( Country.class );
metadataSources.addPackage( Customer.class.getPackage().getName() );
SessionFactoryImplementor sessionImpl = ( SessionFactoryImplementor ) metadataSources
.getMetadataBuilder( serviceRegistry ).build().buildSessionFactory();
assertTrue(
"fetch profile not parsed properly",