HHH-5832 : JPA Query and IdClass Causing NullPointerException

This commit is contained in:
Gail Badner 2011-09-27 23:02:57 -07:00
parent e14e47968f
commit 3c4ed4fe6b
12 changed files with 651 additions and 26 deletions

View File

@ -23,6 +23,7 @@
*/
package org.hibernate.ejb.metamodel;
import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.metamodel.Attribute;
import javax.persistence.metamodel.IdentifiableType;
@ -68,6 +69,17 @@ public abstract class AbstractIdentifiableType<X>
return ( AbstractIdentifiableType<? super X> ) super.getSupertype();
}
/**
* Indicates if a non-null super type is required to provide the
* identifier attribute(s) if this object does not have a declared
* identifier.
* .
* @return true, if a non-null super type is required to provide
* the identifier attribute(s) if this object does not have a
* declared identifier; false, otherwise.
*/
protected abstract boolean requiresSupertypeForNonDeclaredIdentifier();
protected AbstractIdentifiableType<? super X> requireSupertype() {
if ( getSupertype() == null ) {
throw new IllegalStateException( "No supertype found" );
@ -97,7 +109,7 @@ public abstract class AbstractIdentifiableType<X>
}
else {
//yuk yuk bad me
if (this instanceof MappedSuperclassTypeImpl) {
if ( ! requiresSupertypeForNonDeclaredIdentifier()) {
final AbstractIdentifiableType<? super X> supertype = getSupertype();
if (supertype != null) {
id_ = supertype.getId( javaType );
@ -162,11 +174,33 @@ public abstract class AbstractIdentifiableType<X>
}
}
private boolean hasIdClassAttributesDefined() {
return idClassAttributes != null ||
( getSupertype() != null && getSupertype().hasIdClassAttributesDefined() );
}
/**
* {@inheritDoc}
*/
public Set<SingularAttribute<? super X, ?>> getIdClassAttributes() {
checkIdClass();
if ( idClassAttributes != null ) {
checkIdClass();
}
else {
// Java does not allow casting requireSupertype().getIdClassAttributes()
// to Set<SingularAttribute<? super X, ?>> because the
// superclass X is a different Java type from this X
// (i.e, getSupertype().getJavaType() != getJavaType()).
// It will, however, allow a Set<SingularAttribute<? super X, ?>>
// to be initialized with requireSupertype().getIdClassAttributes(),
// since getSupertype().getJavaType() is a superclass of getJavaType()
if ( requiresSupertypeForNonDeclaredIdentifier() ) {
idClassAttributes = new HashSet<SingularAttribute<? super X, ?>>( requireSupertype().getIdClassAttributes() );
}
else if ( getSupertype() != null && hasIdClassAttributesDefined() ) {
idClassAttributes = new HashSet<SingularAttribute<? super X, ?>>( getSupertype().getIdClassAttributes() );
}
}
return idClassAttributes;
}
@ -254,6 +288,13 @@ public abstract class AbstractIdentifiableType<X>
}
public void applyIdClassAttributes(Set<SingularAttribute<? super X,?>> idClassAttributes) {
for ( SingularAttribute<? super X,?> idClassAttribute : idClassAttributes ) {
if ( AbstractIdentifiableType.this == idClassAttribute.getDeclaringType() ) {
@SuppressWarnings({ "unchecked" })
SingularAttribute<X,?> declaredAttribute = ( SingularAttribute<X,?> ) idClassAttribute;
addAttribute( declaredAttribute );
}
}
AbstractIdentifiableType.this.idClassAttributes = idClassAttributes;
}

View File

@ -59,4 +59,9 @@ public class EntityTypeImpl<X>
public PersistenceType getPersistenceType() {
return PersistenceType.ENTITY;
}
@Override
protected boolean requiresSupertypeForNonDeclaredIdentifier() {
return true;
}
}

View File

@ -16,4 +16,9 @@ public class MappedSuperclassTypeImpl<X> extends AbstractIdentifiableType<X> imp
public PersistenceType getPersistenceType() {
return PersistenceType.MAPPED_SUPERCLASS;
}
@Override
protected boolean requiresSupertypeForNonDeclaredIdentifier() {
return false;
}
}

