001: package org.apache.torque.util;
002:
003: /*
004: * Licensed to the Apache Software Foundation (ASF) under one
005: * or more contributor license agreements. See the NOTICE file
006: * distributed with this work for additional information
007: * regarding copyright ownership. The ASF licenses this file
008: * to you under the Apache License, Version 2.0 (the
009: * "License"); you may not use this file except in compliance
010: * with the License. You may obtain a copy of the License at
011: *
012: * http://www.apache.org/licenses/LICENSE-2.0
013: *
014: * Unless required by applicable law or agreed to in writing,
015: * software distributed under the License is distributed on an
016: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017: * KIND, either express or implied. See the License for the
018: * specific language governing permissions and limitations
019: * under the License.
020: */
021:
022: import java.util.Calendar;
023: import java.util.Date;
024: import java.util.List;
025: import java.util.Map;
026:
027: import org.apache.commons.configuration.BaseConfiguration;
028: import org.apache.commons.configuration.Configuration;
029: import org.apache.commons.lang.SerializationUtils;
030: import org.apache.torque.BaseTestCase;
031: import org.apache.torque.Torque;
032: import org.apache.torque.TorqueException;
033: import org.apache.torque.adapter.DBFactory;
034: import org.apache.torque.map.ColumnMap;
035: import org.apache.torque.map.DatabaseMap;
036: import org.apache.torque.map.TableMap;
037: import org.apache.torque.util.Criteria.Criterion;
038: import org.apache.torque.util.Criteria.Join;
039:
040: /**
041: * Test class for Criteria.
042: *
043: * @author <a href="mailto:celkins@scardini.com">Christopher Elkins</a>
044: * @author <a href="mailto:sam@neurogrid.com">Sam Joseph</a>
045: * @author <a href="mailto:seade@backstagetech.com.au">Scott Eade</a>
046: * @version $Id: CriteriaTest.java 535591 2007-05-06 10:05:04Z tfischer $
047: */
048: public class CriteriaTest extends BaseTestCase {
049:
050: /** The criteria to use in the test. */
051: private Criteria c;
052:
053: /**
054: * Creates a new instance.
055: *
056: * @param name the name of the test to run
057: */
058: public CriteriaTest(String name) {
059: super (name);
060: }
061:
062: /**
063: * Initializes the criteria.
064: */
065: public void setUp() {
066: super .setUp();
067: c = new Criteria();
068: }
069:
070: /**
071: * Test basic adding of strings.
072: */
073: public void testAddString() {
074: final String table = "myTable";
075: final String column = "myColumn";
076: final String value = "myValue";
077:
078: // Add the string
079: c.add(table, column, (Object) value);
080:
081: // Verify that the key exists
082: assertTrue(c.containsKey(table, column));
083:
084: // Verify that what we get out is what we put in
085: assertTrue(c.getString(table, column).equals(value));
086: }
087:
088: /**
089: * test various properties of Criterion and nested criterion
090: */
091: public void testNestedCriterion() {
092: final String table2 = "myTable2";
093: final String column2 = "myColumn2";
094: final String value2 = "myValue2";
095:
096: final String table3 = "myTable3";
097: final String column3 = "myColumn3";
098: final String value3 = "myValue3";
099:
100: final String table4 = "myTable4";
101: final String column4 = "myColumn4";
102: final String value4 = "myValue4";
103:
104: final String table5 = "myTable5";
105: final String column5 = "myColumn5";
106: final String value5 = "myValue5";
107:
108: Criteria.Criterion crit2 = c.getNewCriterion(table2, column2,
109: (Object) value2, Criteria.EQUAL);
110: Criteria.Criterion crit3 = c.getNewCriterion(table3, column3,
111: (Object) value3, Criteria.EQUAL);
112: Criteria.Criterion crit4 = c.getNewCriterion(table4, column4,
113: (Object) value4, Criteria.EQUAL);
114: Criteria.Criterion crit5 = c.getNewCriterion(table5, column5,
115: (Object) value5, Criteria.EQUAL);
116:
117: crit2.and(crit3).or(crit4.and(crit5));
118: String expect = "((myTable2.myColumn2='myValue2' "
119: + "AND myTable3.myColumn3='myValue3') "
120: + "OR (myTable4.myColumn4='myValue4' "
121: + "AND myTable5.myColumn5='myValue5'))";
122: String result = crit2.toString();
123: assertEquals(expect, result);
124:
125: Criteria.Criterion crit6 = c.getNewCriterion(table2, column2,
126: (Object) value2, Criteria.EQUAL);
127: Criteria.Criterion crit7 = c.getNewCriterion(table3, column3,
128: (Object) value3, Criteria.EQUAL);
129: Criteria.Criterion crit8 = c.getNewCriterion(table4, column4,
130: (Object) value4, Criteria.EQUAL);
131: Criteria.Criterion crit9 = c.getNewCriterion(table5, column5,
132: (Object) value5, Criteria.EQUAL);
133:
134: crit6.and(crit7).or(crit8).and(crit9);
135: expect = "(((myTable2.myColumn2='myValue2' "
136: + "AND myTable3.myColumn3='myValue3') "
137: + "OR myTable4.myColumn4='myValue4') "
138: + "AND myTable5.myColumn5='myValue5')";
139: result = crit6.toString();
140: assertEquals(expect, result);
141:
142: // should make sure we have tests for all possibilities
143:
144: Criteria.Criterion[] crita = crit2.getAttachedCriterion();
145:
146: assertEquals(crit2, crita[0]);
147: assertEquals(crit3, crita[1]);
148: assertEquals(crit4, crita[2]);
149: assertEquals(crit5, crita[3]);
150:
151: List tables = crit2.getAllTables();
152:
153: assertEquals(crit2.getTable(), tables.get(0));
154: assertEquals(crit3.getTable(), tables.get(1));
155: assertEquals(crit4.getTable(), tables.get(2));
156: assertEquals(crit5.getTable(), tables.get(3));
157:
158: // simple confirmations that equality operations work
159: assertTrue(crit2.hashCode() == crit2.hashCode());
160: assertEquals(crit2.toString(), crit2.toString());
161: }
162:
163: /**
164: * Tests <= and =>.
165: */
166: public void testBetweenCriterion() {
167: Criteria.Criterion cn1 = c.getNewCriterion("INVOICE.COST",
168: new Integer(1000), Criteria.GREATER_EQUAL);
169: Criteria.Criterion cn2 = c.getNewCriterion("INVOICE.COST",
170: new Integer(5000), Criteria.LESS_EQUAL);
171: c.add(cn1.and(cn2));
172: String expect = "SELECT FROM INVOICE WHERE "
173: + "(INVOICE.COST>=1000 AND INVOICE.COST<=5000)";
174: String result = null;
175: try {
176: result = BasePeer.createQueryString(c);
177: } catch (TorqueException e) {
178: fail("TorqueException thrown in BasePeer.createQueryString()");
179: }
180:
181: assertEquals(expect, result);
182: }
183:
184: /**
185: * Verify that AND and OR criterion are nested correctly.
186: */
187: public void testPrecedence() {
188: Criteria.Criterion cn1 = c.getNewCriterion("INVOICE.COST",
189: "1000", Criteria.GREATER_EQUAL);
190: Criteria.Criterion cn2 = c.getNewCriterion("INVOICE.COST",
191: "2000", Criteria.LESS_EQUAL);
192: Criteria.Criterion cn3 = c.getNewCriterion("INVOICE.COST",
193: "8000", Criteria.GREATER_EQUAL);
194: Criteria.Criterion cn4 = c.getNewCriterion("INVOICE.COST",
195: "9000", Criteria.LESS_EQUAL);
196: c.add(cn1.and(cn2));
197: c.or(cn3.and(cn4));
198:
199: String expect = "SELECT FROM INVOICE WHERE "
200: + "((INVOICE.COST>='1000' AND INVOICE.COST<='2000') "
201: + "OR (INVOICE.COST>='8000' AND INVOICE.COST<='9000'))";
202:
203: String result = null;
204: try {
205: result = BasePeer.createQueryString(c);
206: } catch (TorqueException e) {
207: fail("TorqueException thrown in BasePeer.createQueryString()");
208: }
209:
210: assertEquals(expect, result);
211: }
212:
213: /**
214: * Test Criterion.setIgnoreCase().
215: * As the output is db specific the test just prints the result to
216: * System.out
217: */
218: public void testCriterionIgnoreCase() {
219: Criteria myCriteria = new Criteria();
220:
221: Criteria.Criterion expected = myCriteria.getNewCriterion(
222: "TABLE.COLUMN", (Object) "FoObAr", Criteria.LIKE);
223: Criteria.Criterion result = expected.setIgnoreCase(true);
224: assertEquals(
225: "Criterion mis-match after calling setIgnoreCase(true)",
226: expected.toString(), result.toString());
227: }
228:
229: /**
230: * Test that true is evaluated correctly.
231: */
232: public void testBoolean() {
233: Criteria c = new Criteria().add("TABLE.COLUMN", true);
234:
235: String expect = "SELECT FROM TABLE WHERE TABLE.COLUMN=1";
236:
237: String result = null;
238: try {
239: result = BasePeer.createQueryString(c);
240: } catch (TorqueException e) {
241: fail("TorqueException thrown in BasePeer.createQueryString()");
242: }
243:
244: assertEquals(expect, result);
245:
246: // test the postgresql variation
247: c = new Criteria();
248: Criteria.Criterion cc = c.getNewCriterion("TABLE.COLUMN",
249: Boolean.TRUE, Criteria.EQUAL);
250:
251: Configuration conf = new BaseConfiguration();
252: conf.addProperty("driver", "org.postgresql.Driver");
253: try {
254: cc.setDB(DBFactory.create("org.postgresql.Driver"));
255: } catch (Exception e) {
256: fail("Exception thrown in DBFactory");
257: }
258:
259: assertEquals("TABLE.COLUMN=TRUE", cc.toString());
260: }
261:
262: /**
263: * testcase for addDate()
264: */
265: public void testAddDate() {
266: Criteria c = new Criteria();
267: c.addDate("TABLE.DATE_COLUMN", 2003, 0, 22);
268:
269: String expect = "SELECT FROM TABLE WHERE TABLE.DATE_COLUMN='20030122000000'";
270:
271: String result = null;
272: try {
273: result = BasePeer.createQueryString(c);
274: } catch (TorqueException e) {
275: e.printStackTrace();
276: fail("TorqueException thrown in BasePeer.createQueryString()");
277: }
278: assertEquals(expect, result);
279: }
280:
281: /**
282: * testcase for andDate()
283: * issue TORQUE-42
284: */
285: public void testAndDate() {
286: Criteria c = new Criteria();
287: c.addDate("TABLE.DATE_COLUMN", 2003, 0, 22,
288: Criteria.GREATER_THAN);
289: c.andDate("TABLE.DATE_COLUMN", 2004, 0, 22, Criteria.LESS_THAN);
290:
291: String expect = "SELECT FROM TABLE WHERE (TABLE.DATE_COLUMN>'20030122000000' AND TABLE.DATE_COLUMN<'20040122000000')";
292:
293: String result = null;
294: try {
295: result = BasePeer.createQueryString(c);
296: } catch (TorqueException e) {
297: e.printStackTrace();
298: fail("TorqueException thrown in BasePeer.createQueryString()");
299: }
300: assertEquals(expect, result);
301: }
302:
303: /**
304: * testcase for add(Date)
305: */
306: public void testDateAdd() {
307: Calendar cal = Calendar.getInstance();
308: cal.set(2003, 0, 22, 0, 0, 0);
309: Date date = cal.getTime();
310: Criteria c = new Criteria();
311: c.add("TABLE.DATE_COLUMN", date);
312:
313: String expect = "SELECT FROM TABLE WHERE TABLE.DATE_COLUMN='20030122000000'";
314:
315: String result = null;
316: try {
317: result = BasePeer.createQueryString(c);
318: } catch (TorqueException e) {
319: e.printStackTrace();
320: fail("TorqueException thrown in BasePeer.createQueryString()");
321: }
322: assertEquals(expect, result);
323: }
324:
325: public void testCurrentDate() {
326: Criteria c = new Criteria().add("TABLE.DATE_COLUMN",
327: Criteria.CURRENT_DATE).add("TABLE.TIME_COLUMN",
328: Criteria.CURRENT_TIME);
329:
330: String expect = "SELECT FROM TABLE WHERE TABLE.TIME_COLUMN=CURRENT_TIME AND TABLE.DATE_COLUMN=CURRENT_DATE";
331:
332: String result = null;
333: try {
334: result = BasePeer.createQueryString(c);
335: } catch (TorqueException e) {
336: e.printStackTrace();
337: fail("TorqueException thrown in BasePeer.createQueryString()");
338: }
339:
340: assertEquals(expect, result);
341: }
342:
343: public void testCountAster() {
344: Criteria c = new Criteria().addSelectColumn("COUNT(*)").add(
345: "TABLE.DATE_COLUMN", Criteria.CURRENT_DATE).add(
346: "TABLE.TIME_COLUMN", Criteria.CURRENT_TIME);
347:
348: String expect = "SELECT COUNT(*) FROM TABLE WHERE TABLE.TIME_COLUMN=CURRENT_TIME AND TABLE.DATE_COLUMN=CURRENT_DATE";
349:
350: String result = null;
351: try {
352: result = BasePeer.createQueryString(c);
353: } catch (TorqueException e) {
354: e.printStackTrace();
355: fail("TorqueException thrown in BasePeer.createQueryString()");
356: }
357:
358: assertEquals(expect, result);
359:
360: }
361:
362: /**
363: * This test case has been written to try out the fix applied to resolve
364: * TRQS73 - i.e. ensuring that Criteria.toString() does not alter any limit
365: * or offset that may be stored in the Criteria object. This testcase
366: * could actually pass without the fix if the database in use does not
367: * support native limits and offsets.
368: */
369: public void testCriteriaToStringOffset() {
370: Criteria c = new Criteria().add("TABLE.DATE_COLUMN",
371: Criteria.CURRENT_DATE).setOffset(3).setLimit(5);
372:
373: String toStringExpect = "Criteria:: TABLE.DATE_COLUMN<=>TABLE.DATE_COLUMN=CURRENT_DATE: "
374: + "\nCurrent Query SQL (may not be complete or applicable): "
375: + "SELECT FROM TABLE WHERE TABLE.DATE_COLUMN=CURRENT_DATE LIMIT 5 OFFSET 3";
376:
377: String cString = c.toString();
378: //System.out.println(cString);
379: assertEquals(toStringExpect, cString);
380:
381: // Note that this is intentionally the same as above as the behaviour is
382: // only observed on subsequent invocations of toString().
383: cString = c.toString();
384: //System.out.println(cString);
385: assertEquals(toStringExpect, cString);
386: }
387:
388: /**
389: * TORQUE-87
390: */
391: public void testCriteriaWithOffsetNoLimit() {
392: Criteria c = new Criteria().add("TABLE.DATE_COLUMN",
393: Criteria.CURRENT_DATE).setOffset(3);
394:
395: String toStringExpect = "Criteria:: TABLE.DATE_COLUMN<=>TABLE.DATE_COLUMN=CURRENT_DATE: "
396: + "\nCurrent Query SQL (may not be complete or applicable): "
397: + "SELECT FROM TABLE WHERE TABLE.DATE_COLUMN=CURRENT_DATE LIMIT 18446744073709551615 OFFSET 3";
398:
399: String cString = c.toString();
400: //System.out.println(cString);
401: assertEquals(toStringExpect, cString);
402:
403: // Note that this is intentionally the same as above as the behaviour is
404: // only observed on subsequent invocations of toString().
405: cString = c.toString();
406: //System.out.println(cString);
407: assertEquals(toStringExpect, cString);
408: }
409:
410: /**
411: * This test case has been written to try out the fix applied to resolve
412: * TRQS73 - i.e. ensuring that Criteria.toString() does not alter any limit
413: * or offset that may be stored in the Criteria object. This testcase
414: * could actually pass without the fix if the database in use does not
415: * support native limits and offsets.
416: */
417: public void testCriteriaToStringLimit() {
418: Criteria c = new Criteria().add("TABLE.DATE_COLUMN",
419: Criteria.CURRENT_DATE).setLimit(5);
420:
421: String toStringExpect = "Criteria:: TABLE.DATE_COLUMN<=>TABLE.DATE_COLUMN=CURRENT_DATE: "
422: + "\nCurrent Query SQL (may not be complete or applicable): "
423: + "SELECT FROM TABLE WHERE TABLE.DATE_COLUMN=CURRENT_DATE LIMIT 5";
424:
425: String cString = c.toString();
426: //System.out.println(cString);
427: assertEquals(toStringExpect, cString);
428:
429: // Note that this is intentionally the same as above as the behaviour is
430: // only observed on subsequent invocations of toString().
431: cString = c.toString();
432: //System.out.println(cString);
433: assertEquals(toStringExpect, cString);
434: }
435:
436: /**
437: * This test case verifies if the Criteria.LIKE comparison type will
438: * get replaced through Criteria.EQUAL if there are no SQL wildcards
439: * in the given value.
440: */
441: public void testLikeWithoutWildcards() {
442: Criteria c = new Criteria();
443: c.add("TABLE.COLUMN", (Object) "no wildcards", Criteria.LIKE);
444:
445: String expect = "SELECT FROM TABLE WHERE TABLE.COLUMN = 'no wildcards'";
446:
447: String result = null;
448: try {
449: result = BasePeer.createQueryString(c);
450: } catch (TorqueException e) {
451: e.printStackTrace();
452: fail("TorqueException thrown in BasePeer.createQueryString()");
453: }
454:
455: assertEquals(expect, result);
456: }
457:
458: /**
459: * This test case verifies if the Criteria.NOT_LIKE comparison type will
460: * get replaced through Criteria.NOT_EQUAL if there are no SQL wildcards
461: * in the given value.
462: */
463: public void testNotLikeWithoutWildcards() {
464: Criteria c = new Criteria();
465: c.add("TABLE.COLUMN", (Object) "no wildcards",
466: Criteria.NOT_LIKE);
467:
468: String firstExpect = "SELECT FROM TABLE WHERE TABLE.COLUMN != 'no wildcards'";
469: String secondExpect = "SELECT FROM TABLE WHERE TABLE.COLUMN <> 'no wildcards'";
470:
471: String result = null;
472: try {
473: result = BasePeer.createQueryString(c);
474: } catch (TorqueException e) {
475: e.printStackTrace();
476: fail("TorqueException thrown in BasePeer.createQueryString()");
477: }
478:
479: assertTrue(result.equals(firstExpect)
480: || result.equals(secondExpect));
481: }
482:
483: /**
484: * Test that serialization works.
485: */
486: public void testSerialization() {
487: c.setOffset(10);
488: c.setLimit(11);
489: c.setIgnoreCase(true);
490: c.setSingleRecord(true);
491: c.setCascade(true);
492: c.setDbName("myDB");
493: c.setAll();
494: c.setDistinct();
495: c.addSelectColumn("Author.NAME");
496: c.addSelectColumn("Author.AUTHOR_ID");
497: c.addDescendingOrderByColumn("Author.NAME");
498: c.addAscendingOrderByColumn("Author.AUTHOR_ID");
499: c.addAlias("Writer", "Author");
500: c.addAsColumn("AUTHOR_NAME", "Author.NAME");
501: c.addJoin("Author.AUTHOR_ID", "Book.AUTHOR_ID",
502: Criteria.INNER_JOIN);
503: c.add("Author.NAME", (Object) "author%", Criteria.LIKE);
504:
505: // Some direct Criterion checks
506: Criterion cn = c.getCriterion("Author.NAME");
507: cn.setIgnoreCase(true);
508: assertEquals("author%", cn.getValue());
509: assertEquals(Criteria.LIKE, cn.getComparison());
510: Criterion cnDirectClone = (Criterion) SerializationUtils
511: .clone(cn);
512: assertEquals(cn, cnDirectClone);
513:
514: // Clone the object
515: Criteria cClone = (Criteria) SerializationUtils.clone(c);
516:
517: // Check the clone
518: assertEquals(c.size(), cClone.size());
519: assertEquals(10, cClone.getOffset());
520: assertEquals(c.getOffset(), cClone.getOffset());
521: assertEquals(11, cClone.getLimit());
522: assertEquals(c.getLimit(), cClone.getLimit());
523: assertEquals(true, cClone.isIgnoreCase());
524: assertEquals(c.isIgnoreCase(), cClone.isIgnoreCase());
525: assertEquals(true, cClone.isSingleRecord());
526: assertEquals(c.isSingleRecord(), cClone.isSingleRecord());
527: assertEquals(true, cClone.isCascade());
528: assertEquals(c.isCascade(), cClone.isCascade());
529: assertEquals("myDB", cClone.getDbName());
530: assertEquals(c.getDbName(), cClone.getDbName());
531: List selectModifiersClone = cClone.getSelectModifiers();
532: assertTrue(selectModifiersClone.contains(Criteria.ALL
533: .toString()));
534: assertTrue(selectModifiersClone.contains(Criteria.DISTINCT
535: .toString()));
536: assertEquals(c.getSelectModifiers(), cClone
537: .getSelectModifiers());
538: List selectColumnsClone = cClone.getSelectColumns();
539: assertTrue(selectColumnsClone.contains("Author.NAME"));
540: assertTrue(selectColumnsClone.contains("Author.AUTHOR_ID"));
541: assertEquals(c.getSelectColumns(), cClone.getSelectColumns());
542: List orderByColumnsClone = cClone.getOrderByColumns();
543: assertTrue(orderByColumnsClone.contains("Author.NAME DESC"));
544: assertTrue(orderByColumnsClone.contains("Author.AUTHOR_ID ASC"));
545: assertEquals(c.getOrderByColumns(), cClone.getOrderByColumns());
546: Map aliasesClone = cClone.getAliases();
547: assertTrue(aliasesClone.containsKey("Writer"));
548: assertEquals("Author", aliasesClone.get("Writer"));
549: assertEquals(c.getAliases(), cClone.getAliases());
550: Map asColumnsClone = cClone.getAsColumns();
551: assertTrue(asColumnsClone.containsKey("AUTHOR_NAME"));
552: assertEquals("Author.NAME", asColumnsClone.get("AUTHOR_NAME"));
553: assertEquals(c.getAsColumns(), cClone.getAsColumns());
554:
555: // Check Joins
556: List joinsClone = cClone.getJoins();
557: Join joinClone = (Join) joinsClone.get(0);
558: assertEquals("Author.AUTHOR_ID", joinClone.getLeftColumn());
559: assertEquals("Book.AUTHOR_ID", joinClone.getRightColumn());
560: assertEquals(Criteria.INNER_JOIN, joinClone.getJoinType());
561: assertEquals(c.getJoins(), cClone.getJoins());
562:
563: // Some Criterion checks
564: Criterion cnClone = cClone.getCriterion("Author.NAME");
565: assertEquals("author%", cnClone.getValue());
566: assertEquals(Criteria.LIKE, cnClone.getComparison());
567: assertEquals(cn.isIgnoreCase(), cnClone.isIgnoreCase());
568:
569: // Confirm that equals() checks all of the above.
570: assertEquals(c, cClone);
571:
572: // Check hashCode() too.
573: assertEquals(c.hashCode(), cClone.hashCode());
574: }
575:
576: /**
577: * Test that {@link Criteria#equals(Object)} works correctly for a simple
578: * Criteria object.
579: * @throws TorqueException
580: */
581: public void testEquals() throws TorqueException {
582: c.addSelectColumn("Author.NAME");
583: c.addSelectColumn("Author.AUTHOR_ID");
584: c.add("Author.NAME", "foobar");
585: Criteria cClone = (Criteria) SerializationUtils.clone(c);
586: assertTrue(c.equals(cClone));
587: }
588:
589: /**
590: * Checks whether orderBy works.
591: */
592: public void testOrderBy() throws TorqueException {
593: // we need a rudimentary databaseMap for this test case to work
594: DatabaseMap dbMap = Torque
595: .getDatabaseMap(Torque.getDefaultDB());
596:
597: TableMap tableMap = new TableMap("AUTHOR", dbMap);
598: dbMap.addTable(tableMap);
599:
600: ColumnMap columnMap = new ColumnMap("NAME", tableMap);
601: columnMap.setType("");
602: tableMap.addColumn(columnMap);
603:
604: columnMap = new ColumnMap("AUTHOR_ID", tableMap);
605: columnMap.setType(new Integer(0));
606: tableMap.addColumn(columnMap);
607:
608: // check that alias'ed tables are referenced by their alias
609: // name when added to the select clause.
610: Criteria criteria = new Criteria();
611: criteria.addSelectColumn("AUTHOR.NAME");
612: criteria.addAlias("a", "AUTHOR");
613: criteria.addJoin("AUTHOR.AUTHOR_ID", "a." + "AUTHOR_ID");
614: criteria.addAscendingOrderByColumn("a.NAME");
615:
616: String result = BasePeer.createQueryString(criteria);
617: assertEquals("SELECT AUTHOR.NAME, a.NAME "
618: + "FROM AUTHOR, AUTHOR a "
619: + "WHERE AUTHOR.AUTHOR_ID=a.AUTHOR_ID "
620: + "ORDER BY a.NAME ASC", result);
621: }
622:
623: }
|