Сводка (код ниже)
У меня есть объект ProcessInstance с отношением ManyToOne с объектом ExpectedBusinessTimestamp.В контроллере я загружаю ProcessInstance (в том числе ExpectedBusinessTimestamp), изменяю поле и затем сохраняю ProcessInstance.
Операция сохранения завершается неудачно с NullPointerException в методе сравнения ToTexpectedBusinessTimestamp, потому что левый объект ( этот объект в CompareTo) не был загружен должным образом.Объект this не равен NULL, но заполнен только его идентификатор, все остальные поля имеют значение NULL.
Я думаю, что по какой-то причине во время сохранения ProcessInstanceперезагружается из базы данных, но по какой-то причине не загружает с ним ExpectedBusinessTimestamp, даже если для FetchType явно задано значение EAGER.Когда операция сохранения затем сравнивает сохраненный ProcessInstance с тем, который находится в памяти, в какой-то момент сравниваются ExpectedBusinessTimestamps, но тот из базы данных не загружается, что приводит к исключению NullPointerException.
Код: ProcessInstance
@Entity
public class ProcessInstance{
@ManyToOne
private ExpectedBusinessTimestamp expectedBusinessTimestamp;
public ExpectedBusinessTimestamp getExpectedBusinessTimestamp() {
return expectedBusinessTimestamp;
}
public void setExpectedBusinessTimestamp(ExpectedBusinessTimestamp expectedBusinessTimestamp){
this.expectedBusinessTimestamp = expectedBusinessTimestamp;
}
}
Код: ExpectedBusinessTimestamp
@Entity
public class ExpectedBusinessTimestamp {
@OneToMany(mappedBy = "expectedBusinessTimestamp")
List<ProcessInstance> processInstances;
public List<ProcessInstance> getProcessInstances(){ return processInstances; }
}
Код: контроллер
ProcessInstance previousInstance = processInstanceRepository.findPrevious(
processDefinition, expectedBusinessTimestamp);
previousInstance.setLatestVersion(false);
processInstanceRepository.save(previousInstance);
Подробнее
Классы кода, конечно, немного сложнее, чем показано, но я не хотел вставлять здесь весь код.Если что-то релевантное отсутствует, пожалуйста, дайте мне знать.
Отладка позволила мне подтвердить:
- В хранилище есть AutoWired in.
- Загружен предыдущий экземпляр (включая ExpectedBusinessTimestamp)
- При сохранении сущность загружается из базы данных (это глубоко в стеке вызовов, спящий режим jpa и т. д., а не в моем коде).
- При сохранении сравниватьExpectBusinessTimestamp неоднократно вызывается.В одном из этих случаев, ExpectedBusinessTimestamp имеет только заполненный Id, все остальные поля являются пустыми.При сравнении этих полей выдается исключение NullPointerException.