1 16 17 package org.springframework.orm.hibernate3; 18 19 import java.sql.Connection ; 20 import java.sql.DatabaseMetaData ; 21 import java.sql.SQLException ; 22 import java.sql.Savepoint ; 23 import java.util.ArrayList ; 24 import java.util.List ; 25 import java.util.Properties ; 26 27 import javax.sql.DataSource ; 28 29 import junit.framework.TestCase; 30 import org.easymock.MockControl; 31 import org.hibernate.FlushMode; 32 import org.hibernate.HibernateException; 33 import org.hibernate.Interceptor; 34 import org.hibernate.JDBCException; 35 import org.hibernate.Query; 36 import org.hibernate.SessionFactory; 37 import org.hibernate.Transaction; 38 import org.hibernate.cfg.Configuration; 39 import org.hibernate.classic.Session; 40 import org.hibernate.dialect.HSQLDialect; 41 42 import org.springframework.beans.factory.BeanFactory; 43 import org.springframework.core.JdkVersion; 44 import org.springframework.dao.DataIntegrityViolationException; 45 import org.springframework.jdbc.datasource.DriverManagerDataSource; 46 import org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy; 47 import org.springframework.jdbc.support.SQLStateSQLExceptionTranslator; 48 import org.springframework.transaction.CannotCreateTransactionException; 49 import org.springframework.transaction.PlatformTransactionManager; 50 import org.springframework.transaction.TransactionDefinition; 51 import org.springframework.transaction.TransactionStatus; 52 import org.springframework.transaction.UnexpectedRollbackException; 53 import org.springframework.transaction.support.TransactionCallback; 54 import org.springframework.transaction.support.TransactionCallbackWithoutResult; 55 import org.springframework.transaction.support.TransactionSynchronizationManager; 56 import org.springframework.transaction.support.TransactionTemplate; 57 58 62 public class HibernateTransactionManagerTests extends TestCase { 63 64 public void testTransactionCommit() throws Exception { 65 MockControl dsControl = MockControl.createControl(DataSource .class); 66 final DataSource ds = (DataSource ) dsControl.getMock(); 67 MockControl conControl = MockControl.createControl(Connection .class); 68 Connection con = (Connection ) conControl.getMock(); 69 MockControl sfControl = MockControl.createControl(SessionFactory.class); 70 final SessionFactory sf = (SessionFactory) sfControl.getMock(); 71 MockControl sessionControl = MockControl.createControl(Session.class); 72 final Session session = (Session) sessionControl.getMock(); 73 MockControl txControl = MockControl.createControl(Transaction.class); 74 Transaction tx = (Transaction) txControl.getMock(); 75 MockControl queryControl = MockControl.createControl(Query.class); 76 Query query = (Query) queryControl.getMock(); 77 78 final List list = new ArrayList (); 79 list.add("test"); 80 con.getTransactionIsolation(); 81 conControl.setReturnValue(Connection.TRANSACTION_READ_COMMITTED); 82 con.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE); 83 conControl.setVoidCallable(1); 84 con.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED); 85 conControl.setVoidCallable(1); 86 con.isReadOnly(); 87 conControl.setReturnValue(false, 1); 88 sf.openSession(); 89 sfControl.setReturnValue(session, 1); 90 session.beginTransaction(); 91 sessionControl.setReturnValue(tx, 1); 92 session.connection(); 93 sessionControl.setReturnValue(con, 2); 94 session.createQuery("some query string"); 95 sessionControl.setReturnValue(query, 1); 96 query.setTimeout(10); 97 queryControl.setReturnValue(query, 1); 98 query.list(); 99 queryControl.setReturnValue(list, 1); 100 tx.commit(); 101 txControl.setVoidCallable(1); 102 session.close(); 103 sessionControl.setReturnValue(null, 1); 104 105 dsControl.replay(); 106 conControl.replay(); 107 sfControl.replay(); 108 sessionControl.replay(); 109 txControl.replay(); 110 queryControl.replay(); 111 112 LocalSessionFactoryBean lsfb = new LocalSessionFactoryBean() { 113 protected SessionFactory newSessionFactory(Configuration config) throws HibernateException { 114 return sf; 115 } 116 }; 117 lsfb.afterPropertiesSet(); 118 final SessionFactory sfProxy = (SessionFactory) lsfb.getObject(); 119 120 HibernateTransactionManager tm = new HibernateTransactionManager(); 121 tm.setJdbcExceptionTranslator(new SQLStateSQLExceptionTranslator()); 122 tm.setSessionFactory(sfProxy); 123 tm.setDataSource(ds); 124 TransactionTemplate tt = new TransactionTemplate(tm); 125 tt.setIsolationLevel(TransactionDefinition.ISOLATION_SERIALIZABLE); 126 tt.setTimeout(10); 127 assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sfProxy)); 128 assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); 129 assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive()); 130 131 Object result = tt.execute(new TransactionCallback() { 132 public Object doInTransaction(TransactionStatus status) { 133 assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sfProxy)); 134 assertTrue("Has thread connection", TransactionSynchronizationManager.hasResource(ds)); 135 assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly()); 136 assertTrue(TransactionSynchronizationManager.isActualTransactionActive()); 137 assertEquals(session, sfProxy.getCurrentSession()); 138 HibernateTemplate ht = new HibernateTemplate(sfProxy); 139 return ht.find("some query string"); 140 } 141 }); 142 assertTrue("Correct result list", result == list); 143 144 assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sfProxy)); 145 assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); 146 assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive()); 147 dsControl.verify(); 148 conControl.verify(); 149 sfControl.verify(); 150 sessionControl.verify(); 151 txControl.verify(); 152 queryControl.verify(); 153 } 154 155 public void testTransactionRollback() throws Exception { 156 MockControl conControl = MockControl.createControl(Connection .class); 157 Connection con = (Connection ) conControl.getMock(); 158 MockControl sfControl = MockControl.createControl(SessionFactory.class); 159 final SessionFactory sf = (SessionFactory) sfControl.getMock(); 160 MockControl sessionControl = MockControl.createControl(Session.class); 161 Session session = (Session) sessionControl.getMock(); 162 MockControl txControl = MockControl.createControl(Transaction.class); 163 Transaction tx = (Transaction) txControl.getMock(); 164 165 sf.openSession(); 166 sfControl.setReturnValue(session, 1); 167 session.beginTransaction(); 168 sessionControl.setReturnValue(tx, 1); 169 session.close(); 170 sessionControl.setReturnValue(null, 1); 171 tx.rollback(); 172 txControl.setVoidCallable(1); 173 session.connection(); 174 sessionControl.setReturnValue(con, 2); 175 con.isReadOnly(); 176 conControl.setReturnValue(false, 1); 177 sfControl.replay(); 178 sessionControl.replay(); 179 txControl.replay(); 180 181 PlatformTransactionManager tm = new HibernateTransactionManager(sf); 182 TransactionTemplate tt = new TransactionTemplate(tm); 183 assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); 184 assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive()); 185 186 try { 187 tt.execute(new TransactionCallback() { 188 public Object doInTransaction(TransactionStatus status) { 189 assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf)); 190 HibernateTemplate ht = new HibernateTemplate(sf); 191 return ht.executeFind(new HibernateCallback() { 192 public Object doInHibernate(org.hibernate.Session session) { 193 throw new RuntimeException ("application exception"); 194 } 195 }); 196 } 197 }); 198 fail("Should have thrown RuntimeException"); 199 } 200 catch (RuntimeException ex) { 201 } 203 204 assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); 205 assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive()); 206 sfControl.verify(); 207 sessionControl.verify(); 208 txControl.verify(); 209 } 210 211 public void testTransactionRollbackOnly() throws Exception { 212 MockControl conControl = MockControl.createControl(Connection .class); 213 Connection con = (Connection ) conControl.getMock(); 214 MockControl sfControl = MockControl.createControl(SessionFactory.class); 215 final SessionFactory sf = (SessionFactory) sfControl.getMock(); 216 MockControl sessionControl = MockControl.createControl(Session.class); 217 Session session = (Session) sessionControl.getMock(); 218 MockControl txControl = MockControl.createControl(Transaction.class); 219 Transaction tx = (Transaction) txControl.getMock(); 220 221 sf.openSession(); 222 sfControl.setReturnValue(session, 1); 223 session.beginTransaction(); 224 sessionControl.setReturnValue(tx, 1); 225 session.flush(); 226 sessionControl.setVoidCallable(1); 227 session.close(); 228 sessionControl.setReturnValue(null, 1); 229 tx.rollback(); 230 txControl.setVoidCallable(1); 231 session.connection(); 232 sessionControl.setReturnValue(con, 2); 233 con.isReadOnly(); 234 conControl.setReturnValue(false, 1); 235 sfControl.replay(); 236 sessionControl.replay(); 237 txControl.replay(); 238 239 PlatformTransactionManager tm = new HibernateTransactionManager(sf); 240 TransactionTemplate tt = new TransactionTemplate(tm); 241 assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); 242 243 tt.execute(new TransactionCallback() { 244 public Object doInTransaction(TransactionStatus status) { 245 assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf)); 246 HibernateTemplate ht = new HibernateTemplate(sf); 247 ht.setFlushMode(HibernateTemplate.FLUSH_EAGER); 248 ht.execute(new HibernateCallback() { 249 public Object doInHibernate(org.hibernate.Session session) { 250 return null; 251 } 252 }); 253 status.setRollbackOnly(); 254 return null; 255 } 256 }); 257 258 assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); 259 sfControl.verify(); 260 sessionControl.verify(); 261 txControl.verify(); 262 } 263 264 public void testParticipatingTransactionWithCommit() throws Exception { 265 MockControl conControl = MockControl.createControl(Connection .class); 266 Connection con = (Connection ) conControl.getMock(); 267 MockControl sfControl = MockControl.createControl(SessionFactory.class); 268 final SessionFactory sf = (SessionFactory) sfControl.getMock(); 269 MockControl sessionControl = MockControl.createControl(Session.class); 270 final Session session = (Session) sessionControl.getMock(); 271 MockControl txControl = MockControl.createControl(Transaction.class); 272 Transaction tx = (Transaction) txControl.getMock(); 273 274 sf.openSession(); 275 sfControl.setReturnValue(session, 1); 276 session.beginTransaction(); 277 sessionControl.setReturnValue(tx, 1); 278 session.flush(); 279 sessionControl.setVoidCallable(1); 280 session.close(); 281 sessionControl.setReturnValue(null, 1); 282 tx.commit(); 283 txControl.setVoidCallable(1); 284 session.connection(); 285 sessionControl.setReturnValue(con, 2); 286 con.isReadOnly(); 287 conControl.setReturnValue(false, 1); 288 sfControl.replay(); 289 sessionControl.replay(); 290 txControl.replay(); 291 292 LocalSessionFactoryBean lsfb = new LocalSessionFactoryBean() { 293 protected SessionFactory newSessionFactory(Configuration config) throws HibernateException { 294 return sf; 295 } 296 }; 297 lsfb.afterPropertiesSet(); 298 final SessionFactory sfProxy = (SessionFactory) lsfb.getObject(); 299 300 PlatformTransactionManager tm = new HibernateTransactionManager(sfProxy); 301 final TransactionTemplate tt = new TransactionTemplate(tm); 302 final List l = new ArrayList (); 303 l.add("test"); 304 305 Object result = tt.execute(new TransactionCallback() { 306 public Object doInTransaction(TransactionStatus status) { 307 return tt.execute(new TransactionCallback() { 308 public Object doInTransaction(TransactionStatus status) { 309 assertEquals(session, sfProxy.getCurrentSession()); 310 HibernateTemplate ht = new HibernateTemplate(sfProxy); 311 ht.setFlushMode(HibernateTemplate.FLUSH_EAGER); 312 return ht.executeFind(new HibernateCallback() { 313 public Object doInHibernate(org.hibernate.Session session) { 314 return l; 315 } 316 }); 317 } 318 }); 319 } 320 }); 321 assertTrue("Correct result list", result == l); 322 323 sfControl.verify(); 324 sessionControl.verify(); 325 txControl.verify(); 326 } 327 328 public void testParticipatingTransactionWithRollback() throws Exception { 329 MockControl conControl = MockControl.createControl(Connection .class); 330 Connection con = (Connection ) conControl.getMock(); 331 MockControl sfControl = MockControl.createControl(SessionFactory.class); 332 final SessionFactory sf = (SessionFactory) sfControl.getMock(); 333 MockControl sessionControl = MockControl.createControl(Session.class); 334 Session session = (Session) sessionControl.getMock(); 335 MockControl txControl = MockControl.createControl(Transaction.class); 336 Transaction tx = (Transaction) txControl.getMock(); 337 338 sf.openSession(); 339 sfControl.setReturnValue(session, 1); 340 session.beginTransaction(); 341 sessionControl.setReturnValue(tx, 1); 342 session.close(); 343 sessionControl.setReturnValue(null, 1); 344 tx.rollback(); 345 txControl.setVoidCallable(1); 346 session.connection(); 347 sessionControl.setReturnValue(con, 2); 348 con.isReadOnly(); 349 conControl.setReturnValue(false, 1); 350 sfControl.replay(); 351 sessionControl.replay(); 352 txControl.replay(); 353 354 PlatformTransactionManager tm = new HibernateTransactionManager(sf); 355 final TransactionTemplate tt = new TransactionTemplate(tm); 356 try { 357 tt.execute(new TransactionCallback() { 358 public Object doInTransaction(TransactionStatus status) { 359 return tt.execute(new TransactionCallback() { 360 public Object doInTransaction(TransactionStatus status) { 361 HibernateTemplate ht = new HibernateTemplate(sf); 362 ht.setFlushMode(HibernateTemplate.FLUSH_EAGER); 363 return ht.executeFind(new HibernateCallback() { 364 public Object doInHibernate(org.hibernate.Session session) { 365 throw new RuntimeException ("application exception"); 366 } 367 }); 368 } 369 }); 370 } 371 }); 372 fail("Should have thrown RuntimeException"); 373 } 374 catch (RuntimeException ex) { 375 } 377 378 sfControl.verify(); 379 sessionControl.verify(); 380 txControl.verify(); 381 } 382 383 public void testParticipatingTransactionWithRollbackOnly() throws Exception { 384 MockControl conControl = MockControl.createControl(Connection .class); 385 Connection con = (Connection ) conControl.getMock(); 386 MockControl sfControl = MockControl.createControl(SessionFactory.class); 387 final SessionFactory sf = (SessionFactory) sfControl.getMock(); 388 MockControl sessionControl = MockControl.createControl(Session.class); 389 Session session = (Session) sessionControl.getMock(); 390 MockControl txControl = MockControl.createControl(Transaction.class); 391 Transaction tx = (Transaction) txControl.getMock(); 392 393 sf.openSession(); 394 sfControl.setReturnValue(session, 1); 395 session.beginTransaction(); 396 sessionControl.setReturnValue(tx, 1); 397 session.close(); 398 sessionControl.setReturnValue(null, 1); 399 tx.rollback(); 400 txControl.setVoidCallable(1); 401 session.connection(); 402 sessionControl.setReturnValue(con, 2); 403 con.isReadOnly(); 404 conControl.setReturnValue(false, 1); 405 sfControl.replay(); 406 sessionControl.replay(); 407 txControl.replay(); 408 409 PlatformTransactionManager tm = new HibernateTransactionManager(sf); 410 final TransactionTemplate tt = new TransactionTemplate(tm); 411 final List l = new ArrayList (); 412 l.add("test"); 413 414 try { 415 tt.execute(new TransactionCallback() { 416 public Object doInTransaction(TransactionStatus status) { 417 return tt.execute(new TransactionCallback() { 418 public Object doInTransaction(TransactionStatus status) { 419 HibernateTemplate ht = new HibernateTemplate(sf); 420 ht.execute(new HibernateCallback() { 421 public Object doInHibernate(org.hibernate.Session session) { 422 return l; 423 } 424 }); 425 status.setRollbackOnly(); 426 return null; 427 } 428 }); 429 } 430 }); 431 fail("Should have thrown UnexpectedRollbackException"); 432 } 433 catch (UnexpectedRollbackException ex) { 434 } 436 437 sfControl.verify(); 438 sessionControl.verify(); 439 txControl.verify(); 440 } 441 442 public void testParticipatingTransactionWithWithRequiresNew() throws Exception { 443 MockControl sfControl = MockControl.createControl(SessionFactory.class); 444 final SessionFactory sf = (SessionFactory) sfControl.getMock(); 445 MockControl session1Control = MockControl.createControl(Session.class); 446 Session session1 = (Session) session1Control.getMock(); 447 MockControl session2Control = MockControl.createControl(Session.class); 448 Session session2 = (Session) session2Control.getMock(); 449 MockControl conControl = MockControl.createControl(Connection .class); 450 Connection con = (Connection ) conControl.getMock(); 451 MockControl txControl = MockControl.createControl(Transaction.class); 452 Transaction tx = (Transaction) txControl.getMock(); 453 454 sf.openSession(); 455 sfControl.setReturnValue(session1, 1); 456 sf.openSession(); 457 sfControl.setReturnValue(session2, 1); 458 session1.beginTransaction(); 459 session1Control.setReturnValue(tx, 1); 460 session2.beginTransaction(); 461 session2Control.setReturnValue(tx, 1); 462 session2.flush(); 463 session2Control.setVoidCallable(1); 464 session1.close(); 465 session1Control.setReturnValue(null, 1); 466 session2.close(); 467 session2Control.setReturnValue(null, 1); 468 tx.commit(); 469 txControl.setVoidCallable(2); 470 session1.connection(); 471 session1Control.setReturnValue(con, 2); 472 session2.connection(); 473 session2Control.setReturnValue(con, 2); 474 con.isReadOnly(); 475 conControl.setReturnValue(false, 2); 476 sfControl.replay(); 477 session1Control.replay(); 478 session2Control.replay(); 479 conControl.replay(); 480 txControl.replay(); 481 482 PlatformTransactionManager tm = new HibernateTransactionManager(sf); 483 final TransactionTemplate tt = new TransactionTemplate(tm); 484 tt.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW); 485 486 assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); 487 tt.execute(new TransactionCallback() { 488 public Object doInTransaction(TransactionStatus status) { 489 final SessionHolder holder = (SessionHolder) TransactionSynchronizationManager.getResource(sf); 490 assertTrue("Has thread session", holder != null); 491 assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly()); 492 assertTrue(TransactionSynchronizationManager.isActualTransactionActive()); 493 tt.execute(new TransactionCallback() { 494 public Object doInTransaction(TransactionStatus status) { 495 HibernateTemplate ht = new HibernateTemplate(sf); 496 ht.setFlushMode(HibernateTemplate.FLUSH_EAGER); 497 return ht.executeFind(new HibernateCallback() { 498 public Object doInHibernate(org.hibernate.Session session) { 499 assertTrue("Not enclosing session", session != holder.getSession()); 500 assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly()); 501 assertTrue(TransactionSynchronizationManager.isActualTransactionActive()); 502 return null; 503 } 504 }); 505 } 506 }); 507 assertTrue("Same thread session as before", 508 holder.getSession() == SessionFactoryUtils.getSession(sf, false)); 509 assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly()); 510 assertTrue(TransactionSynchronizationManager.isActualTransactionActive()); 511 return null; 512 } 513 }); 514 assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); 515 516 sfControl.verify(); 517 session1Control.verify(); 518 session2Control.verify(); 519 conControl.verify(); 520 txControl.verify(); 521 } 522 523 public void testParticipatingTransactionWithWithNotSupported() throws Exception { 524 MockControl sfControl = MockControl.createControl(SessionFactory.class); 525 final SessionFactory sf = (SessionFactory) sfControl.getMock(); 526 MockControl sessionControl = MockControl.createControl(Session.class); 527 Session session = (Session) sessionControl.getMock(); 528 MockControl conControl = MockControl.createControl(Connection .class); 529 Connection con = (Connection ) conControl.getMock(); 530 MockControl txControl = MockControl.createControl(Transaction.class); 531 Transaction tx = (Transaction) txControl.getMock(); 532 533 sf.openSession(); 534 sfControl.setReturnValue(session, 2); 535 session.getSessionFactory(); 536 sessionControl.setReturnValue(sf, 1); 537 session.beginTransaction(); 538 sessionControl.setReturnValue(tx, 1); 539 session.getFlushMode(); 540 sessionControl.setReturnValue(FlushMode.AUTO, 1); 541 session.flush(); 542 sessionControl.setVoidCallable(2); 543 session.close(); 544 sessionControl.setReturnValue(null, 2); 545 tx.commit(); 546 txControl.setVoidCallable(1); 547 session.connection(); 548 sessionControl.setReturnValue(con, 2); 549 con.isReadOnly(); 550 conControl.setReturnValue(false, 1); 551 sfControl.replay(); 552 sessionControl.replay(); 553 conControl.replay(); 554 txControl.replay(); 555 556 HibernateTransactionManager tm = new HibernateTransactionManager(sf); 557 final TransactionTemplate tt = new TransactionTemplate(tm); 558 tt.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW); 559 560 assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); 561 tt.execute(new TransactionCallback() { 562 public Object doInTransaction(TransactionStatus status) { 563 SessionHolder holder = (SessionHolder) TransactionSynchronizationManager.getResource(sf); 564 assertTrue("Has thread session", holder != null); 565 assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly()); 566 assertTrue(TransactionSynchronizationManager.isActualTransactionActive()); 567 tt.setPropagationBehavior(TransactionDefinition.PROPAGATION_NOT_SUPPORTED); 568 tt.execute(new TransactionCallback() { 569 public Object doInTransaction(TransactionStatus status) { 570 assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); 571 assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly()); 572 assertFalse(TransactionSynchronizationManager.isActualTransactionActive()); 573 HibernateTemplate ht = new HibernateTemplate(sf); 574 ht.setFlushMode(HibernateTemplate.FLUSH_EAGER); 575 return ht.executeFind(new HibernateCallback() { 576 public Object doInHibernate(org.hibernate.Session session) { 577 return null; 578 } 579 }); 580 } 581 }); 582 assertTrue("Same thread session as before", 583 holder.getSession() == SessionFactoryUtils.getSession(sf, false)); 584 assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly()); 585 assertTrue(TransactionSynchronizationManager.isActualTransactionActive()); 586 return null; 587 } 588 }); 589 assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); 590 591 sfControl.verify(); 592 sessionControl.verify(); 593 txControl.verify(); 594 } 595 596 public void testTransactionWithPropagationSupports() throws Exception { 597 MockControl sfControl = MockControl.createControl(SessionFactory.class); 598 final SessionFactory sf = (SessionFactory) sfControl.getMock(); 599 MockControl sessionControl = MockControl.createControl(Session.class); 600 final Session session = (Session) sessionControl.getMock(); 601 sf.openSession(); 602 sfControl.setReturnValue(session, 1); 603 session.getSessionFactory(); 604 sessionControl.setReturnValue(sf, 1); 605 session.getFlushMode(); 606 sessionControl.setReturnValue(FlushMode.NEVER, 1); 607 session.flush(); 608 sessionControl.setVoidCallable(1); 609 session.close(); 610 sessionControl.setReturnValue(null, 1); 611 sfControl.replay(); 612 sessionControl.replay(); 613 614 LocalSessionFactoryBean lsfb = new LocalSessionFactoryBean() { 615 protected SessionFactory newSessionFactory(Configuration config) throws HibernateException { 616 return sf; 617 } 618 }; 619 lsfb.afterPropertiesSet(); 620 final SessionFactory sfProxy = (SessionFactory) lsfb.getObject(); 621 622 PlatformTransactionManager tm = new HibernateTransactionManager(sfProxy); 623 TransactionTemplate tt = new TransactionTemplate(tm); 624 tt.setPropagationBehavior(TransactionDefinition.PROPAGATION_SUPPORTS); 625 assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sfProxy)); 626 627 tt.execute(new TransactionCallback() { 628 public Object doInTransaction(TransactionStatus status) { 629 assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sfProxy)); 630 assertTrue("Is not new transaction", !status.isNewTransaction()); 631 assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly()); 632 assertFalse(TransactionSynchronizationManager.isActualTransactionActive()); 633 HibernateTemplate ht = new HibernateTemplate(sfProxy); 634 ht.setFlushMode(HibernateTemplate.FLUSH_EAGER); 635 ht.execute(new HibernateCallback() { 636 public Object doInHibernate(org.hibernate.Session session) { 637 return null; 638 } 639 }); 640 assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sfProxy)); 641 assertEquals(session, sfProxy.getCurrentSession()); 642 return null; 643 } 644 }); 645 646 assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sfProxy)); 647 sfControl.verify(); 648 sessionControl.verify(); 649 } 650 651 public void testTransactionCommitWithEntityInterceptor() throws Exception { 652 MockControl interceptorControl = MockControl.createControl(org.hibernate.Interceptor.class); 653 Interceptor entityInterceptor = (Interceptor) interceptorControl.getMock(); 654 interceptorControl.replay(); 655 MockControl conControl = MockControl.createControl(Connection .class); 656 Connection con = (Connection ) conControl.getMock(); 657 MockControl sfControl = MockControl.createControl(SessionFactory.class); 658 final SessionFactory sf = (SessionFactory) sfControl.getMock(); 659 MockControl sessionControl = MockControl.createControl(Session.class); 660 Session session = (Session) sessionControl.getMock(); 661 MockControl txControl = MockControl.createControl(Transaction.class); 662 Transaction tx = (Transaction) txControl.getMock(); 663 664 sf.openSession(entityInterceptor); 665 sfControl.setReturnValue(session, 1); 666 session.beginTransaction(); 667 sessionControl.setReturnValue(tx, 1); 668 session.close(); 669 sessionControl.setReturnValue(null, 1); 670 tx.commit(); 671 txControl.setVoidCallable(1); 672 session.connection(); 673 sessionControl.setReturnValue(con, 2); 674 con.isReadOnly(); 675 conControl.setReturnValue(false, 1); 676 sfControl.replay(); 677 sessionControl.replay(); 678 txControl.replay(); 679 conControl.replay(); 680 681 HibernateTransactionManager tm = new HibernateTransactionManager(sf); 682 tm.setEntityInterceptor(entityInterceptor); 683 TransactionTemplate tt = new TransactionTemplate(tm); 684 tt.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW); 685 final List l = new ArrayList (); 686 l.add("test"); 687 assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); 688 assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive()); 689 690 Object result = tt.execute(new TransactionCallback() { 691 public Object doInTransaction(TransactionStatus status) { 692 assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf)); 693 HibernateTemplate ht = new HibernateTemplate(sf); 694 return ht.executeFind(new HibernateCallback() { 695 public Object doInHibernate(org.hibernate.Session session) throws HibernateException { 696 return l; 697 } 698 }); 699 } 700 }); 701 assertTrue("Correct result list", result == l); 702 703 assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); 704 assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive()); 705 interceptorControl.verify(); 706 sfControl.verify(); 707 sessionControl.verify(); 708 txControl.verify(); 709 conControl.verify(); 710 } 711 712 public void testTransactionCommitWithEntityInterceptorBeanName() throws Exception { 713 MockControl interceptorControl = MockControl.createControl(org.hibernate.Interceptor.class); 714 Interceptor entityInterceptor = (Interceptor) interceptorControl.getMock(); 715 interceptorControl.replay(); 716 MockControl interceptor2Control = MockControl.createControl(org.hibernate.Interceptor.class); 717 Interceptor entityInterceptor2 = (Interceptor) interceptor2Control.getMock(); 718 interceptor2Control.replay(); 719 720 MockControl conControl = MockControl.createControl(Connection .class); 721 Connection con = (Connection ) conControl.getMock(); 722 MockControl sfControl = MockControl.createControl(SessionFactory.class); 723 final SessionFactory sf = (SessionFactory) sfControl.getMock(); 724 MockControl sessionControl = MockControl.createControl(Session.class); 725 Session session = (Session) sessionControl.getMock(); 726 MockControl txControl = MockControl.createControl(Transaction.class); 727 Transaction tx = (Transaction) txControl.getMock(); 728 729 sf.openSession(entityInterceptor); 730 sfControl.setReturnValue(session, 1); 731 sf.openSession(entityInterceptor2); 732 sfControl.setReturnValue(session, 1); 733 session.beginTransaction(); 734 sessionControl.setReturnValue(tx, 2); 735 session.close(); 736 sessionControl.setReturnValue(null, 2); 737 tx.commit(); 738 txControl.setVoidCallable(2); 739 session.connection(); 740 sessionControl.setReturnValue(con, 4); 741 con.isReadOnly(); 742 conControl.setReturnValue(false, 2); 743 sfControl.replay(); 744 sessionControl.replay(); 745 txControl.replay(); 746 conControl.replay(); 747 748 MockControl beanFactoryControl = MockControl.createControl(BeanFactory.class); 749 BeanFactory beanFactory = (BeanFactory) beanFactoryControl.getMock(); 750 beanFactory.getBean("entityInterceptor", Interceptor.class); 751 beanFactoryControl.setReturnValue(entityInterceptor, 1); 752 beanFactory.getBean("entityInterceptor", Interceptor.class); 753 beanFactoryControl.setReturnValue(entityInterceptor2, 1); 754 beanFactoryControl.replay(); 755 756 HibernateTransactionManager tm = new HibernateTransactionManager(sf); 757 tm.setEntityInterceptorBeanName("entityInterceptor"); 758 tm.setBeanFactory(beanFactory); 759 760 TransactionTemplate tt = new TransactionTemplate(tm); 761 tt.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW); 762 assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); 763 assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive()); 764 765 for (int i = 0; i < 2; i++) { 766 tt.execute(new TransactionCallbackWithoutResult() { 767 public void doInTransactionWithoutResult(TransactionStatus status) { 768 assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf)); 769 HibernateTemplate ht = new HibernateTemplate(sf); 770 ht.execute(new HibernateCallback() { 771 public Object doInHibernate(org.hibernate.Session session) throws HibernateException { 772 return null; 773 } 774 }); 775 } 776 }); 777 } 778 779 assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); 780 assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive()); 781 interceptorControl.verify(); 782 interceptor2Control.verify(); 783 sfControl.verify(); 784 sessionControl.verify(); 785 txControl.verify(); 786 conControl.verify(); 787 beanFactoryControl.verify(); 788 } 789 790 public void testTransactionCommitWithReadOnly() throws Exception { 791 MockControl conControl = MockControl.createControl(Connection .class); 792 Connection con = (Connection ) conControl.getMock(); 793 MockControl sfControl = MockControl.createControl(SessionFactory.class); 794 final SessionFactory sf = (SessionFactory) sfControl.getMock(); 795 MockControl sessionControl = MockControl.createControl(Session.class); 796 Session session = (Session) sessionControl.getMock(); 797 MockControl txControl = MockControl.createControl(Transaction.class); 798 Transaction tx = (Transaction) txControl.getMock(); 799 MockControl queryControl = MockControl.createControl(Query.class); 800 Query query = (Query) queryControl.getMock(); 801 802 final List list = new ArrayList (); 803 list.add("test"); 804 sf.openSession(); 805 sfControl.setReturnValue(session, 1); 806 session.beginTransaction(); 807 sessionControl.setReturnValue(tx, 1); 808 session.setFlushMode(FlushMode.NEVER); 809 sessionControl.setVoidCallable(1); 810 session.connection(); 811 sessionControl.setReturnValue(con, 2); 812 con.setReadOnly(true); 813 conControl.setVoidCallable(1); 814 session.createQuery("some query string"); 815 sessionControl.setReturnValue(query, 1); 816 query.list(); 817 queryControl.setReturnValue(list, 1); 818 tx.commit(); 819 txControl.setVoidCallable(1); 820 con.isReadOnly(); 821 conControl.setReturnValue(true, 1); 822 con.setReadOnly(false); 823 conControl.setVoidCallable(1); 824 session.close(); 825 sessionControl.setReturnValue(null, 1); 826 827 conControl.replay(); 828 sfControl.replay(); 829 sessionControl.replay(); 830 txControl.replay(); 831 queryControl.replay(); 832 833 HibernateTransactionManager tm = new HibernateTransactionManager(sf); 834 TransactionTemplate tt = new TransactionTemplate(tm); 835 tt.setReadOnly(true); 836 assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); 837 assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive()); 838 839 Object result = tt.execute(new TransactionCallback() { 840 public Object doInTransaction(TransactionStatus status) { 841 assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf)); 842 assertTrue(TransactionSynchronizationManager.isCurrentTransactionReadOnly()); 843 assertTrue(TransactionSynchronizationManager.isActualTransactionActive()); 844 HibernateTemplate ht = new HibernateTemplate(sf); 845 return ht.find("some query string"); 846 } 847 }); 848 assertTrue("Correct result list", result == list); 849 850 assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); 851 assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive()); 852 853 conControl.verify(); 854 sfControl.verify(); 855 sessionControl.verify(); 856 txControl.verify(); 857 queryControl.verify(); 858 } 859 860 public void testTransactionCommitWithFlushFailure() throws Exception { 861 MockControl conControl = MockControl.createControl(Connection .class); 862 Connection con = (Connection ) conControl.getMock(); 863 MockControl sfControl = MockControl.createControl(SessionFactory.class); 864 final SessionFactory sf = (SessionFactory) sfControl.getMock(); 865 MockControl sessionControl = MockControl.createControl(Session.class); 866 Session session = (Session) sessionControl.getMock(); 867 MockControl txControl = MockControl.createControl(Transaction.class); 868 Transaction tx = (Transaction) txControl.getMock(); 869 870 sf.openSession(); 871 sfControl.setReturnValue(session, 1); 872 session.beginTransaction(); 873 sessionControl.setReturnValue(tx, 1); 874 tx.commit(); 875 SQLException sqlEx = new SQLException ("argh", "27"); 876 txControl.setThrowable(new JDBCException("mymsg", sqlEx), 1); 877 session.close(); 878 sessionControl.setReturnValue(null, 1); 879 tx.rollback(); 880 txControl.setVoidCallable(1); 881 session.connection(); 882 sessionControl.setReturnValue(con, 2); 883 con.isReadOnly(); 884 conControl.setReturnValue(false, 1); 885 886 sfControl.replay(); 887 sessionControl.replay(); 888 txControl.replay(); 889 conControl.replay(); 890 891 HibernateTransactionManager tm = new HibernateTransactionManager(sf); 892 TransactionTemplate tt = new TransactionTemplate(tm); 893 final List l = new ArrayList (); 894 l.add("test"); 895 assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); 896 assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive()); 897 898 try { 899 tt.execute(new TransactionCallback() { 900 public Object doInTransaction(TransactionStatus status) { 901 assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf)); 902 HibernateTemplate ht = new HibernateTemplate(sf); 903 return ht.executeFind(new HibernateCallback() { 904 public Object doInHibernate(org.hibernate.Session session) throws HibernateException { 905 return l; 906 } 907 }); 908 } 909 }); 910 fail("Should have thrown DataIntegrityViolationException"); 911 } 912 catch (DataIntegrityViolationException ex) { 913 assertEquals(sqlEx, ex.getCause()); 915 assertTrue(ex.getMessage().indexOf("mymsg") != -1); 916 } 917 918 assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); 919 assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive()); 920 sfControl.verify(); 921 sessionControl.verify(); 922 txControl.verify(); 923 conControl.verify(); 924 } 925 926 public void testTransactionCommitWithPreBound() throws Exception { 927 MockControl dsControl = MockControl.createControl(DataSource .class); 928 final DataSource ds = (DataSource ) dsControl.getMock(); 929 MockControl conControl = MockControl.createControl(Connection .class); 930 Connection con = (Connection ) conControl.getMock(); 931 MockControl sfControl = MockControl.createControl(SessionFactory.class); 932 final SessionFactory sf = (SessionFactory) sfControl.getMock(); 933 MockControl sessionControl = MockControl.createControl(Session.class); 934 final Session session = (Session) sessionControl.getMock(); 935 MockControl txControl = MockControl.createControl(Transaction.class); 936 Transaction tx = (Transaction) txControl.getMock(); 937 938 session.beginTransaction(); 939 sessionControl.setReturnValue(tx, 1); 940 session.getFlushMode(); 941 sessionControl.setReturnValue(FlushMode.NEVER, 1); 942 session.setFlushMode(FlushMode.AUTO); 943 sessionControl.setVoidCallable(1); 944 session.setFlushMode(FlushMode.NEVER); 945 sessionControl.setVoidCallable(1); 946 session.connection(); 947 sessionControl.setReturnValue(con, 2); 948 con.getTransactionIsolation(); 949 conControl.setReturnValue(Connection.TRANSACTION_READ_COMMITTED); 950 con.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE); 951 conControl.setVoidCallable(1); 952 con.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED); 953 conControl.setVoidCallable(1); 954 tx.commit(); 955 txControl.setVoidCallable(1); 956 con.isReadOnly(); 957 conControl.setReturnValue(false, 1); 958 dsControl.replay(); 959 conControl.replay(); 960 sfControl.replay(); 961 sessionControl.replay(); 962 txControl.replay(); 963 964 HibernateTransactionManager tm = new HibernateTransactionManager(); 965 tm.setSessionFactory(sf); 966 tm.setDataSource(ds); 967 TransactionTemplate tt = new TransactionTemplate(tm); 968 tt.setIsolationLevel(TransactionDefinition.ISOLATION_SERIALIZABLE); 969 final List l = new ArrayList (); 970 l.add("test"); 971 assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); 972 assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive()); 973 TransactionSynchronizationManager.bindResource(sf, new SessionHolder(session)); 974 assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf)); 975 976 Object result = tt.execute(new TransactionCallback() { 977 public Object doInTransaction(TransactionStatus status) { 978 assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf)); 979 assertTrue("Has thread connection", TransactionSynchronizationManager.hasResource(ds)); 980 SessionHolder sessionHolder = (SessionHolder) TransactionSynchronizationManager.getResource(sf); 981 assertTrue("Has thread transaction", sessionHolder.getTransaction() != null); 982 HibernateTemplate ht = new HibernateTemplate(sf); 983 ht.setExposeNativeSession(true); 984 return ht.executeFind(new HibernateCallback() { 985 public Object doInHibernate(org.hibernate.Session sess) throws HibernateException { 986 assertEquals(session, sess); 987 return l; 988 } 989 }); 990 } 991 }); 992 assertTrue("Correct result list", result == l); 993 994 assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf)); 995 SessionHolder sessionHolder = (SessionHolder) TransactionSynchronizationManager.getResource(sf); 996 assertTrue("Hasn't thread transaction", sessionHolder.getTransaction() == null); 997 TransactionSynchronizationManager.unbindResource(sf); 998 assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); 999 assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive()); 1000 dsControl.verify(); 1001 conControl.verify(); 1002 sfControl.verify(); 1003 sessionControl.verify(); 1004 txControl.verify(); 1005 } 1006 1007 public void testTransactionRollbackWithPreBound() throws Exception { 1008 MockControl dsControl = MockControl.createControl(DataSource .class); 1009 final DataSource ds = (DataSource ) dsControl.getMock(); 1010 MockControl conControl = MockControl.createControl(Connection .class); 1011 Connection con = (Connection ) conControl.getMock(); 1012 MockControl sfControl = MockControl.createControl(SessionFactory.class); 1013 final SessionFactory sf = (SessionFactory) sfControl.getMock(); 1014 MockControl sessionControl = MockControl.createControl(Session.class); 1015 final Session session = (Session) sessionControl.getMock(); 1016 MockControl tx1Control = MockControl.createControl(Transaction.class); 1017 final Transaction tx1 = (Transaction) tx1Control.getMock(); 1018 MockControl tx2Control = MockControl.createControl(Transaction.class); 1019 final Transaction tx2 = (Transaction) tx2Control.getMock(); 1020 1021 session.beginTransaction(); 1022 sessionControl.setReturnValue(tx1, 1); 1023 tx1.rollback(); 1024 tx1Control.setVoidCallable(1); 1025 session.clear(); 1026 sessionControl.setVoidCallable(1); 1027 session.beginTransaction(); 1028 sessionControl.setReturnValue(tx2, 1); 1029 tx2.commit(); 1030 tx2Control.setVoidCallable(1); 1031 1032 session.getFlushMode(); 1033 sessionControl.setReturnValue(FlushMode.NEVER, 2); 1034 session.setFlushMode(FlushMode.AUTO); 1035 sessionControl.setVoidCallable(2); 1036 session.setFlushMode(FlushMode.NEVER); 1037 sessionControl.setVoidCallable(2); 1038 session.connection(); 1039 sessionControl.setReturnValue(con, 4); 1040 con.isReadOnly(); 1041 conControl.setReturnValue(false, 2); 1042 1043 dsControl.replay(); 1044 conControl.replay(); 1045 sfControl.replay(); 1046 sessionControl.replay(); 1047 tx1Control.replay(); 1048 tx2Control.replay(); 1049 1050 HibernateTransactionManager tm = new HibernateTransactionManager(); 1051 tm.setSessionFactory(sf); 1052 tm.setDataSource(ds); 1053 final TransactionTemplate tt = new TransactionTemplate(tm); 1054 assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); 1055 assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive()); 1056 TransactionSynchronizationManager.bindResource(sf, new SessionHolder(session)); 1057 assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf)); 1058 1059 try { 1060 tt.execute(new TransactionCallbackWithoutResult() { 1061 public void doInTransactionWithoutResult(TransactionStatus status) { 1062 assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf)); 1063 assertTrue("Has thread connection", TransactionSynchronizationManager.hasResource(ds)); 1064 SessionHolder sessionHolder = (SessionHolder) TransactionSynchronizationManager.getResource(sf); 1065 assertEquals(tx1, sessionHolder.getTransaction()); 1066 tt.execute(new TransactionCallbackWithoutResult() { 1067 public void doInTransactionWithoutResult(TransactionStatus status) { 1068 status.setRollbackOnly(); 1069 HibernateTemplate ht = new HibernateTemplate(sf); 1070 ht.setExposeNativeSession(true); 1071 ht.execute(new HibernateCallback() { 1072 public Object doInHibernate(org.hibernate.Session sess) throws HibernateException { 1073 assertEquals(session, sess); 1074 return null; 1075 } 1076 }); 1077 } 1078 }); 1079 } 1080 }); 1081 fail("Should have thrown UnexpectedRollbackException"); 1082 } 1083 catch (UnexpectedRollbackException ex) { 1084 } 1086 1087 assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf)); 1088 SessionHolder sessionHolder = (SessionHolder) TransactionSynchronizationManager.getResource(sf); 1089 assertTrue("Hasn't thread transaction", sessionHolder.getTransaction() == null); 1090 assertTrue("Not marked rollback-only", !sessionHolder.isRollbackOnly()); 1091 1092 tt.execute(new TransactionCallbackWithoutResult() { 1093 public void doInTransactionWithoutResult(TransactionStatus status) { 1094 assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf)); 1095 assertTrue("Has thread connection", TransactionSynchronizationManager.hasResource(ds)); 1096 SessionHolder sessionHolder = (SessionHolder) TransactionSynchronizationManager.getResource(sf); 1097 assertEquals(tx2, sessionHolder.getTransaction()); 1098 HibernateTemplate ht = new HibernateTemplate(sf); 1099 ht.setExposeNativeSession(true); 1100 ht.execute(new HibernateCallback() { 1101 public Object doInHibernate(org.hibernate.Session sess) throws HibernateException { 1102 assertEquals(session, sess); 1103 return null; 1104 } 1105 }); 1106 } 1107 }); 1108 1109 assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf)); 1110 assertTrue("Hasn't thread transaction", sessionHolder.getTransaction() == null); 1111 TransactionSynchronizationManager.unbindResource(sf); 1112 assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); 1113 assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive()); 1114 1115 dsControl.verify(); 1116 conControl.verify(); 1117 sfControl.verify(); 1118 sessionControl.verify(); 1119 tx1Control.verify(); 1120 tx2Control.verify(); 1121 } 1122 1123 public void testExistingTransactionWithPropagationNestedAndRollback() throws Exception { 1124 doTestExistingTransactionWithPropagationNestedAndRollback(false); 1125 } 1126 1127 public void testExistingTransactionWithManualSavepointAndRollback() throws Exception { 1128 doTestExistingTransactionWithPropagationNestedAndRollback(true); 1129 } 1130 1131 private void doTestExistingTransactionWithPropagationNestedAndRollback(final boolean manualSavepoint) 1132 throws Exception { 1133 1134 if (JdkVersion.getMajorJavaVersion() < JdkVersion.JAVA_14) { 1135 return; 1136 } 1137 1138 MockControl dsControl = MockControl.createControl(DataSource .class); 1139 final DataSource ds = (DataSource ) dsControl.getMock(); 1140 MockControl conControl = MockControl.createControl(Connection .class); 1141 Connection con = (Connection ) conControl.getMock(); 1142 MockControl mdControl = MockControl.createControl(DatabaseMetaData .class); 1143 DatabaseMetaData md = (DatabaseMetaData ) mdControl.getMock(); 1144 MockControl spControl = MockControl.createControl(Savepoint .class); 1145 Savepoint sp = (Savepoint ) spControl.getMock(); 1146 MockControl sfControl = MockControl.createControl(SessionFactory.class); 1147 final SessionFactory sf = (SessionFactory) sfControl.getMock(); 1148 MockControl sessionControl = MockControl.createControl(Session.class); 1149 Session session = (Session) sessionControl.getMock(); 1150 MockControl txControl = MockControl.createControl(Transaction.class); 1151 Transaction tx = (Transaction) txControl.getMock(); 1152 MockControl queryControl = MockControl.createControl(Query.class); 1153 Query query = (Query) queryControl.getMock(); 1154 1155 final List list = new ArrayList (); 1156 list.add("test"); 1157 con.isReadOnly(); 1158 conControl.setReturnValue(false, 1); 1159 sf.openSession(); 1160 sfControl.setReturnValue(session, 1); 1161 session.beginTransaction(); 1162 sessionControl.setReturnValue(tx, 1); 1163 session.connection(); 1164 sessionControl.setReturnValue(con, 2); 1165 md.supportsSavepoints(); 1166 mdControl.setReturnValue(true, 1); 1167 con.getMetaData(); 1168 conControl.setReturnValue(md, 1); 1169 con.setSavepoint(); 1170 conControl.setReturnValue(sp, 1); 1171 con.rollback(sp); 1172 conControl.setVoidCallable(1); 1173 session.createQuery("some query string"); 1174 sessionControl.setReturnValue(query, 1); 1175 query.list(); 1176 queryControl.setReturnValue(list, 1); 1177 session.close(); 1178 sessionControl.setReturnValue(null, 1); 1179 tx.commit(); 1180 txControl.setVoidCallable(1); 1181 dsControl.replay(); 1182 conControl.replay(); 1183 mdControl.replay(); 1184 spControl.replay(); 1185 sfControl.replay(); 1186 sessionControl.replay(); 1187 txControl.replay(); 1188 queryControl.replay(); 1189 1190 HibernateTransactionManager tm = new HibernateTransactionManager(); 1191 tm.setJdbcExceptionTranslator(new SQLStateSQLExceptionTranslator()); 1192 tm.setNestedTransactionAllowed(true); 1193 tm.setSessionFactory(sf); 1194 tm.setDataSource(ds); 1195 final TransactionTemplate tt = new TransactionTemplate(tm); 1196 tt.setPropagationBehavior(TransactionDefinition.PROPAGATION_NESTED); 1197 assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); 1198 assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); 1199 assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive()); 1200 1201 Object result = tt.execute(new TransactionCallback() { 1202 public Object doInTransaction(TransactionStatus status) { 1203 assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf)); 1204 assertTrue("Has thread connection", TransactionSynchronizationManager.hasResource(ds)); 1205 if (manualSavepoint) { 1206 Object savepoint = status.createSavepoint(); 1207 status.rollbackToSavepoint(savepoint); 1208 } 1209 else { 1210 tt.execute(new TransactionCallbackWithoutResult() { 1211 protected void doInTransactionWithoutResult(TransactionStatus status) { 1212 assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf)); 1213 assertTrue("Has thread connection", TransactionSynchronizationManager.hasResource(ds)); 1214 status.setRollbackOnly(); 1215 } 1216 }); 1217 } 1218 HibernateTemplate ht = new HibernateTemplate(sf); 1219 return ht.find("some query string"); 1220 } 1221 }); 1222 assertTrue("Correct result list", result == list); 1223 1224 assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); 1225 assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); 1226 assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive()); 1227 dsControl.verify(); 1228 conControl.verify(); 1229 mdControl.verify(); 1230 spControl.verify(); 1231 sfControl.verify(); 1232 sessionControl.verify(); 1233 txControl.verify(); 1234 queryControl.verify(); 1235 } 1236 1237 public void testTransactionCommitWithNonExistingDatabase() throws Exception { 1238 final DriverManagerDataSource ds = new DriverManagerDataSource(); 1239 LocalSessionFactoryBean lsfb = new LocalSessionFactoryBean(); 1240 lsfb.setDataSource(ds); 1241 Properties props = new Properties (); 1242 props.setProperty("hibernate.dialect", HSQLDialect.class.getName()); 1243 lsfb.setHibernateProperties(props); 1244 lsfb.afterPropertiesSet(); 1245 final SessionFactory sf = (SessionFactory) lsfb.getObject(); 1246 1247 HibernateTransactionManager tm = new HibernateTransactionManager(); 1248 tm.setSessionFactory(sf); 1249 tm.afterPropertiesSet(); 1250 TransactionTemplate tt = new TransactionTemplate(tm); 1251 tt.setIsolationLevel(TransactionDefinition.ISOLATION_SERIALIZABLE); 1252 tt.setTimeout(10); 1253 assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); 1254 assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); 1255 assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive()); 1256 1257 try { 1258 tt.execute(new TransactionCallback() { 1259 public Object doInTransaction(TransactionStatus status) { 1260 assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf)); 1261 assertTrue("Has thread connection", TransactionSynchronizationManager.hasResource(ds)); 1262 HibernateTemplate ht = new HibernateTemplate(sf); 1263 return ht.find("from java.lang.Object"); 1264 } 1265 }); 1266 fail("Should have thrown CannotCreateTransactionException"); 1267 } 1268 catch (CannotCreateTransactionException ex) { 1269 } 1271 1272 assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); 1273 assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); 1274 assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive()); 1275 } 1276 1277 public void testTransactionCommitWithNonExistingDatabaseAndLazyConnection() throws Exception { 1278 DriverManagerDataSource dsTarget = new DriverManagerDataSource(); 1279 final LazyConnectionDataSourceProxy ds = new LazyConnectionDataSourceProxy(); 1280 ds.setTargetDataSource(dsTarget); 1281 ds.setDefaultAutoCommit(true); 1282 ds.setDefaultTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED); 1283 1284 LocalSessionFactoryBean lsfb = new LocalSessionFactoryBean(); 1285 lsfb.setDataSource(ds); 1286 Properties props = new Properties (); 1287 props.setProperty("hibernate.dialect", HSQLDialect.class.getName()); 1288 lsfb.setHibernateProperties(props); 1289 lsfb.afterPropertiesSet(); 1290 final SessionFactory sf = (SessionFactory) lsfb.getObject(); 1291 1292 HibernateTransactionManager tm = new HibernateTransactionManager(); 1293 tm.setSessionFactory(sf); 1294 tm.afterPropertiesSet(); 1295 TransactionTemplate tt = new TransactionTemplate(tm); 1296 tt.setIsolationLevel(TransactionDefinition.ISOLATION_SERIALIZABLE); 1297 tt.setTimeout(10); 1298 assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); 1299 assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); 1300 assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive()); 1301 1302 tt.execute(new TransactionCallback() { 1303 public Object doInTransaction(TransactionStatus status) { 1304 assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf)); 1305 assertTrue("Has thread connection", TransactionSynchronizationManager.hasResource(ds)); 1306 HibernateTemplate ht = new HibernateTemplate(sf); 1307 return ht.find("from java.lang.Object"); 1308 } 1309 }); 1310 1311 assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf)); 1312 assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); 1313 assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive()); 1314 } 1315 1316 protected void tearDown() { 1317 assertTrue(TransactionSynchronizationManager.getResourceMap().isEmpty()); 1318 assertFalse(TransactionSynchronizationManager.isSynchronizationActive()); 1319 assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly()); 1320 assertFalse(TransactionSynchronizationManager.isActualTransactionActive()); 1321 } 1322 1323} 1324 | Popular Tags |