|
|
|
@ -3278,14 +3278,13 @@ declarative SQL script execution with default transaction rollback semantics. |
|
|
|
|
.Avoid false positives when testing ORM code |
|
|
|
|
[NOTE] |
|
|
|
|
==== |
|
|
|
|
When you test application code that manipulates the state of the Hibernate session, make |
|
|
|
|
sure to __flush__ the underlying session within test methods that execute that code. |
|
|
|
|
When you test application code that manipulates the state of the Hibernate or JPA session, |
|
|
|
|
make sure to __flush__ the underlying session within test methods that execute that code. |
|
|
|
|
Failing to flush the underlying session can produce __false positives__: your test may |
|
|
|
|
pass, but the same code throws an exception in a live, production environment. In the |
|
|
|
|
following Hibernate-based example test case, one method demonstrates a false positive, |
|
|
|
|
and the other method correctly exposes the results of flushing the session. Note that |
|
|
|
|
this applies to JPA and any other ORM frameworks that maintain an in-memory __unit of |
|
|
|
|
work__. |
|
|
|
|
this applies to any ORM frameworks that maintain an in-memory __unit of work__. |
|
|
|
|
|
|
|
|
|
[source,java,indent=0] |
|
|
|
|
[subs="verbatim,quotes"] |
|
|
|
@ -3298,11 +3297,11 @@ work__. |
|
|
|
|
@Test // no expected exception! |
|
|
|
|
public void falsePositive() { |
|
|
|
|
updateEntityInHibernateSession(); |
|
|
|
|
// False positive: an exception will be thrown once the session is |
|
|
|
|
// finally flushed (i.e., in production code) |
|
|
|
|
// False positive: an exception will be thrown once the Hibernate |
|
|
|
|
// Session is finally flushed (i.e., in production code) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Test(expected = GenericJDBCException.class) |
|
|
|
|
@Test(expected = ...) |
|
|
|
|
public void updateWithSessionFlush() { |
|
|
|
|
updateEntityInHibernateSession(); |
|
|
|
|
// Manual flush is required to avoid false positive in test |
|
|
|
@ -3311,6 +3310,33 @@ work__. |
|
|
|
|
|
|
|
|
|
// ... |
|
|
|
|
---- |
|
|
|
|
|
|
|
|
|
Or for JPA: |
|
|
|
|
|
|
|
|
|
[source,java,indent=0] |
|
|
|
|
[subs="verbatim,quotes"] |
|
|
|
|
---- |
|
|
|
|
// ... |
|
|
|
|
|
|
|
|
|
@Autowired |
|
|
|
|
private EntityManager entityManager; |
|
|
|
|
|
|
|
|
|
@Test // no expected exception! |
|
|
|
|
public void falsePositive() { |
|
|
|
|
updateEntityInJpaTransaction(); |
|
|
|
|
// False positive: an exception will be thrown once the JPA |
|
|
|
|
// EntityManager is finally flushed (i.e., in production code) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Test(expected = ...) |
|
|
|
|
public void updateWithEntityManagerFlush() { |
|
|
|
|
updateEntityInJpaTransaction(); |
|
|
|
|
// Manual flush is required to avoid false positive in test |
|
|
|
|
entityManager.flush(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// ... |
|
|
|
|
---- |
|
|
|
|
==== |
|
|
|
|
|
|
|
|
|
|
|
|
|
|