Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/392.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/hibernate/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何为Wicket/Spring页面视图使用单个事务?_Java_Hibernate_Spring_Jpa_Wicket - Fatal编程技术网

Java 如何为Wicket/Spring页面视图使用单个事务?

Java 如何为Wicket/Spring页面视图使用单个事务?,java,hibernate,spring,jpa,wicket,Java,Hibernate,Spring,Jpa,Wicket,我前面的问题让我想到了Wicket中的事务划分 虽然通过将业务逻辑向下移动到Spring管理层很容易解决该示例,但在其他地方这是不可能的 我有一个通用DAO类,由Hibernate实现,具有 public class HibernateDAO<T> implements DAO<T> { protected final Class<T> entityClass; private final SessionFactory sessionFact

我前面的问题让我想到了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);
    }

}
公共类HibernateDAO实现DAO{
受保护的最终类entityClass;
私人最终会议工厂会议工厂;
@交易的
公共T加载(可序列化id){
return(T)getSession().get(entityClass,id);
}
@交易的
公共无效保存或更新(T对象){
getSession().saveOrUpdate(对象);
}
}
以及获取它的通用模型

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

}
公共类DAOEntityModel扩展了LoadableDetachableModel{
私家道道;
私有最终可序列化id;
公共DAOEntityModel(DAO-DAO,可序列化id){
this.dao=dao;
this.id=id;
}
公共道实体模型(道实体,U实体){
这个(dao,entity.getId());
}
公共可序列化的getId(){
返回id;
}
@凌驾
受保护的T荷载(){
返回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);
    }    
}
公共类ScreenDetailsPanel扩展面板{
@SpringBean(name=“screenDAO”)私有DAO;
public ScreenDetailsPanel(字符串面板ID、长屏幕ID){
超级(专家组ID);
最终IModel screenModel=新的DAOEntityModel(dao,screenId);
表格=新表格(“表格”){
@重写受保护的void onSubmit(){
Screen=screenModel.getObject();
dao.saveOrUpdate(屏幕);
}};
form.add(
新文本字段(“名称”,新属性模型(屏幕模型,“名称”);
添加(表格);
}    
}
到目前为止一切都很好-谢谢你坚持

所以我的问题是——当表单提交时,PropertyModel将加载screenModel,这将发生在@Transactional dao.load(id)描述的事务中。当dao.saveOrUpdate(对象)的(不同)事务启动时,更改的提交将被取消。在这两个时间之间,所有下注都已关闭,因此对象可能不再存在于要提交的数据库中


对于DB代码和事务,我从来没有完全确定过。尽管我可以构建其他更复杂但更危险的场景,但我是否应该对此不屑一顾?如果没有,我看不出如何在一个事务中划分整个页面逻辑,这是我的直觉告诉我的目标。

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

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

我还没有实现它,但是我很确定@ireddick solution in在Wicket请求周期中懒洋洋地启动tx in是这里最好的解决方案。我将接受这个代理,以防止堆栈溢出困扰我接受答案。

我还没有实现它,但我非常确定@ireddick solution in在Wicket请求周期中懒洋洋地启动tx in是最好的解决方案。我将接受这个代理,以防止堆栈溢出困扰我接受答案。

就是这样,Wicket鼓励这些小模型很好地分配逻辑,但很难将它们的调用封装在一个tx中。我试图找出是否有Wicket解决方案来解决这个问题,或者,如果这不是一个真正的问题。@Duncan McGregor:@Transactional对数据库中的对象进行更新/升级的方法就足够了。当然,对象可能已不存在或已更新。这在网络应用程序中更可能发生。根据您的访问层,您可能会遇到一个异常(如JPA中的optimisticlockexception),这取决于您的服务/UI层。我想,如果由于正确描述事务而无法处理此类错误,我会更高兴。这就是问题所在,Wicket鼓励这些能够很好地分布逻辑的小模型,但是很难将它们的调用封装在一个tx中。我试图找出是否有Wicket解决方案来解决这个问题,或者,如果这不是一个真正的问题。@Duncan McGregor:@Transactional对数据库中的对象进行更新/升级的方法就足够了。当然,对象可能已不存在或已更新。这在网络应用程序中更可能发生。根据你的访问层,你会得到一个异常(如JPA中的optimisticlockexception),这取决于你的服务/用户界面层。我想如果我不能处理这样一个错误,因为正确描述了交易,我会更高兴。重复感谢这个链接-我不认为这是一个重复的问题,尽管看起来你的答案可能是解决方案。公正的评论。我提到的问题实际上太宽泛了。我将为这个问题添加一个答案,并概述解决方案。如果您这样做,我将不胜感激。我想他们应该