有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java如何在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打电话真是太遗憾了。在这些情况下保存(订单),但我不想在OSIV上更改刷新模式

是否有人找到任何方法将“请求处理”(如onClick)声明为需要事务

理想情况下,我假设事务将在请求周期的早期启动,并由OSIV提交,以便所有逻辑和呈现都将在同一事务中进行


共 (2) 个答案

  1. # 1 楼答案

    我通常更喜欢使用额外的“服务”层代码来包装基本DAO 逻辑,并通过@Transactional提供事务。这让我能够更好地区分表示和业务逻辑,而且 更容易测试

    但是,既然您已经使用了OSIV,那么您可以在代码周围放置一些AOP拦截器 让它冲洗一下

  2. # 2 楼答案

    免责声明:我从未真正尝试过这个,但我认为它会奏效。这也可能比你想写的代码多一点。最后,我假设您的WebApplication子类是SpringWebApplication。到目前为止你还支持我吗

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

    步骤1:将PlatformTransactionManager注入到您的网页中:

    @SpringBean
    private PlatformTransactionManager platformTransactionManager;
    

    第2步:在您的网页中创建一个静态TransactionDefinition,我们将稍后参考:

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

    请随意更改TransactionDefinition设置和/或将定义移动到适当的共享位置。这个特定的定义指示Spring启动一个新事务,即使已经启动了一个事务,也要使用最大事务隔离级别

    步骤3:将事务管理添加到onClick方法:

    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());      
                }
            }
        } 
    };
    

    这就应该奏效了