JPA возвращает ноль для удаленных элементов из набора - PullRequest
0 голосов
/ 02 мая 2010

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

В моем интерфейсе у меня есть набор атрибутов (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 Ответ

0 голосов
/ 02 мая 2010

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

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

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

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

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

Я изменил его, сделав следующее:

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

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

...