View File

@ -244,7 +244,10 @@ class MetadataContext {
}
}
else if ( persistentClass.hasIdentifierMapper() ) {
jpaEntityType.getBuilder().applyIdClassAttributes( buildIdClassAttributes( jpaEntityType, persistentClass ) );
@SuppressWarnings( "unchecked")
Iterator<Property> propertyIterator = persistentClass.getIdentifierMapper().getPropertyIterator();
Set<SingularAttribute<? super X, ?>> attributes = buildIdClassAttributes( jpaEntityType, propertyIterator );
jpaEntityType.getBuilder().applyIdClassAttributes( attributes );
}
else {
final KeyValue value = persistentClass.getIdentifier();
@ -276,9 +279,9 @@ class MetadataContext {
}
//an MappedSuperclass can have no identifier if the id is set below in the hierarchy
else if ( mappingType.getIdentifierMapper() != null ){
final Set<SingularAttribute<? super X, ?>> attributes = buildIdClassAttributes(
jpaMappingType, mappingType
);
@SuppressWarnings( "unchecked")
Iterator<Property> propertyIterator = mappingType.getIdentifierMapper().getPropertyIterator();
Set<SingularAttribute<? super X, ?>> attributes = buildIdClassAttributes( jpaMappingType, propertyIterator );
jpaMappingType.getBuilder().applyIdClassAttributes( attributes );
}
}
@ -302,26 +305,12 @@ class MetadataContext {
}
private <X> Set<SingularAttribute<? super X, ?>> buildIdClassAttributes(
EntityTypeImpl<X> jpaEntityType,
PersistentClass persistentClass) {
Set<SingularAttribute<? super X, ?>> attributes = new HashSet<SingularAttribute<? super X, ?>>();
@SuppressWarnings( "unchecked")
Iterator<Property> properties = persistentClass.getIdentifierMapper().getPropertyIterator();
while ( properties.hasNext() ) {
attributes.add( attributeFactory.buildIdAttribute( jpaEntityType, properties.next() ) );
}
return attributes;
}
private <X> Set<SingularAttribute<? super X, ?>> buildIdClassAttributes(
MappedSuperclassTypeImpl<X> jpaMappingType,
MappedSuperclass mappingType) {
LOG.trace("Building old-school composite identifier [" + mappingType.getMappedClass().getName() + "]");
Set<SingularAttribute<? super X, ?>> attributes = new HashSet<SingularAttribute<? super X, ?>>();
@SuppressWarnings( "unchecked" )
Iterator<Property> properties = mappingType.getIdentifierMapper().getPropertyIterator();
while ( properties.hasNext() ) {
attributes.add( attributeFactory.buildIdAttribute( jpaMappingType, properties.next() ) );
AbstractIdentifiableType<X> ownerType,
Iterator<Property> propertyIterator) {
LOG.trace("Building old-school composite identifier [" + ownerType.getJavaType().getName() + "]");
Set<SingularAttribute<? super X, ?>> attributes = new HashSet<SingularAttribute<? super X, ?>>();
while ( propertyIterator.hasNext() ) {
attributes.add( attributeFactory.buildIdAttribute( ownerType, propertyIterator.next() ) );
}
return attributes;
}

View File

@ -0,0 +1,54 @@
/*
* 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.ejb.criteria.idclass;
import javax.persistence.Column;
import javax.persistence.Id;
import javax.persistence.IdClass;
import javax.persistence.Entity;
import javax.persistence.MappedSuperclass;
import javax.persistence.Table;
/**
* @author Erich Heard
*/
@MappedSuperclass
@Table( name = "HELPER" )
@IdClass( org.hibernate.ejb.criteria.idclass.HelperId.class )
public class Helper {
@Id
private String name;
public String getName( ) { return this.name; }
public void setName( String value ) { this.name = value; }
@Id
private String type;
public String getType( ) { return this.type; }
public void setType( String value ) { this.type = value; }
@Override
public String toString( ) {
return "[Name:" + this.getName( ) + "; Type: " + this.getType( ) + "]";
}
}

View File

@ -0,0 +1,77 @@
/*
* 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.ejb.criteria.idclass;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Embeddable;
import javax.persistence.Id;
/**
* @author Gail Badner
*/
@Embeddable
public class HelperId implements Serializable {
private static final long serialVersionUID = 9122480802791185646L;
@Id
@Column( name = "NAME", length = 12 )
private String name;
public String getName( ) { return this.name; }
public void setName( String value ) { this.name = value; }
@Id
@Column( name = "HELPER_TYPE", length = 4 )
private String type;
public String getType( ) { return this.type; }
public void setType( String value ) { this.type = value; }
@Override
public boolean equals( Object obj ) {
if( obj == null ) return false;
if( !( obj instanceof HelperId ) ) return false;
HelperId id = ( HelperId )obj;
if( this.getName() == null || id.getName() == null || this.getType() == null || id.getType() == null ) return false;
return this.toString( ).equals( id.toString( ) );
}
@Override
public int hashCode( ) {
return this.toString( ).hashCode( );
}
@Override
public String toString( ) {
StringBuilder buf = new StringBuilder( "[id:" );
buf.append( ( this.getName() == null ) ? "null" : this.getName( ) );
buf.append( ";type:" );
buf.append( ( this.getType() == null ) ? "null" : this.getType() );
buf.append( "]" );
return buf.toString( );
}
}

View File

@ -0,0 +1,195 @@
/*
* 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.ejb.criteria.idclass;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.*;
import javax.persistence.criteria.*;
import junit.framework.Assert;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.hibernate.ejb.metamodel.AbstractMetamodelSpecificTest;
/**
* @author Erich Heard
*/
public class IdClassPredicateTest extends AbstractMetamodelSpecificTest {
@Override
public Class[] getAnnotatedClasses() {
return new Class[] {
Widget.class,
Tool.class
};
}
@Before
public void prepareTestData() {
EntityManager em = entityManagerFactory().createEntityManager();
em.getTransaction().begin();
Widget w = new Widget();
w.setCode( "AAA" );
w.setDivision( "NA" );
w.setCost( 10.00 );
em.persist( w );
w = new Widget();
w.setCode( "AAA" );
w.setDivision( "EU" );
w.setCost( 12.50 );
em.persist( w );
w = new Widget();
w.setCode( "AAA" );
w.setDivision( "ASIA" );
w.setCost( 110.00 );
em.persist( w );
w = new Widget();
w.setCode( "BBB" );
w.setDivision( "NA" );
w.setCost( 14.00 );
em.persist( w );
w = new Widget();
w.setCode( "BBB" );
w.setDivision( "EU" );
w.setCost( 8.75 );
em.persist( w );
w = new Widget();
w.setCode( "BBB" );
w.setDivision( "ASIA" );
w.setCost( 86.22 );
em.persist( w );
Tool t = new Tool();
t.setName( "AAA" );
t.setType( "NA" );
t.setCost( 10.00 );
em.persist( t );
t = new Tool();
t.setName( "AAA" );
t.setType( "EU" );
t.setCost( 12.50 );
em.persist( t );
t = new Tool();
t.setName( "AAA" );
t.setType( "ASIA" );
t.setCost( 110.00 );
em.persist( t );
t = new Tool();
t.setName( "BBB" );
t.setType( "NA" );
t.setCost( 14.00 );
em.persist( t );
t = new Tool();
t.setName( "BBB" );
t.setType( "EU" );
t.setCost( 8.75 );
em.persist( t );
t = new Tool();
t.setName( "BBB" );
t.setType( "ASIA" );
t.setCost( 86.22 );
em.persist( t );
em.getTransaction().commit();
em.close();
}
@After
public void cleanupTestData() {
EntityManager em = getOrCreateEntityManager();
em.getTransaction().begin();
em.createQuery( "delete Widget" ).executeUpdate();
em.createQuery( "delete Tool" ).executeUpdate();
em.getTransaction().commit();
em.close();
}
@Test
public void testDeclaredIdClassAttributes( ) {
EntityManager em = getOrCreateEntityManager();
em.getTransaction().begin();
// Packaging arguments for use in query.
List<String> divisions = new ArrayList<String>( );
divisions.add( "NA" );
divisions.add( "EU" );
// Building the query.
CriteriaBuilder criteria = em.getCriteriaBuilder( );
CriteriaQuery<Widget> query = criteria.createQuery( Widget.class );
Root<Widget> root = query.from( Widget.class );
Predicate predicate = root.get( "division" ).in( divisions );
query.where( predicate );
// Retrieving query.;
List<Widget> widgets = em.createQuery( query ).getResultList( );
Assert.assertEquals( 4, widgets.size() );
em.getTransaction().commit();
em.close();
}
@Test
public void testSupertypeIdClassAttributes( ) {
EntityManager em = getOrCreateEntityManager();
em.getTransaction().begin();
// Packaging arguments for use in query.
List<String> types = new ArrayList<String>( );
types.add( "NA" );
types.add( "EU" );
// Building the query.
CriteriaBuilder criteria = em.getCriteriaBuilder( );
CriteriaQuery<Tool> query = criteria.createQuery( Tool.class );
Root<Tool> root = query.from( Tool.class );
Predicate predicate = root.get( "type" ).in( types );
query.where( predicate );
// Retrieving query.
List<Tool> tools = em.createQuery( query ).getResultList( );
Assert.assertEquals( 4, tools.size() );
em.getTransaction().commit();
em.close();
}
}

View File

@ -0,0 +1,47 @@
/*
* 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.ejb.criteria.idclass;
import javax.persistence.Column;
import javax.persistence.Id;
import javax.persistence.IdClass;
import javax.persistence.Entity;
import javax.persistence.Table;
/**
* @author Gail Badner
*/
@Entity
@Table( name = "TOOL" )
public class Tool extends Helper {
@Column( name = "COST" )
private Double cost;
public Double getCost( ) { return this.cost; }
public void setCost( Double value ) { this.cost = value; }
@Override
public String toString( ) {
return "[" + super.toString() + "; Cost: " + this.getCost( ) + "]";
}
}

View File

@ -0,0 +1,58 @@
/*
* 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.ejb.criteria.idclass;
import javax.persistence.Column;
import javax.persistence.Id;
import javax.persistence.IdClass;
import javax.persistence.Entity;
import javax.persistence.Table;
/**
* @author Erich Heard
*/
@Entity
@Table( name = "WIDGET" )
@IdClass( org.hibernate.ejb.criteria.idclass.WidgetId.class )
public class Widget {
@Id
private String code;
public String getCode( ) { return this.code; }
public void setCode( String value ) { this.code = value; }
@Id
private String division;
public String getDivision( ) { return this.division; }
public void setDivision( String value ) { this.division = value; }
@Column( name = "COST" )
private Double cost;
public Double getCost( ) { return this.cost; }
public void setCost( Double value ) { this.cost = value; }
@Override
public String toString( ) {
return "[Code:" + this.getCode( ) + "; Division: " + this.getDivision( ) + "; Cost: " + this.getCost( ) + "]";
}
}

View File

@ -0,0 +1,77 @@
/*
* 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.ejb.criteria.idclass;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Embeddable;
import javax.persistence.Id;
/**
* @author Erich Heard
*/
@Embeddable
public class WidgetId implements Serializable {
private static final long serialVersionUID = 9122480802791185644L;
@Id
@Column( name = "CODE", length = 3 )
private String code;
public String getCode( ) { return this.code; }
public void setCode( String value ) { this.code = value; }
@Id
@Column( name = "DIVISION", length = 4 )
private String division;
public String getDivision( ) { return this.division; }
public void setDivision( String value ) { this.division = value; }
@Override
public boolean equals( Object obj ) {
if( obj == null ) return false;
if( !( obj instanceof WidgetId ) ) return false;
WidgetId id = ( WidgetId )obj;
if( this.getCode( ) == null || id.getCode( ) == null || this.getDivision( ) == null || id.getDivision( ) == null ) return false;
return this.toString( ).equals( id.toString( ) );
}
@Override
public int hashCode( ) {
return this.toString( ).hashCode( );
}
@Override
public String toString( ) {
StringBuffer buf = new StringBuffer( "[id:" );
buf.append( ( this.getCode( ) == null ) ? "null" : this.getCode( ).toString( ) );
buf.append( ";code:" );
buf.append( ( this.getDivision( ) == null ) ? "null" : this.getDivision( ) );
buf.append( "]" );
return buf.toString( );
}
}

View File

@ -0,0 +1,42 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2011 by Red Hat Inc and/or its affiliates or by
* third-party contributors as indicated by either @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.ejb.test.metadata;
import javax.persistence.Entity;
/**
* @author Gail Badner
*/
@Entity(name="HomoGigantus")
public class Giant extends Person {
private long height;
public long getHeight() {
return height;
}
public void setHeight(long height) {
this.height = height;
}
}

View File

@ -49,6 +49,7 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
@ -133,6 +134,39 @@ public class MetadataTest extends BaseEntityManagerFunctionalTestCase {
assertEquals( 2, ids.size() );
for (SingularAttribute<? super Person,?> localId : ids) {
assertTrue( localId.isId() );
assertSame( personType, localId.getDeclaringType() );
assertSame( localId, personType.getDeclaredAttribute( localId.getName() ) );
assertSame( localId, personType.getDeclaredSingularAttribute( localId.getName() ) );
assertSame( localId, personType.getAttribute( localId.getName() ) );
assertSame( localId, personType.getSingularAttribute( localId.getName() ) );
assertTrue( personType.getAttributes().contains( localId ) );
}
final EntityType<Giant> giantType = entityManagerFactory().getMetamodel().entity( Giant.class );
assertEquals( "HomoGigantus", giantType.getName() );
assertFalse( giantType.hasSingleIdAttribute() );
final Set<SingularAttribute<? super Giant,?>> giantIds = giantType.getIdClassAttributes();
assertNotNull( giantIds );
assertEquals( 2, giantIds.size() );
assertEquals( personType.getIdClassAttributes(), giantIds );
for (SingularAttribute<? super Giant,?> localGiantId : giantIds) {
assertTrue( localGiantId.isId() );
try {
giantType.getDeclaredAttribute( localGiantId.getName() );
fail( localGiantId.getName() + " is a declared attribute, but shouldn't be");
}
catch ( IllegalArgumentException ex) {
// expected
}
try {
giantType.getDeclaredSingularAttribute( localGiantId.getName() );
fail( localGiantId.getName() + " is a declared singular attribute, but shouldn't be");
}
catch ( IllegalArgumentException ex) {
// expected
}
assertSame( localGiantId, giantType.getAttribute( localGiantId.getName() ) );
assertTrue( giantType.getAttributes().contains( localGiantId ) );
}
final EntityType<FoodItem> foodType = entityManagerFactory().getMetamodel().entity( FoodItem.class );
@ -369,6 +403,7 @@ public class MetadataTest extends BaseEntityManagerFunctionalTestCase {
Fridge.class,
FoodItem.class,
Person.class,
Giant.class,
House.class,
Dog.class,
Cat.class,