我正在使用 Spring 4 和 Hibernate 4。我遇到了很多其他人都遇到的问题。我希望我的 Spring 表单只编辑实体的某些属性,而不是全部。
默认情况下,如果我加载一个持久化实体,在表单中显示它的一些属性以进行编辑,将其发布到我的控制器并保存......任何未包含在表单中的属性值都会丢失。我确实理解为什么会发生这种情况,并且我知道那里有一些解决方案。
1)在保存时,从数据库加载实体,只从模型中复制你想要的属性,保存。
2)当表单启动时,加载实体并使用@SessionAttributes 功能将其存储在请求之间的会话中。
但我不喜欢其中任何一个。也许我遗漏了一些东西,但解决方案似乎相当简单。在某处,默认的 Spring web binder 正在创建实体的实例以将表单属性复制到其中。如果我可以覆盖它并使用 ID 从数据库加载持久化实体,然后让 Spring 的绑定将其用作目标实体(仅复制随表单提交的属性,而其他属性保持不变)......那么我认为会解决我的问题。
我一直在寻找如何/在哪里可以使用自定义 WebDataBinder 类。我不知道如何......而且我什至不确定这是否是我应该寻找的地方。
有什么建议么?
谢谢!!
编辑:
我将举一个假设的例子来试图更好地解释我的问题。假设我有一个实体类 Customer,它有 50 个属性。我有一个仅用于更新联系信息的表格。这只是 50 个属性中的 5 个。
街道
城市
状态
邮编
电话
如果我这样做是在 Spring 表单中,当提交表单以保存时,Spring 会创建一个新的“空白”实体,使用表单中的值填充它并将其传递给我的控制器......这就是保存的内容。问题是,由于其他属性,如 firstName、lastName、customerType 等,没有包含在表单中,Spring 将它们单独放置并且它们保持为空。当我告诉 Hibernate 使用 Spring 提供的实体更新实体时,Hibernate 认为我希望 firstName、lastName 等为空,因为这些是我在 bean 中提供的值。它不知道我只改变了其中的几个。
那么会发生什么?我的 50 个房产价值中有 45 个被吹走了。
在下面的评论中,Sp00m 提出了一个可行的解决方案……在隐藏字段中包含所有其他属性。但由于各种原因,这个解决方案让我非常头疼。
如果我可以让 Spring 从数据库中加载实体(而不是创建一个新的/空白实体),然后只填充那些与表单一起提交的字段。我相信这会解决我的问题。
可以在此处找到类似的讨论(但使用隐藏字段解决方案).. http://www.coderanch.com/t/529490/Spring/Spring-MVC-Hibernate-Update-column