EntityManager.find не может найти объект, но использование Критериев, которые делает API

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

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

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

... и вот код, я использую с Критериями 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 пустой указатель возвратов, но Критерии находят Пользователя? Я попробовал эти два альтернативных метода в том же самом месте в программе.

Вот соответствующие части Пользовательского объекта:

@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;
    }
    ...
}
7
задан Pascal Thivent 9 October 2010 в 16:46
поделиться

5 ответов

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

11
ответ дан 6 December 2019 в 10:47
поделиться

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

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

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

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

3
ответ дан 6 December 2019 в 10:47
поделиться

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

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

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

1
ответ дан 6 December 2019 в 10:47
поделиться

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

0
ответ дан 6 December 2019 в 10:47
поделиться

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

Если его нет в базе данных, убедитесь, что диспетчер сущностей был сброшен или текущая транзакция была зафиксирована.

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

0
ответ дан 6 December 2019 в 10:47
поделиться
Другие вопросы по тегам:

Похожие вопросы: