java - 使用 hibernate @Version 控制进行 DTO 实体映射

标签 java hibernate jpa

我正在使用@Version注释在hibernate中提供版本控制。我的问题是关于数据从 DTO 到实体的正确映射。 我觉得正确的方法如下,但我想知道是否有更好的方法或者每个人都是这样做的。

  • 调用来找我的服务
  • 我加载要更新的实体(假设 AddressEntity 的版本 = 1)
  • 我将 AddressDTO 值映射到 AE,包括子集合(如果有)
  • 完成映射后,我分离实体 AE(仅在惰性子集合映射后才分离)
  • 现在我将版本从 DTO 映射到 AE(因为 hibernate 不允许更新托管实体中的版本)
  • 现在我调用 merge 来更新这个分离的 AE 实体

1)从语义和逻辑角度来说,这是正确的方式吗?

2)(有点脱离上下文) hibernate 合并已经在上下文中并托管的对象是否有开销,即我可以安全地使用合并来进行所有更新,无论托管/非托管还是仅合并+刷新用于非托管并刷新更新一些属性后进行管理?

最佳答案

让我尝试逐步回答您的问题:

  1. 假设您已加载 AddressEntity (having id=123 and version=1) 。设置属性值 AddressEntityAddreeDto包括idversion值(value)观。发送AddressDto到用户界面。
  2. AddresDto 进行的更改。已调用为您服务。创建 AddressEntity 的实例并设置 AddressDto 中的值包括idversion值(value)观。这个新AddressEntity现在已变成分离实例,因为它具有持久标识,但不能保证其状态与数据库状态同步。
  3. Hibernate 允许您重用此 Addressentity通过将实例与新的持久性管理器重新关联,可以将其重新关联到新事务中。可以通过调用 update() 将该分离的实例与新 session 重新关联。您不需要再次加载实体。update()方法强制更新数据库中对象的持久状态。

    设置 addressEntity属性:

    addressEntity.setId(dto.getId()); addressEntity.setVersion(dto.getVersion());

    附加addressEntity到新 session :

    交易 tx = sessionTwo.beginTransaction(); sessionTwo.update(addressEntity);

    tx.commit(); sessionTwo.close();

  4. session.update将执行类似于以下的 SQL:

    更新 ADDRESS_ENTITY 设置...,VERSION=2 其中 ID=123 且 VERSION=1

  5. 如果另一个应用程序事务在加载后更新了相同的 ADDRESS_ENTITY,则 VERSION 列将不包含值 1,并且该行将不会更新,并且您将收到 stale object state exception 。您可以捕获异常并通知用户有关过时数据的信息。

关于java - 使用 hibernate @Version 控制进行 DTO 实体映射,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18731516/

相关文章:

java - 查询同一项时未命中ehcache

java - JEE、eclipselink、glassfish4.0无法持久化实体

java - 为什么 Mutiny 调用方法会阻塞

java - 如何使用附加包扩展 BndTool 存储库?

java - Spring Maven 和 Tomcat 的 Hibernate 问题

java - 如何指定嵌入属性中的属性?

java - 填充 Filter 类中的 JSP 下拉列表

java - Android 套接字到 Java ServerSocket 连接

java - 无法在 Selenium Webdriver 中设置 cookie

mysql - 在 Hibernate JUnit 测试生成约束异常时遇到问题