[英]How to wrap Wicket page rendering in a Spring / Hibernate transaction?
[英]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.