1 /* Copyright 2004-2005 the original author or authors.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
7 * http://www.apache.org/licenses/LICENSE-2.0
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
15 package org
.codehaus
.groovy
.grails
.orm
.hibernate
.metaclass
;
17 import org
.codehaus
.groovy
.grails
.commons
.GrailsApplication
;
18 import org
.codehaus
.groovy
.grails
.orm
.hibernate
.cfg
.GrailsHibernateUtil
;
19 import org
.hibernate
.Criteria
;
20 import org
.hibernate
.HibernateException
;
21 import org
.hibernate
.Session
;
22 import org
.hibernate
.SessionFactory
;
23 import org
.hibernate
.criterion
.Restrictions
;
24 import org
.hibernate
.criterion
.Disjunction
;
25 import org
.springframework
.orm
.hibernate3
.HibernateCallback
;
27 import java
.sql
.SQLException
;
28 import java
.util
.Iterator
;
29 import java
.util
.List
;
31 import java
.util
.regex
.Pattern
;
34 * The "findBy*" static persistent method. This method allows querying for
35 * instances of grails domain classes based on their properties. This method returns the first result of the query
38 * Account.findByHolder("Joe Blogs"); // Where class "Account" has a property called "holder"
39 * Account.findByHolderAndBranch("Joe Blogs", "London" ); // Where class "Account" has a properties called "holder" and "branch"
41 * @author Graeme Rocher
45 public class FindByPersistentMethod
extends AbstractClausedStaticPersistentMethod
{
47 private static final String OPERATOR_OR
= "Or";
48 private static final String OPERATOR_AND
= "And";
50 private static final String METHOD_PATTERN
= "(findBy)(\\w+)";
51 private static final String
[] OPERATORS
= new String
[]{ OPERATOR_AND
, OPERATOR_OR
};
53 public FindByPersistentMethod(GrailsApplication application
,SessionFactory sessionFactory
, ClassLoader classLoader
) {
54 super(application
,sessionFactory
, classLoader
, Pattern
.compile( METHOD_PATTERN
),OPERATORS
);
57 protected Object
doInvokeInternalWithExpressions(final Class clazz
, String methodName
, final Object
[] arguments
, final List expressions
, String operatorInUse
) {
59 final String operator
= OPERATOR_OR
.equals(operatorInUse
) ? OPERATOR_OR
: OPERATOR_AND
;
60 return super.getHibernateTemplate().execute( new HibernateCallback() {
62 public Object
doInHibernate(Session session
) throws HibernateException
, SQLException
{
65 Criteria crit
= session
.createCriteria(clazz
);
66 if(arguments
.length
> 0) {
67 if(arguments
[0] instanceof Map
) {
68 Map argMap
= (Map
)arguments
[0];
69 GrailsHibernateUtil
.populateArgumentsForCriteria(crit
,argMap
);
72 if(operator
.equals(OPERATOR_OR
)) {
73 Disjunction dis
= Restrictions
.disjunction();
74 for (Iterator i
= expressions
.iterator(); i
.hasNext();) {
75 GrailsMethodExpression current
= (GrailsMethodExpression
) i
.next();
76 dis
.add( current
.getCriterion() );
81 for (Iterator i
= expressions
.iterator(); i
.hasNext();) {
82 GrailsMethodExpression current
= (GrailsMethodExpression
) i
.next();
83 crit
.add( current
.getCriterion() );
87 crit
.setMaxResults(1);
88 return crit
.uniqueResult();