Как использовать JPA - EntityGraph для загрузки только подмножества атрибутов лица @Basic? - PullRequest
0 голосов
/ 27 ноября 2018

Я нашел эту документацию о графах сущностей ... прочитав ее, я понял, что вы можете использовать графы сущностей для извлечения только подмножества @Basic полей данной сущности.(До сих пор я использовал графы сущностей для извлечения отношений EAGERLY, т.е., например, для загрузки Employee [включая все его атрибуты] и связанного с ним Отдела [включая все его атрибуты]) ...

ИтакЯ решил попробовать это с помощью небольшого теста:

@Entity
@Table(name = "employee")
@NamedEntityGraphs({
    @NamedEntityGraph(
        name = "OnlyName",
        attributeNodes = @NamedAttributeNode(value = "name")
    )
})
public class Employee implements Serializable {
    ...
    @Id
    @Column(name = "code", updatable = false)
    private Long code;

    @Basic(fetch = FetchType.LAZY)
    @Column(name = "name", nullable = false)
    private String name;

    @Basic(fetch = FetchType.LAZY)
    @Column(name = "last_name", nullable = false)
    private String lastName;

    @Lob @Basic(fetch = FetchType.LAZY)
    @Column(name = "picture", nullable = false)
    private byte[] picture;

    public Employee() {
       super();
    }
    ...
}

Затем, чтобы получить мою сущность, я использовал следующий код:

    private Employee retrieveFromDatabase(long code) {
        EntityGraph<Employee> graph;                // Material Entity Graph

        Map<String, Object> map = new HashMap<>();

        graph = (EntityGraph<Employee>) this.em.createEntityGraph("OnlyName");
        map.put("javax.persistence.fetchgraph", graph);


        return this.em.find(Employee.class, code, map);
    }

Теперь этот код всегда возвращает сотрудникасо всеми полями, извлеченными из базы данных;даже журналы Hibernate показывают запрос, который выбирает все поля сотрудников:

Hibernate: select employee0_.code as code1_0_0_, employee0_.last_name as last_name2_0_0_, employee0_.name as name3_0_0_, employee0_.picture as picture4_0_0_ from employee employee0_ where employee0_.code=? )

Когда я ожидал такой запрос: select employee0_.code as code1_0_0_, mployee0_.name as name3_0_0_ from employee employee0_ where employee0_.code=?

Итак, чтоЯ делаю не так?Разве эта функция не поддерживается Hibernate ??

ПРИМЕЧАНИЕ: Для теста я использовал hibernate 5.0.10 и wildfly10 ...

Спасибо!

1 Ответ

0 голосов
/ 23 декабря 2018

На самом деле, вы не делаете ничего плохого.Тем не менее, вам не хватает важной информации из Hibernate ORM User Guide (v5.0.x) .В разделе 2.3.2 мы находим его:

fetch - FetchType (по умолчанию EAGER)

Определяет, должен ли этот атрибут извлекаться с нетерпением или лениво.JPA говорит, что EAGER является требованием к провайдеру (Hibernate), чтобы значение выбиралось при получении владельца, в то время как LAZY - просто подсказка, что значение выбирается при обращении к атрибуту. Hibernate игнорирует этот параметр для основных типов , если вы не используете расширение байт-кода.См. BytecodeEnhancement для получения дополнительной информации о получении и улучшении байт-кода.

Итак: несмотря на то, что вы даете подсказку к методу em.find(..), дело за JPAПоставщик - здесь: Hibernate - чтобы решить, будут ли основные атрибуты загружены с нетерпением или нет.В вашем случае сущность Employee содержит только атрибуты @Basic.

Для справки, а также для большего контекста и более подробного объяснения см. Также это руководство .Он охватывает различия между подсказками запросов "javax.persistence.fetchgraph" и "javax.persistence.loadgraph" и содержит пример кода, который демонстрирует вышеупомянутое поведение для поставщика сохраняемости JPA Hibernate.

Примечания: я проверил ..

  • .. Руководства пользователя Hibernate ORM 5.1 , 5.2 и 5.3 : все версии содержат одно и то же утверждение в политике по умолчанию для игнорирования основных атрибутов.
  • .. официальный документ спецификации JPA 2.1 .На странице 117 (PDF) в разделе 3.7.4 мы находим:

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

Последняя цитата из спецификации JPA подтверждает Руководство пользователя ORM , что это нормально для такой реализации.

Мой совет :

Посмотрите на BytecodeEnhancement , как указано в Руководстве пользователя Hibernate ORM (см. Выше).

Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...