[英]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.