Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

GRAILS-7336 & GRAILS-7154 adding readOnly, fetchSize, timeout, and flushMode options to grails dynamic finders/criteria/executeQuery methods #61

Merged
merged 1 commit into from

2 participants

@tednaleid

"readOnly", "fetchSize", "timeout", and "flushMode" work just like the existing pagination/cache parameters on all of the dynamic finders (findBy, findAllBy, list, etc) as well as executeQuery.

All of these methods are already on the Hibernate 3.6 Criteria and Query objects, this patch simply passes those values through to hibernate.

If accepted, I'll also update the grails-docs repo with notes around the 4 new parameters that have been added to the map.

@tednaleid tednaleid GRAILS-7336 & GRAILS-7154 adding readOnly, fetchSize, timeout, and fl…
…ushMode options to grails dynamic finders/criteria/executeQuery methods
931e7a7
@jeffbrown jeffbrown merged commit cc9a926 into grails:master
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on May 1, 2011
  1. @tednaleid

    GRAILS-7336 & GRAILS-7154 adding readOnly, fetchSize, timeout, and fl…

    tednaleid authored
    …ushMode options to grails dynamic finders/criteria/executeQuery methods
This page is out of date. Refresh to see the latest.
View
71 ...ate/src/main/groovy/org/codehaus/groovy/grails/orm/hibernate/cfg/GrailsHibernateUtil.java
@@ -57,6 +57,10 @@
private static final String DYNAMIC_FILTER_ENABLER = "dynamicFilterEnabler";
public static SimpleTypeConverter converter = new SimpleTypeConverter();
+ public static final String ARGUMENT_FETCH_SIZE = "fetchSize";
+ public static final String ARGUMENT_TIMEOUT = "timeout";
+ public static final String ARGUMENT_READ_ONLY = "readOnly";
+ public static final String ARGUMENT_FLUSH_MODE = "flushMode";
public static final String ARGUMENT_MAX = "max";
public static final String ARGUMENT_OFFSET = "offset";
public static final String ARGUMENT_ORDER = "order";
@@ -140,6 +144,7 @@ private static void configureDomainClass(SessionFactory sessionFactory, GrailsAp
/**
* Populates criteria arguments for the given target class and arguments map
*
+ * @param grailsApplication the GrailsApplication instance
* @param targetClass The target class
* @param c The criteria instance
* @param argMap The arguments map
@@ -156,6 +161,18 @@ public static void populateArgumentsForCriteria(GrailsApplication grailsApplicat
if (argMap.containsKey(ARGUMENT_OFFSET)) {
offsetParam = converter.convertIfNecessary(argMap.get(ARGUMENT_OFFSET),Integer.class);
}
+ if (argMap.containsKey(ARGUMENT_FETCH_SIZE)) {
+ c.setFetchSize(converter.convertIfNecessary(argMap.get(ARGUMENT_FETCH_SIZE),Integer.class));
+ }
+ if (argMap.containsKey(ARGUMENT_TIMEOUT)) {
+ c.setTimeout(converter.convertIfNecessary(argMap.get(ARGUMENT_TIMEOUT),Integer.class));
+ }
+ if (argMap.containsKey(ARGUMENT_FLUSH_MODE)) {
+ c.setFlushMode(converter.convertIfNecessary(argMap.get(ARGUMENT_FLUSH_MODE),FlushMode.class));
+ }
+ if (argMap.containsKey(ARGUMENT_READ_ONLY)) {
+ c.setReadOnly(GrailsClassUtils.getBooleanFromMap(ARGUMENT_READ_ONLY, argMap));
+ }
String orderParam = (String)argMap.get(ARGUMENT_ORDER);
Object fetchObj = argMap.get(ARGUMENT_FETCH);
if (fetchObj instanceof Map) {
@@ -213,59 +230,7 @@ public static void populateArgumentsForCriteria(GrailsApplication grailsApplicat
*/
@SuppressWarnings("rawtypes")
public static void populateArgumentsForCriteria(Class<?> targetClass, Criteria c, Map argMap) {
- Integer maxParam = null;
- Integer offsetParam = null;
- if (argMap.containsKey(ARGUMENT_MAX)) {
- maxParam = converter.convertIfNecessary(argMap.get(ARGUMENT_MAX),Integer.class);
- }
- if (argMap.containsKey(ARGUMENT_OFFSET)) {
- offsetParam = converter.convertIfNecessary(argMap.get(ARGUMENT_OFFSET),Integer.class);
- }
- String orderParam = (String)argMap.get(ARGUMENT_ORDER);
- Object fetchObj = argMap.get(ARGUMENT_FETCH);
- if (fetchObj instanceof Map) {
- Map fetch = (Map)fetchObj;
- for (Object o : fetch.keySet()) {
- String associationName = (String) o;
- c.setFetchMode(associationName, getFetchMode(fetch.get(associationName)));
- }
- }
-
- final String sort = (String)argMap.get(ARGUMENT_SORT);
- final String order = ORDER_DESC.equalsIgnoreCase(orderParam) ? ORDER_DESC : ORDER_ASC;
- final int max = maxParam == null ? -1 : maxParam;
- final int offset = offsetParam == null ? -1 : offsetParam;
- if (max > -1) {
- c.setMaxResults(max);
- }
- if (offset > -1) {
- c.setFirstResult(offset);
- }
- if (GrailsClassUtils.getBooleanFromMap(ARGUMENT_CACHE, argMap)) {
- c.setCacheable(true);
- }
- if (GrailsClassUtils.getBooleanFromMap(ARGUMENT_LOCK, argMap)) {
- c.setLockMode(LockMode.UPGRADE);
- }
- else {
- if (argMap.get(ARGUMENT_CACHE) == null) {
- cacheCriteriaByMapping(targetClass, c);
- }
- }
- if (sort != null) {
- boolean ignoreCase = true;
- Object caseArg = argMap.get(ARGUMENT_IGNORE_CASE);
- if (caseArg instanceof Boolean) {
- ignoreCase = (Boolean) caseArg;
- }
- addOrderPossiblyNested(null, c, targetClass, sort, order, ignoreCase);
- }
- else {
- Mapping m = GrailsDomainBinder.getMapping(targetClass);
- if (m != null && !StringUtils.isBlank(m.getSort())) {
- addOrderPossiblyNested(null, c, targetClass, m.getSort(), m.getOrder(), true);
- }
- }
+ populateArgumentsForCriteria(null, targetClass, c, argMap);
}
/**
View
56 ...oovy/org/codehaus/groovy/grails/orm/hibernate/metaclass/ExecuteQueryPersistentMethod.java
@@ -32,6 +32,7 @@
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
+import org.hibernate.FlushMode;
import org.springframework.beans.SimpleTypeConverter;
import org.springframework.orm.hibernate3.HibernateCallback;
@@ -62,24 +63,39 @@ protected Object doInvokeInternal(Class clazz, String methodName, Closure additi
checkMethodSignature(clazz, arguments);
final String query = arguments[0].toString();
- final Map paginateParams = extractPaginateParams(arguments);
+ final Map queryMetaParams = extractQueryMetaParams(arguments);
final List positionalParams = extractPositionalParams(arguments);
final Map namedParams = extractNamedParams(arguments);
return getHibernateTemplate().executeFind(new HibernateCallback<Object>() {
public Object doInHibernate(Session session) throws HibernateException, SQLException {
Query q = session.createQuery(query);
+
// process paginate params
- if (paginateParams.containsKey(GrailsHibernateUtil.ARGUMENT_MAX)) {
- Integer maxParam = converter.convertIfNecessary(paginateParams.get(GrailsHibernateUtil.ARGUMENT_MAX),Integer.class);
+ if (queryMetaParams.containsKey(GrailsHibernateUtil.ARGUMENT_MAX)) {
+ Integer maxParam = converter.convertIfNecessary(queryMetaParams.get(GrailsHibernateUtil.ARGUMENT_MAX), Integer.class);
q.setMaxResults(maxParam.intValue());
}
- if (paginateParams.containsKey(GrailsHibernateUtil.ARGUMENT_OFFSET)) {
- Integer offsetParam = converter.convertIfNecessary(paginateParams.remove(GrailsHibernateUtil.ARGUMENT_OFFSET), Integer.class);
+ if (queryMetaParams.containsKey(GrailsHibernateUtil.ARGUMENT_OFFSET)) {
+ Integer offsetParam = converter.convertIfNecessary(queryMetaParams.remove(GrailsHibernateUtil.ARGUMENT_OFFSET), Integer.class);
q.setFirstResult(offsetParam.intValue());
}
- if (paginateParams.containsKey(GrailsHibernateUtil.ARGUMENT_CACHE)) {
- q.setCacheable(((Boolean)paginateParams.remove(GrailsHibernateUtil.ARGUMENT_CACHE)).booleanValue());
+ if (queryMetaParams.containsKey(GrailsHibernateUtil.ARGUMENT_CACHE)) {
+ q.setCacheable(((Boolean)queryMetaParams.remove(GrailsHibernateUtil.ARGUMENT_CACHE)).booleanValue());
+ }
+ if (queryMetaParams.containsKey(GrailsHibernateUtil.ARGUMENT_FETCH_SIZE)) {
+ Integer fetchSizeParam = converter.convertIfNecessary(queryMetaParams.remove(GrailsHibernateUtil.ARGUMENT_FETCH_SIZE), Integer.class);
+ q.setFetchSize(fetchSizeParam.intValue());
+ }
+ if (queryMetaParams.containsKey(GrailsHibernateUtil.ARGUMENT_TIMEOUT)) {
+ Integer timeoutParam = converter.convertIfNecessary(queryMetaParams.remove(GrailsHibernateUtil.ARGUMENT_TIMEOUT), Integer.class);
+ q.setFetchSize(timeoutParam.intValue());
+ }
+ if (queryMetaParams.containsKey(GrailsHibernateUtil.ARGUMENT_READ_ONLY)) {
+ q.setReadOnly(((Boolean) queryMetaParams.remove(GrailsHibernateUtil.ARGUMENT_READ_ONLY)).booleanValue());
+ }
+ if (queryMetaParams.containsKey(GrailsHibernateUtil.ARGUMENT_FLUSH_MODE)) {
+ q.setFlushMode((FlushMode) queryMetaParams.remove(GrailsHibernateUtil.ARGUMENT_FLUSH_MODE));
}
// process positional HQL params
int index = 0;
@@ -123,16 +139,20 @@ private void checkMethodSignature(Class clazz, Object[] arguments) {
}
@SuppressWarnings({ "unchecked", "rawtypes" })
- private Map extractPaginateParams(Object[] arguments) {
+ private Map extractQueryMetaParams(Object[] arguments) {
Map result = new HashMap();
- int paginateParamsIndex = 0;
- if (arguments.length == 2 && arguments[1] instanceof Map) paginateParamsIndex = 1;
- else if (arguments.length == 3) paginateParamsIndex = 2;
- if (paginateParamsIndex > 0) {
- Map sourceMap = (Map) arguments[paginateParamsIndex];
- if (sourceMap.containsKey(GrailsHibernateUtil.ARGUMENT_MAX)) result.put(GrailsHibernateUtil.ARGUMENT_MAX, sourceMap.get(GrailsHibernateUtil.ARGUMENT_MAX));
- if (sourceMap.containsKey(GrailsHibernateUtil.ARGUMENT_OFFSET)) result.put(GrailsHibernateUtil.ARGUMENT_OFFSET, sourceMap.get(GrailsHibernateUtil.ARGUMENT_OFFSET));
- if (sourceMap.containsKey(GrailsHibernateUtil.ARGUMENT_CACHE)) result.put(GrailsHibernateUtil.ARGUMENT_CACHE, sourceMap.get(GrailsHibernateUtil.ARGUMENT_CACHE));
+ int metaParamsIndex = 0;
+ if (arguments.length == 2 && arguments[1] instanceof Map) metaParamsIndex = 1;
+ else if (arguments.length == 3) metaParamsIndex = 2;
+ if (metaParamsIndex > 0) {
+ Map sourceMap = (Map) arguments[metaParamsIndex];
+ if (sourceMap.containsKey(GrailsHibernateUtil.ARGUMENT_MAX)) result.put(GrailsHibernateUtil.ARGUMENT_MAX, sourceMap.remove(GrailsHibernateUtil.ARGUMENT_MAX));
+ if (sourceMap.containsKey(GrailsHibernateUtil.ARGUMENT_OFFSET)) result.put(GrailsHibernateUtil.ARGUMENT_OFFSET, sourceMap.remove(GrailsHibernateUtil.ARGUMENT_OFFSET));
+ if (sourceMap.containsKey(GrailsHibernateUtil.ARGUMENT_CACHE)) result.put(GrailsHibernateUtil.ARGUMENT_CACHE, sourceMap.remove(GrailsHibernateUtil.ARGUMENT_CACHE));
+ if (sourceMap.containsKey(GrailsHibernateUtil.ARGUMENT_FLUSH_MODE)) result.put(GrailsHibernateUtil.ARGUMENT_FLUSH_MODE, sourceMap.remove(GrailsHibernateUtil.ARGUMENT_FLUSH_MODE));
+ if (sourceMap.containsKey(GrailsHibernateUtil.ARGUMENT_TIMEOUT)) result.put(GrailsHibernateUtil.ARGUMENT_TIMEOUT, sourceMap.remove(GrailsHibernateUtil.ARGUMENT_TIMEOUT));
+ if (sourceMap.containsKey(GrailsHibernateUtil.ARGUMENT_FETCH_SIZE)) result.put(GrailsHibernateUtil.ARGUMENT_FETCH_SIZE, sourceMap.remove(GrailsHibernateUtil.ARGUMENT_FETCH_SIZE));
+ if (sourceMap.containsKey(GrailsHibernateUtil.ARGUMENT_READ_ONLY)) result.put(GrailsHibernateUtil.ARGUMENT_READ_ONLY, sourceMap.remove(GrailsHibernateUtil.ARGUMENT_READ_ONLY));
}
return result;
}
@@ -158,10 +178,6 @@ private Map extractNamedParams(Object[] arguments) {
Map result = new HashMap();
if (arguments.length < 2 || !(arguments[1] instanceof Map)) return result;
result.putAll((Map) arguments[1]);
- // max, offset and cache are processed by paginate params
- result.remove(GrailsHibernateUtil.ARGUMENT_MAX);
- result.remove(GrailsHibernateUtil.ARGUMENT_OFFSET);
- result.remove(GrailsHibernateUtil.ARGUMENT_CACHE);
return result;
}
}
View
59 .../test/groovy/org/codehaus/groovy/grails/orm/hibernate/cfg/GrailsHibernateUtilTests.groovy
@@ -0,0 +1,59 @@
+package org.codehaus.groovy.grails.orm.hibernate.cfg
+
+import org.hibernate.Criteria
+import static org.codehaus.groovy.grails.orm.hibernate.cfg.GrailsHibernateUtil.*
+import org.hibernate.FlushMode
+
+class GrailsHibernateUtilTests extends GroovyTestCase {
+ @Override protected void setUp() {
+ super.setUp()
+ }
+
+ @Override protected void tearDown() {
+ super.tearDown()
+ }
+
+ void testPopulateArgumentsForCriteria_fetchSize() {
+ assertMockedCriteriaCalledFor("setFetchSize", ARGUMENT_FETCH_SIZE, 10)
+ }
+
+ void testPopulateArgumentsForCriteria_timeout() {
+ assertMockedCriteriaCalledFor("setTimeout", ARGUMENT_TIMEOUT, 60)
+ }
+
+ void testPopulateArgumentsForCriteria_readOnly() {
+ assertMockedCriteriaCalledFor("setReadOnly", ARGUMENT_READ_ONLY, true)
+ }
+
+ // works for criteria methods with primitive arguments
+ protected assertMockedCriteriaCalledFor(String methodName, String keyName, value) {
+ Boolean methodCalled = false
+
+ Criteria criteria = [
+ (methodName): { passedValue ->
+ assertEquals value, passedValue
+ methodCalled = true
+ return
+ }
+ ] as Criteria
+
+ GrailsHibernateUtil.populateArgumentsForCriteria(null, null, criteria, [(keyName): value])
+ assertTrue methodCalled
+ }
+
+ void testPopulateArgumentsForCriteria_flushMode() {
+ Boolean methodCalled = false
+ FlushMode value = FlushMode.MANUAL
+
+ Criteria criteria = [
+ setFlushMode: { FlushMode passedValue ->
+ assertEquals value, passedValue
+ methodCalled = true
+ return
+ }
+ ] as Criteria
+
+ GrailsHibernateUtil.populateArgumentsForCriteria(null, null, criteria, [flushMode: value])
+ assertTrue methodCalled
+ }
+}
Something went wrong with that request. Please try again.