Issue 1:
Rick Herrick opened SPR-1439 and commented

Our system is a mish-mash of various mailing systems, including sendmail, JavaMail, KanaMail, and some others. I'd like to be able to collect all of these different message types in a list and do a batch send. The problem is that the base MailSender.send() method takes a SimpleMailMessage class instead of the base MailMessage interface. The problem is that I'm also submitting MimeMailMessages, which don't extend SimpleMailMessage. So I can't just pass in a generic MailMessage object (which could be a SimpleMailMessage or a MimeMailMessage or one of the other MailMessage-derived types I've created) into send().

This is obviously done because MailMessage doesn't have any getter methods and these are necessary. I'd suggest adding the getters to the base MailMessage interface. That lets generic sender and message code work on these base methods, while letting us develop the necessary code to support special functionality elsewhere. So the two steps I'm suggesting are:

Add getters to MailMessage interface.

Change the send() methods in MailSender to take MailMessage instead of SimpleMailMessage.

Issue Links:

#6711 MailSender should use interface instead of class SimpleMailMessage ("is duplicated by")

1 votes, 2 watchers

Issue 2:
Den Orlov opened SPR-5079 and commented

Background

I have integration tests that:

put some test data into database using Hibernate

wait some time, so DB stored procedures triggered by scheduler will process my data

retrieve from db some data and check its correctness, again using Hibernate

When I used Spring's "JUnit 3.8 legacy support" all of these three steps were organized in one test method using the protected endTransaction() and startNewTransaction() methods in AbstractTransactionalSpringContextTests between steps #1 and #2.

Status Quo

Now I am migrating my code to use the Spring TestContext Framework (TCF), but it doesn't provide support for programmatically starting or stopping the test-managed transaction.

Deliverables

The term test-manged means a transaction managed by the TCF, either declaratively or programmatically.

See also "Design Considerations" below.

Introduce a mechanism in the TCF that supports the following features:

end the current test-managed transaction

start a new test-managed transaction

configure the current test-managed transaction to be committed once the test completes

configure the current test-managed transaction to be rolled back once the test completes

Refactor TransactionalTestExecutionListener to use this new mechanism internally.

Consider introducing a JUnit TestRule that simplifies the programming model (e.g., by delegating to the proposed TestTransaction façade).

Design Considerations

Introduce a TestTransaction class that acts as a façade to the functionality previously available in TransactionalTestExecutionListener. For example, TestTransaction could define methods that could provide the following API:

TestTransaction.start()

TestTransaction.end()

TestTransaction.rollback(boolean)

Options for Interacting with the Test Transaction

Dependency Injection of TestTransaction

Ideally, we would like to be able to have the TestTransaction injected into our test instance. However, since the DependencyInjectionTestExecutionListener must come before the TransactionalTestExecutionListener in the chain of listeners, dependency injection would only be possible by introducing yet another "transactional" TestExecutionListener that creates a proxy bean or bean of type ObjectFactory in the ApplicationContext. Such a proxy bean would serve as a placeholder for dependency injection into the test instance, and the TransactionalTestExecutionListener could later set a value either directly in the proxy/ObjectFactory or via a ThreadLocal.

But we would like to avoid having two (2) TestExecutionListener implementations for transactional support. Plus, the placeholder-bean approach could present more problems than it solves.

Dependency Injection of TestContext

A second option would be to inject the TestContext into test instances (see #12947) and provide access to the TestTransaction as an attribute (note that TestContext implements AttributeAccessor), but this would open up use of the TestContext within test classes (i.e., no longer limited to the TestExecutionListener API). In addition, developers would be forced to navigate the TestContext to obtain the TestTransaction, thus making the programming model less intuitive.

Purely ThreadLocal Approach

The final option is to follow a purely ThreadLocal-based approach with TestTransaction encapsulating the details and providing static methods instead of instance methods.

Related Resources

Diff for TransactionalTestExecutionListener. This commit introduced caching of the TransactionContext keyed by Method and removed the previous support for the transactionFlaggedForCommit functionality.

#9315

#9218

Affects: 2.5.6

Issue Links:

#16558 Document programmatic test transaction management support ("is depended on by")

#10548 Provide support in TestContext framework equivalent to AbstractTransactionalSpringContextTests ("is duplicated by")

#9315 TransactionalTestExecutionListener uses cached TransactionManager (TM), even after ApplicationContext that created the TM has been marked 'dirty' and closed.

#12947 Introduce autowiring support for the current TestContext

#9218 Transactional JUnit test with timeout does not create a transaction

Referenced from: commits bdceaa4, f667e43, 90f0d14

30 votes, 22 watchers