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, такой проблемы нет.
Я изменил это, чтобы сделать следующее вместо этого:
- а) Получить новый объект через поиск по идентификатору удаленного объекта.
- б) Удалить этот новый объект.
И вот, это решило проблему! (Я был бы признателен за любые комментарии о том, что то, что я сделал, было совершенно неправильно и приведет к проблемам в будущем, но на данный момент это работает.)