-
Notifications
You must be signed in to change notification settings - Fork 92
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implemented rudimental treat support in core and reenabled some tests
- Loading branch information
Showing
70 changed files
with
2,242 additions
and
1,232 deletions.
There are no files selected for viewing
538 changes: 269 additions & 269 deletions
538
core/impl/src/main/java/com/blazebit/persistence/impl/AbstractFullQueryBuilder.java
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
85 changes: 85 additions & 0 deletions
85
core/impl/src/main/java/com/blazebit/persistence/impl/EntityMetamodel.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
package com.blazebit.persistence.impl; | ||
|
||
import javax.persistence.metamodel.EmbeddableType; | ||
import javax.persistence.metamodel.EntityType; | ||
import javax.persistence.metamodel.ManagedType; | ||
import javax.persistence.metamodel.Metamodel; | ||
import java.util.Collections; | ||
import java.util.HashMap; | ||
import java.util.Map; | ||
import java.util.Set; | ||
|
||
/** | ||
* This is a wrapper around the JPA {@link Metamodel} allows additionally efficient access by other attributes than a Class. | ||
* | ||
* @author Christian Beikov | ||
* @since 1.2 | ||
*/ | ||
public class EntityMetamodel implements Metamodel { | ||
|
||
private final Metamodel delegate; | ||
private final Map<String, EntityType<?>> entityNameMap; | ||
private final Map<Class<?>, ManagedType<?>> classMap; | ||
|
||
public EntityMetamodel(Metamodel delegate) { | ||
this.delegate = delegate; | ||
Set<ManagedType<?>> managedTypes = delegate.getManagedTypes(); | ||
Map<String, EntityType<?>> nameToType = new HashMap<String, EntityType<?>>(managedTypes.size()); | ||
Map<Class<?>, ManagedType<?>> classToType = new HashMap<Class<?>, ManagedType<?>>(managedTypes.size()); | ||
|
||
for (ManagedType<?> t : managedTypes) { | ||
if (t instanceof EntityType<?>) { | ||
EntityType<?> e = (EntityType<?>) t; | ||
nameToType.put(e.getName(), e); | ||
} | ||
classToType.put(t.getJavaType(), t); | ||
} | ||
|
||
this.entityNameMap = Collections.unmodifiableMap(nameToType); | ||
this.classMap = Collections.unmodifiableMap(classToType); | ||
} | ||
|
||
@Override | ||
public <X> EntityType<X> entity(Class<X> cls) { | ||
return delegate.entity(cls); | ||
} | ||
|
||
@Override | ||
public <X> ManagedType<X> managedType(Class<X> cls) { | ||
return delegate.managedType(cls); | ||
} | ||
|
||
public ManagedType<?> managedType(String name) { | ||
ManagedType<?> t = entityNameMap.get(name); | ||
if (t == null) { | ||
throw new IllegalStateException("Managed type with name '" + name + "' does not exist!"); | ||
} | ||
|
||
return t; | ||
} | ||
|
||
@SuppressWarnings({ "unchecked" }) | ||
public <X> ManagedType<X> getManagedType(Class<X> cls) { | ||
return (ManagedType<X>) classMap.get(cls); | ||
} | ||
|
||
@Override | ||
public <X> EmbeddableType<X> embeddable(Class<X> cls) { | ||
return delegate.embeddable(cls); | ||
} | ||
|
||
@Override | ||
public Set<ManagedType<?>> getManagedTypes() { | ||
return delegate.getManagedTypes(); | ||
} | ||
|
||
@Override | ||
public Set<EntityType<?>> getEntities() { | ||
return delegate.getEntities(); | ||
} | ||
|
||
@Override | ||
public Set<EmbeddableType<?>> getEmbeddables() { | ||
return delegate.getEmbeddables(); | ||
} | ||
} |
208 changes: 102 additions & 106 deletions
208
core/impl/src/main/java/com/blazebit/persistence/impl/EntitySelectResolveVisitor.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,107 +1,103 @@ | ||
package com.blazebit.persistence.impl; | ||
|
||
import java.util.ArrayList; | ||
import java.util.Comparator; | ||
import java.util.LinkedHashSet; | ||
import java.util.Set; | ||
import java.util.SortedSet; | ||
import java.util.TreeSet; | ||
|
||
import javax.persistence.FetchType; | ||
import javax.persistence.metamodel.Attribute; | ||
import javax.persistence.metamodel.EntityType; | ||
import javax.persistence.metamodel.Metamodel; | ||
|
||
import com.blazebit.persistence.impl.expression.AggregateExpression; | ||
import com.blazebit.persistence.impl.expression.FunctionExpression; | ||
import com.blazebit.persistence.impl.expression.PathElementExpression; | ||
import com.blazebit.persistence.impl.expression.PathExpression; | ||
import com.blazebit.persistence.impl.expression.SimplePathReference; | ||
import com.blazebit.persistence.impl.expression.VisitorAdapter; | ||
|
||
/** | ||
* This visitor resolves entity references to their attributes. This is needed for entity references | ||
* in the select clause when used in combination with aggregate functions. We have to decompose the | ||
* entity and add the components to the group by because all component will end up in the select clause. | ||
* | ||
* @author Christian Beikov | ||
* @since 1.0.5 | ||
*/ | ||
public class EntitySelectResolveVisitor extends VisitorAdapter { | ||
|
||
private final Metamodel m; | ||
private final Set<PathExpression> pathExpressions; | ||
|
||
public EntitySelectResolveVisitor(Metamodel m) { | ||
this(m, new LinkedHashSet<PathExpression>()); | ||
} | ||
|
||
public EntitySelectResolveVisitor(Metamodel m, Set<PathExpression> pathExpressions) { | ||
this.m = m; | ||
this.pathExpressions = pathExpressions; | ||
} | ||
|
||
public Set<PathExpression> getPathExpressions() { | ||
return pathExpressions; | ||
} | ||
|
||
@Override | ||
public void visit(FunctionExpression expression) { | ||
if (!(expression instanceof AggregateExpression)) { | ||
super.visit(expression); | ||
} | ||
} | ||
|
||
@Override | ||
public void visit(PathExpression expression) { | ||
if (expression.getField() == null) { | ||
/** | ||
* We need to resolve entity selects because hibernate will | ||
* select every entity attribute. Since we need every select in | ||
* the group by (because of DB2) we need to resolve such entity | ||
* selects here | ||
*/ | ||
JoinNode baseNode = ((JoinNode) expression.getBaseNode()); | ||
EntityType<?> entityType; | ||
|
||
try { | ||
entityType = m.entity(baseNode.getPropertyClass()); | ||
} catch (IllegalArgumentException e) { | ||
// ignore if the expression is not an entity | ||
return; | ||
} | ||
|
||
// we need to ensure a deterministic order for testing | ||
SortedSet<Attribute<?, ?>> sortedAttributes = new TreeSet<Attribute<?, ?>>(new Comparator<Attribute<?, ?>>() { | ||
|
||
@Override | ||
public int compare(Attribute<?, ?> o1, Attribute<?, ?> o2) { | ||
return o1.getName().compareTo(o2.getName()); | ||
} | ||
|
||
}); | ||
sortedAttributes.addAll(entityType.getAttributes()); | ||
for (Attribute<?, ?> attr : sortedAttributes) { | ||
boolean resolve = false; | ||
if (ExpressionUtils.isAssociation(attr) && !attr.isCollection()) { | ||
resolve = true; | ||
} else if (ExpressionUtils.getFetchType(attr) == FetchType.EAGER) { | ||
if (attr.getPersistentAttributeType() == Attribute.PersistentAttributeType.ELEMENT_COLLECTION) { | ||
throw new UnsupportedOperationException("Eager element collections are not supported"); | ||
} | ||
resolve = true; | ||
} | ||
|
||
if (resolve) { | ||
PathExpression attrPath = new PathExpression(new ArrayList<PathElementExpression>(expression.getExpressions())); | ||
attrPath.setPathReference(new SimplePathReference(baseNode, attr.getName())); | ||
pathExpressions.add(attrPath); | ||
} | ||
} | ||
} | ||
} | ||
|
||
public void resolve(JoinNode baseNode) { | ||
|
||
} | ||
package com.blazebit.persistence.impl; | ||
|
||
import java.util.ArrayList; | ||
import java.util.Comparator; | ||
import java.util.LinkedHashSet; | ||
import java.util.Set; | ||
import java.util.SortedSet; | ||
import java.util.TreeSet; | ||
|
||
import javax.persistence.FetchType; | ||
import javax.persistence.metamodel.Attribute; | ||
import javax.persistence.metamodel.EntityType; | ||
import javax.persistence.metamodel.Metamodel; | ||
|
||
import com.blazebit.persistence.impl.expression.*; | ||
|
||
/** | ||
* This visitor resolves entity references to their attributes. This is needed for entity references | ||
* in the select clause when used in combination with aggregate functions. We have to decompose the | ||
* entity and add the components to the group by because all components will end up in the select clause. | ||
* | ||
* @author Christian Beikov | ||
* @since 1.0.5 | ||
*/ | ||
public class EntitySelectResolveVisitor extends VisitorAdapter { | ||
|
||
private final Metamodel m; | ||
private final Set<PathExpression> pathExpressions; | ||
|
||
public EntitySelectResolveVisitor(Metamodel m) { | ||
this(m, new LinkedHashSet<PathExpression>()); | ||
} | ||
|
||
public EntitySelectResolveVisitor(Metamodel m, Set<PathExpression> pathExpressions) { | ||
this.m = m; | ||
this.pathExpressions = pathExpressions; | ||
} | ||
|
||
public Set<PathExpression> getPathExpressions() { | ||
return pathExpressions; | ||
} | ||
|
||
@Override | ||
public void visit(FunctionExpression expression) { | ||
if (!(expression instanceof AggregateExpression)) { | ||
super.visit(expression); | ||
} | ||
} | ||
|
||
@Override | ||
public void visit(PathExpression expression) { | ||
if (expression.getField() == null) { | ||
/** | ||
* We need to resolve entity selects because hibernate will | ||
* select every entity attribute. Since we need every select in | ||
* the group by (because of DB2) we need to resolve such entity | ||
* selects here | ||
*/ | ||
JoinNode baseNode = ((JoinNode) expression.getBaseNode()); | ||
EntityType<?> entityType; | ||
|
||
try { | ||
entityType = m.entity(baseNode.getPropertyClass()); | ||
} catch (IllegalArgumentException e) { | ||
// ignore if the expression is not an entity | ||
return; | ||
} | ||
|
||
// we need to ensure a deterministic order for testing | ||
SortedSet<Attribute<?, ?>> sortedAttributes = new TreeSet<Attribute<?, ?>>(new Comparator<Attribute<?, ?>>() { | ||
|
||
@Override | ||
public int compare(Attribute<?, ?> o1, Attribute<?, ?> o2) { | ||
return o1.getName().compareTo(o2.getName()); | ||
} | ||
|
||
}); | ||
// TODO: a polymorphic query will fail because we don't collect subtype properties | ||
sortedAttributes.addAll(entityType.getAttributes()); | ||
for (Attribute<?, ?> attr : sortedAttributes) { | ||
boolean resolve = false; | ||
if (ExpressionUtils.isAssociation(attr) && !attr.isCollection()) { | ||
resolve = true; | ||
} else if (ExpressionUtils.getFetchType(attr) == FetchType.EAGER) { | ||
if (attr.getPersistentAttributeType() == Attribute.PersistentAttributeType.ELEMENT_COLLECTION) { | ||
throw new UnsupportedOperationException("Eager element collections are not supported"); | ||
} | ||
resolve = true; | ||
} | ||
|
||
if (resolve) { | ||
PathExpression attrPath = new PathExpression(new ArrayList<PathElementExpression>(expression.getExpressions())); | ||
attrPath.setPathReference(new SimplePathReference(baseNode, attr.getName(), null)); | ||
pathExpressions.add(attrPath); | ||
} | ||
} | ||
} | ||
} | ||
|
||
public void resolve(JoinNode baseNode) { | ||
|
||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.