У меня следующие отношения:
@Entity
public class SomeEntity {
//...
@EmbeddedId
private SomeEntityIdentity id;
@OneToOne
@NotFound(action = NotFoundAction.EXCEPTION) //This is the important bit
@JoinColumns({
//...
})
private OtherEntity example;
//...
}
Затем я использую данные Spring findOne(), чтобы захватить мою сущность по идентификатору:
SomeEntityIdentity id = new SomeEntityIdentity();
id.setAttribute1(1);
id.setAttribute2(new BigDecimal(123));
return this.someEntityRepository.findOne(id);
Проблема в том, что исключение не генерируется, если OtherEntity не найден, поскольку findOne() просто возвращает null. Даже если я установил @OneToOne(optional = false), я все равно получаю ноль от findOne(), когда я исключал только OtherEntity как нуль.
Я считаю, что должно быть создано исключение. Есть ли у кого-нибудь идеи?
Спасибо!
Редактировать: Классы идентификации и репозитория ниже.
@Embeddable
public class SomeEntityIdentity implements Serializable {
private int attribute1;
private BigDecimal attribute2;
public void setAttribute1(int attribute1) {
this.attribute1 = attribute1;
}
public void setAttribute2(BigDecimal attribute2) {
this.attribute2 = attribute2;
}
}
public interface SomeEntityRepository extends JpaRepository<SomeEntity, SomeEntityIdentity> {
}
Вы уверены, что объект с данным идентификатором существует? Выложите пожалуйста SomeEntityIdentity. @EmbeddedId предполагает, что идентификатор состоит из более чем одного свойства, но вы устанавливаете только одно свойство на id перед вызовом findOne.
@Matt, SomeEntity существует в базе данных, я взял SQL из журналов отладки спящего режима и подтвердил, что запись возвращена. Объект, которого нет в базе данных, - это OtherEntity.
@crizzis, что касается идентичности, это был просто пример, поскольку я не могу раскрыть фактические имена полей. Я обновил свой вопрос, чтобы отразить фактический код, который у меня есть, с измененными только именами. Я на 100% уверен, что запись SomeEntity существует, спящий режим выполняет левое внешнее соединение, и запрос возвращает результат, если я выполняю его в клиенте SQL.
Работает ли получение SomeEntity при наличии OtherEntity? Просто дикий выстрел, но может ли здесь BigDecimal виноват? Можно ли вместо этого использовать BigInteger (или Long) в вашем случае? Я предполагаю, что new BigDecimal(123) по какой-то причине не равен В самом деле значению db
Попробуйте использовать getOne() вместо findOne(). Вероятно проблема в том, что findOne() возвращает Optional.empty()
Исключение будет выдано только в том случае, если другой объект не найден в ассоциации.
Спасибо всем, кто внес свой вклад! В конечном итоге это были несовместимые версии между Spring и Hibernate.




Оказалось несовместимость версий Hibernate и Spring Data.
В этом проекте использовался Hibernate 4.3.1.Final для использования преимуществ JPA 2.1; но с spring-data-jpa1.6.6.RELEASE, он не поддерживает эту версию Hibernate.
Поскольку все работало правильно (до этой проблемы), я сначала этого не заметил. Когда я попытался обновить spring-data-jpa до версии, совместимой с Hibernate 4.3, я не смог, потому что spring-data-jpa переходит из Hibernate 3 в Hibernate 5 в версиях 2.0.x. Для этого также, кажется, требуется Java 8, так что мне это не подходило.
Завершился переход на Hibernate 3.6.10.Final, и все стало работать нормально.
TL; DR: Всегда проверяйте совместимость версий между Spring и другими библиотеками, даже если нет очевидных ошибок.
Я просто хотел закончить, сказав, что управление версиями Spring - это настоящая боль.
Конфигурация рабочей зависимости:
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>3.6.10.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>3.6.10.Final</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>1.6.6.RELEASE</version>
</dependency>
Я получаю ту же ошибку в спящем режиме 5.4.12.Final. Я пробовал перейти на «3.6.10.Final», как и вы, но теперь вместо этого он всегда выдает исключение, независимо от значения, которое я предоставляю для @NotFound.
Хм, а разве он не работает корректно? Когда
findOne()не возвращает экземплярSomeEntity, аннотация@NotFoundв любом случае никогда не обрабатывается. Я должен сказать, что никогда не использовал эту конструкцию, но я бы так понял ваш случай.