JPA 对于从集合中删除的项目返回 null

发布于 2024-08-31 08:43:09 字数 1878 浏览 7 评论 0原文

这可能与我几天前的问题有关,但我什至不知道如何解释这部分。 (这是一种完全不同的父子关系。)

在我的界面中,我有一组属性 (Attribute) 和一对多关系中每个属性的有效值 (ValidValue)。在 Spring MVC 前端,我有一个页面供管理员编辑这些值。提交后,如果这些字段中的任何一个(作为 标签)为空,我将像这样删除 ValidValue 对象:

Set<ValidValue> existingValues = new HashSet<ValidValue>(attribute.getValidValues());
Set<ValidValue> finalValues = new HashSet<ValidValue>();
for(ValidValue validValue : attribute.getValidValues()) {
    if(!validValue.getValue().isEmpty()) {
        finalValues.add(validValue);
    }
}

existingValues.removeAll(finalValues);
for(ValidValue removedValue : existingValues) {
    getApplicationDataService().removeValidValue(removedValue);
}
attribute.setValidValues(finalValues);
getApplicationDataService().modifyAttribute(attribute);

问题是,虽然数据库已适当更新,但下次我查询 Attribute 对象时,它们返回时,其 ValidValue 集中有一个额外的条目 - null,因此,下次我迭代要显示的值时,它会在中间显示一个额外的空白值。我已经确认这种情况发生在合并或查找时,在“执行查询 ReadObjectQuery(entity.Attribute)”时。

代码(在 ApplicationDataService 中):

public void modifyAttribute(Attribute attribute) {
    getJpaTemplate().merge(attribute);
}

public void removeValidValue(ValidValue removedValue) {
    ValidValue merged = getJpaTemplate().merge(removedValue);
    getJpaTemplate().remove(merged);
}

这是我用来修改数据库的 实体类的相关部分:

Entity
@Table(name = "attribute")
public class Attribute {
    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "attribute")
    private Set<ValidValue> validValues = new HashSet<ValidValue>(0);
}

@Entity
@Table(name = "valid_value")
public class ValidValue {
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "attr_id", nullable = false)
    private Attribute attribute;
}

This may be related to my question from a few days ago, but I'm not even sure how to explain this part. (It's an entirely different parent-child relationship.)

In my interface, I have a set of attributes (Attribute) and valid values (ValidValue) for each one in a one-to-many relationship. In the Spring MVC frontend, I have a page for an administrator to edit these values. Once it's submitted, if any of these fields (as <input> tags) are blank, I remove the ValidValue object like so:

Set<ValidValue> existingValues = new HashSet<ValidValue>(attribute.getValidValues());
Set<ValidValue> finalValues = new HashSet<ValidValue>();
for(ValidValue validValue : attribute.getValidValues()) {
    if(!validValue.getValue().isEmpty()) {
        finalValues.add(validValue);
    }
}

existingValues.removeAll(finalValues);
for(ValidValue removedValue : existingValues) {
    getApplicationDataService().removeValidValue(removedValue);
}
attribute.setValidValues(finalValues);
getApplicationDataService().modifyAttribute(attribute);

The problem is that while the database is updated appropriately, the next time I query for the Attribute objects, they're returned with an extra entry in their ValidValue set -- a null, and thus, the next time I iterate through the values to display, it shows an extra blank value in the middle. I've confirmed that this happens at the point of a merge or find, at the point of "Execute query ReadObjectQuery(entity.Attribute).

Here's the code I'm using to modify the database (in the ApplicationDataService):

public void modifyAttribute(Attribute attribute) {
    getJpaTemplate().merge(attribute);
}

public void removeValidValue(ValidValue removedValue) {
    ValidValue merged = getJpaTemplate().merge(removedValue);
    getJpaTemplate().remove(merged);
}

Here are the relevant parts of the entity classes:

Entity
@Table(name = "attribute")
public class Attribute {
    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "attribute")
    private Set<ValidValue> validValues = new HashSet<ValidValue>(0);
}

@Entity
@Table(name = "valid_value")
public class ValidValue {
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "attr_id", nullable = false)
    private Attribute attribute;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

梦回旧景 2024-09-07 08:43:09

通过数小时的随机实验修复了另一个 JPA 问题。希望这能帮助其他人解决同样的问题。

显然,问题是我试图删除修改后的对象。本质上,我所做的就是让 Spring 表单直接修改 ValidValue 对象,然后进行迭代以抛出任何修改为“”(空字符串)值的对象。

一旦到达数据管理器,我尝试分两步删除:

  • a)合并,向数据库中的对象发送更新,将值设置为“”。
  • b) 删除发送删除的合并对象。

在这个序列中,下次我获取 Attribute 对象时,由于某种原因,集合中有一个额外的 null 值。如果我得到所有 ValidValue 对象,就没有这样的问题。

我将其更改为执行以下操作:

  • a) 通过查找已删除对象的 ID 来获取新对象。
  • b) 删除该新对象。

你瞧,这解决了问题! (如果有人评论我的做法是完全错误的,并且会导致以后出现问题,我将不胜感激,但就目前而言,它是有效的。)

Another JPA issue fixed by hours of random experimentation. Hopefully this will help someone else with the same kind of issue.

The problem, apparently, was that I was trying to remove the modified object. Essentially, what I was doing was letting the Spring form modify the ValidValue objects directly, and then iterating through to throw out any that were modified to a value of "" (empty string).

Once that got to the data manager, I tried to remove in two steps:

  • a) Merge, which sent an update to the object in the database, setting the value to "".
  • b) Remove the merged object, which sent the delete.

In this sequence, the next time I got the Attribute object, for some reason, there was an extra null value in the set. If I got all ValidValue objects, no such issue.

I changed it to do the following instead:

  • a) Get a new object through a find on the ID of the removed object.
  • b) Remove that new object.

Lo and behold, that solved the issue! (I'd appreciate any comments about how what I did was entirely wrong and will lead to issues down the road, but for now, it works.)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文