1 package org.hibernate.test.hql; 3 4 import java.util.List ; 5 import java.util.Date ; 6 7 import junit.framework.Test; 8 import junit.framework.TestSuite; 9 10 import org.hibernate.Transaction; 11 import org.hibernate.QueryException; 12 import org.hibernate.hql.ast.HqlSqlWalker; 13 import org.hibernate.id.IdentifierGenerator; 14 import org.hibernate.persister.entity.EntityPersister; 15 import org.hibernate.engine.SessionFactoryImplementor; 16 import org.hibernate.classic.Session; 17 import org.hibernate.dialect.HSQLDialect; 18 import org.hibernate.test.TestCase; 19 20 21 26 public class BulkManipulationTest extends TestCase { 27 28 public BulkManipulationTest(String name) { 29 super( name ); 30 } 31 32 public static Test suite() { 33 return new TestSuite( BulkManipulationTest.class ); 34 } 35 36 protected String [] getMappings() { 37 return new String [] { 38 "hql/Animal.hbm.xml", 39 "hql/Vehicle.hbm.xml", 40 "hql/KeyManyToOneEntity.hbm.xml", 41 "hql/Versions.hbm.xml" 42 }; 43 } 44 45 46 48 public void testDeleteNonExistentEntity() { 49 Session s = openSession(); 50 Transaction t = s.beginTransaction(); 51 52 try { 53 s.createQuery( "delete NonExistentEntity" ).executeUpdate(); 54 fail( "no exception thrown" ); 55 } 56 catch( QueryException e ) { 57 System.out.println( "Caught expected error type : " + e.getMessage() ); 58 } 59 60 t.commit(); 61 s.close(); 62 } 63 64 public void testUpdateNonExistentEntity() { 65 Session s = openSession(); 66 Transaction t = s.beginTransaction(); 67 68 try { 69 s.createQuery( "update NonExistentEntity e set e.someProp = ?" ).executeUpdate(); 70 fail( "no exception thrown" ); 71 } 72 catch( QueryException e ) { 73 System.out.println( "Caught expected error type : " + e.getMessage() ); 74 } 75 76 t.commit(); 77 s.close(); 78 } 79 80 public void testSimpleInsert() { 81 TestData data = new TestData(); 82 data.prepare(); 83 84 Session s = openSession(); 85 Transaction t = s.beginTransaction(); 86 87 s.createQuery( "insert into Pickup (id, vin, owner) select id, vin, owner from Car" ).executeUpdate(); 88 89 t.commit(); 90 t = s.beginTransaction(); 91 92 s.createQuery( "delete Vehicle" ).executeUpdate(); 93 94 t.commit(); 95 s.close(); 96 97 data.cleanup(); 98 } 99 100 public void testInsertWithMismatchedTypes() { 101 TestData data = new TestData(); 102 data.prepare(); 103 104 Session s = openSession(); 105 Transaction t = s.beginTransaction(); 106 try { 107 s.createQuery( "insert into Pickup (owner, vin, id) select id, vin, owner from Car" ).executeUpdate(); 108 fail( "mismatched types did not error" ); 109 } 110 catch( QueryException e ) { 111 } 113 114 t.commit(); 115 t = s.beginTransaction(); 116 117 s.createQuery( "delete Vehicle" ).executeUpdate(); 118 119 t.commit(); 120 s.close(); 121 122 data.cleanup(); 123 } 124 125 public void testInsertIntoSuperclassPropertiesFails() { 126 TestData data = new TestData(); 127 data.prepare(); 128 129 Session s = openSession(); 130 Transaction t = s.beginTransaction(); 131 132 try { 133 s.createQuery( "insert into Human (id, bodyWeight) select id, bodyWeight from Lizard" ).executeUpdate(); 134 fail( "superclass prop insertion did not error" ); 135 } 136 catch( QueryException e ) { 137 } 139 140 t.commit(); 141 t = s.beginTransaction(); 142 143 s.createQuery( "delete Animal where mother is not null" ).executeUpdate(); 144 s.createQuery( "delete Animal" ).executeUpdate(); 145 146 t.commit(); 147 s.close(); 148 149 data.cleanup(); 150 } 151 152 public void testInsertAcrossMappedJoinFails() { 153 TestData data = new TestData(); 154 data.prepare(); 155 156 Session s = openSession(); 157 Transaction t = s.beginTransaction(); 158 159 try { 160 s.createQuery( "insert into Joiner (name, joinedName) select vin, owner from Car" ).executeUpdate(); 161 fail( "mapped-join insertion did not error" ); 162 } 163 catch( QueryException e ) { 164 } 166 167 t.commit(); 168 t = s.beginTransaction(); 169 170 s.createQuery( "delete Joiner" ).executeUpdate(); 171 s.createQuery( "delete Vehicle" ).executeUpdate(); 172 173 t.commit(); 174 s.close(); 175 176 data.cleanup(); 177 } 178 179 public void testInsertWithGeneratedId() { 180 EntityPersister persister = sfi().getEntityPersister( PettingZoo.class.getName() ); 182 IdentifierGenerator generator = persister.getIdentifierGenerator(); 183 if ( !HqlSqlWalker.supportsIdGenWithBulkInsertion( generator ) ) { 184 return; 185 } 186 187 Zoo zoo = new Zoo(); 189 zoo.setName( "zoo" ); 190 191 Session s = openSession(); 192 Transaction t = s.beginTransaction(); 193 s.save( zoo ); 194 t.commit(); 195 s.close(); 196 197 s = openSession(); 198 t = s.beginTransaction(); 199 int count = s.createQuery( "insert into PettingZoo (name) select name from Zoo" ).executeUpdate(); 200 t.commit(); 201 s.close(); 202 203 assertEquals( "unexpected insertion count", 1, count ); 204 205 s = openSession(); 206 t = s.beginTransaction(); 207 PettingZoo pz = ( PettingZoo ) s.createQuery( "from PettingZoo" ).uniqueResult(); 208 t.commit(); 209 s.close(); 210 211 assertEquals( zoo.getName(), pz.getName() ); 212 assertTrue( zoo.getId() != pz.getId() ); 213 214 s = openSession(); 215 t = s.beginTransaction(); 216 s.createQuery( "delete Zoo" ).executeUpdate(); 217 t.commit(); 218 s.close(); 219 } 220 221 public void testInsertWithGeneratedVersionAndId() { 222 EntityPersister persister = sfi().getEntityPersister( IntegerVersioned.class.getName() ); 224 IdentifierGenerator generator = persister.getIdentifierGenerator(); 225 if ( !HqlSqlWalker.supportsIdGenWithBulkInsertion( generator ) ) { 226 return; 227 } 228 229 Session s = openSession(); 230 Transaction t = s.beginTransaction(); 231 232 IntegerVersioned entity = new IntegerVersioned( "int-vers" ); 233 s.save( entity ); 234 s.createQuery( "select id, name, version from IntegerVersioned" ).list(); 235 t.commit(); 236 s.close(); 237 238 Long initialId = entity.getId(); 239 int initialVersion = entity.getVersion(); 240 241 s = openSession(); 242 t = s.beginTransaction(); 243 int count = s.createQuery( "insert into IntegerVersioned ( name ) select name from IntegerVersioned" ).executeUpdate(); 244 t.commit(); 245 s.close(); 246 247 assertEquals( "unexpected insertion count", 1, count ); 248 249 s = openSession(); 250 t = s.beginTransaction(); 251 IntegerVersioned created = ( IntegerVersioned ) s.createQuery( "from IntegerVersioned where id <> :initialId" ) 252 .setLong( "initialId", initialId.longValue() ) 253 .uniqueResult(); 254 t.commit(); 255 s.close(); 256 257 assertEquals( "version was not seeded", initialVersion, created.getVersion() ); 258 259 s = openSession(); 260 t = s.beginTransaction(); 261 s.createQuery( "delete IntegerVersioned" ).executeUpdate(); 262 t.commit(); 263 s.close(); 264 } 265 266 public void testInsertWithGeneratedTimestampVersion() { 267 268 } 269 270 272 public void testIncrementCounterVersion() { 273 Session s = openSession(); 274 Transaction t = s.beginTransaction(); 275 276 IntegerVersioned entity = new IntegerVersioned( "int-vers" ); 277 s.save( entity ); 278 t.commit(); 279 s.close(); 280 281 int initialVersion = entity.getVersion(); 282 283 s = openSession(); 284 t = s.beginTransaction(); 285 int count = s.createQuery( "update versioned IntegerVersioned set name = name" ).executeUpdate(); 286 assertEquals( "incorrect exec count", 1, count ); 287 t.commit(); 288 289 t = s.beginTransaction(); 290 entity = ( IntegerVersioned ) s.load( IntegerVersioned.class, entity.getId() ); 291 assertEquals( "version not incremented", initialVersion + 1, entity.getVersion() ); 292 293 s.delete( entity ); 294 t.commit(); 295 s.close(); 296 } 297 298 public void testIncrementTimestampVersion() { 299 Session s = openSession(); 300 Transaction t = s.beginTransaction(); 301 302 TimestampVersioned entity = new TimestampVersioned( "ts-vers" ); 303 s.save( entity ); 304 t.commit(); 305 s.close(); 306 307 Date initialVersion = entity.getVersion(); 308 309 synchronized (this) { 310 try { 311 wait(300); 312 } 313 catch (InterruptedException ie) {} 314 } 315 316 s = openSession(); 317 t = s.beginTransaction(); 318 int count = s.createQuery( "update versioned TimestampVersioned set name = name" ).executeUpdate(); 319 assertEquals( "incorrect exec count", 1, count ); 320 t.commit(); 321 322 t = s.beginTransaction(); 323 entity = ( TimestampVersioned ) s.load( TimestampVersioned.class, entity.getId() ); 324 assertTrue( "version not incremented", entity.getVersion().after( initialVersion ) ); 325 326 s.delete( entity ); 327 t.commit(); 328 s.close(); 329 } 330 331 public void testUpdateOnComponent() { 332 Session s = openSession(); 333 Transaction t = s.beginTransaction(); 334 335 Human human = new Human(); 336 human.setName( new Name() ); 337 human.getName().setFirst("Stevee"); 338 human.getName().setInitial('X'); 339 human.getName().setLast("Ebersole"); 340 341 s.save( human ); 342 s.flush(); 343 344 t.commit(); 345 346 String correctName = "Steve"; 347 348 t = s.beginTransaction(); 349 350 int count = s.createQuery( "update Human set name.first = :correction where id = :id" ) 351 .setString( "correction", correctName ) 352 .setLong( "id", human.getId().longValue() ) 353 .executeUpdate(); 354 355 assertEquals( "Incorrect update count", 1, count ); 356 357 t.commit(); 358 359 t = s.beginTransaction(); 360 361 s.refresh( human ); 362 363 assertEquals( "Update did not execute properly", correctName, human.getName().getFirst() ); 364 365 s.createQuery( "delete Human" ).executeUpdate(); 366 t.commit(); 367 368 s.close(); 369 } 370 371 public void testUpdateOnImplicitJoinFails() { 372 Session s = openSession(); 373 Transaction t = s.beginTransaction(); 374 375 Human human = new Human(); 376 human.setName( new Name() ); 377 human.getName().setFirst( "Steve" ); 378 379 Human mother = new Human(); 380 mother.setName( new Name() ); 381 mother.getName().setFirst( "Jane" ); 382 human.setMother( mother ); 383 384 s.save( human ); 385 s.save( mother ); 386 s.flush(); 387 388 t.commit(); 389 390 t = s.beginTransaction(); 391 try { 392 s.createQuery( "update Human set mother.name.initial = :initial" ).setString( "initial", "F" ).executeUpdate(); 393 fail( "update allowed across implicit join" ); 394 } 395 catch( QueryException e ) { 396 System.out.println( "TEST (OK) : " + e.getMessage() ); 397 } 399 400 s.createQuery( "delete Human where mother is not null" ).executeUpdate(); 401 s.createQuery( "delete Human" ).executeUpdate(); 402 t.commit(); 403 s.close(); 404 } 405 406 public void testUpdateOnDiscriminatorSubclass() { 407 TestData data = new TestData(); 408 data.prepare(); 409 410 Session s = openSession(); 411 Transaction t = s.beginTransaction(); 412 413 int count = s.createQuery( "update PettingZoo set name = name" ).executeUpdate(); 414 assertEquals( "Incorrect discrim subclass update count", 1, count ); 415 416 t.rollback(); 417 t = s.beginTransaction(); 418 419 count = s.createQuery( "update PettingZoo pz set pz.name = pz.name where pz.id = :id" ) 420 .setLong( "id", data.pettingZoo.getId().longValue() ) 421 .executeUpdate(); 422 assertEquals( "Incorrect discrim subclass update count", 1, count ); 423 424 t.rollback(); 425 t = s.beginTransaction(); 426 427 count = s.createQuery( "update Zoo as z set z.name = z.name" ).executeUpdate(); 428 assertEquals( "Incorrect discrim subclass update count", 2, count ); 429 430 t.rollback(); 431 t = s.beginTransaction(); 432 433 count = s.createQuery( "update Zoo as z set name = name where id = :id" ) 436 .setLong( "id", data.zoo.getId().longValue() ) 437 .executeUpdate(); 438 assertEquals( "Incorrect discrim subclass update count", 1, count ); 439 440 t.commit(); 441 s.close(); 442 443 data.cleanup(); 444 } 445 446 public void testUpdateOnAnimal() { 447 TestData data = new TestData(); 448 data.prepare(); 449 450 Session s = openSession(); 451 Transaction t = s.beginTransaction(); 452 int count = s.createQuery( "update Animal set description = description where description = :desc" ) 453 .setString( "desc", data.frog.getDescription() ) 454 .executeUpdate(); 455 assertEquals( "Incorrect entity-updated count", 1, count ); 456 457 count = s.createQuery( "update Animal set description = :newDesc where description = :desc" ) 458 .setString( "desc", data.polliwog.getDescription() ) 459 .setString( "newDesc", "Tadpole" ) 460 .executeUpdate(); 461 assertEquals( "Incorrect entity-updated count", 1, count ); 462 463 Animal tadpole = ( Animal ) s.load( Animal.class, data.polliwog.getId() ); 464 assertEquals( "Update did not take effect", "Tadpole", tadpole.getDescription() ); 465 466 count = s.createQuery( "update Animal set bodyWeight = bodyWeight + :w1 + :w2" ) 467 .setDouble( "w1", 1 ) 468 .setDouble( "w2", 2 ) 469 .executeUpdate(); 470 assertEquals( "incorrect count on 'complex' update assignment", count, 6 ); 471 472 count = s.createQuery( "update Animal set bodyWeight = ( select max(bodyWeight) from Animal )" ) 473 .executeUpdate(); 474 475 t.commit(); 476 s.close(); 477 478 data.cleanup(); 479 } 480 481 public void testUpdateOnMammal() { 482 TestData data = new TestData(); 483 data.prepare(); 484 485 Session s = openSession(); 486 Transaction t = s.beginTransaction(); 487 488 int count = s.createQuery( "update Mammal set description = description" ).executeUpdate(); 489 assertEquals( "incorrect update count against 'middle' of joined-subclass hierarchy", 2, count ); 490 491 t.commit(); 492 s.close(); 493 494 data.cleanup(); 495 } 496 497 498 500 public void testSimpleDeleteOnAnimal() { 501 if ( getDialect().hasSelfReferentialForeignKeyBug() || getDialect() instanceof HSQLDialect ) { 502 return; 506 } 507 508 TestData data = new TestData(); 509 data.prepare(); 510 511 Session s = openSession(); 512 Transaction t = s.beginTransaction(); 513 514 int count = s.createQuery( "delete from Animal as a where a.id = :id" ) 515 .setLong( "id", data.polliwog.getId().longValue() ) 516 .executeUpdate(); 517 assertEquals( "Incorrect delete count", 1, count ); 518 519 count = s.createQuery( "delete Animal a" ).executeUpdate(); 520 assertEquals( "Incorrect delete count", 5, count ); 521 522 List list = s.createQuery( "select a from Animal as a" ).list(); 523 assertTrue( "table not empty", list.isEmpty() ); 524 525 t.commit(); 526 s.close(); 527 data.cleanup(); 528 } 529 530 public void testDeleteOnDiscriminatorSubclass() { 531 TestData data = new TestData(); 532 data.prepare(); 533 534 Session s = openSession(); 535 Transaction t = s.beginTransaction(); 536 537 int count = s.createQuery( "delete PettingZoo" ).executeUpdate(); 538 assertEquals( "Incorrect discrim subclass delete count", 1, count ); 539 540 count = s.createQuery( "delete Zoo" ).executeUpdate(); 541 assertEquals( "Incorrect discrim subclass delete count", 1, count ); 542 543 t.commit(); 544 s.close(); 545 546 data.cleanup(); 547 } 548 549 public void testDeleteOnJoinedSubclass() { 550 TestData data = new TestData(); 551 data.prepare(); 552 553 Session s = openSession(); 554 Transaction t = s.beginTransaction(); 555 556 int count = s.createQuery( "delete Mammal where bodyWeight > 150" ).executeUpdate(); 557 assertEquals( "Incorrect deletion count on joined subclass", 1, count ); 558 559 count = s.createQuery( "delete Mammal" ).executeUpdate(); 560 assertEquals( "Incorrect deletion count on joined subclass", 1, count ); 561 562 t.commit(); 563 s.close(); 564 565 data.cleanup(); 566 } 567 568 public void testDeleteOnMappedJoin() { 569 TestData data = new TestData(); 570 data.prepare(); 571 572 Session s = openSession(); 573 Transaction t = s.beginTransaction(); 574 575 int count = s.createQuery( "delete Joiner where joinedName = :joinedName" ).setString( "joinedName", "joined-name" ).executeUpdate(); 576 assertEquals( "Incorrect deletion count on joined subclass", 1, count ); 577 578 t.commit(); 579 s.close(); 580 581 data.cleanup(); 582 } 583 584 public void testDeleteUnionSubclassAbstractRoot() { 585 TestData data = new TestData(); 586 data.prepare(); 587 588 Session s = openSession(); 590 Transaction t = s.beginTransaction(); 591 592 int count = s.createQuery( "delete Vehicle where owner = :owner" ).setString( "owner", "Steve" ).executeUpdate(); 593 assertEquals( "incorrect restricted update count", 1, count ); 594 595 count = s.createQuery( "delete Vehicle" ).executeUpdate(); 596 assertEquals( "incorrect update count", 3, count ); 597 t.commit(); 598 s.close(); 599 600 data.cleanup(); 601 } 602 603 public void testDeleteUnionSubclassConcreteSubclass() { 604 TestData data = new TestData(); 605 data.prepare(); 606 607 Session s = openSession(); 609 Transaction t = s.beginTransaction(); 610 611 int count = s.createQuery( "delete Truck where owner = :owner" ).setString( "owner", "Steve" ).executeUpdate(); 612 assertEquals( "incorrect restricted update count", 1, count ); 613 614 count = s.createQuery( "delete Truck" ).executeUpdate(); 615 assertEquals( "incorrect update count", 2, count ); 616 t.commit(); 617 s.close(); 618 619 data.cleanup(); 620 } 621 622 public void testDeleteUnionSubclassLeafSubclass() { 623 TestData data = new TestData(); 624 data.prepare(); 625 626 Session s = openSession(); 628 Transaction t = s.beginTransaction(); 629 630 int count = s.createQuery( "delete Car where owner = :owner" ).setString( "owner", "Kirsten" ).executeUpdate(); 631 assertEquals( "incorrect restricted update count", 1, count ); 632 633 count = s.createQuery( "delete Car" ).executeUpdate(); 634 assertEquals( "incorrect update count", 0, count ); 635 t.commit(); 636 s.close(); 637 638 data.cleanup(); 639 } 640 641 private class TestData { 642 643 private Animal polliwog; 644 private Animal catepillar; 645 private Animal frog; 646 private Animal butterfly; 647 648 private Zoo zoo; 649 private Zoo pettingZoo; 650 651 private void prepare() { 652 Session s = openSession(); 653 Transaction txn = s.beginTransaction(); 654 655 polliwog = new Animal(); 656 polliwog.setBodyWeight( 12 ); 657 polliwog.setDescription( "Polliwog" ); 658 659 catepillar = new Animal(); 660 catepillar.setBodyWeight( 10 ); 661 catepillar.setDescription( "Catepillar" ); 662 663 frog = new Animal(); 664 frog.setBodyWeight( 34 ); 665 frog.setDescription( "Frog" ); 666 667 polliwog.setFather( frog ); 668 frog.addOffspring( polliwog ); 669 670 butterfly = new Animal(); 671 butterfly.setBodyWeight( 9 ); 672 butterfly.setDescription( "Butterfly" ); 673 674 catepillar.setMother( butterfly ); 675 butterfly.addOffspring( catepillar ); 676 677 s.save( frog ); 678 s.save( polliwog ); 679 s.save( butterfly ); 680 s.save( catepillar ); 681 682 Dog dog = new Dog(); 683 dog.setBodyWeight( 200 ); 684 dog.setDescription( "dog" ); 685 s.save( dog ); 686 687 Cat cat = new Cat(); 688 cat.setBodyWeight( 100 ); 689 cat.setDescription( "cat" ); 690 s.save( cat ); 691 692 zoo = new Zoo(); 693 zoo.setName( "Zoo" ); 694 pettingZoo = new PettingZoo(); 695 pettingZoo.setName( "Petting Zoo" ); 696 697 s.save( zoo ); 698 s.save( pettingZoo ); 699 700 Joiner joiner = new Joiner(); 701 joiner.setJoinedName( "joined-name" ); 702 joiner.setName( "name" ); 703 s.save( joiner ); 704 705 Car car = new Car(); 706 car.setVin( "123c" ); 707 car.setOwner( "Kirsten" ); 708 s.save( car ); 709 710 Truck truck = new Truck(); 711 truck.setVin( "123t" ); 712 truck.setOwner( "Steve" ); 713 s.save( truck ); 714 715 SUV suv = new SUV(); 716 suv.setVin( "123s" ); 717 suv.setOwner( "Joe" ); 718 s.save( suv ); 719 720 Pickup pickup = new Pickup(); 721 pickup.setVin( "123p" ); 722 pickup.setOwner( "Cecelia" ); 723 s.save( pickup ); 724 725 txn.commit(); 726 s.close(); 727 } 728 729 private void cleanup() { 730 Session s = openSession(); 731 Transaction txn = s.beginTransaction(); 732 733 s.createQuery("delete from Animal where mother is not null or father is not null").executeUpdate(); 734 String [] entityNames = new String [] { "Animal", "Zoo", "Joiner", "Vehicle" }; 735 for ( int i = 0; i < entityNames.length; i++ ) { 736 s.createQuery( "delete from " + entityNames[i] ).executeUpdate(); 737 } 738 739 txn.commit(); 740 s.close(); 741 } 742 } 743 744 private SessionFactoryImplementor sfi() { 745 return ( SessionFactoryImplementor ) getSessions(); 746 } 747 } 748 | Popular Tags |