1 package org.hibernate.test.filter; 3 4 import java.util.ArrayList ; 5 import java.util.Calendar ; 6 import java.util.Date ; 7 import java.util.GregorianCalendar ; 8 import java.util.Iterator ; 9 import java.util.List ; 10 import java.util.Set ; 11 12 import junit.framework.Test; 13 import junit.framework.TestSuite; 14 15 import org.apache.commons.logging.Log; 16 import org.apache.commons.logging.LogFactory; 17 import org.hibernate.EntityMode; 18 import org.hibernate.FetchMode; 19 import org.hibernate.Hibernate; 20 import org.hibernate.Session; 21 import org.hibernate.Transaction; 22 import org.hibernate.cache.CacheKey; 23 import org.hibernate.cache.entry.CollectionCacheEntry; 24 import org.hibernate.cfg.Configuration; 25 import org.hibernate.cfg.Environment; 26 import org.hibernate.criterion.Expression; 27 import org.hibernate.engine.SessionFactoryImplementor; 28 import org.hibernate.impl.SessionFactoryImpl; 29 import org.hibernate.persister.collection.CollectionPersister; 30 import org.hibernate.test.TestCase; 31 import org.hibernate.transform.DistinctRootEntityResultTransformer; 32 33 38 public class DynamicFilterTest extends TestCase { 39 40 private Log log = LogFactory.getLog( DynamicFilterTest.class ); 41 42 43 public DynamicFilterTest(String testName) { 44 super( testName ); 45 } 46 47 public void testSecondLevelCachedCollectionsFiltering() { 48 TestData testData = new TestData(); 49 testData.prepare(); 50 51 Session session = openSession(); 52 53 Salesperson sp = ( Salesperson ) session.load( Salesperson.class, testData.steveId ); 55 Hibernate.initialize( sp.getOrders() ); 56 CollectionPersister persister = ( ( SessionFactoryImpl ) getSessions() ) 57 .getCollectionPersister( Salesperson.class.getName() + ".orders" ); 58 assertTrue( "No cache for collection", persister.hasCache() ); 59 CollectionCacheEntry cachedData = ( CollectionCacheEntry ) persister.getCache().getCache() 60 .read( new CacheKey( testData.steveId, persister.getKeyType(), persister.getRole(), EntityMode.POJO, sfi() ) ); 61 assertNotNull( "collection was not in cache", cachedData ); 62 63 session.close(); 64 65 session = openSession(); 66 session.enableFilter( "fulfilledOrders" ).setParameter( "asOfDate", testData.lastMonth.getTime() ); 67 sp = ( Salesperson ) session.createQuery( "from Salesperson as s where s.id = :id" ) 68 .setLong( "id", testData.steveId.longValue() ) 69 .uniqueResult(); 70 assertEquals( "Filtered-collection not bypassing 2L-cache", 1, sp.getOrders().size() ); 71 72 CollectionCacheEntry cachedData2 = ( CollectionCacheEntry ) persister.getCache().getCache() 73 .read( new CacheKey( testData.steveId, persister.getKeyType(), persister.getRole(), EntityMode.POJO, sfi() ) ); 74 assertNotNull( "collection no longer in cache!", cachedData2 ); 75 assertSame( "Different cache values!", cachedData, cachedData2 ); 76 77 session.close(); 78 79 session = openSession(); 80 session.enableFilter( "fulfilledOrders" ).setParameter( "asOfDate", testData.lastMonth.getTime() ); 81 sp = ( Salesperson ) session.load( Salesperson.class, testData.steveId ); 82 assertEquals( "Filtered-collection not bypassing 2L-cache", 1, sp.getOrders().size() ); 83 84 session.close(); 85 86 session = openSession(); 88 sp = ( Salesperson ) session.load( Salesperson.class, testData.steveId ); 89 assertEquals( "Actual cached version got over-written", 2, sp.getOrders().size() ); 90 91 session.close(); 92 testData.release(); 93 } 94 95 public void testCombinedClassAndCollectionFiltersEnabled() { 96 TestData testData = new TestData(); 97 testData.prepare(); 98 99 Session session = openSession(); 100 session.enableFilter( "regionlist" ).setParameterList( "regions", new String []{"LA", "APAC"} ); 101 session.enableFilter( "fulfilledOrders" ).setParameter( "asOfDate", testData.lastMonth.getTime() ); 102 103 List salespersons = session.createQuery( "select s from Salesperson as s" ).list(); 105 assertEquals( "Incorrect salesperson count", 1, salespersons.size() ); 106 Salesperson sp = ( Salesperson ) salespersons.get( 0 ); 107 assertEquals( "Incorrect order count", 1, sp.getOrders().size() ); 108 109 session.clear(); 110 111 salespersons = session.createQuery( "select s from Salesperson as s left join fetch s.orders" ).list(); 113 assertEquals( "Incorrect salesperson count", 1, salespersons.size() ); 114 sp = ( Salesperson ) salespersons.get( 0 ); 115 assertEquals( "Incorrect order count", 1, sp.getOrders().size() ); 116 117 session.close(); 118 testData.release(); 119 } 120 121 public void testHqlFilters() { 122 log.info( "Starting HQL filter tests" ); 126 TestData testData = new TestData(); 127 testData.prepare(); 128 129 Session session = openSession(); 130 session.enableFilter( "region" ).setParameter( "region", "APAC" ); 131 132 session.enableFilter( "effectiveDate" ) 133 .setParameter( "asOfDate", testData.lastMonth.getTime() ); 134 135 log.info( "HQL against Salesperson..." ); 136 List results = session.createQuery( "select s from Salesperson as s left join fetch s.orders" ).list(); 137 assertTrue( "Incorrect filtered HQL result count [" + results.size() + "]", results.size() == 1 ); 138 Salesperson result = ( Salesperson ) results.get( 0 ); 139 assertTrue( "Incorrect collectionfilter count", result.getOrders().size() == 1 ); 140 141 log.info( "HQL against Product..." ); 142 results = session.createQuery( "from Product as p where p.stockNumber = ?" ).setInteger( 0, 124 ).list(); 143 assertTrue( results.size() == 1 ); 144 145 session.close(); 146 testData.release(); 147 } 148 149 public void testCriteriaQueryFilters() { 150 log.info( "Starting Criteria-query filter tests" ); 154 TestData testData = new TestData(); 155 testData.prepare(); 156 157 Session session = openSession(); 158 session.enableFilter( "region" ).setParameter( "region", "APAC" ); 159 160 session.enableFilter( "fulfilledOrders" ) 161 .setParameter( "asOfDate", testData.lastMonth.getTime() ); 162 163 session.enableFilter( "effectiveDate" ) 164 .setParameter( "asOfDate", testData.lastMonth.getTime() ); 165 166 log.info( "Criteria query against Salesperson..." ); 167 List salespersons = session.createCriteria( Salesperson.class ) 168 .setFetchMode( "orders", FetchMode.JOIN ) 169 .list(); 170 assertEquals( "Incorrect salesperson count", 1, salespersons.size() ); 171 assertEquals( "Incorrect order count", 1, ( ( Salesperson ) salespersons.get( 0 ) ).getOrders().size() ); 172 173 log.info( "Criteria query against Product..." ); 174 List products = session.createCriteria( Product.class ) 175 .add( Expression.eq( "stockNumber", new Integer ( 124 ) ) ) 176 .list(); 177 assertEquals( "Incorrect product count", 1, products.size() ); 178 179 session.close(); 180 testData.release(); 181 } 182 183 public void testGetFilters() { 184 log.info( "Starting get() filter tests (eager assoc. fetching)." ); 188 TestData testData = new TestData(); 189 testData.prepare(); 190 191 Session session = openSession(); 192 session.enableFilter( "region" ).setParameter( "region", "APAC" ); 193 194 log.info( "Performing get()..." ); 195 Salesperson salesperson = ( Salesperson ) session.get( Salesperson.class, testData.steveId ); 196 assertNotNull( salesperson ); 197 assertEquals( "Incorrect order count", 1, salesperson.getOrders().size() ); 198 199 session.close(); 200 testData.release(); 201 } 202 203 public void testOneToManyFilters() { 204 log.info( "Starting one-to-many collection loader filter tests." ); 208 TestData testData = new TestData(); 209 testData.prepare(); 210 211 Session session = openSession(); 212 session.enableFilter( "seniorSalespersons" ) 213 .setParameter( "asOfDate", testData.lastMonth.getTime() ); 214 215 log.info( "Performing load of Department..." ); 216 Department department = ( Department ) session.load( Department.class, testData.deptId ); 217 Set salespersons = department.getSalespersons(); 218 assertEquals( "Incorrect salesperson count", 1, salespersons.size() ); 219 220 session.close(); 221 testData.release(); 222 } 223 224 public void testInStyleFilterParameter() { 225 log.info( "Starting one-to-many collection loader filter tests." ); 229 TestData testData = new TestData(); 230 testData.prepare(); 231 232 Session session = openSession(); 233 session.enableFilter( "regionlist" ) 234 .setParameterList( "regions", new String []{"LA", "APAC"} ); 235 236 log.debug( "Performing query of Salespersons" ); 237 List salespersons = session.createQuery( "from Salesperson" ).list(); 238 assertEquals( "Incorrect salesperson count", 1, salespersons.size() ); 239 240 session.close(); 241 testData.release(); 242 } 243 244 public void testManyToManyFilterOnCriteria() { 245 TestData testData = new TestData(); 246 testData.prepare(); 247 248 Session session = openSession(); 249 session.enableFilter( "effectiveDate" ).setParameter( "asOfDate", new Date () ); 250 251 Product prod = ( Product ) session.createCriteria( Product.class ) 252 .setResultTransformer( new DistinctRootEntityResultTransformer() ) 253 .add( Expression.eq( "id", testData.prod1Id ) ) 254 .uniqueResult(); 255 256 assertNotNull( prod ); 257 assertEquals( "Incorrect Product.categories count for filter", 1, prod.getCategories().size() ); 258 259 session.close(); 260 testData.release(); 261 } 262 263 public void testManyToManyFilterOnLoad() { 264 TestData testData = new TestData(); 265 testData.prepare(); 266 267 Session session = openSession(); 268 session.enableFilter( "effectiveDate" ).setParameter( "asOfDate", new Date () ); 269 270 Product prod = ( Product ) session.get( Product.class, testData.prod1Id ); 271 272 long initLoadCount = getSessions().getStatistics().getCollectionLoadCount(); 273 long initFetchCount = getSessions().getStatistics().getCollectionFetchCount(); 274 275 int size = prod.getCategories().size(); 277 assertEquals( "Incorrect filtered collection count", 1, size ); 278 279 long currLoadCount = getSessions().getStatistics().getCollectionLoadCount(); 280 long currFetchCount = getSessions().getStatistics().getCollectionFetchCount(); 281 282 assertTrue( 283 "load with join fetch of many-to-many did not trigger join fetch", 284 ( initLoadCount == currLoadCount ) && ( initFetchCount == currFetchCount ) 285 ); 286 287 long initEntityLoadCount = getSessions().getStatistics().getEntityLoadCount(); 289 Iterator itr = prod.getCategories().iterator(); 290 while ( itr.hasNext() ) { 291 Category cat = ( Category ) itr.next(); 292 System.out.println( " ===> " + cat.getName() ); 293 } 294 long currEntityLoadCount = getSessions().getStatistics().getEntityLoadCount(); 295 296 assertTrue( 297 "load with join fetch of many-to-many did not trigger *complete* join fetch", 298 ( initEntityLoadCount == currEntityLoadCount ) 299 ); 300 301 session.close(); 302 testData.release(); 303 } 304 305 public void testManyToManyOnCollectionLoadAfterHQL() { 306 TestData testData = new TestData(); 307 testData.prepare(); 308 309 Session session = openSession(); 310 session.enableFilter( "effectiveDate" ).setParameter( "asOfDate", new Date () ); 311 312 List result = session.createQuery( "from Product as p where p.id = :id" ) 314 .setLong( "id", testData.prod1Id.longValue() ) 315 .list(); 316 assertTrue( "No products returned from HQL", !result.isEmpty() ); 317 318 Product prod = ( Product ) result.get( 0 ); 319 assertNotNull( prod ); 320 assertEquals( "Incorrect Product.categories count for filter on collection load", 1, prod.getCategories().size() ); 321 322 session.close(); 323 testData.release(); 324 } 325 326 public void testManyToManyFilterOnQuery() { 327 TestData testData = new TestData(); 328 testData.prepare(); 329 330 Session session = openSession(); 331 session.enableFilter( "effectiveDate" ).setParameter( "asOfDate", new Date () ); 332 333 List result = session.createQuery( "from Product p inner join fetch p.categories" ).list(); 334 assertTrue( "No products returned from HQL many-to-many filter case", !result.isEmpty() ); 335 336 Product prod = ( Product ) result.get( 0 ); 337 338 assertNotNull( prod ); 339 assertEquals( "Incorrect Product.categories count for filter with HQL", 1, prod.getCategories().size() ); 340 341 session.close(); 342 testData.release(); 343 } 344 345 public void testManyToManyBase() { 346 TestData testData = new TestData(); 347 testData.prepare(); 348 349 Session session = openSession(); 350 351 Product prod = ( Product ) session.get( Product.class, testData.prod1Id ); 352 353 long initLoadCount = getSessions().getStatistics().getCollectionLoadCount(); 354 long initFetchCount = getSessions().getStatistics().getCollectionFetchCount(); 355 356 int size = prod.getCategories().size(); 358 assertEquals( "Incorrect non-filtered collection count", 2, size ); 359 360 long currLoadCount = getSessions().getStatistics().getCollectionLoadCount(); 361 long currFetchCount = getSessions().getStatistics().getCollectionFetchCount(); 362 363 assertTrue( 364 "load with join fetch of many-to-many did not trigger join fetch", 365 ( initLoadCount == currLoadCount ) && ( initFetchCount == currFetchCount ) 366 ); 367 368 long initEntityLoadCount = getSessions().getStatistics().getEntityLoadCount(); 370 Iterator itr = prod.getCategories().iterator(); 371 while ( itr.hasNext() ) { 372 Category cat = ( Category ) itr.next(); 373 System.out.println( " ===> " + cat.getName() ); 374 } 375 long currEntityLoadCount = getSessions().getStatistics().getEntityLoadCount(); 376 377 assertTrue( 378 "load with join fetch of many-to-many did not trigger *complete* join fetch", 379 ( initEntityLoadCount == currEntityLoadCount ) 380 ); 381 382 session.close(); 383 testData.release(); 384 } 385 386 public void testManyToManyBaseThruCriteria() { 387 TestData testData = new TestData(); 388 testData.prepare(); 389 390 Session session = openSession(); 391 392 List result = session.createCriteria( Product.class ) 393 .add( Expression.eq( "id", testData.prod1Id ) ) 394 .list(); 395 396 Product prod = ( Product ) result.get( 0 ); 397 398 long initLoadCount = getSessions().getStatistics().getCollectionLoadCount(); 399 long initFetchCount = getSessions().getStatistics().getCollectionFetchCount(); 400 401 int size = prod.getCategories().size(); 403 assertEquals( "Incorrect non-filtered collection count", 2, size ); 404 405 long currLoadCount = getSessions().getStatistics().getCollectionLoadCount(); 406 long currFetchCount = getSessions().getStatistics().getCollectionFetchCount(); 407 408 assertTrue( 409 "load with join fetch of many-to-many did not trigger join fetch", 410 ( initLoadCount == currLoadCount ) && ( initFetchCount == currFetchCount ) 411 ); 412 413 long initEntityLoadCount = getSessions().getStatistics().getEntityLoadCount(); 415 Iterator itr = prod.getCategories().iterator(); 416 while ( itr.hasNext() ) { 417 Category cat = ( Category ) itr.next(); 418 System.out.println( " ===> " + cat.getName() ); 419 } 420 long currEntityLoadCount = getSessions().getStatistics().getEntityLoadCount(); 421 422 assertTrue( 423 "load with join fetch of many-to-many did not trigger *complete* join fetch", 424 ( initEntityLoadCount == currEntityLoadCount ) 425 ); 426 427 session.close(); 428 testData.release(); 429 } 430 431 432 437 protected String [] getMappings() { 438 return new String []{ 439 "filter/defs.hbm.xml", 440 "filter/LineItem.hbm.xml", 441 "filter/Order.hbm.xml", 442 "filter/Product.hbm.xml", 443 "filter/Salesperson.hbm.xml", 444 "filter/Department.hbm.xml", 445 "filter/Category.hbm.xml" 446 }; 447 } 448 449 protected void configure(Configuration cfg) { 450 cfg.setProperty( Environment.MAX_FETCH_DEPTH, "1" ); 451 cfg.setProperty( Environment.GENERATE_STATISTICS, "true" ); 453 cfg.setProperty( Environment.USE_QUERY_CACHE, "true" ); 454 } 455 456 public static Test suite() { 457 return new TestSuite( DynamicFilterTest.class ); 458 } 459 460 private class TestData { 461 private Long steveId; 462 private Long deptId; 463 private Long prod1Id; 464 private Calendar lastMonth; 465 private Calendar nextMonth; 466 private Calendar sixMonthsAgo; 467 private Calendar fourMonthsAgo; 468 469 private List entitiesToCleanUp = new ArrayList (); 470 471 private void prepare() { 472 Session session = openSession(); 473 Transaction transaction = session.beginTransaction(); 474 475 lastMonth = new GregorianCalendar (); 476 lastMonth.add( Calendar.MONTH, -1 ); 477 478 nextMonth = new GregorianCalendar (); 479 nextMonth.add( Calendar.MONTH, 1 ); 480 481 sixMonthsAgo = new GregorianCalendar (); 482 sixMonthsAgo.add( Calendar.MONTH, -6 ); 483 484 fourMonthsAgo = new GregorianCalendar (); 485 fourMonthsAgo.add( Calendar.MONTH, -4 ); 486 487 Department dept = new Department(); 488 dept.setName( "Sales" ); 489 490 session.save( dept ); 491 deptId = dept.getId(); 492 entitiesToCleanUp.add( dept ); 493 494 Salesperson steve = new Salesperson(); 495 steve.setName( "steve" ); 496 steve.setRegion( "APAC" ); 497 steve.setHireDate( sixMonthsAgo.getTime() ); 498 499 steve.setDepartment( dept ); 500 dept.getSalespersons().add( steve ); 501 502 Salesperson max = new Salesperson(); 503 max.setName( "max" ); 504 max.setRegion( "EMEA" ); 505 max.setHireDate( nextMonth.getTime() ); 506 507 max.setDepartment( dept ); 508 dept.getSalespersons().add( max ); 509 510 session.save( steve ); 511 session.save( max ); 512 entitiesToCleanUp.add( steve ); 513 entitiesToCleanUp.add( max ); 514 515 steveId = steve.getId(); 516 517 Category cat1 = new Category( "test cat 1", lastMonth.getTime(), nextMonth.getTime() ); 518 Category cat2 = new Category( "test cat 2", sixMonthsAgo.getTime(), fourMonthsAgo.getTime() ); 519 520 Product product1 = new Product(); 521 product1.setName( "Acme Hair Gel" ); 522 product1.setStockNumber( 123 ); 523 product1.setEffectiveStartDate( lastMonth.getTime() ); 524 product1.setEffectiveEndDate( nextMonth.getTime() ); 525 526 product1.addCategory( cat1 ); 527 product1.addCategory( cat2 ); 528 529 session.save( product1 ); 530 entitiesToCleanUp.add( product1 ); 531 prod1Id = product1.getId(); 532 533 Order order1 = new Order(); 534 order1.setBuyer( "gavin" ); 535 order1.setRegion( "APAC" ); 536 order1.setPlacementDate( sixMonthsAgo.getTime() ); 537 order1.setFulfillmentDate( fourMonthsAgo.getTime() ); 538 order1.setSalesperson( steve ); 539 order1.addLineItem( product1, 500 ); 540 541 session.save( order1 ); 542 entitiesToCleanUp.add( order1 ); 543 544 Product product2 = new Product(); 545 product2.setName( "Acme Super-Duper DTO Factory" ); 546 product2.setStockNumber( 124 ); 547 product2.setEffectiveStartDate( sixMonthsAgo.getTime() ); 548 product2.setEffectiveEndDate( new Date () ); 549 550 Category cat3 = new Category( "test cat 2", sixMonthsAgo.getTime(), new Date () ); 551 product2.addCategory( cat3 ); 552 553 session.save( product2 ); 554 entitiesToCleanUp.add( product2 ); 555 556 Product product3 = new Product(); 558 product3.setName( "Uncategorized product" ); 559 session.save( product3 ); 560 entitiesToCleanUp.add( product3 ); 561 562 Order order2 = new Order(); 563 order2.setBuyer( "christian" ); 564 order2.setRegion( "EMEA" ); 565 order2.setPlacementDate( lastMonth.getTime() ); 566 order2.setSalesperson( steve ); 567 order2.addLineItem( product2, -1 ); 568 569 session.save( order2 ); 570 entitiesToCleanUp.add( order2 ); 571 572 transaction.commit(); 573 session.close(); 574 } 575 576 private void release() { 577 Session session = openSession(); 578 Transaction transaction = session.beginTransaction(); 579 580 Iterator itr = entitiesToCleanUp.iterator(); 581 while ( itr.hasNext() ) { 582 session.delete( itr.next() ); 583 } 584 585 transaction.commit(); 586 session.close(); 587 } 588 } 589 590 private SessionFactoryImplementor sfi() { 591 return ( SessionFactoryImplementor ) getSessions(); 592 } 593 } 594 | Popular Tags |