java - 如何加载持久的 Hibernate 实体进行绑定(bind),以便非表单属性不会丢失?

标签 java spring hibernate spring-mvc spring-4

我正在使用 Spring 4 和 Hibernate 4。 我遇到了一个似乎很多其他人都遇到的问题。我希望我的 Spring 表单仅编辑实体的某些属性,而不是整个实体。

默认情况下,如果我加载持久实体,在表单中显示它的一些属性以进行编辑,将其发布到我的 Controller 并保存...表单中未包含的任何属性值都会丢失。我确实理解为什么会发生这种情况,并且我知道有一些解决方案。

1)在保存时,从数据库加载实体,仅从模型中复制所需的属性,然后保存。

2)当表单启动时,加载实体并使用@SessionAttributes功能将其存储在请求之间的 session 中。

但我不喜欢其中任何一个。也许我错过了一些东西,但解决方案似乎相当简单。 在某个地方,默认的 Spring Web 绑定(bind)器正在创建实体的实例以将表单属性复制到其中。如果我可以覆盖它并使用 ID 从数据库加载持久实体,然后让 Spring 的绑定(bind)使用它作为目标实体(仅复制随表单提交的属性,而其他属性保持不变)...那么我认为这可以解决我的问题。

我一直在寻找如何/在哪里使用自定义 WebDataBinder 类。我不明白如何......而且我什至不确定这是否是我应该寻找的地方。

有什么建议吗?

谢谢!!

编辑:
我将给出一个假设的例子来尝试更好地解释我的问题。 假设我有一个实体类 Customer,它有 50 个属性。我有一张仅用于更新联系信息的表格。这只是 50 个属性中的 5 个。

街道
城市
状态
压缩
电话

如果我在 Spring 表单中执行此操作,当提交表单进行保存时,Spring 会创建一个新的“空白”实体,用表单中的值填充它并将其传递给我的 Controller ...这就是保存的内容。问题是,由于表单中未包含其他属性(例如,firstName、lastName、customerType 等),Spring 不理会它们,并且它们保持为 null。当我告诉 Hibernate 使用 Spring 提供的实体更新实体时,Hibernate 认为我希望firstName、lastName 等为空,因为这些是我在 bean 中提供的值。它不知道我只改变了其中的几个。
那么会发生什么呢?我的 50 处特性中有 45 处被吹走。

在下面的评论中,Sp00m 建议了一个可行的解决方案...将所有其他属性包含在隐藏字段中。但由于种种原因,这个解决方案让我非常头疼。

如果我能让 Spring 从数据库加载实体(而不是创建新的/空白实体),然后仅填充随表单提交的那些字段。我相信这会解决我的问题。

类似的讨论(但使用隐藏域解决方案)可以在这里找到.. http://www.coderanch.com/t/529490/Spring/Spring-MVC-Hibernate-Update-column

最佳答案

所以这是适合我的解决方案。 通过在 Controller 中添加以下带注释的方法,Spring 使用它来实例化实体以进行绑定(bind)。正是我所需要的。

(我之前确实尝试过这个,但是我没有在注释中指定模型属性名称,这显然是不好的。)

感谢所有提出评论和建议的人。

@ModelAttribute("entity")
public MyEntity getEntity(@RequestParam(required=false) Integer id)
{ 
    if (id == null)
    {
        return myEntityManager.createEntity(entityClass);
    }
    else
    {
        return myEntityManager.find(entityClass, id);
    }
}

关于java - 如何加载持久的 Hibernate 实体进行绑定(bind),以便非表单属性不会丢失?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23344346/

相关文章:

java - 文本文件解析上的数组 IndexOutOfBoundsException

java - Spring Framework中new关键字的作用

java - Hibernate 4 EntityManager CriteriaBuilder sortby 嵌套属性

java - Hibernate 应用程序作为 Azure 中的 WebJob "Could not open connection"异常

java - 为什么 id 字段不能在 EclipseLink 的 where 子句中使用

java - 使用spring boot使用gmail smtp发送邮件

java - JUnit 测试 IndexOutOfBoundsException

java - Android响应脚本问题

java - 使用 Spring Java 配置 Autowiring bean

SpringIntegration : Service-Activator not invoking method