PL-7517 Count does not work correctly for in-memory constraints

This commit is contained in:
Andrey Subbotin 2016-07-12 12:12:30 +04:00
parent a24e7c3cfc
commit e5b80ee144
3 changed files with 61 additions and 19 deletions

View File

@ -206,26 +206,55 @@ public class DataManagerBean implements DataManager {
return 0;
}
QueryTransformer transformer = QueryTransformerFactory.createTransformer(context.getQuery().getQueryString());
transformer.replaceWithCount();
context = context.copy();
context.getQuery().setQueryString(transformer.getResult());
queryResultsManager.savePreviousQueryResults(context);
Number result;
try (Transaction tx = persistence.createTransaction()) {
EntityManager em = persistence.getEntityManager();
em.setSoftDeletion(context.isSoftDeletion());
persistence.getEntityManagerContext().setDbHints(context.getDbHints());
if (security.hasMemoryConstraints(metaClass, ConstraintOperationType.READ, ConstraintOperationType.ALL) ) {
context = context.copy();
List resultList;
try (Transaction tx = persistence.createTransaction()) {
EntityManager em = persistence.getEntityManager();
em.setSoftDeletion(context.isSoftDeletion());
persistence.getEntityManagerContext().setDbHints(context.getDbHints());
Query query = createQuery(em, context);
result = (Number) query.getSingleResult();
boolean ensureDistinct = false;
if (serverConfig.getInMemoryDistinct() && context.getQuery() != null) {
QueryTransformer transformer = QueryTransformerFactory.createTransformer(
context.getQuery().getQueryString());
ensureDistinct = transformer.removeDistinct();
if (ensureDistinct) {
context.getQuery().setQueryString(transformer.getResult());
}
}
context.getQuery().setFirstResult(0);
context.getQuery().setMaxResults(0);
tx.commit();
Query query = createQuery(em, context);
query.setView(createRestrictedView(context));
resultList = getResultList(context, query, ensureDistinct);
tx.commit();
}
return resultList.size();
} else {
QueryTransformer transformer = QueryTransformerFactory.createTransformer(context.getQuery().getQueryString());
transformer.replaceWithCount();
context = context.copy();
context.getQuery().setQueryString(transformer.getResult());
Number result;
try (Transaction tx = persistence.createTransaction()) {
EntityManager em = persistence.getEntityManager();
em.setSoftDeletion(context.isSoftDeletion());
persistence.getEntityManagerContext().setDbHints(context.getDbHints());
Query query = createQuery(em, context);
result = (Number) query.getSingleResult();
tx.commit();
}
return result.longValue();
}
return result.longValue();
}
@Override

View File

@ -137,4 +137,9 @@ public interface Security {
* Check if there are registered constraints for the metaClass or it's original metaClass
*/
boolean hasConstraints(MetaClass metaClass);
/**
* Check if there are registered memory constraints of specified {@param operationTypes} for the metaClass or it's original metaClass
*/
boolean hasMemoryConstraints(MetaClass metaClass, ConstraintOperationType... operationTypes);
}

View File

@ -39,10 +39,7 @@ import org.springframework.stereotype.Component;
import javax.inject.Inject;
import java.text.ParseException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.*;
import java.util.function.Predicate;
import static com.haulmont.cuba.security.entity.ConstraintOperationType.ALL;
@ -181,6 +178,17 @@ public class SecurityImpl implements Security {
return userSession.hasConstraints(mainMetaClassName);
}
@Override
public boolean hasMemoryConstraints(MetaClass metaClass, ConstraintOperationType... operationTypes) {
UserSession userSession = userSessionSource.getUserSession();
String mainMetaClassName = extendedEntities.getOriginalOrThisMetaClass(metaClass).getName();
List<ConstraintData> constraints = userSession.getConstraints(mainMetaClassName, constraint ->
constraint.getCheckType().memory() && constraint.getOperationType() != null
&& Arrays.asList(operationTypes).contains(constraint.getOperationType())
);
return !constraints.isEmpty();
}
protected List<ConstraintData> getConstraints(MetaClass metaClass, Predicate<ConstraintData> predicate) {
UserSession userSession = userSessionSource.getUserSession();
String mainMetaClassName = extendedEntities.getOriginalOrThisMetaClass(metaClass).getName();