OPENJPA-2377 - Fix criteria query methods to meet spec requirements.

git-svn-id: https://svn.apache.org/repos/asf/openjpa/trunk@1482427 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Albert Lee 2013-05-14 16:26:39 +00:00
parent c6ee8caa41
commit 937aad666b
3 changed files with 83 additions and 14 deletions

View File

@ -18,9 +18,15 @@
*/
package org.apache.openjpa.persistence.criteria;
import static javax.persistence.metamodel.Type.PersistenceType.EMBEDDABLE;
import static javax.persistence.metamodel.Type.PersistenceType.ENTITY;
import java.math.BigDecimal;
import java.util.List;
import java.util.Set;
import javax.persistence.Embeddable;
import javax.persistence.Entity;
import javax.persistence.Parameter;
import javax.persistence.Query;
import javax.persistence.Tuple;
@ -36,6 +42,7 @@ import javax.persistence.criteria.SetJoin;
import javax.persistence.criteria.Subquery;
import javax.persistence.metamodel.EmbeddableType;
import javax.persistence.metamodel.EntityType;
import javax.persistence.metamodel.ManagedType;
import javax.persistence.metamodel.Metamodel;
import javax.persistence.metamodel.SetAttribute;
@ -95,6 +102,43 @@ public class TestMetaModelTypesafeCriteria extends CriteriaTest {
videoStore_ = mm.entity(VideoStore.class);
}
public void testEntityEmbeddableTest() {
Metamodel mm = em.getMetamodel();
assertEquals(mm.managedType(Account.class).getPersistenceType(), ENTITY);
assertEquals(mm.managedType(Address.class).getPersistenceType(), EMBEDDABLE);
assertNotNull(mm.entity(Account.class));
assertNotNull(mm.embeddable(Address.class));
try {
mm.entity(Address.class);
fail("Expecting IllegalArgumentException");
} catch (IllegalArgumentException iaex) {
}
try {
mm.embeddable(Account.class);
fail("Expecting IllegalArgumentException");
} catch (IllegalArgumentException iaex) {
}
int numEntity = 0;
int numEmbeddables = 0;
for (Class<?> clz : getDomainClasses()) {
if (clz.getAnnotation(Embeddable.class) != null) {
++numEmbeddables;
} else if (clz.getAnnotation(Entity.class) != null) {
++numEntity;
}
}
Set<EmbeddableType<?>> embs = mm.getEmbeddables();
assertEquals(embs.size(), numEmbeddables);
Set<EntityType<?>> ents = mm.getEntities();
assertEquals(ents.size(), numEntity);
Set<ManagedType<?>> metaTypes = mm.getManagedTypes();
assertEquals(metaTypes.size(), numEntity + numEmbeddables);
}
public void testStringEqualExpression() {
String jpql = "select c from Customer c "
+ "where c.name='Autowest Toyota'";

View File

@ -343,7 +343,7 @@ class CriteriaQueryImpl<T> implements OpenJPACriteriaQuery<T>, AliasContext {
public <X> Root<X> from(Class<X> cls) {
EntityType<X> entity = _model.entity(cls);
EntityType<X> entity = _model.entityImpl(cls);
if (entity == null)
throw new IllegalArgumentException(_loc.get("root-non-entity", cls).getMessage());
return from(entity);

View File

@ -68,6 +68,7 @@ public class MetamodelImpl implements Metamodel, Resolver {
private final MetaDataRepository repos;
private Map<Class<?>, Type<?>> _basics = new HashMap<Class<?>, Type<?>>();
private Map<Class<?>, EntityType<?>> _entities = new HashMap<Class<?>, EntityType<?>>();
private Set<EntityType<?>> _entitiesOnlySet = null;
private Map<Class<?>, EmbeddableType<?>> _embeddables = new HashMap<Class<?>, EmbeddableType<?>>();
private Map<Class<?>, MappedSuperclassType<?>> _mappedsupers = new HashMap<Class<?>, MappedSuperclassType<?>>();
private Map<Class<?>, Types.PseudoEntity<?>> _pseudos = new HashMap<Class<?>, Types.PseudoEntity<?>>();
@ -86,15 +87,15 @@ public class MetamodelImpl implements Metamodel, Resolver {
PersistenceType type = getPersistenceType(meta);
switch (type) {
case ENTITY:
find(cls, _entities, ENTITY);
find(cls, _entities, ENTITY, false);
if (meta.isEmbeddable())
find(cls, _embeddables, EMBEDDABLE);
find(cls, _embeddables, EMBEDDABLE, false);
break;
case EMBEDDABLE:
find(cls, _embeddables, EMBEDDABLE);
find(cls, _embeddables, EMBEDDABLE, false);
break;
case MAPPED_SUPERCLASS:
find(cls, _mappedsupers, MAPPED_SUPERCLASS);
find(cls, _mappedsupers, MAPPED_SUPERCLASS, false);
break;
default:
}
@ -113,7 +114,7 @@ public class MetamodelImpl implements Metamodel, Resolver {
* @throws IllegalArgumentException if not an embeddable class
*/
public <X> EmbeddableType<X> embeddable(Class<X> clazz) {
return (EmbeddableType<X>)find(clazz, _embeddables, EMBEDDABLE);
return (EmbeddableType<X>)find(clazz, _embeddables, EMBEDDABLE, false);
}
/**
@ -123,7 +124,27 @@ public class MetamodelImpl implements Metamodel, Resolver {
* @throws IllegalArgumentException if not an entity
*/
public <X> EntityType<X> entity(Class<X> clazz) {
return (EntityType<X>) find(clazz, _entities, ENTITY);
return (EntityType<X>) find(clazz, _entities, ENTITY, false);
}
public <X> EntityType<X> entityImpl(Class<X> clazz) {
return (EntityType<X>) find(clazz, _entities, ENTITY, true);
}
/*
* Return the most up-to-date entity only set in the current meta model.
*/
private Collection<EntityType<?>> getEntityValuesOnly() {
if (_entitiesOnlySet == null) {
_entitiesOnlySet = new HashSet<EntityType<?>>();
for (Class<?> cls : _entities.keySet()) {
// if key indicates it is a embeddable, do not add to the _entitiesOnlySet.
if (!_embeddables.containsKey(cls)) {
_entitiesOnlySet.add(_entities.get(cls));
}
}
}
return _entitiesOnlySet;
}
/**
@ -139,7 +160,7 @@ public class MetamodelImpl implements Metamodel, Resolver {
* @return the metamodel entity types
*/
public Set<EntityType<?>> getEntities() {
return unmodifiableSet(_entities.values());
return unmodifiableSet(getEntityValuesOnly());
}
/**
@ -148,7 +169,7 @@ public class MetamodelImpl implements Metamodel, Resolver {
*/
public Set<ManagedType<?>> getManagedTypes() {
Set<ManagedType<?>> result = new HashSet<ManagedType<?>>();
result.addAll(_entities.values());
result.addAll(getEntityValuesOnly());
result.addAll(_embeddables.values());
result.addAll(_mappedsupers.values());
return result;
@ -162,10 +183,10 @@ public class MetamodelImpl implements Metamodel, Resolver {
* @throws IllegalArgumentException if not a managed class
*/
public <X> ManagedType<X> managedType(Class<X> clazz) {
if (_entities.containsKey(clazz))
return (EntityType<X>) _entities.get(clazz);
if (_embeddables.containsKey(clazz))
return (EmbeddableType<X>) _embeddables.get(clazz);
if (_entities.containsKey(clazz))
return (EntityType<X>) _entities.get(clazz);
if (_mappedsupers.containsKey(clazz))
return (MappedSuperclassType<X>) _mappedsupers.get(clazz);
throw new IllegalArgumentException(_loc.get("type-not-managed", clazz)
@ -216,9 +237,12 @@ public class MetamodelImpl implements Metamodel, Resolver {
* The managed type may become instantiated as a side-effect.
*/
private <V extends ManagedType<?>> V find(Class<?> cls, Map<Class<?>,V> container,
PersistenceType expected) {
if (container.containsKey(cls))
return container.get(cls);
PersistenceType expected, boolean implFind) {
if (container.containsKey(cls)) {
if (implFind || expected != ENTITY || !_embeddables.containsKey(cls)) {
return container.get(cls);
}
}
ClassMetaData meta = repos.getMetaData(cls, null, false);
if (meta != null) {
instantiate(cls, meta, container, expected);
@ -252,6 +276,7 @@ public class MetamodelImpl implements Metamodel, Resolver {
case ENTITY:
Types.Entity<X> entity = new Types.Entity<X>(meta, this);
_entities.put(cls, entity);
_entitiesOnlySet = null;
populate(entity);
break;
case MAPPED_SUPERCLASS: