My application loads entities from a Hibernate DAO, with OpenSessionInViewFilter to allow rendering.
In some cases I want to make a minor change to a field –
Long orderId ...
link = new Link("cancel") {
@Override public void onClick() {
Order order = orderDAO.load(orderId);
order.setCancelledTime(timeSource.getCurrentTime());
};
but such a change is not persisted, as the OSIV doesn’t flush.
It seems a real shame to have to call orderDOA.save(order) in these cases, but I don’t want to go as far as changing the FlushMode on the OSIV.
Has anyone found any way of declaring a ‘request handling’ (such as onClick) as requiring a transaction?
Ideally I suppose the transaction would be started early in the request cycle, and committed by the OSIV, so that all logic and rendering would take place in same transaction.
Disclaimer : I’ve never actually tried this, but I think it would work. This also may be a little bit more code than you want to write. Finally, I’m assuming that your WebApplication subclasses SpringWebApplication. Are you with me so far?
The plan is to tell Spring that we want to run the statements of you onClick method in a transaction. In order to do that, we have to do three things.
Step 1 : inject the PlatformTransactionManager into your WebPage:
Step 2 : create a static TransactionDefinition in your WebPage that we will later reference:
Feel free to change the TransactionDefinition settings and/or move the definition to a shared location as appropriate. This particular definition instructs Spring to start a new transaction even if there’s already one started and to use the maximum transaction isolation level.
Step 3 : add transaction management to the onClick method:
And that should do the trick!