Извлечение ленивого объекта OneToOne извлекает все остальные объекты OneToOne в пределах одного и того же объекта. - PullRequest
3 голосов
/ 09 июля 2019

Используя Entity entity = hibernateTemplate.get(Entity.class, id);, когда я нажимаю entity.getChild(), который является отношением OneToOne, все остальные отношения OneToOne также загружаются.Я использую hibernate 5.4.1-Final.

Я использую расширение байт-кода, как показано ниже:

<configuration>
    <failOnError>true</failOnError>
    <enableLazyInitialization>true</enableLazyInitialization>
    <enableDirtyTracking>false</enableDirtyTracking> 
    <enableAssociationManagement>true</enableAssociationManagement>
</configuration>

A.java

@Entity
@Table(name = "A")
public class A {

    @Id
    @Column(name = "ID_A")
    private String id;

    @OneToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "ID_A")
    @LazyToOne(LazyToOneOption.NO_PROXY)
    private B b;

    @OneToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "ID_A")
    @LazyToOne(LazyToOneOption.NO_PROXY)
    private C c;

...
getters/setters
...

B.java

@Entity
@Table(name = "B")
public class B {

    @Id
    @Column(name = "ID_A")
    private String id;

}

C.java

@Entity
@Table(name = "C")
public class C {

    @Id
    @Column(name = "ID_A")
    private String id;

}

Итак, когда я делаю

A a = hibernateTemplate.get(A.class, "100"); 
// triggers an Hibernate query only on A entity. The B and C aren't fetched => OK

// Hibernate: select a0_.ID_A as ID_A_27_0_ from A a0_ where a0_.ID_A=?

a.getB(); // ERROR : triggers two queries : one on C and one on B
// Hibernate: select c0_.ID_A as ID_A _26_0_ from C c0_ where c0_.ID_A =?
// Hibernate: select b0_.ID_A as ID_A _13_0_ from B b0_ where b0_.ID_A =?

Даже еслиЯ получаю B в HQLQuery, у меня все еще есть запрос к C:

Query<A> queryA = hibernateTemplate.createHQLQuery("from A a join fetch a.b where a.id=:id", A.class);
queryA.setParameter("id", "100");
A a = queryA.uniqueResult(); // triggers an inner join
// Hibernate: select a0_.as ID_A1_27_0_, b1_.ID_A as ID_A1_13_1_ from A a0_ inner join B b1_ on a0_.ID_A=b1_.ID_A where a0_.ID_A=? 
a.getB(); // KO -> triggers a query to select C !
// Hibernate: select c0_.ID_A as ID_A1_26_0_ from C c0_ where c0_.ID_A=?

Я попытался выполнить двойное сопоставление (OneToOne с указанным mappedBy) без успеха.PK B и C совпадают с A.

Я ожидаю, что a.getB(); не вызовет выборку C. Это ошибка в спящем режиме?Я не могу найти ничего относительно этого поведения в их документации.

Правильно ли мое отображение?

1 Ответ

1 голос
/ 15 июля 2019

Кажется, что он работает как задумано :) b и c принадлежат одной и той же "LazyGroup" по умолчанию. Если какой-либо из b или c должен быть загружен, вся группа будет.

Цитата из документации по байт-коду:

Ленивые атрибуты могут быть назначены для загрузки вместе, и это называется "ленивая группа". По умолчанию все особые атрибуты являются частью единая группа, что означает, что когда один ленивый исключительный атрибут Доступ ко всем ленивым исключительным атрибутам загружаются. Ленивое множественное число атрибуты, по умолчанию, сами по себе являются ленивой группой. это поведение явно контролируется через @ org.hibernate.annotations.LazyGroup аннотация.

Просто добавьте @LazyGroup("b") в поле b и @LazyGroup("c") в c, и оно должно работать как положено: b будет загружено только в getB(), anc c в getC().

Подробнее об этом здесь и здесь .

...