繁体   English   中英

如何将单个事务用于 Wicket / Spring 页面视图?

[英]How to use a single transaction for a Wicket / Spring page view?

我之前的问题如何在 Spring / Hibernate 事务中包装 Wicket 页面渲染? 让我想到了 Wicket 中的事务划分。

虽然通过将业务逻辑向下移动到 Spring 管理的层中可以轻松解决该示例,但在其他地方这是不可能的。

我有一个通用的 DAO class,由 Hibernate 实现,带有

public class HibernateDAO<T> implements DAO<T> {

    protected final Class<T> entityClass;
    private final SessionFactory sessionFactory;

    @Transactional
    public T load(Serializable id) {
        return (T) getSession().get(entityClass, id);
    }

    @Transactional
    public void saveOrUpdate(T object) {
        getSession().saveOrUpdate(object);
    }

}

和一个通用的 model 来获取它

public class DAOEntityModel<T> extends LoadableDetachableModel<T>{

    private DAO<T> dao;
    private final Serializable id;

    public DAOEntityModel(DAO<T> dao, Serializable id) {
        this.dao = dao;
        this.id = id;
    }

    public <U extends Entity> DAOEntityModel(DAO<T> dao, U entity) {
        this(dao, entity.getId());
    }

    public Serializable getId() {
        return id;
    }

    @Override
    protected T load() {
        return dao.load(id);
    }

}

现在我有一个改变实体的最小形式

public class ScreenDetailsPanel extends Panel {

    @SpringBean(name="screenDAO") private DAO<Screen> dao;

    public ScreenDetailsPanel(String panelId, Long screenId) {
        super(panelId);
        final IModel<Screen> screenModel = new DAOEntityModel<Screen>(dao, screenId);
        Form<Screen> form = new Form<Screen>("form") {
            @Override protected void onSubmit() {
                Screen screen = screenModel.getObject();
                dao.saveOrUpdate(screen);
            }};
        form.add(
            new TextField<String>("name", new PropertyModel<String>(screenModel, "name")));
        add(form);
    }    
}

到目前为止一切顺利 - 感谢您的坚持!

所以我的问题是——提交表单时,PropertyModel 将加载screenModel,这将发生在@Transactional dao.load(id) 所描绘的事务中。 当为 dao.saveOrUpdate(object) 启动(不同的)事务时,将提交更改。 在这些时间之间,所有赌注都关闭了,因此 object 可能不再存在于要提交的数据库中。

我从不完全确定数据库代码和事务。 尽管我可以构建其他更复杂但更危险的场景,但我是否应该对此不以为然? 如果不是,我看不到如何在单个事务中划分整个页面逻辑,这是我的直觉告诉我应该瞄准的。

通常,您可以通过将@Transactional注释放在服务级别 class 上来解决此问题,该服务级别由您的前端层代码使用,该代码包含 DAO 操作 - 以便加载和保存发生在同一个事务中。 换句话说,您可以通过在表单和 DAO 代码之间创建一层代码来解决这个问题,即“服务层”,它提供业务级逻辑并从表示层隐藏 DAO 的存在。

我还没有实现它,但我很确定如何控制 Wicket forms 中的 JPA 持久性中的@ireddick 解决方案? 在 Wicket 请求周期中懒惰地启动 tx 是最好的解决方案。 我将接受这个代理,以阻止 Stack Overflow 唠叨我接受答案。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM