JPA возвращает ноль для удаленных элементов из набора

Это может быть связано с моим вопросом несколько дней назад, но я даже не знаю, как объяснить эту часть. (Это совершенно разные отношения родитель-ребенок.)

В моем интерфейсе у меня есть набор атрибутов (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 - нулем, и, таким образом, в следующий раз, когда я перебираю значения в дисплей, он показывает дополнительное пустое значение в середине. Я подтвердил, что это происходит в момент слияния или поиска, в точке "Выполнить запрос 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;
}

1 ответ

Другая проблема JPA, исправленная часами случайных экспериментов. Надеюсь, это поможет кому-то еще с такой же проблемой.

Проблема, по-видимому, заключалась в том, что я пытался удалить измененный объект. По сути, я делал так, чтобы форма Spring напрямую изменяла объекты ValidValue, а затем выполняла итерацию, чтобы выбрасывать любые, которые были изменены до значения "" (пустая строка).

Как только это попало в диспетчер данных, я попытался удалить в два этапа:

  • а) Слияние, которое отправило обновление объекта в базу данных, установив значение "".
  • б) Удалить слитый объект, с которого отправлено удаление.

В этой последовательности в следующий раз, когда я получил объект Attribute, по какой-то причине в наборе было дополнительное нулевое значение. Если я получил все объекты ValidValue, такой проблемы нет.

Я изменил это, чтобы сделать следующее вместо этого:

  • а) Получить новый объект через поиск по идентификатору удаленного объекта.
  • б) Удалить этот новый объект.

И вот, это решило проблему! (Я был бы признателен за любые комментарии о том, что то, что я сделал, было совершенно неправильно и приведет к проблемам в будущем, но на данный момент это работает.)

Другие вопросы по тегам