如何在Spring / Hibernate事务中包装Wicket页面呈现? [英] How to wrap Wicket page rendering in a Spring / Hibernate transaction?

查看:99
本文介绍了如何在Spring / Hibernate事务中包装Wicket页面呈现?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的应用程序从Hibernate DAO加载实体,使用OpenSessionInViewFilter来渲染。



在某些情况下,我想对字段做一些小改动 -

  Long orderId ... 

link = new Link(cancel){
@Override public void onClick(){
Order order = orderDAO.load(orderId);
order.setCancelledTime(timeSource.getCurrentTime());
};

但这样的更改不会持续,因为OSIV不会刷新。



在这些情况下,必须调用orderDOA.save(order),这似乎是一个真正的耻辱,但我不希望改变OSIV上的FlushMode。



有没有人找到任何方式将'请求处理'(如onClick)声明为需要事务?

理想情况下,我认为事务将在请求周期的早期开始,并由OSIV提交,以便所有逻辑和呈现将在同一事务中进行。

p>

解决方案

免责声明:我从来没有真正尝试过这一点,但我认为它会起作用。这也可能比你想写的代码多一点。最后,我假设你的WebApplication是SpringWebApplication的子类。到目前为止,你是否和我在一起?



计划是告诉Spring我们想在事务中运行你的onClick方法。为了做到这一点,我们必须做三件事。



第1步:将PlatformTransactionManager注入您的网页:

  @SpringBean 
私人PlatformTransactionManager platformTransactionManager;

第二步:在您的WebPage中创建一个静态的TransactionDefinition,我们稍后会参考它:

  protected static final TransactionDefinition TRANSACTION_DEFINITION; 
static {
TRANSACTION_DEFINITION = new DefaultTransactionDefinition(TransactionDefinition.PROPAGATION_REQUIRES_NEW); $(b)((DefaultTransactionDefinition)TRANSACTION_DEFINITION).setIsolationLevel(TransactionDefinition.ISOLATION_SERIALIZABLE);



$ b

随意更改TransactionDefinition设置和/适当的位置。这个特殊的定义指示Spring即使已经启动了一个新的事务并且使用最大的事务隔离级别来启动一个新的事务。步骤3:将事务管理添加到onClick方法:

  link = new Link(cancel){
@Override
public void onClick() {
TransactionTemplate(platformTransactionManager,TRANSACTION_DEFINITION).execute(new TransactionCallback(){
@Override
public Object doInTransaction(TransactionStatus status){
Order order = orderDAO.load(orderId );
order.setCancelledTime(timeSource.getCurrentTime());
}
}
}
};

这应该会有诀窍!


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:

@SpringBean
private PlatformTransactionManager platformTransactionManager;

Step 2 : create a static TransactionDefinition in your WebPage that we will later reference:

protected static final TransactionDefinition TRANSACTION_DEFINITION;
static {
    TRANSACTION_DEFINITION = new DefaultTransactionDefinition(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
    ((DefaultTransactionDefinition) TRANSACTION_DEFINITION).setIsolationLevel(TransactionDefinition.ISOLATION_SERIALIZABLE);
}

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:

link = new Link("cancel") {
    @Override 
    public void onClick() {
        new TransactionTemplate(platformTransactionManager, TRANSACTION_DEFINITION).execute(new TransactionCallback() {
            @Override
            public Object doInTransaction(TransactionStatus status) {
                Order order = orderDAO.load(orderId);
                order.setCancelledTime(timeSource.getCurrentTime());      
            }
        }
    } 
};

And that should do the trick!

这篇关于如何在Spring / Hibernate事务中包装Wicket页面呈现?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