Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/357.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何让Hibernate在不将整个图更新到数据库的情况下识别对对象图所做的更改_Java_Hibernate_Jpa - Fatal编程技术网

Java 如何让Hibernate在不将整个图更新到数据库的情况下识别对对象图所做的更改

Java 如何让Hibernate在不将整个图更新到数据库的情况下识别对对象图所做的更改,java,hibernate,jpa,Java,Hibernate,Jpa,我甚至不知道如何用谷歌搜索这个问题,所以如果这是一个常见的问题,请告诉我答案 问题的一般描述是,一个或多个父记录具有一组“Document”类型的子记录。对象图实际上比这更深更复杂,但这些是我的问题的相关部分 通常,当用户点击Save时,我们使用merge()更新整个对象图。但是我们需要保存文档记录…并且在文档上单击“添加”或“删除”时只保存文档记录。他们可以根据自己的需要进行任意数量的添加/删除。没有即时更新,因此,当他们想要更新描述时,这会发生在“Save”上 即时更新工作正常。问题是,在以

我甚至不知道如何用谷歌搜索这个问题,所以如果这是一个常见的问题,请告诉我答案

问题的一般描述是,一个或多个父记录具有一组“Document”类型的子记录。对象图实际上比这更深更复杂,但这些是我的问题的相关部分

通常,当用户点击Save时,我们使用merge()更新整个对象图。但是我们需要保存文档记录…并且在文档上单击“添加”或“删除”时只保存文档记录。他们可以根据自己的需要进行任意数量的添加/删除。没有即时更新,因此,当他们想要更新描述时,这会发生在“Save”上

即时更新工作正常。问题是,在以后的请求中,用户点击“保存”,从而更新父记录和子记录,如果在这个过程中有删除,我会得到javax.persistence.EntityNotFoundException,尽管我确实从其父记录集中删除了对象

在删除时,我做了以下操作:

    item.getDocuments().remove(document);
    documentService.deleteDocumentByID(document.getId());
第一行将它从父记录中删除,我想这会通知hibernate不要因为我在下一行中删除它而惊慌失措,就像我在该ID上运行HQL“delete”时一样

然后,在Save中,它基本上只是整个对象图上的一个“merge()”


有没有办法让Hibernate同意我在merge()之外添加/删除该文档?请注意,我不想将整个对象图保存在文档add/remove上。只有文档记录。

使用
merge
时,该对象的所有基本属性以及具有
CascadeType.merge
的所有关联都将刷新到数据库中。因此,为了更改刷新的内容,您需要正确配置它

如果由于有多个用例而需要不同的更新/刷新图,则必须提出不同的解决方案,即可能引入DTO并将更改从DTO应用到托管实体,而不是使用
合并

如果您还想避免所有不必要的select语句用于状态同步,我建议您看看它提供了什么

您可以创建一个可更新的实体视图,该视图仅用于更新文档集合

@EntityView(Item.class)
@UpdatableEntityView
public interface ItemUpdateView {
  @IdMapping
  Integer getId();
  @UpdatableMapping
  Set<DocumentView> getDocuments();
}
@EntityView(Document.class)
public interface DocumentView {
  @IdMapping
  Integer getId();
  String getName();
}
刷新更改可以这样做:

entityViewManager.save(entityManager, dto);

您将看到,它只会刷新真正更改的内容,而不必执行select语句,这会破坏它的脏跟踪功能。

当您使用
merge
时,该对象的所有基本属性以及所有具有
级联类型的关联。merge
将刷新到数据库中。因此,为了更改刷新的内容,您需要正确配置它

如果由于有多个用例而需要不同的更新/刷新图,则必须提出不同的解决方案,即可能引入DTO并将更改从DTO应用到托管实体,而不是使用
合并

如果您还想避免所有不必要的select语句用于状态同步,我建议您看看它提供了什么

您可以创建一个可更新的实体视图,该视图仅用于更新文档集合

@EntityView(Item.class)
@UpdatableEntityView
public interface ItemUpdateView {
  @IdMapping
  Integer getId();
  @UpdatableMapping
  Set<DocumentView> getDocuments();
}
@EntityView(Document.class)
public interface DocumentView {
  @IdMapping
  Integer getId();
  String getName();
}
刷新更改可以这样做:

entityViewManager.save(entityManager, dto);

您将看到,它只会刷新真正更改的内容,而不必执行select语句,这会破坏它的脏跟踪功能。

我知道在删除后,您仍在使用
对象,对吗?如果是这样,您是否绝对确定
item.getDocuments().remove(document)
有效?您是否通过调试验证它是否返回
true
?@crizzis-我调试后发现该项已从集合中删除,删除DocumentById后,该文档也从数据库中丢失。我知道删除后,您仍在使用
对象,对吗?如果是这样,您是否绝对确定
item.getDocuments().remove(document)
有效?您是否通过调试验证它是否返回
true
?@crizzis-我调试后发现该项已从集合中删除,删除DocumentById后,该文档也从数据库中丢失。