java - 如何对 Wicket/Spring 页面 View 使用单个事务?

标签 java hibernate spring jpa wicket

我之前的问题How to wrap Wicket page rendering in a Spring / Hibernate transaction?让我开始思考 Wicket 中的事务划分。

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

我有一个通用的 DAO 类,由 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);
    }

}

以及一个获取它的通用模型

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) 启动的(不同)事务提交时,将提交更改。在这些时间之间,所有的赌注都会被取消,因此该对象可能不再存在于要提交的数据库中。

我从来不完全确定数据库代码和事务。尽管我可以构建其他更复杂但更危险的场景,但我是否应该耸耸肩,认为这不太可能?如果不是,我就看不出如何在单个事务中划分整个页面逻辑,而这正是我的直觉告诉我我应该追求的目标。

最佳答案

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

关于java - 如何对 Wicket/Spring 页面 View 使用单个事务?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6161743/

相关文章:

java - 如何访问对象的这个参数

java - Hibernate 中的嵌套 JOIN 查询

java - Spring Boot 不绑定(bind)到 Tomcat 端口

java - 自定义 Spring Boot 启动器 : how do you contribute i18n messages to the MessageSource?

java - Spring Data 和 JDBC/ORM 模块的区别

java - HDFS中用于异构Hadoop集群的数据放置和分发

java - 为什么Hibernate 5.0.6 发布包中不包含事务实现jar?

java - Gson:从 Json 字符串实例化接口(interface)

java - 玩2.5 Ebean和JPA : NoSuchMethodError

java - 如何为两个不同的列组合在实体类上添加唯一约束