gpt4 book ai didi

java - Hibernate 验证从集合中删除的集合成员

转载 作者:行者123 更新时间:2023-12-01 11:41:10 24 4
gpt4 key购买 nike

我遇到了一个奇怪的现象。在简化形式中,我的实体类如下所示:

@Entity
@Audited
public class Product {

@Id
@Column(length = 32)
private String id = IdGenerator.createId();

/** Descriptive texts, samples, comments etc.; ONIX composite Product/OtherText */
@OneToMany(fetch=FetchType.LAZY, cascade=CascadeType.ALL, orphanRemoval=true)
@JoinColumn(name="product_id")
@Index(name="idx_prod_text")
private Set<Text> texts;

...
}

@Entity
@Audited
public class Text {

@Id
@Column(length = 32)
private String id = IdGenerator.createId();

@NotNull
@Column(nullable=false, length=3)
private String type;
...
}

HashCode 和 equals 在 id 字段上工作。我已经构建了一个通用的预验证例程,用于以用户友好的方式自动更正和生成警告。对空类型文本的自动更正是从产品的集合中删除此文本(通过调用 product.getTexts().removeAll(entitiesToRemove))。

现在我得到了一个产品(之前从数据库读取,因此附加到 Hibernate session ),它附加了一个类型为 null 的文本。它会自动更正,并且有问题的文本将从集合中删除,如上所述。到目前为止,一切都很好;在调试器中检查产品表明文本不再位于文本集合中。但是当我调用 productRepository.saveAndFlush(product) () 时,我得到了

javax.validation.ConstraintViolationException: Validation failed for classes [de.vlx.metadatastore.model.product.Text] during persist time for groups [javax.validation.groups.Default, ]
List of constraint violations:[
ConstraintViolationImpl{interpolatedMessage='darf nicht null sein', propertyPath=type, rootBeanClass=class de.vlx.metadatastore.model.product.Text, messageTemplate='{javax.validation.constraints.NotNull.message}'}
]

看来这段文字还是经过Hibernate验证的?即使它从未存在于数据库中(当然也有 NotNull 约束),并且不再存在于产品的文本集合中?

更奇怪的是:当我尝试通过在已删除实体的类型上设置虚拟值来修复此问题时,我没有得到上述异常,而是得到 org.springframework.dao.DataIntegrityViolationException提示 type 为 null。

到底是哪种魔法在起作用,我能做些什么来解决这个问题?

使用的版本: hibernate 4.1.7.FinalSpring-data-jpa 1.6.0.RELEASESpring-core 3.2.9.RELEASE

更新:通过密集调试,我最近发现(由于产品以多种方式交付,如 xml 和 excel 文件,并且与当前版本的合并是一个相当复杂的过程)在这种情况下,先前版本中的所有文本都将被删除,并且更新添加,然后在中央验证例程中删除错误文本。但是 Hibernate 已将添加存储在其操作队列中,并且希望在删除之前执行插入。并且插入内容与初始(空)值一起存储,因此更新有问题的文本没有帮助。

我仍然完全不知道该怎么办。看来我必须确保任何时候都没有无效对象可以进入任何集合,因为事后修复将无济于事。

最佳答案

看起来你有两个选择:

  • 确保文本未设置为 null 并保持“未修改”状态,然后仅删除该条目。
  • 或者在自动更正功能期间设置伪文本,实际上可以避免 NotNull 约束。

当然,第一种可能性更好,因为我不确定设置伪文本不会在删除语句之前触发更新语句。

更新:我看到了有关托管实体的问题的一些可能性(不需要这个,所以未经测试):

  • 使用 entityManager.refresh 刷新清理代码中的 Text 实体。这将导致选择问题,但应该避免该问题。
  • 也许您可以从当前 session 中使用evict?不知道hibernate在这里会如何 react 。
  • 最好避免使用中间 DTO 而不是实体来修改 Text 值,并将它们合并到您的服务方法中。我认为这将是我的首选解决方案。

关于java - Hibernate 验证从集合中删除的集合成员,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29514328/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com