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