【问题标题】:Best way to update some fields of a detached object on Hibernate?在 Hibernate 上更新分离对象的某些字段的最佳方法?
【发布时间】:2010-01-18 20:06:03
【问题描述】:

我想知道在 Java 上使用 HB 更新分离对象的某些字段的最佳方法是什么。特别是当对象具有子对象属性时。例如(删除注释并减少字段数以减少噪音):

public class Parent {
   int id;
   String field2;
   ...
   Child child;
}

public class Child {
   int id;
   String field3;
} 

在 MVC webapp 中更新 Parent 时,我可以使用 Session.get(Parent.class,123) 调用父实例,使用它来填充表单并显示它。没有 DTO,只是将分离的父级传递给视图并绑定到表单。现在,我只想允许用户更新父级的 field2 属性。因此,当用户发布表单时,我会得到一个填充了 id 和 field2 的 Parent 实例(我认为 mvc 框架在这里无关紧要,绑定时的行为基本相同)。
现在,哪种策略最适合执行实体的更新?我可以考虑几种选择,但我想听专家的意见:)(请记住,我不想放松父实例和子实例之间的关系)

A) 再次从 Session 中检索父实例并手动替换更新的字段

Parent pojoParent; //binded with the data of the Form.
Parent entity = Session.get(Parent.class,pojoParent.getId());
entity.setField2(pojoParent.getField2()).          

我经常使用这个。但是 pojoParent 似乎被用作卧底 DTO。如果要更新的字段数量变大,也会变得很糟糕。

B) 将 Child 存储在某处(httpSession?)并在以后关联它。

Parent parent = Session.get(Parent.class,123);
//bind the retrieved parent to the form
// store the Child from parent.getChild() on the httpSession
...
//when the users submits the form...
pojoParent.setChild(someHttpSessionContext.getAttribute('Child'))
Session.save(pojoParent);

我认为这是废话,但我在一些项目中看到了它......

C) 将 Parent 和 Child 之间的关系设置为不可变。在关系上使用 updatable=false 我可以更新任何父字段,而不必担心失去孩子。无论如何,这是相当严格的,并且关系永远不会更新。

那么,您认为解决这种情况的最佳方法是什么?

提前谢谢你!

【问题讨论】:

    标签: java hibernate orm


    【解决方案1】:

    加载一个Parent对象后,你说

    现在,我只想让用户更新 parent 的 field2 属性

    根据用例,您可以使用 UpdateableParent 对象

    public class UpdateableParent {
    
       private String field2;
    
       // getter's and setter's
    
    }
    

    现在我们的父存储库

    @Repository
    public class ParentRepositoryImpl implements ParentRepository {
    
        @Autowired
        private SessionFactory sessionFactory;
    
    
        public void updateSpecificUseCase(UpdateableParent updateableParentObject) {
    
            Parent parent = sessionFactory.getCurrentSession().load(Parent.class, updateableParentObject.getId());
    
            try {
                // jakarta commons takes care of copying Updateable Parent object to Parent object
    
                BeanUtils.copyProperties(parent, updateableParentObject);
            } catch (Exception e) {
                throw new IllegalStateException("Error occured when updating a Parent object", e);
            }
    
        }
    
    }
    

    它的优点

    • 很安全:您只需更新您真正想要的内容
    • 您不必担心 MVC 框架(某些 MVC 框架允许您设置 allowedFields 属性)。如果您忘记了一些允许的字段会怎样???

    虽然不是技术相关的问题,Seam 框架允许你只更新你想要的。所以你不必担心使用什么模式。

    问候,

    【讨论】:

      【解决方案2】:

      A) 检索父实例 再次会话并手动替换 更新的字段

      这似乎是我过去几年用过的最实用的版本。

      B) 将孩子存放在某处 (httpSession?) 并关联它 后者。

      我建议不要这样做,特别是如果您想遵循 REST 范式,这使得服务器端状态完全被禁止。尽管发起会话的用户离开去喝咖啡,但您最终将使用堆空间来存储分离的对象:)

      C) 设置 Parent 和 孩子是不可变的。

      恕我直言,这也不是一个好方法,尽管它适合具有小型持久性模型的小型项目。但即使在小型应用程序中,尝试修改代码时也可能会导致头疼。

      【讨论】:

        【解决方案3】:

        您可以直接修改分离的对象,然后使用会话上的merge 方法将对象重新附加到会话。

        【讨论】:

          猜你喜欢
          • 2015-09-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-08-10
          相关资源
          最近更新 更多