EntityManager.find не удается найти объект, но использование Criteria API позволяет

StackOverflow https://stackoverflow.com/questions/3205256

Вопрос

Я столкнулся с довольно странным случаем в Java EE 6, где с помощью JPA EntityManager find метод вместе с основным идентификатором объекта возвращает null, но использование Criteria API для выбора всех объектов с этим идентификатором работает нормально.

Вот код, который я использую для find:

// Always returns null, even for records I know for sure are in there.
user = em.find(User.class, userId);

...и вот код, который я использую с Criteria API:

CriteriaBuilder builder = em.getCriteriaBuilder();
CriteriaQuery<User> criteria = builder.createQuery(User.class);
Root<User> u = criteria.from(User.class);
TypedQuery<User> query = em.createQuery(
    criteria.select(u).where(builder.equal(u.get("id"), userId)));
user = query.getSingleResult();

Есть идеи, почему find возвращает null, но критерии находят пользователя?Я попробовал эти два альтернативных метода в одном и том же месте программы.

Вот соответствующие части объекта User:

@Entity
@Table(name = "USERS")
@Access(AccessType.PROPERTY)
public class User implements Serializable {
    ...
    private Long id;
    ...
    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "user_id_generator")
    @SequenceGenerator(name = "user_id_generator", sequenceName = "user_sequence", allocationSize = 1)
    @Column(name="id")
    public Long getId() {
        return this.id;
    }

    public void setId(Long id) {
        this.id = id;
    }
    ...
}
Это было полезно?

Решение

Я выяснил проблему.Это было связано с полем в базе данных, будучи генеракодицетагкодом, где ему не должно быть разрешено.Это было связано со мной редактирование его вручную.После того, как я добавил значение для этого поля, проблема ушла.

Другие советы

Какой поставщик вы используете?

Где вы выполняете эту находку, в или вне транзакции?Вы промываете и очищаете их до поиска?

Использование ECLIPSELINK в качестве провайдера, а моя собственная подобная модель, я не могу воспроизвести это.

Предполагая, что ваш провайдер может войти в систему SQL, вы видите SQL, иду на DB на Find?Как выглядит SQL, и он выполняется правильно в SQL Plus etc ...

Я подтверждаю это решение.То же самое случилось и со мной.У меня были столбцы , помеченные как NOT NULL, затем во время тестирования в моем приложении я отключил ограничение в базе данных для двух столбцов (внешних ключей), однако не изменил (optional = false) атрибут @ManyToOne отношение в моем классе сущностей.После удаления атрибута, чтобы модель соответствовала базе данных, все начало работать нормально.Странно, что среда не выдает какого-либо предупреждения или исключения.

Дважды проверьте, что вы передаете генеракодицетагкод в следующем фрагменте:

// Always returns null, even for records I know for sure are in there.
user = em.find(User.class, userId);
.

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

Одна из причин может быть, что поле «ID» не было правильно помечено как идентификатор для объекта пользователя.

В качестве здравоохранения проверьте ваш код, находящее время, прежде чем выполнить поиск, чтобы самостоятельно выполнить ручное запрос на базе данных, чтобы убедиться, что соответствующая запись пользователя присутствует с ожидаемым идентификатором.

Если это не в базе данных, убедитесь, что менеджер объекта был покрасен, или текущая транзакция была совершена.

Например, если вы используете Hibernate в качестве провайдера, возможно, что объект «сохраняется» просто в кэше, и изменения на самом деле не были нажаты в базу данных.Соответственно, критерии, проходящиеся через реализацию Hibernate, получат объект, но INTER Manager Find не сможет найти объект.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top