[OLINGO-1095] Check for embedded attributes
diff --git a/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAQueryBuilder.java b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAQueryBuilder.java
index bf20832..6852a17 100644
--- a/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAQueryBuilder.java
+++ b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAQueryBuilder.java
@@ -18,14 +18,6 @@
******************************************************************************/
package org.apache.olingo.odata2.jpa.processor.core.access.data;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import javax.persistence.EntityManager;
-import javax.persistence.Query;
-
import org.apache.olingo.odata2.api.edm.EdmException;
import org.apache.olingo.odata2.api.uri.UriInfo;
import org.apache.olingo.odata2.api.uri.info.DeleteUriInfo;
@@ -44,6 +36,16 @@
import org.apache.olingo.odata2.jpa.processor.api.jpql.JPQLStatement;
import org.apache.olingo.odata2.jpa.processor.api.model.JPAEdmMapping;
+import javax.persistence.EntityManager;
+import javax.persistence.Query;
+import javax.persistence.metamodel.Attribute;
+import javax.persistence.metamodel.EntityType;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
public class JPAQueryBuilder {
enum UriInfoType {
@@ -177,7 +179,7 @@
JPQLContext jpqlContext = buildJPQLContext(contextType, uriParserResultView);
JPQLStatement jpqlStatement = JPQLStatement.createBuilder(jpqlContext).build();
- return em.createQuery(normalizeMembers(jpqlStatement.toString()));
+ return em.createQuery(normalizeMembers(em, jpqlStatement.toString()));
}
@@ -195,24 +197,19 @@
public ODataJPATombstoneEntityListener getODataJPATombstoneEntityListener(UriInfo uriParserResultView)
throws InstantiationException, IllegalAccessException, EdmException {
JPAEdmMapping mapping = (JPAEdmMapping) uriParserResultView.getTargetEntitySet().getEntityType().getMapping();
- ODataJPATombstoneEntityListener listener = null;
if (mapping.getODataJPATombstoneEntityListener() != null) {
- listener = (ODataJPATombstoneEntityListener) mapping.getODataJPATombstoneEntityListener().newInstance();
+ return (ODataJPATombstoneEntityListener) mapping.getODataJPATombstoneEntityListener().newInstance();
}
- return listener;
+ return null;
}
public JPQLContext buildJPQLContext(JPQLContextType contextType, UriInfo uriParserResultView)
throws ODataJPAModelException, ODataJPARuntimeException {
- JPQLContext jpqlContext = null;
if (pageSize > 0 && (contextType == JPQLContextType.SELECT || contextType == JPQLContextType.JOIN)) {
- jpqlContext = JPQLContext.createBuilder(contextType,
- uriParserResultView, true).build();
+ return JPQLContext.createBuilder(contextType, uriParserResultView, true).build();
} else {
- jpqlContext = JPQLContext.createBuilder(contextType,
- uriParserResultView).build();
+ return JPQLContext.createBuilder(contextType, uriParserResultView).build();
}
- return jpqlContext;
}
public JPQLContextType determineJPQLContextType(UriInfo uriParserResultView, UriInfoType type) {
@@ -240,10 +237,10 @@
return contextType;
}
- private static final Pattern NORMALIZATION_NEEDED_PATTERN = Pattern.compile(".*[\\s\\(](\\S+\\.\\S+\\.\\S+).*");
+ private static final Pattern NORMALIZATION_NEEDED_PATTERN = Pattern.compile(".*[\\s(](\\S+\\.\\S+\\.\\S+).*");
private static final Pattern JOIN_ALIAS_PATTERN = Pattern.compile(".*\\sJOIN\\s(\\S*\\s\\S*).*");
- private static String normalizeMembers(String jpqlQuery) {
+ private static String normalizeMembers(EntityManager em, String jpqlQuery) {
// check if normalization is needed (if query contains "x.y.z" elements
// starting with space or parenthesis)
Matcher normalizationNeededMatcher = NORMALIZATION_NEEDED_PATTERN.matcher(jpqlQuery);
@@ -251,6 +248,10 @@
return jpqlQuery;
}
+ if (containsEmbeddedAttributes(em, jpqlQuery)) {
+ return jpqlQuery;
+ }
+
String normalizedJpqlQuery = jpqlQuery;
Map<String, String> joinAliases = new HashMap<String, String>();
@@ -306,6 +307,36 @@
JPQLStatement.KEYWORD.SELECT_DISTINCT + JPQLStatement.DELIMITER.SPACE);
}
+ /**
+ * Verify via {@link EntityManager} if one of the attributes of the selected entity
+ * contains a embedded attribute.
+ * Return true if at least one embedded attribute is found or false if non embedded
+ * attribute is found.
+ *
+ * @param em according entity manager
+ * @param jpqlQuery query to verify
+ * @return true if at least one embedded attribute is found or false if non embedded
+ * attribute is found.
+ */
+ private static boolean containsEmbeddedAttributes(EntityManager em, String jpqlQuery) {
+ Set<EntityType<?>> types = em.getMetamodel().getEntities();
+ int pos = jpqlQuery.indexOf("FROM ") + 5;
+ int lastpos = jpqlQuery.indexOf(" ", pos);
+ final String queriedEntity = jpqlQuery.substring(pos, lastpos);
+ for (EntityType<?> type : types) {
+ if(queriedEntity.equals(type.getName())) {
+ Set<Attribute<?, ?>> attributes = (Set<Attribute<?, ?>>) type.getAttributes();
+ for (Attribute<?, ?> attribute : attributes) {
+ if(jpqlQuery.contains(attribute.getName()) &&
+ attribute.getPersistentAttributeType() == Attribute.PersistentAttributeType.EMBEDDED) {
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+ }
+
private static int ordinalIndexOf(String str, char s, int n) {
int pos = str.indexOf(s, 0);
while (n-- > 0 && pos != -1) {