1 //$Id: QueryImpl.java 11171 2007-02-08 03:40:51Z epbernard $
2 package org.hibernate.ejb;
3
4 import java.util.Calendar;
5 import java.util.Collection;
6 import java.util.Date;
7 import java.util.List;
8 import java.util.HashSet;
9 import java.util.Set;
10 import javax.persistence.FlushModeType;
11 import javax.persistence.NoResultException;
12 import javax.persistence.NonUniqueResultException;
13 import javax.persistence.Query;
14 import javax.persistence.TemporalType;
15 import static javax.persistence.TemporalType.*;
16 import javax.persistence.TransactionRequiredException;
17
18 import org.hibernate.CacheMode;
19 import org.hibernate.FlushMode;
20 import org.hibernate.HibernateException;
21 import org.hibernate.QueryParameterException;
22 import org.hibernate.TypeMismatchException;
23 import org.hibernate.ejb.util.ConfigurationHelper;
24 import org.hibernate.hql.QueryExecutionRequestException;
25
26 /**
27 * @author <a href="mailto:gavin@hibernate.org">Gavin King</a>
28 * @author Emmanuel Bernard
29 */
30 public class QueryImpl implements Query, HibernateQuery {
31 private org.hibernate.Query query;
32 private HibernateEntityManagerImplementor em;
33 private Boolean isPositional = null;
34
35 public QueryImpl(org.hibernate.Query query, AbstractEntityManagerImpl em) {
36 this.query = query;
37 this.em = em;
38 }
39
40 public org.hibernate.Query getHibernateQuery() {
41 return query;
42 }
43
44 public int executeUpdate() {
45 try {
46 if ( ! em.isTransactionInProgress() ) {
47 em.throwPersistenceException( new TransactionRequiredException( "Executing an update/delete query" ) );
48 return 0;
49 }
50 return query.executeUpdate();
51 }
52 catch (QueryExecutionRequestException he) {
53 throw new IllegalStateException(he);
54 }
55 catch( TypeMismatchException e ) {
56 throw new IllegalArgumentException(e);
57 }
58 catch (HibernateException he) {
59 em.throwPersistenceException( he );
60 return 0;
61 }
62 }
63
64 public List getResultList() {
65 try {
66 return query.list();
67 }
68 catch (QueryExecutionRequestException he) {
69 throw new IllegalStateException(he);
70 }
71 catch( TypeMismatchException e ) {
72 throw new IllegalArgumentException(e);
73 }
74 catch (HibernateException he) {
75 em.throwPersistenceException( he );
76 return null;
77 }
78 }
79
80 public Object getSingleResult() {
81 try {
82 List result = query.list();
83 if ( result.size() == 0 ) {
84 em.throwPersistenceException( new NoResultException( "No entity found for query" ) );
85 }
86 else if ( result.size() > 1 ) {
87 Set uniqueResult = new HashSet(result);
88 if ( uniqueResult.size() > 1 ) {
89 em.throwPersistenceException( new NonUniqueResultException( "result returns " + uniqueResult.size() + " elements") );
90 }
91 else {
92 return uniqueResult.iterator().next();
93 }
94
95 }
96 else {
97 return result.get(0);
98 }
99 return null; //should never happen
100 }
101 catch (QueryExecutionRequestException he) {
102 throw new IllegalStateException(he);
103 }
104 catch( TypeMismatchException e ) {
105 throw new IllegalArgumentException(e);
106 }
107 catch (HibernateException he) {
108 em.throwPersistenceException( he );
109 return null;
110 }
111 }
112
113 public Query setMaxResults(int maxResult) {
114 if ( maxResult < 0 ) {
115 throw new IllegalArgumentException(
116 "Negative ("
117 + maxResult
118 + ") parameter passed in to setMaxResults"
119 );
120 }
121 query.setMaxResults( maxResult );
122 return this;
123 }
124
125 public Query setFirstResult(int firstResult) {
126 if ( firstResult < 0 ) {
127 throw new IllegalArgumentException(
128 "Negative ("
129 + firstResult
130 + ") parameter passed in to setFirstResult"
131 );
132 }
133 query.setFirstResult( firstResult );
134 return this;
135 }
136
137 public Query setHint(String hintName, Object value) {
138 try {
139 if ( "org.hibernate.timeout".equals( hintName ) ) {
140 query.setTimeout( (Integer) value );
141 }
142 else if ( "org.hibernate.comment".equals( hintName ) ) {
143 query.setComment( (String) value );
144 }
145 else if ( "org.hibernate.fetchSize".equals( hintName ) ) {
146 query.setFetchSize( (Integer) value );
147 }
148 else if ( "org.hibernate.cacheRegion".equals( hintName ) ) {
149 query.setCacheRegion( (String) value );
150 }
151 else if ( "org.hibernate.cacheable".equals( hintName ) ) {
152 query.setCacheable( (Boolean) value );
153 }
154 else if ( "org.hibernate.readOnly".equals( hintName ) ) {
155 query.setReadOnly( (Boolean) value );
156 }
157 else if ( "org.hibernate.cacheMode".equals( hintName ) ) {
158 query.setCacheMode( (CacheMode) value );
159 }
160 else if ( "org.hibernate.flushMode".equals( hintName ) ) {
161 query.setFlushMode( ConfigurationHelper.getFlushMode( value ) );
162 }
163 //TODO:
164 /*else if ( "org.hibernate.lockMode".equals( hintName ) ) {
165 query.setLockMode( alias, lockMode );
166 }*/
167 }
168 catch (ClassCastException e) {
169 throw new IllegalArgumentException( "Value for hint" );
170 }
171 return this;
172 }
173
174 public Query setParameter(String name, Object value) {
175 try {
176 if ( value instanceof Collection ) {
177 query.setParameterList( name, (Collection) value );
178 }
179 else {
180 query.setParameter( name, value );
181 }
182 return this;
183 }
184 catch (QueryParameterException e) {
185 throw new IllegalArgumentException( e );
186 }
187 catch (HibernateException he) {
188 em.throwPersistenceException( he );
189 return null;
190 }
191 }
192
193 public Query setParameter(String name, Date value, TemporalType temporalType) {
194 try {
195 if ( temporalType == DATE ) {
196 query.setDate( name, value );
197 }
198 else if ( temporalType == TIME ) {
199 query.setTime( name, value );
200 }
201 else if ( temporalType == TIMESTAMP ) {
202 query.setTimestamp( name, value );
203 }
204 return this;
205 }
206 catch (QueryParameterException e) {
207 throw new IllegalArgumentException( e );
208 }
209 catch (HibernateException he) {
210 em.throwPersistenceException( he );
211 return null;
212 }
213 }
214
215 public Query setParameter(String name, Calendar value, TemporalType temporalType) {
216 try {
217 if ( temporalType == DATE ) {
218 query.setCalendarDate( name, value );
219 }
220 else if ( temporalType == TIME ) {
221 throw new IllegalArgumentException( "not yet implemented" );
222 }
223 else if ( temporalType == TIMESTAMP ) {
224 query.setCalendar( name, value );
225 }
226 return this;
227 }
228 catch (QueryParameterException e) {
229 throw new IllegalArgumentException( e );
230 }
231 catch (HibernateException he) {
232 em.throwPersistenceException( he );
233 return null;
234 }
235 }
236
237 public Query setParameter(int position, Object value) {
238 try {
239 if ( isPositionalParameter() ) {
240 this.setParameter( Integer.toString( position ), value );
241 }
242 else {
243 query.setParameter( position - 1, value );
244 }
245 return this;
246 }
247 catch (QueryParameterException e) {
248 throw new IllegalArgumentException( e );
249 }
250 catch (HibernateException he) {
251 em.throwPersistenceException( he );
252 return null;
253 }
254 }
255
256 private boolean isPositionalParameter() {
257 if (isPositional == null) {
258 //compute it
259 String queryString = query.getQueryString();
260 int index = queryString.indexOf( '?' );
261 //there is a ? and the following char is a digit
262 if (index == -1) {
263 //no ?
264 isPositional = true;
265 }
266 else if ( index == queryString.length() - 1 ) {
267 // "... ?"
268 isPositional = false;
269 }
270 else {
271 isPositional = Character.isDigit( queryString.charAt( index + 1 ) );
272 }
273 }
274 return isPositional;
275 }
276
277 public Query setParameter(int position, Date value, TemporalType temporalType) {
278 try {
279 if ( isPositionalParameter() ) {
280 String name = Integer.toString( position );
281 this.setParameter( name, value, temporalType );
282 }
283 else {
284 if ( temporalType == DATE ) {
285 query.setDate( position - 1, value );
286 }
287 else if ( temporalType == TIME ) {
288 query.setTime( position - 1, value );
289 }
290 else if ( temporalType == TIMESTAMP ) {
291 query.setTimestamp( position - 1, value );
292 }
293 }
294 return this;
295 }
296 catch (QueryParameterException e) {
297 throw new IllegalArgumentException( e );
298 }
299 catch (HibernateException he) {
300 em.throwPersistenceException( he );
301 return null;
302 }
303 }
304
305 public Query setParameter(int position, Calendar value, TemporalType temporalType) {
306 try {
307 if ( isPositionalParameter() ) {
308 String name = Integer.toString( position );
309 this.setParameter( name, value, temporalType );
310 }
311 else {
312 if ( temporalType == DATE ) {
313 query.setCalendarDate( position - 1, value );
314 }
315 else if ( temporalType == TIME ) {
316 throw new IllegalArgumentException( "not yet implemented" );
317 }
318 else if ( temporalType == TIMESTAMP ) {
319 query.setCalendar( position - 1, value );
320 }
321 }
322 return this;
323 }
324 catch (QueryParameterException e) {
325 throw new IllegalArgumentException( e );
326 }
327 catch (HibernateException he) {
328 em.throwPersistenceException( he );
329 return null;
330 }
331 }
332
333 public Query setFlushMode(FlushModeType flushMode) {
334 if ( flushMode == FlushModeType.AUTO ) {
335 query.setFlushMode( FlushMode.AUTO );
336 }
337 else if ( flushMode == FlushModeType.COMMIT ) {
338 query.setFlushMode( FlushMode.COMMIT );
339 }
340 return this;
341 }
342 }