/tests/com/google/appengine/datanucleus/query/JPQLQueryTest.java
Java | 3434 lines | 2943 code | 393 blank | 98 comment | 47 complexity | 3aab801a7e71a928c5a79dcec9a57053 MD5 | raw file
Large files files are truncated, but you can click here to view the full file
1/********************************************************************** 2 Copyright (c) 2009 Google Inc. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 **********************************************************************/ 16package com.google.appengine.datanucleus.query; 17 18import com.google.appengine.api.datastore.DatastoreFailureException; 19import com.google.appengine.api.datastore.DatastoreTimeoutException; 20import com.google.appengine.api.datastore.Entity; 21import com.google.appengine.api.datastore.Key; 22import com.google.appengine.api.datastore.KeyFactory; 23import com.google.appengine.api.datastore.Query.FilterOperator; 24import com.google.appengine.api.datastore.Query.FilterPredicate; 25import com.google.appengine.api.datastore.Query.SortDirection; 26import com.google.appengine.api.datastore.Query.SortPredicate; 27import com.google.appengine.api.datastore.ShortBlob; 28import com.google.appengine.api.datastore.dev.LocalDatastoreService; 29import com.google.appengine.datanucleus.DatastoreManager; 30import com.google.appengine.datanucleus.DatastoreServiceFactoryInternal; 31import com.google.appengine.datanucleus.DatastoreServiceInterceptor; 32import com.google.appengine.datanucleus.ExceptionThrowingDatastoreDelegate; 33import com.google.appengine.datanucleus.PrimitiveArrays; 34import com.google.appengine.datanucleus.TestUtils; 35import com.google.appengine.datanucleus.Utils; 36import com.google.appengine.datanucleus.WriteBlocker; 37import com.google.appengine.datanucleus.jpa.JPATestCase; 38import com.google.appengine.datanucleus.test.jdo.Flight; 39import com.google.appengine.datanucleus.test.jdo.KitchenSink; 40import com.google.appengine.datanucleus.test.jdo.Person; 41import com.google.appengine.datanucleus.test.jpa.BidirectionalChildListJPA; 42import com.google.appengine.datanucleus.test.jpa.BidirectionalChildLongPkListJPA; 43import com.google.appengine.datanucleus.test.jpa.BidirectionalGrandchildListJPA; 44import com.google.appengine.datanucleus.test.jpa.Book; 45import com.google.appengine.datanucleus.test.jpa.DetachableJPA; 46import com.google.appengine.datanucleus.test.jpa.HasBytesJPA; 47import com.google.appengine.datanucleus.test.jpa.HasDoubleJPA; 48import com.google.appengine.datanucleus.test.jpa.HasEncodedStringPkJPA; 49import com.google.appengine.datanucleus.test.jpa.HasEncodedStringPkSeparateIdFieldJPA; 50import com.google.appengine.datanucleus.test.jpa.HasEncodedStringPkSeparateNameFieldJPA; 51import com.google.appengine.datanucleus.test.jpa.HasEnumJPA; 52import com.google.appengine.datanucleus.test.jpa.HasFloatJPA; 53import com.google.appengine.datanucleus.test.jpa.HasKeyAncestorStringPkJPA; 54import com.google.appengine.datanucleus.test.jpa.HasKeyPkJPA; 55import com.google.appengine.datanucleus.test.jpa.HasLongPkJPA; 56import com.google.appengine.datanucleus.test.jpa.HasMultiValuePropsJPA; 57import com.google.appengine.datanucleus.test.jpa.HasOneToManyKeyPkListJPA; 58import com.google.appengine.datanucleus.test.jpa.HasOneToManyKeyPkSetJPA; 59import com.google.appengine.datanucleus.test.jpa.HasOneToManyListJPA; 60import com.google.appengine.datanucleus.test.jpa.HasOneToManyLongPkListJPA; 61import com.google.appengine.datanucleus.test.jpa.HasOneToManyLongPkSetJPA; 62import com.google.appengine.datanucleus.test.jpa.HasOneToManyUnencodedStringPkListJPA; 63import com.google.appengine.datanucleus.test.jpa.HasOneToManyUnencodedStringPkSetJPA; 64import com.google.appengine.datanucleus.test.jpa.HasOneToOneJPA; 65import com.google.appengine.datanucleus.test.jpa.HasOneToOneParentJPA; 66import com.google.appengine.datanucleus.test.jpa.HasStringAncestorStringPkJPA; 67import com.google.appengine.datanucleus.test.jpa.HasUnencodedStringPkJPA; 68import com.google.appengine.datanucleus.test.jpa.InTheHouseJPA; 69import com.google.appengine.datanucleus.test.jpa.NullDataJPA; 70import com.google.appengine.datanucleus.test.jpa.AbstractBaseClassesJPA.Base1; 71import com.google.appengine.datanucleus.test.jpa.UnidirectionalSingeTableChildJPA.UnidirTop; 72import com.google.apphosting.api.ApiProxy; 73import com.google.apphosting.api.DatastorePb; 74 75import org.datanucleus.api.jpa.JPAQuery; 76import org.datanucleus.exceptions.NucleusFatalUserException; 77import org.datanucleus.exceptions.NucleusUserException; 78import org.datanucleus.query.expression.Expression; 79import org.easymock.EasyMock; 80 81import java.io.ByteArrayOutputStream; 82import java.io.IOException; 83import java.io.ObjectOutputStream; 84import java.math.BigDecimal; 85import java.util.Arrays; 86import java.util.Collections; 87import java.util.Date; 88import java.util.HashMap; 89import java.util.HashSet; 90import java.util.Iterator; 91import java.util.List; 92import java.util.Map; 93import java.util.Set; 94import java.util.concurrent.ExecutionException; 95import java.util.concurrent.Future; 96 97import javax.persistence.NoResultException; 98import javax.persistence.NonUniqueResultException; 99import javax.persistence.PersistenceException; 100import javax.persistence.Query; 101import javax.persistence.QueryTimeoutException; 102import javax.persistence.TypedQuery; 103 104import static com.google.appengine.datanucleus.test.jdo.Flight.newFlightEntity; 105 106/** 107 * @author Max Ross <maxr@google.com> 108 */ 109public class JPQLQueryTest extends JPATestCase { 110 111 private static final List<SortPredicate> NO_SORTS = Collections.emptyList(); 112 private static final List<FilterPredicate> NO_FILTERS = Collections.emptyList(); 113 114 private static final FilterPredicate TITLE_EQ_2 = 115 new FilterPredicate("title", FilterOperator.EQUAL, 2L); 116 private static final FilterPredicate TITLE_EQ_2STR = 117 new FilterPredicate("title", FilterOperator.EQUAL, "2"); 118 private static final FilterPredicate ISBN_EQ_4 = 119 new FilterPredicate("isbn", FilterOperator.EQUAL, 4L); 120 private static final FilterPredicate TITLE_GT_2 = 121 new FilterPredicate("title", FilterOperator.GREATER_THAN, 2L); 122 private static final FilterPredicate TITLE_GTE_2 = 123 new FilterPredicate("title", FilterOperator.GREATER_THAN_OR_EQUAL, 2L); 124 private static final FilterPredicate ISBN_LT_4 = 125 new FilterPredicate("isbn", FilterOperator.LESS_THAN, 4L); 126 private static final FilterPredicate ISBN_LTE_4 = 127 new FilterPredicate("isbn", FilterOperator.LESS_THAN_OR_EQUAL, 4L); 128 private static final FilterPredicate TITLE_NEQ_NULL_LITERAL = 129 new FilterPredicate("title", FilterOperator.NOT_EQUAL, null); 130 private static final FilterPredicate TITLE_NEQ_2_LITERAL = 131 new FilterPredicate("title", FilterOperator.NOT_EQUAL, 2L); 132 private static final SortPredicate TITLE_ASC = 133 new SortPredicate("title", SortDirection.ASCENDING); 134 private static final SortPredicate ISBN_DESC = 135 new SortPredicate("isbn", SortDirection.DESCENDING); 136 private static final FilterPredicate TITLE_IN_2_ARGS = 137 new FilterPredicate("title", FilterOperator.IN, Arrays.asList("2", 2L)); 138 private static final FilterPredicate TITLE_IN_3_ARGS = 139 new FilterPredicate("title", FilterOperator.IN, Arrays.asList("2", 2L, false)); 140 141 @Override 142 protected void setUp() throws Exception { 143 super.setUp(); 144 DatastoreServiceInterceptor.install(getStoreManager(), new WriteBlocker()); 145 } 146 147 @Override 148 protected void tearDown() throws Exception { 149 try { 150 super.tearDown(); 151 } finally { 152 DatastoreServiceInterceptor.uninstall(); 153 } 154 } 155 156 @Override 157 protected EntityManagerFactoryName getEntityManagerFactoryName() { 158 return EntityManagerFactoryName.nontransactional_ds_non_transactional_ops_allowed; 159 } 160 161 public void testUnsupportedFilters_NoResultExpr() { 162 String baseQuery = "SELECT FROM " + Book.class.getName() + " b "; 163 testUnsupportedFilters(baseQuery); 164 } 165 166 public void testUnsupportedFilters_PrimaryResultExpr() { 167 String baseQuery = "SELECT b FROM " + Book.class.getName() + " b "; 168 testUnsupportedFilters(baseQuery); 169 } 170 171 private void testUnsupportedFilters(String baseQuery) { 172 Set<Expression.Operator> unsupportedOps = 173 new HashSet<Expression.Operator>(DatastoreQuery.UNSUPPORTED_OPERATORS); 174 baseQuery += "WHERE "; 175 assertQueryUnsupportedByOrm(baseQuery + "NOT title = 'foo'", Expression.OP_NOT, unsupportedOps); 176 assertQueryUnsupportedByOrm(baseQuery + "(title + author) = 'foo'", Expression.OP_ADD, 177 unsupportedOps); 178 assertQueryUnsupportedByOrm(baseQuery + "title + author = 'foo'", Expression.OP_ADD, 179 unsupportedOps); 180 assertQueryUnsupportedByOrm(baseQuery + "(title - author) = 'foo'", Expression.OP_SUB, 181 unsupportedOps); 182 assertQueryUnsupportedByOrm(baseQuery + "title - author = 'foo'", Expression.OP_SUB, 183 unsupportedOps); 184 assertQueryUnsupportedByOrm(baseQuery + "(title / author) = 'foo'", Expression.OP_DIV, 185 unsupportedOps); 186 assertQueryUnsupportedByOrm(baseQuery + "title / author = 'foo'", Expression.OP_DIV, 187 unsupportedOps); 188 assertQueryUnsupportedByOrm(baseQuery + "(title * author) = 'foo'", Expression.OP_MUL, 189 unsupportedOps); 190 assertQueryUnsupportedByOrm(baseQuery + "title * author = 'foo'", Expression.OP_MUL, 191 unsupportedOps); 192 assertQueryUnsupportedByOrm(baseQuery + "(title % author) = 'foo'", Expression.OP_MOD, 193 unsupportedOps); 194 assertQueryUnsupportedByOrm(baseQuery + "title % author = 'foo'", Expression.OP_MOD, 195 unsupportedOps); 196 assertQueryRequiresUnsupportedDatastoreFeature(baseQuery + "title LIKE '%foo'"); 197 // can't have 'or' on multiple properties 198 assertQueryRequiresUnsupportedDatastoreFeature(baseQuery + "title = 'yar' or author = null"); 199 assertQueryRequiresUnsupportedDatastoreFeature(baseQuery + "isbn = 4 and (title = 'yar' or author = 'yam')"); 200 assertQueryRequiresUnsupportedDatastoreFeature(baseQuery + "title IN('yar') or author = 'yam'"); 201 // can only check equality 202 assertQueryRequiresUnsupportedDatastoreFeature(baseQuery + "title > 5 or title < 2"); 203 204 // multiple inequality filters 205 // TODO(maxr) Make this pass against the real datastore. 206 // We need to have it return BadRequest instead of NeedIndex for that to happen. 207 assertQueryUnsupportedByDatastore(baseQuery + "(title > 2 AND isbn < 4)", IllegalArgumentException.class); 208 // inequality filter prop is not the same as the first order by prop 209 assertQueryUnsupportedByDatastore(baseQuery + "(title > 2) order by isbn", IllegalArgumentException.class); 210 // gets split into multiple inequality props 211 assertQueryUnsupportedByDatastore(baseQuery + "title <> 2 AND isbn <> 4", IllegalArgumentException.class); 212 assertEquals( 213 new HashSet<Expression.Operator>(Arrays.asList(Expression.OP_CONCAT, Expression.OP_COM, 214 Expression.OP_NEG, Expression.OP_IS, 215 Expression.OP_LIKE, 216 Expression.OP_ISNOT)), unsupportedOps); 217 } 218 219 public void testEvaluateInMemory() { 220 ds.put(null, newFlightEntity("1", "yar", "bam", 1, 2)); 221 ds.put(null, newFlightEntity("1", "yam", null, 1, 2)); 222 223 // This is impossible in the datastore, so run totally in-memory 224 String query = "SELECT f FROM " + Flight.class.getName() + " f WHERE origin = 'yar' OR dest IS null"; 225 Query q = em.createQuery(query); 226 q.setHint("datanucleus.query.evaluateInMemory", "true"); 227 try { 228 List<Flight> results = (List<Flight>) q.getResultList(); 229 assertEquals("Number of results was wrong", 2, results.size()); 230 } catch (RuntimeException e) { 231 fail("Threw exception when evaluating query in-memory, but should have run"); 232 } 233 } 234 235 public void testSupportedFilters_NoResultExpr() { 236 String baseQuery = "SELECT FROM " + Book.class.getName() + " b "; 237 testSupportedFilters(baseQuery); 238 } 239 240 public void testSupportedFilters_PrimaryResultExpr() { 241 String baseQuery = "SELECT b FROM " + Book.class.getName() + " b "; 242 testSupportedFilters(baseQuery); 243 } 244 245 private void testSupportedFilters(String baseQuery) { 246 247 assertQuerySupported(baseQuery, NO_FILTERS, NO_SORTS); 248 249 baseQuery += "WHERE "; 250 assertQuerySupported(baseQuery + "title = 2", Utils.newArrayList(TITLE_EQ_2), NO_SORTS); 251 assertQuerySupported(baseQuery + "title = \"2\"", Utils.newArrayList(TITLE_EQ_2STR), NO_SORTS); 252 assertQuerySupported(baseQuery + "(title = 2)", Utils.newArrayList(TITLE_EQ_2), NO_SORTS); 253 assertQuerySupported(baseQuery + "title = 2 AND isbn = 4", 254 Utils.newArrayList(TITLE_EQ_2,ISBN_EQ_4), 255 NO_SORTS); 256 assertQuerySupported(baseQuery + "(title = 2 AND isbn = 4)", 257 Utils.newArrayList(TITLE_EQ_2, ISBN_EQ_4), 258 NO_SORTS); 259 assertQuerySupported(baseQuery + "(title = 2) AND (isbn = 4)", Utils.newArrayList( 260 TITLE_EQ_2, ISBN_EQ_4), NO_SORTS); 261 assertQuerySupported(baseQuery + "title > 2", Utils.newArrayList(TITLE_GT_2), NO_SORTS); 262 assertQuerySupported(baseQuery + "title >= 2", Utils.newArrayList(TITLE_GTE_2), NO_SORTS); 263 assertQuerySupported(baseQuery + "isbn < 4", Utils.newArrayList(ISBN_LT_4), NO_SORTS); 264 assertQuerySupported(baseQuery + "isbn <= 4", Utils.newArrayList(ISBN_LTE_4), NO_SORTS); 265 266 baseQuery = "SELECT FROM " + Book.class.getName() + " b "; 267 assertQuerySupported(baseQuery + "ORDER BY title ASC", NO_FILTERS, 268 Utils.newArrayList(TITLE_ASC)); 269 assertQuerySupported(baseQuery + "ORDER BY isbn DESC", NO_FILTERS, 270 Utils.newArrayList(ISBN_DESC)); 271 assertQuerySupported(baseQuery + "ORDER BY title ASC, isbn DESC", NO_FILTERS, 272 Utils.newArrayList(TITLE_ASC, ISBN_DESC)); 273 274 assertQuerySupported(baseQuery + "WHERE title = 2 AND isbn = 4 ORDER BY title ASC, isbn DESC", 275 Utils.newArrayList(TITLE_EQ_2, ISBN_EQ_4), 276 Utils.newArrayList(TITLE_ASC, ISBN_DESC)); 277 assertQuerySupported(baseQuery + "WHERE title <> null", 278 Utils.newArrayList(TITLE_NEQ_NULL_LITERAL), NO_SORTS); 279 assertQuerySupported(baseQuery + "WHERE title <> 2", 280 Utils.newArrayList(TITLE_NEQ_2_LITERAL), NO_SORTS); 281 assertQuerySupported(baseQuery + "WHERE title = '2' OR title = 2", 282 Utils.newArrayList(TITLE_IN_2_ARGS), NO_SORTS); 283 assertQuerySupported(baseQuery + "WHERE title = '2' OR title = 2 OR title = false", 284 Utils.newArrayList(TITLE_IN_3_ARGS), NO_SORTS); 285 assertQuerySupported(baseQuery + "WHERE title IN ('2', 2)", 286 Utils.newArrayList(TITLE_IN_2_ARGS), NO_SORTS); 287 assertQuerySupported(baseQuery + "WHERE title IN ('2', 2, false)", 288 Utils.newArrayList(TITLE_IN_3_ARGS), NO_SORTS); 289 assertQuerySupported(baseQuery + "WHERE (title = '2' OR title = 2) AND isbn = 4", 290 Utils.newArrayList(ISBN_EQ_4, TITLE_IN_2_ARGS), NO_SORTS); 291 assertQuerySupported(baseQuery + "WHERE title IN ('2', 2) AND isbn = 4", 292 Utils.newArrayList(ISBN_EQ_4, TITLE_IN_2_ARGS), NO_SORTS); 293 assertQuerySupported(baseQuery + "WHERE (title = '2' OR title = 2 OR title = false) AND isbn = 4", 294 Utils.newArrayList(ISBN_EQ_4, TITLE_IN_3_ARGS), NO_SORTS); 295 assertQuerySupported(baseQuery + "WHERE title IN ('2', 2, false) AND isbn = 4", 296 Utils.newArrayList(ISBN_EQ_4, TITLE_IN_3_ARGS), NO_SORTS); 297 } 298 299 public void test2Equals2OrderBy() { 300 ds.put(Book.newBookEntity("Joe Blow", "67890", "Bar Book")); 301 ds.put(Book.newBookEntity("Joe Blow", "11111", "Bar Book")); 302 ds.put(Book.newBookEntity("Joe Blow", "12345", "Foo Book")); 303 ds.put(Book.newBookEntity("Joe Blow", "54321", "A Book")); 304 ds.put(Book.newBookEntity("Jane Blow", "13579", "Baz Book")); 305 306 Query q = em.createQuery("SELECT FROM " + 307 Book.class.getName() + " b" + 308 " WHERE author = 'Joe Blow'" + 309 " ORDER BY title DESC, isbn ASC"); 310 311 @SuppressWarnings("unchecked") 312 List<Book> result = (List<Book>) q.getResultList(); 313 314 assertEquals(4, result.size()); 315 assertEquals("12345", result.get(0).getIsbn()); 316 assertEquals("11111", result.get(1).getIsbn()); 317 assertEquals("67890", result.get(2).getIsbn()); 318 assertEquals("54321", result.get(3).getIsbn()); 319 } 320 321 public void testDefaultOrderingIsAsc() { 322 ds.put(Book.newBookEntity("Joe Blow", "67890", "Bar Book")); 323 ds.put(Book.newBookEntity("Joe Blow", "11111", "Bar Book")); 324 ds.put(Book.newBookEntity("Joe Blow", "12345", "Foo Book")); 325 ds.put(Book.newBookEntity("Joe Blow", "54321", "A Book")); 326 ds.put(Book.newBookEntity("Jane Blow", "13579", "Baz Book")); 327 328 Query q = em.createQuery("SELECT FROM " + 329 Book.class.getName() + " b" + 330 " WHERE author = 'Joe Blow'" + 331 " ORDER BY title"); 332 333 @SuppressWarnings("unchecked") 334 List<Book> result = (List<Book>) q.getResultList(); 335 336 assertEquals(4, result.size()); 337 assertEquals("54321", result.get(0).getIsbn()); 338 assertEquals("67890", result.get(1).getIsbn()); 339 assertEquals("11111", result.get(2).getIsbn()); 340 assertEquals("12345", result.get(3).getIsbn()); 341 } 342 343 public void testLimitQuery() { 344 ds.put(Book.newBookEntity("Joe Blow", "67890", "Bar Book")); 345 ds.put(Book.newBookEntity("Joe Blow", "11111", "Bar Book")); 346 ds.put(Book.newBookEntity("Joe Blow", "12345", "Foo Book")); 347 ds.put(Book.newBookEntity("Joe Blow", "54321", "A Book")); 348 ds.put(Book.newBookEntity("Jane Blow", "13579", "Baz Book")); 349 350 Query q = em.createQuery("SELECT FROM " + 351 Book.class.getName() + " b" + 352 " WHERE author = 'Joe Blow'" + 353 " ORDER BY title DESC, isbn ASC"); 354 355 q.setMaxResults(1); 356 @SuppressWarnings("unchecked") 357 List<Book> result1 = (List<Book>) q.getResultList(); 358 assertEquals(1, result1.size()); 359 assertEquals("12345", result1.get(0).getIsbn()); 360 361 q.setMaxResults(0); 362 @SuppressWarnings("unchecked") 363 List<Book> result2 = (List<Book>) q.getResultList(); 364 assertEquals(0, result2.size()); 365 366 try { 367 q.setMaxResults(-1); 368 fail("expected iae"); 369 } catch (IllegalArgumentException iae) { 370 // good 371 } 372 } 373 374 public void testOffsetQuery() { 375 ds.put(Book.newBookEntity("Joe Blow", "67890", "Bar Book")); 376 ds.put(Book.newBookEntity("Joe Blow", "11111", "Bar Book")); 377 ds.put(Book.newBookEntity("Joe Blow", "12345", "Foo Book")); 378 ds.put(Book.newBookEntity("Joe Blow", "54321", "A Book")); 379 ds.put(Book.newBookEntity("Jane Blow", "13579", "Baz Book")); 380 Query q = em.createQuery("SELECT FROM " + 381 Book.class.getName() + " b" + 382 " WHERE author = 'Joe Blow'" + 383 " ORDER BY title DESC, isbn ASC"); 384 385 q.setFirstResult(0); 386 @SuppressWarnings("unchecked") 387 List<Book> result1 = (List<Book>) q.getResultList(); 388 assertEquals(4, result1.size()); 389 assertEquals("12345", result1.get(0).getIsbn()); 390 391 q.setFirstResult(1); 392 @SuppressWarnings("unchecked") 393 List<Book> result2 = (List<Book>) q.getResultList(); 394 assertEquals(3, result2.size()); 395 assertEquals("11111", result2.get(0).getIsbn()); 396 397 try { 398 q.setFirstResult(-1); 399 fail("expected iae"); 400 } catch (IllegalArgumentException iae) { 401 // good 402 } 403 } 404 405 public void testOffsetLimitQuery() { 406 ds.put(Book.newBookEntity("Joe Blow", "67890", "Bar Book")); 407 ds.put(Book.newBookEntity("Joe Blow", "11111", "Bar Book")); 408 ds.put(Book.newBookEntity("Joe Blow", "12345", "Foo Book")); 409 ds.put(Book.newBookEntity("Joe Blow", "54321", "A Book")); 410 ds.put(Book.newBookEntity("Jane Blow", "13579", "Baz Book")); 411 Query q = em.createQuery("SELECT FROM " + 412 Book.class.getName() + " b" + 413 " WHERE author = 'Joe Blow'" + 414 " ORDER BY title DESC, isbn ASC"); 415 416 q.setFirstResult(0); 417 q.setMaxResults(0); 418 @SuppressWarnings("unchecked") 419 List<Book> result1 = (List<Book>) q.getResultList(); 420 assertEquals(0, result1.size()); 421 422 q.setFirstResult(1); 423 q.setMaxResults(0); 424 @SuppressWarnings("unchecked") 425 List<Book> result2 = (List<Book>) q.getResultList(); 426 assertEquals(0, result2.size()); 427 428 q.setFirstResult(0); 429 q.setMaxResults(1); 430 @SuppressWarnings("unchecked") 431 List<Book> result3 = (List<Book>) q.getResultList(); 432 assertEquals(1, result3.size()); 433 434 q.setFirstResult(0); 435 q.setMaxResults(2); 436 @SuppressWarnings("unchecked") 437 List<Book> result4 = (List<Book>) q.getResultList(); 438 assertEquals(2, result4.size()); 439 assertEquals("12345", result4.get(0).getIsbn()); 440 441 q.setFirstResult(1); 442 q.setMaxResults(1); 443 @SuppressWarnings("unchecked") 444 List<Book> result5 = (List<Book>) q.getResultList(); 445 assertEquals(1, result5.size()); 446 assertEquals("11111", result5.get(0).getIsbn()); 447 448 q.setFirstResult(2); 449 q.setMaxResults(5); 450 @SuppressWarnings("unchecked") 451 List<Book> result6 = (List<Book>) q.getResultList(); 452 assertEquals(2, result6.size()); 453 assertEquals("67890", result6.get(0).getIsbn()); 454 } 455 456 public void testSerialization() throws IOException { 457 Query q = em.createQuery("select from " + Book.class.getName() + " b "); 458 q.getResultList(); 459 460 JPQLQuery innerQuery = (JPQLQuery) ((JPAQuery) q).getInternalQuery(); 461 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 462 ObjectOutputStream oos = new ObjectOutputStream(baos); 463 // the fact that this doesn't blow up is the test 464 oos.writeObject(innerQuery); 465 } 466 467 public void testBindVariables() { 468 469 assertQuerySupported("select from " + Book.class.getName() + " b where title = :titleParam", 470 Utils.newArrayList(TITLE_EQ_2), NO_SORTS, "titleParam", 2L); 471 472 assertQuerySupported("select from " + Book.class.getName() + " b" + 473 " where title = :titleParam AND isbn = :isbnParam", 474 Utils.newArrayList(TITLE_EQ_2, ISBN_EQ_4), NO_SORTS, "titleParam", 2L, "isbnParam", 4L); 475 476 assertQuerySupported("select from " + Book.class.getName() + " b" + 477 " where title = :titleParam AND isbn = :isbnParam order by title asc, isbn desc", 478 Utils.newArrayList(TITLE_EQ_2, ISBN_EQ_4), 479 Utils.newArrayList(TITLE_ASC, ISBN_DESC), "titleParam", 2L, "isbnParam", 4L); 480 } 481 482 public void testKeyQuery() { 483 Entity bookEntity = Book.newBookEntity("Joe Blow", "67890", "Bar Book"); 484 ds.put(bookEntity); 485 486 javax.persistence.Query q = em.createQuery( 487 "select from " + Book.class.getName() + " b where id = :key"); 488 q.setParameter("key", KeyFactory.keyToString(bookEntity.getKey())); 489 @SuppressWarnings("unchecked") 490 List<Book> books = (List<Book>) q.getResultList(); 491 assertEquals(1, books.size()); 492 assertEquals(bookEntity.getKey(), KeyFactory.stringToKey(books.get(0).getId())); 493 494 // now issue the same query, but instead of providing a String version of 495 // the key, provide the Key itself. 496 q.setParameter("key", bookEntity.getKey()); 497 @SuppressWarnings("unchecked") 498 List<Book> books2 = (List<Book>) q.getResultList(); 499 assertEquals(1, books2.size()); 500 assertEquals(bookEntity.getKey(), KeyFactory.stringToKey(books2.get(0).getId())); 501 } 502 503 public void testKeyQuery_KeyPk() { 504 Entity entityWithName = new Entity(HasKeyPkJPA.class.getSimpleName(), "blarg"); 505 Entity entityWithId = new Entity(HasKeyPkJPA.class.getSimpleName()); 506 ds.put(entityWithName); 507 ds.put(entityWithId); 508 509 Query q = em.createQuery( 510 "select from " + HasKeyPkJPA.class.getName() + " b where id = :key"); 511 q.setParameter("key", entityWithName.getKey()); 512 HasKeyPkJPA result = (HasKeyPkJPA) q.getSingleResult(); 513 assertEquals(entityWithName.getKey(), result.getId()); 514 515 q = em.createQuery("select from " + HasKeyPkJPA.class.getName() + " b where id = :mykey"); 516 q.setParameter("mykey", entityWithId.getKey()); 517 result = (HasKeyPkJPA) q.getSingleResult(); 518 assertEquals(entityWithId.getKey(), result.getId()); 519 520 q = em.createQuery("select from " + HasKeyPkJPA.class.getName() + " b where id = :mykeyname"); 521 q.setParameter("mykeyname", entityWithName.getKey().getName()); 522 result = (HasKeyPkJPA) q.getSingleResult(); 523 assertEquals(entityWithName.getKey(), result.getId()); 524 525 q = em.createQuery("select from " + HasKeyPkJPA.class.getName() + " b where id = :mykeyid"); 526 q.setParameter("mykeyid", entityWithId.getKey().getId()); 527 result = (HasKeyPkJPA) q.getSingleResult(); 528 assertEquals(entityWithId.getKey(), result.getId()); 529 } 530 531 public void testKeyQueryWithSorts() { 532 Entity bookEntity = Book.newBookEntity("Joe Blow", "67890", "Bar Book"); 533 ds.put(bookEntity); 534 535 javax.persistence.Query q = em.createQuery( 536 "select from " + Book.class.getName() + " c where id = :key order by isbn ASC"); 537 q.setParameter("key", KeyFactory.keyToString(bookEntity.getKey())); 538 @SuppressWarnings("unchecked") 539 List<Book> books = (List<Book>) q.getResultList(); 540 assertEquals(1, books.size()); 541 assertEquals(bookEntity.getKey(), KeyFactory.stringToKey(books.get(0).getId())); 542 } 543 544 public void testKeyQuery_MultipleFilters() { 545 Entity bookEntity = Book.newBookEntity("Joe Blow", "67890", "Bar Book"); 546 ds.put(bookEntity); 547 548 javax.persistence.Query q = em.createQuery( 549 "select from " + Book.class.getName() + " c where id = :key and isbn = \"67890\""); 550 q.setParameter("key", KeyFactory.keyToString(bookEntity.getKey())); 551 @SuppressWarnings("unchecked") 552 List<Book> books = (List<Book>) q.getResultList(); 553 assertEquals(1, books.size()); 554 assertEquals(bookEntity.getKey(), KeyFactory.stringToKey(books.get(0).getId())); 555 } 556 557 public void testKeyQuery_NonEqualityFilter() { 558 Entity bookEntity1 = Book.newBookEntity("Joe Blow", "67890", "Bar Book"); 559 ds.put(bookEntity1); 560 561 Entity bookEntity2 = Book.newBookEntity("Joe Blow", "67890", "Bar Book"); 562 ds.put(bookEntity2); 563 564 javax.persistence.Query q = em.createQuery( 565 "select from " + Book.class.getName() 566 + " b where id > :key"); 567 q.setParameter("key", KeyFactory.keyToString(bookEntity1.getKey())); 568 @SuppressWarnings("unchecked") 569 List<Book> books = (List<Book>) q.getResultList(); 570 assertEquals(1, books.size()); 571 assertEquals(bookEntity2.getKey(), KeyFactory.stringToKey(books.get(0).getId())); 572 } 573 574 public void testKeyQuery_SortByKey() { 575 Entity bookEntity1 = Book.newBookEntity("Joe Blow", "67890", "Bar Book"); 576 ds.put(bookEntity1); 577 578 Entity bookEntity2 = Book.newBookEntity("Joe Blow", "67890", "Bar Book"); 579 ds.put(bookEntity2); 580 581 javax.persistence.Query q = em.createQuery( 582 "select from " + Book.class.getName() 583 + " b order by id DESC"); 584 @SuppressWarnings("unchecked") 585 List<Book> books = (List<Book>) q.getResultList(); 586 assertEquals(2, books.size()); 587 assertEquals(bookEntity2.getKey(), KeyFactory.stringToKey(books.get(0).getId())); 588 } 589 590 public void testKeyQuery_FilterAndSortByKeyComponent() { 591 // filter by pk-id 592 assertQueryUnsupportedByDatastore( 593 "select from " + HasEncodedStringPkSeparateIdFieldJPA.class.getName() + " b where id = 4", 594 NucleusFatalUserException.class); 595 // sort by pk-id 596 assertQueryUnsupportedByDatastore( 597 "select from " + HasEncodedStringPkSeparateIdFieldJPA.class.getName() + " b order by id", 598 NucleusFatalUserException.class); 599 // filter by pk-id 600 assertQueryUnsupportedByDatastore( 601 "select from " + HasEncodedStringPkSeparateNameFieldJPA.class.getName() + " b where name = 4", 602 NucleusFatalUserException.class); 603 // sort by pk-id 604 assertQueryUnsupportedByDatastore( 605 "select from " + HasEncodedStringPkSeparateNameFieldJPA.class.getName() + " b order by name", 606 NucleusFatalUserException.class); 607 } 608 609 public void testAncestorQuery() { 610 Entity bookEntity = Book.newBookEntity("Joe Blow", "67890", "Bar Book"); 611 ds.put(bookEntity); 612 Entity 613 hasAncestorEntity = 614 new Entity(HasStringAncestorStringPkJPA.class.getSimpleName(), bookEntity.getKey()); 615 ds.put(hasAncestorEntity); 616 617 javax.persistence.Query q = em.createQuery( 618 "select from " + HasStringAncestorStringPkJPA.class.getName() 619 + " b where ancestorId = :ancId"); 620 q.setParameter("ancId", KeyFactory.keyToString(bookEntity.getKey())); 621 622 @SuppressWarnings("unchecked") 623 List<HasStringAncestorStringPkJPA> 624 haList = 625 (List<HasStringAncestorStringPkJPA>) q.getResultList(); 626 assertEquals(1, haList.size()); 627 assertEquals(bookEntity.getKey(), KeyFactory.stringToKey(haList.get(0).getAncestorId())); 628 629 assertEquals( 630 bookEntity.getKey(), getDatastoreQuery(q).getLatestDatastoreQuery().getAncestor()); 631 assertEquals(NO_FILTERS, getFilterPredicates(q)); 632 assertEquals(NO_SORTS, getSortPredicates(q)); 633 } 634 635 public void testIllegalAncestorQuery() { 636 Entity bookEntity = Book.newBookEntity("Joe Blow", "67890", "Bar Book"); 637 ds.put(bookEntity); 638 Entity 639 hasAncestorEntity = 640 new Entity(HasStringAncestorStringPkJPA.class.getName(), bookEntity.getKey()); 641 ds.put(hasAncestorEntity); 642 643 javax.persistence.Query q = em.createQuery( 644 "select from " + HasStringAncestorStringPkJPA.class.getName() + " b" 645 + " where ancestorId > :ancId"); 646 q.setParameter("ancId", KeyFactory.keyToString(bookEntity.getKey())); 647 q.setHint(DatastoreManager.QUERYEXT_INMEMORY_WHEN_UNSUPPORTED, "false"); 648 try { 649 q.getResultList(); 650 fail("expected udfe"); 651 } catch (PersistenceException pe) { 652 if (pe.getCause() instanceof DatastoreQuery.UnsupportedDatastoreFeatureException) { 653 // good 654 } 655 else { 656 throw pe; 657 } 658 } 659 } 660 661 public void testSortByFieldWithCustomColumn() { 662 ds.put(Book.newBookEntity("Joe Blow", "67890", "Bar Book", 2003)); 663 ds.put(Book.newBookEntity("Joe Blow", "11111", "Bar Book", 2002)); 664 ds.put(Book.newBookEntity("Joe Blow", "12345", "Foo Book", 2001)); 665 666 Query q = em.createQuery("SELECT FROM " + 667 Book.class.getName() + " b" + 668 " WHERE b.author = 'Joe Blow'" + 669 " ORDER BY firstPublished ASC"); 670 671 @SuppressWarnings("unchecked") 672 List<Book> result = (List<Book>) q.getResultList(); 673 674 assertEquals(3, result.size()); 675 assertEquals("12345", result.get(0).getIsbn()); 676 assertEquals("11111", result.get(1).getIsbn()); 677 assertEquals("67890", result.get(2).getIsbn()); 678 } 679 680 private interface BookProvider { 681 682 Book getBook(Key key); 683 } 684 685 private class AttachedBookProvider implements BookProvider { 686 687 public Book getBook(Key key) { 688 return em.find(Book.class, key); 689 } 690 } 691 692 private class TransientBookProvider implements BookProvider { 693 694 public Book getBook(Key key) { 695 Book b = new Book(); 696 b.setId(KeyFactory.keyToString(key)); 697 return b; 698 } 699 } 700 701 private void testFilterByChildObject(BookProvider bp) { 702 Entity parentEntity = new Entity(HasOneToOneJPA.class.getSimpleName()); 703 ds.put(parentEntity); 704 Entity bookEntity = Book.newBookEntity(parentEntity.getKey(), "Joe Blow", "11111", "Bar Book", 1929); 705 ds.put(bookEntity); 706 707 Book book = bp.getBook(bookEntity.getKey()); 708 Query q = em.createQuery( 709 "select from " + HasOneToOneJPA.class.getName() + " c where book = :b"); 710 q.setParameter("b", book); 711 List<HasOneToOneJPA> result = (List<HasOneToOneJPA>) q.getResultList(); 712 assertEquals(1, result.size()); 713 assertEquals(parentEntity.getKey(), KeyFactory.stringToKey(result.get(0).getId())); 714 } 715 716 public void testFilterByChildObject() { 717 testFilterByChildObject(new AttachedBookProvider()); 718 testFilterByChildObject(new TransientBookProvider()); 719 } 720 721 private void testFilterByChildObject_AdditionalFilterOnParent(BookProvider bp) { 722 Entity parentEntity = new Entity(HasOneToOneJPA.class.getSimpleName()); 723 ds.put(parentEntity); 724 Entity bookEntity = Book.newBookEntity(parentEntity.getKey(), "Joe Blow", "11111", "Bar Book", 1929); 725 ds.put(bookEntity); 726 727 Book book = bp.getBook(bookEntity.getKey()); 728 Query q = em.createQuery( 729 "select from " + HasOneToOneJPA.class.getName() + " c where id = :parentId and book = :b"); 730 q.setParameter("parentId", KeyFactory.keyToString(bookEntity.getKey())); 731 q.setParameter("b", book); 732 List<HasOneToOneJPA> result = (List<HasOneToOneJPA>) q.getResultList(); 733 assertTrue(result.isEmpty()); 734 735 q.setParameter("parentId", KeyFactory.keyToString(parentEntity.getKey())); 736 q.setParameter("b", book); 737 result = (List<HasOneToOneJPA>) q.getResultList(); 738 assertEquals(1, result.size()); 739 assertEquals(parentEntity.getKey(), KeyFactory.stringToKey(result.get(0).getId())); 740 } 741 742 public void testFilterByChildObject_AdditionalFilterOnParent() { 743 testFilterByChildObject_AdditionalFilterOnParent(new AttachedBookProvider()); 744 testFilterByChildObject_AdditionalFilterOnParent(new TransientBookProvider()); 745 } 746 747 748 private void testFilterByChildObject_UnsupportedOperator(BookProvider bp) { 749 Entity parentEntity = new Entity(HasOneToOneJPA.class.getSimpleName()); 750 ds.put(parentEntity); 751 Entity bookEntity = Book.newBookEntity(parentEntity.getKey(), "Joe Blow", "11111", "Bar Book", 1929); 752 ds.put(bookEntity); 753 754 Book book = bp.getBook(bookEntity.getKey()); 755 Query q = em.createQuery( 756 "select from " + HasOneToOneJPA.class.getName() + " c where book > :b"); 757 q.setHint(DatastoreManager.QUERYEXT_INMEMORY_WHEN_UNSUPPORTED, "false"); 758 q.setParameter("b", book); 759 try { 760 q.getResultList(); 761 fail("expected udfe"); 762 } catch (PersistenceException pe) { 763 if (pe.getCause() instanceof DatastoreQuery.UnsupportedDatastoreFeatureException) { 764 // good 765 } 766 else { 767 throw pe; 768 } 769 } 770 } 771 772 public void testFilterByChildObject_UnsupportedOperator() { 773 testFilterByChildObject_UnsupportedOperator(new AttachedBookProvider()); 774 testFilterByChildObject_UnsupportedOperator(new TransientBookProvider()); 775 } 776 777 private void testFilterByChildObject_ValueWithoutAncestor(BookProvider bp) { 778 Entity parentEntity = new Entity(HasOneToOneJPA.class.getSimpleName()); 779 ds.put(parentEntity); 780 Entity bookEntity = Book.newBookEntity("Joe Blow", "11111", "Bar Book", 1929); 781 ds.put(bookEntity); 782 783 Book book = bp.getBook(bookEntity.getKey()); 784 Query q = em.createQuery( 785 "select from " + HasOneToOneJPA.class.getName() + " c where book = :b"); 786 q.setParameter("b", book); 787 q.setHint(DatastoreManager.QUERYEXT_INMEMORY_WHEN_UNSUPPORTED, "false"); 788 try { 789 q.getResultList(); 790 fail("expected JPAException"); 791 } catch (PersistenceException e) { 792 // good 793 } 794 } 795 796 public void testFilterByChildObject_ValueWithoutAncestor() { 797 testFilterByChildObject_ValueWithoutAncestor(new AttachedBookProvider()); 798 testFilterByChildObject_ValueWithoutAncestor(new TransientBookProvider()); 799 } 800 801 public void testFilterByChildObject_KeyIsWrongType() { 802 Entity parentEntity = new Entity(HasOneToOneJPA.class.getSimpleName()); 803 ds.put(parentEntity); 804 805 Query q = em.createQuery( 806 "select from " + HasOneToOneJPA.class.getName() + " c where book = :b"); 807 q.setParameter("b", parentEntity.getKey()); 808 q.setHint(DatastoreManager.QUERYEXT_INMEMORY_WHEN_UNSUPPORTED, "false"); 809 try { 810 q.getResultList(); 811 fail("expected JPAException"); 812 } catch (PersistenceException e) { 813 // good 814 } 815 } 816 817 public void testFilterByChildObject_KeyParentIsWrongType() { 818 Key parent = KeyFactory.createKey("yar", 44); 819 Entity bookEntity = new Entity(Book.class.getSimpleName(), parent); 820 821 Query q = em.createQuery( 822 "select from " + HasOneToOneJPA.class.getName() + " c where book = :b"); 823 q.setParameter("b", bookEntity.getKey()); 824 825 assertTrue(q.getResultList().isEmpty()); 826 } 827 828 public void testFilterByChildObject_ValueWithoutId() { 829 Entity parentEntity = new Entity(HasOneToOneJPA.class.getSimpleName()); 830 ds.put(parentEntity); 831 Entity bookEntity = Book.newBookEntity("Joe Blow", "11111", "Bar Book", 1929); 832 ds.put(bookEntity); 833 834 Book book = new Book(); 835 Query q = em.createQuery( 836 "select from " + HasOneToOneJPA.class.getName() + " c where book = :b"); 837 q.setParameter("b", book); 838 q.setHint(DatastoreManager.QUERYEXT_INMEMORY_WHEN_UNSUPPORTED, "false"); 839 try { 840 q.getResultList(); 841 fail("expected JPAException"); 842 } catch (PersistenceException e) { 843 // good 844 } 845 } 846 847 public void testFilterByParentObject() { 848 Entity parentEntity = new Entity(HasOneToManyListJPA.class.getSimpleName()); 849 ds.put(parentEntity); 850 Entity bidirEntity = 851 new Entity(BidirectionalChildListJPA.class.getSimpleName(), parentEntity.getKey()); 852 ds.put(bidirEntity); 853 Entity bidirEntity2 = 854 new Entity(BidirectionalChildListJPA.class.getSimpleName(), parentEntity.getKey()); 855 ds.put(bidirEntity2); 856 857 HasOneToManyListJPA parent = 858 em.find(HasOneToManyListJPA.class, KeyFactory.keyToString(parentEntity.getKey())); 859 Query q = em.createQuery("SELECT FROM " + 860 BidirectionalChildListJPA.class.getName() + 861 " c WHERE parent = :p"); 862 863 q.setParameter("p", parent); 864 @SuppressWarnings("unchecked") 865 List<BidirectionalChildListJPA> result = (List<BidirectionalChildListJPA>) q.getResultList(); 866 assertEquals(2, result.size()); 867 assertEquals(bidirEntity.getKey(), KeyFactory.stringToKey(result.get(0).getId())); 868 assertEquals(bidirEntity2.getKey(), KeyFactory.stringToKey(result.get(1).getId())); 869 } 870 871 public void testFilterByParentLongObjectId() { 872 Entity parentEntity = new Entity(HasOneToManyLongPkListJPA.class.getSimpleName()); 873 ds.put(parentEntity); 874 Entity bidirEntity = 875 new Entity(BidirectionalChildLongPkListJPA.class.getSimpleName(), parentEntity.getKey()); 876 ds.put(bidirEntity); 877 Entity bidirEntity2 = 878 new Entity(BidirectionalChildLongPkListJPA.class.getSimpleName(), parentEntity.getKey()); 879 ds.put(bidirEntity2); 880 881 HasOneToManyLongPkListJPA parent = 882 em.find(HasOneToManyLongPkListJPA.class, KeyFactory.keyToString(parentEntity.getKey())); 883 Query q = em.createQuery("SELECT FROM " + 884 BidirectionalChildLongPkListJPA.class.getName() + " c WHERE parent = :p"); 885 886 q.setParameter("p", parent.getId()); 887 @SuppressWarnings("unchecked") 888 List<BidirectionalChildLongPkListJPA> result = (List<BidirectionalChildLongPkListJPA>) q.getResultList(); 889 assertEquals(2, result.size()); 890 assertEquals(bidirEntity.getKey(), KeyFactory.stringToKey(result.get(0).getId())); 891 assertEquals(bidirEntity2.getKey(), KeyFactory.stringToKey(result.get(1).getId())); 892 } 893 894 public void testFilterByParentIntObjectId() { 895 Entity parentEntity = new Entity(HasOneToManyLongPkListJPA.class.getSimpleName()); 896 ds.put(parentEntity); 897 Entity bidirEntity = 898 new Entity(BidirectionalChildLongPkListJPA.class.getSimpleName(), parentEntity.getKey()); 899 ds.put(bidirEntity); 900 Entity bidirEntity2 = 901 new Entity(BidirectionalChildLongPkListJPA.class.getSimpleName(), parentEntity.getKey()); 902 ds.put(bidirEntity2); 903 904 HasOneToManyLongPkListJPA parent = 905 em.find(HasOneToManyLongPkListJPA.class, KeyFactory.keyToString(parentEntity.getKey())); 906 Query q = em.createQuery("SELECT FROM " + 907 BidirectionalChildLongPkListJPA.class.getName() + " c WHERE parent = :p"); 908 909 q.setParameter("p", parent.getId().intValue()); 910 @SuppressWarnings("unchecked") 911 List<BidirectionalChildLongPkListJPA> result = (List<BidirectionalChildLongPkListJPA>) q.getResultList(); 912 assertEquals(2, result.size()); 913 assertEquals(bidirEntity.getKey(), KeyFactory.stringToKey(result.get(0).getId())); 914 assertEquals(bidirEntity2.getKey(), KeyFactory.stringToKey(result.get(1).getId())); 915 } 916 917 public void testFilterByParentObjectWhereParentIsAChild() { 918 Entity parentEntity = new Entity(HasOneToManyListJPA.class.getSimpleName()); 919 ds.put(parentEntity); 920 Entity childEntity = new Entity(BidirectionalChildListJPA.class.getSimpleName(), parentEntity.getKey()); 921 ds.put(childEntity); 922 Entity grandChildEntity1 = 923 new Entity(BidirectionalGrandchildListJPA.class.getSimpleName(), childEntity.getKey()); 924 ds.put(grandChildEntity1); 925 Entity grandChildEntity2 = 926 new Entity(BidirectionalGrandchildListJPA.class.getSimpleName(), childEntity.getKey()); 927 ds.put(grandChildEntity2); 928 929 BidirectionalChildListJPA child = 930 em.find(BidirectionalChildListJPA.class, KeyFactory.keyToString(childEntity.getKey())); 931 Query q = em.createQuery( 932 "select from " + BidirectionalGrandchildListJPA.class.getName() + " c where parent = :p"); 933 q.setParameter("p", child); 934 @SuppressWarnings("unchecked") 935 List<BidirectionalGrandchildListJPA> result = (List<BidirectionalGrandchildListJPA>) q.getResultList(); 936 assertEquals(2, result.size()); 937 assertEquals(grandChildEntity1.getKey(), KeyFactory.stringToKey(result.get(0).getId())); 938 assertEquals(grandChildEntity2.getKey(), KeyFactory.stringToKey(result.get(1).getId())); 939 } 940 public void testFilterByParentId() { 941 Entity parentEntity = new Entity(HasOneToManyListJPA.class.getSimpleName()); 942 ds.put(parentEntity); 943 Entity 944 bidirEntity = 945 new Entity(BidirectionalChildListJPA.class.getSimpleName(), parentEntity.getKey()); 946 ds.put(bidirEntity); 947 Entity 948 bidirEntity2 = 949 new Entity(BidirectionalChildListJPA.class.getSimpleName(), parentEntity.getKey()); 950 ds.put(bidirEntity2); 951 952 HasOneToManyListJPA parent = 953 em.find(HasOneToManyListJPA.class, KeyFactory.keyToString(parentEntity.getKey())); 954 Query q = em.createQuery("SELECT FROM " + 955 BidirectionalChildListJPA.class.getName() + 956 " c WHERE parent = :p"); 957 958 q.setParameter("p", parent.getId()); 959 @SuppressWarnings("unchecked") 960 List<BidirectionalChildListJPA> result = (List<BidirectionalChildListJPA>) q.getResultList(); 961 assertEquals(2, result.size()); 962 assertEquals(bidirEntity.getKey(), KeyFactory.stringToKey(result.get(0).getId())); 963 assertEquals(bidirEntity2.getKey(), KeyFactory.stringToKey(result.get(1).getId())); 964 } 965 966 public void testFilterByParentKey() { 967 Entity parentEntity = new Entity(HasOneToManyListJPA.class.getSimpleName()); 968 ds.put(parentEntity); 969 Entity 970 bidirEntity = 971 new Entity(BidirectionalChildListJPA.class.getSimpleName(), parentEntity.getKey()); 972 ds.put(bidirEntity); 973 Entity 974 bidirEntity2 = 975 new Entity(BidirectionalChildListJPA.class.getSimpleName(), parentEntity.getKey()); 976 ds.put(bidirEntity2); 977 978 Query q = em.createQuery("SELECT FROM " + 979 BidirectionalChildListJPA.class.getName() + 980 " c WHERE parent = :p"); 981 982 q.setParameter("p", parentEntity.getKey()); 983 @SuppressWarnings("unchecked") 984 List<BidirectionalChildListJPA> result = (List<BidirectionalChildListJPA>) q.getResultList(); 985 assertEquals(2, result.size()); 986 assertEquals(bidirEntity.getKey(), KeyFactory.stringToKey(result.get(0).getId())); 987 assertEquals(bidirEntity2.getKey(), KeyFactory.stringToKey(result.get(1).getId())); 988 } 989 990 public void testFilterByMultiValueProperty() { 991 Entity entity = new Entity(HasMultiValuePropsJPA.class.getSimpleName()); 992 entity.setProperty("strList", Utils.newArrayList("1", "2", "3")); 993 entity.setProperty("keyList", 994 Utils.newArrayList(KeyFactory.createKey("be", "bo"), 995 KeyFactory.createKey("bo", "be"))); 996 ds.put(entity); 997 998 Query q = em.createQuery( 999 "select from " + HasMultiValuePropsJPA.class.getName() 1000 + " c where strList = :p1 AND strList = :p2"); 1001 q.setParameter("p1", "1"); 1002 q.setParameter("p2", "3"); 1003 @SuppressWarnings("unchecked") 1004 List<HasMultiValuePropsJPA> result = (List<HasMultiValuePropsJPA>) q.getResultList(); 1005 assertEquals(1, result.size()); 1006 q.setParameter("p1", "1"); 1007 q.setParameter("p2", "4"); 1008 @SuppressWarnings("unchecked") 1009 List<HasMultiValuePropsJPA> result2 = (List<HasMultiValuePropsJPA>) q.getResultList(); 1010 assertEquals(0, result2.size()); 1011 1012 q = em.createQuery( 1013 "select from " + HasMultiValuePropsJPA.class.getName() + " c where keyList = :p1 AND keyList = :p2"); 1014 q.setParameter("p1", KeyFactory.createKey("be", "bo")); 1015 q.setParameter("p2", KeyFactory.createKey("bo", "be")); 1016 assertEquals(1, result.size()); 1017 q.setParameter("p1", KeyFactory.createKey("be", "bo")); 1018 q.setParameter("p2", KeyFactory.createKey("bo", "be2")); 1019 @SuppressWarnings("unchecked") 1020 List<HasMultiValuePropsJPA> result3 = (List<HasMultiValuePropsJPA>) q.getResultList(); 1021 assertEquals(0, result3.size()); 1022 } 1023 1024 public void testNoPutsAfterLoadingMultiValueProperty() throws NoSuchMethodException { 1025 switchDatasource(EntityManagerFactoryName.nontransactional_ds_non_transactional_ops_allowed); 1026 testFilterByMultiValueProperty(); 1027 em.close(); 1028 } 1029 1030 public void testFilterByMultiValueProperty_MemberOf_ArgsWrongOrder() { 1031 Entity entity = new Entity(HasMultiValuePropsJPA.class.getSimpleName()); 1032 entity.setProperty("strList", Utils.newArrayList("1", "2", "3")); 1033 entity.setProperty("keyList", 1034 Utils.newArrayList(KeyFactory.createKey("be", "bo"), 1035 KeyFactory.createKey("bo", "be"))); 1036 ds.put(entity); 1037 1038 Query q = em.createQuery( 1039 "select from " + HasMultiValuePropsJPA.class.getName() 1040 + " c where strList MEMBER OF :p1 AND strList MEMBER OF :p2"); 1041 q.setParameter("p1", "1"); 1042 q.setParameter("p2", "3"); 1043 @SuppressWarnings("unchecked") 1044 List<HasMultiValuePropsJPA> result = (List<HasMultiValuePropsJPA>) q.getResultList(); 1045 assertEquals(1, result.size()); 1046 q.setParameter("p1", "1"); 1047 q.setParameter("p2", "4"); 1048 @SuppressWarnings("unchecked") 1049 List<HasMultiValuePropsJPA> result2 = (List<HasMultiValuePropsJPA>) q.getResultList(); 1050 assertEquals(0, result2.size()); 1051 1052 q = em.createQuery( 1053 "select from " + HasMultiValuePropsJPA.class.getName() 1054 + " c where keyList MEMBER OF :p1 AND keyList MEMBER OF :p2"); 1055 q.setParameter("p1", KeyFactory.createKey("be", "bo")); 1056 q.setParameter("p2", KeyFactory.createKey("bo", "be")); 1057 result = q.getResultList(); 1058 assertEquals(1, result.size()); 1059 q.setParameter("p1", KeyFactory.createKey("be", "bo")); 1060 q.setParameter("p2", KeyFactory.createKey("bo", "be2")); 1061 @SuppressWarnings("unchecked") 1062 List<HasMultiValuePropsJPA> result3 = (List<HasMultiValuePropsJPA>) q.getResultList(); 1063 assertEquals(0, result3.size()); 1064 } 1065 1066 public void testFilterByMultiValueProperty_MemberOf_ArgsCorrectOrder() { 1067 Entity entity = new Entity(HasMultiValuePropsJPA.class.getSimpleName()); 1068 entity.setProperty("strList", Utils.newArrayList("1", "2", "3")); 1069 entity.setProperty("keyList", 1070 Utils.newArrayList(KeyFactory.createKey("be", "bo"), 1071 KeyFactory.createKey("bo", "be"))); 1072 ds.put(entity); 1073 1074 Query q = em.createQuery( 1075 "select from " + HasMultiValuePropsJPA.class.getName() 1076 + " c where :p1 MEMBER OF strList AND :p2 MEMBER OF strList"); 1077 q.setParameter("p1", "1"); 1078 q.setParameter("p2", "3"); 1079 @SuppressWarnings("unchecked") 1080 List<HasMultiValuePropsJPA> result = (List<HasMultiValuePropsJPA>) q.getResultList(); 1081 assertEquals(1, result.size()); 1082 q.setParameter("p1", "1"); 1083 q.setParameter("p2", "4"); 1084 @SuppressWarnings("unchecked") 1085 List<HasMultiValuePropsJPA> result2 = (List<HasMultiValuePropsJPA>) q.getResultList(); 1086 assertEquals(0, result2.size()); 1087 1088 q = em.createQuery( 1089 "select from " + HasMultiValuePropsJPA.class.getName() 1090 + " c where :p1 MEMBER OF keyList AND :p2 MEMBER OF keyList"); 1091 q.setParameter("p1", KeyFactory.createKey("be", "bo")); 1092 q.setParameter("p2", KeyFactory.createKey("bo", "be")); 1093 result = q.getResultList(); 1094 assertEquals(1, result.size()); 1095 q.setParameter("p1", KeyFactory.createKey("be", "bo")); 1096 q.setParameter("p2", KeyFactory.createKey("bo", "be2")); 1097 @SuppressWarnings("unchecked") 1098 List<HasMultiValuePropsJPA> result3 = (List<HasMultiValuePropsJPA>) q.getResultList(); 1099 assertEquals(0, result3.size()); 1100 1101 // try one with a literal value 1102 q = em.createQuery( 1103 "select from " + HasMultiValuePropsJPA.class.getName() 1104 + " c where '1' MEMBER OF strList"); 1105 result = q.getResultList(); 1106 assertEquals(1, result.size()); 1107 } 1108 1109 public void testFilterByEmbeddedField() { 1110 Entity entity = new Entity(Person.class.getSimpleName()); 1111 e…
Large files files are truncated, but you can click here to view the full file