1 package org.hibernate.impl; 3 4 import java.util.ArrayList ; 5 import java.util.Arrays ; 6 import java.util.Collection ; 7 import java.util.Iterator ; 8 import java.util.List ; 9 import java.util.Map ; 10 11 import org.hibernate.FlushMode; 12 import org.hibernate.HibernateException; 13 import org.hibernate.LockMode; 14 import org.hibernate.Query; 15 import org.hibernate.QueryException; 16 import org.hibernate.SQLQuery; 17 import org.hibernate.ScrollMode; 18 import org.hibernate.ScrollableResults; 19 import org.hibernate.MappingException; 20 import org.hibernate.engine.ResultSetMappingDefinition; 21 import org.hibernate.engine.NamedSQLQueryDefinition; 22 import org.hibernate.engine.QueryParameters; 23 import org.hibernate.engine.SessionImplementor; 24 import org.hibernate.loader.custom.SQLCustomQuery; 25 import org.hibernate.loader.custom.SQLQueryJoinReturn; 26 import org.hibernate.loader.custom.SQLQueryReturn; 27 import org.hibernate.loader.custom.SQLQueryRootReturn; 28 import org.hibernate.loader.custom.SQLQueryScalarReturn; 29 import org.hibernate.type.Type; 30 import org.hibernate.util.CollectionHelper; 31 import org.hibernate.util.StringHelper; 32 33 46 public class SQLQueryImpl extends AbstractQueryImpl implements SQLQuery { 47 48 private final List queryReturns; 49 private final List scalarQueryReturns; 50 private final Collection querySpaces; 51 private final boolean callable; 52 53 59 SQLQueryImpl(NamedSQLQueryDefinition queryDef, SessionImplementor session) { 60 super(queryDef.getQueryString(), queryDef.getFlushMode(), session); 61 if ( queryDef.getResultSetRef() != null ) { 62 ResultSetMappingDefinition definition = session.getFactory().getResultSetMapping( queryDef.getResultSetRef() ); 63 if (definition == null) throw new MappingException("Unable to find resultset-ref definition: " 64 + queryDef.getResultSetRef() ); 65 this.scalarQueryReturns = Arrays.asList( definition.getScalarQueryReturns() ); 66 this.queryReturns = Arrays.asList( definition.getEntityQueryReturns() ); 67 } 68 else { 69 this.scalarQueryReturns = Arrays.asList( queryDef.getScalarQueryReturns() ); 70 this.queryReturns = Arrays.asList( queryDef.getQueryReturns() ); 71 } 72 73 this.querySpaces = queryDef.getQuerySpaces(); 74 this.callable = queryDef.isCallable(); 75 } 76 77 SQLQueryImpl( 78 final String sql, 79 final List queryReturns, 80 final List scalarQueryReturns, 81 final Collection querySpaces, 82 final FlushMode flushMode, 83 boolean callable, final SessionImplementor session 84 ) { 85 super(sql, flushMode, session); 86 this.queryReturns = queryReturns; 87 this.scalarQueryReturns = scalarQueryReturns; 88 this.querySpaces = querySpaces; 89 this.callable = callable; 90 } 91 92 SQLQueryImpl( 93 final String sql, 94 final String returnAliases[], 95 final Class returnClasses[], 96 final LockMode[] lockModes, 97 final SessionImplementor session, 98 final Collection querySpaces, 99 final FlushMode flushMode 100 ) { 101 super(sql, flushMode, session); 102 scalarQueryReturns=null; 103 queryReturns = new ArrayList (returnAliases.length); 104 for ( int i=0; i<returnAliases.length; i++ ) { 105 SQLQueryRootReturn ret = new SQLQueryRootReturn( 106 returnAliases[i], 107 returnClasses[i].getName(), 108 lockModes==null ? LockMode.NONE : lockModes[i] 109 ); 110 queryReturns.add(ret); 111 } 112 this.querySpaces = querySpaces; 113 this.callable = false; 114 } 115 116 SQLQueryImpl( 117 final String sql, 118 final String returnAliases[], 119 final Class returnClasses[], 120 final SessionImplementor session 121 ) { 122 this(sql, returnAliases, returnClasses, null, session, null, null); 123 } 124 125 SQLQueryImpl(String sql, SessionImplementor session) { 126 super(sql, null, session); 127 queryReturns = new ArrayList (); 128 scalarQueryReturns = new ArrayList (); 129 querySpaces = null; 130 callable = false; 131 } 132 133 private static final SQLQueryReturn[] NO_SQL_RETURNS = new SQLQueryReturn[0]; 134 private static final SQLQueryScalarReturn[] NO_SQL_SCALAR_RETURNS = new SQLQueryScalarReturn[0]; 135 136 private SQLQueryReturn[] getQueryReturns() { 137 return (SQLQueryReturn[]) queryReturns.toArray(NO_SQL_RETURNS); 138 } 139 140 private SQLQueryScalarReturn[] getQueryScalarReturns() { 141 return scalarQueryReturns==null ? 142 null : 143 (SQLQueryScalarReturn[]) scalarQueryReturns.toArray(NO_SQL_SCALAR_RETURNS); 144 } 145 146 public List list() throws HibernateException { 147 verifyParameters(); 148 Map namedParams = getNamedParams(); 149 before(); 150 151 SQLCustomQuery cq = new SQLCustomQuery( 152 getQueryReturns(), 153 getQueryScalarReturns(), 154 bindParameterLists(namedParams), 155 querySpaces, 156 getSession().getFactory() 157 ); 158 159 try { 160 return getSession().listCustomQuery( cq, getQueryParameters(namedParams) ); 161 } 162 finally { 163 after(); 164 } 165 } 166 167 public QueryParameters getQueryParameters(Map namedParams) { 168 QueryParameters qp = super.getQueryParameters(namedParams); 169 qp.setCallable(callable); 170 return qp; 171 } 172 173 protected void verifyParameters() { 174 verifyParameters(callable); 175 if((queryReturns==null || queryReturns.isEmpty()) && (scalarQueryReturns==null || scalarQueryReturns.isEmpty())) { 176 throw new QueryException( "addEntity() or addScalar() must be called on a sql query before executing the query.", getQueryString() ); 177 } 178 } 179 180 public ScrollableResults scroll(ScrollMode scrollMode) throws HibernateException { 181 verifyParameters(); 182 Map namedParams = getNamedParams(); 183 before(); 184 185 SQLCustomQuery cq = new SQLCustomQuery( 186 getQueryReturns(), 187 getQueryScalarReturns(), 188 bindParameterLists(namedParams), 189 querySpaces, 190 getSession().getFactory() 191 ); 192 193 QueryParameters qp = getQueryParameters(namedParams); 194 qp.setScrollMode(scrollMode); 195 196 try { 197 return getSession().scrollCustomQuery(cq, qp); 198 } 199 finally { 200 after(); 201 } 202 } 203 204 public ScrollableResults scroll() throws HibernateException { 205 return scroll(ScrollMode.SCROLL_INSENSITIVE); 206 } 207 208 public Iterator iterate() throws HibernateException { 209 throw new UnsupportedOperationException ("SQL queries do not currently support iteration"); 210 } 211 212 public String [] getReturnAliases() throws HibernateException { 213 throw new UnsupportedOperationException ("SQL queries do not currently support returning aliases"); 214 } 215 216 public Type[] getReturnTypes() throws HibernateException { 217 throw new UnsupportedOperationException ("not yet implemented for SQL queries"); 218 } 219 220 public Query setLockMode(String alias, LockMode lockMode) { 221 throw new UnsupportedOperationException ("cannot set the lock mode for a native SQL query"); 222 } 223 224 protected Map getLockModes() { 225 return CollectionHelper.EMPTY_MAP; 227 } 228 229 public SQLQuery addScalar(String columnAlias, Type type) { 230 scalarQueryReturns.add( new SQLQueryScalarReturn(columnAlias, type) ); 231 return this; 232 } 233 234 public SQLQuery addJoin(String alias, String path) { 235 return addJoin(alias, path, LockMode.READ); 236 } 237 238 public SQLQuery addEntity(Class entityClass) { 239 return addEntity( StringHelper.unqualify( entityClass.getName() ), entityClass ); 240 } 241 242 public SQLQuery addEntity(String entityName) { 243 return addEntity( StringHelper.unqualify( entityName ), entityName ); 244 } 245 246 public SQLQuery addEntity(String alias, String entityName) { 247 return addEntity(alias, entityName, LockMode.READ); 248 } 249 250 public SQLQuery addEntity(String alias, Class entityClass) { 251 return addEntity( alias, entityClass.getName() ); 252 } 253 254 public SQLQuery addJoin(String alias, String path, LockMode lockMode) { 255 int loc = path.indexOf('.'); 256 if ( loc<0 ) throw new QueryException("not a property path: " + path); 257 String ownerAlias = path.substring(0, loc); 258 String role = path.substring(loc+1); 259 queryReturns.add( new SQLQueryJoinReturn(alias, ownerAlias, role, CollectionHelper.EMPTY_MAP, lockMode) ); 260 return this; 261 } 262 263 public SQLQuery addEntity(String alias, String entityName, LockMode lockMode) { 264 queryReturns.add( new SQLQueryRootReturn(alias, entityName, lockMode) ); 265 return this; 266 } 267 268 public SQLQuery addEntity(String alias, Class entityClass, LockMode lockMode) { 269 return addEntity( alias, entityClass.getName(), lockMode ); 270 } 271 272 public SQLQuery setResultSetMapping(String name) { 273 ResultSetMappingDefinition mapping = session.getFactory().getResultSetMapping(name); 274 if (mapping == null) throw new MappingException("Unknown SqlResultSetMapping named:" + name); 275 SQLQueryReturn[] returns = mapping.getEntityQueryReturns(); 276 int length = returns.length; 277 for (int index = 0 ; index < length ; index++ ) { 278 queryReturns.add( returns[index] ); 279 } 280 SQLQueryScalarReturn[] scalarReturns = mapping.getScalarQueryReturns(); 281 length = scalarReturns.length; 282 for (int index = 0 ; index < length ; index++ ) { 283 scalarQueryReturns.add( scalarReturns[index] ); 284 } 285 return this; 286 } 287 } 288 | Popular Tags |