mirror of https://github.com/apache/openjpa.git
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:
parent
c6ee8caa41
commit
937aad666b
|
@ -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'";
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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:
|
||||
|
|
Loading…
Reference in New Issue