在Hibernate上更新分离对象的某些字段的最佳方法?

我想知道在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已填充(我认为mvc框架在这里不重要,绑定时所有行为大致相同)。
现在,哪种策略最适合执行实体更新? 我可以想一些替代方案,但我想听听专家:)(请记住,我不想放松父实例和子实例之间的关系)

A)再次从Session中重新获取Parent实例,并手动替换更新的字段

 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我可以更新任何父字段而不必担心丢失孩子。 无论如何,这是非常严格的,关系永远不会更新。

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

先感谢您!

加载一个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框架只允许您更新所需内容。 所以你不必担心使用什么模式。

问候,

A)再次从Session中重新获取Parent实例,并手动替换更新的字段

这似乎是我过去几年使用的function最多的版本。

B)将Child存储在某处(httpSession?)并将其关联到后者。

我建议不要这样做,特别是如果你想遵循REST范式,它使服务器端状态成为完全禁止。 并且最终会为分离的对象使用堆空间,尽管发起会话的用户会离开咖啡馆:)

C)将Parent和Child之间的关系设置为不可变。

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

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