Необязательное отношение OneToOne в Hibernate - PullRequest
2 голосов
/ 14 января 2020

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

@Entity
@Data
@Table(name = "A")
public class Country {
    @Id
    private UUID id;
    private String someCommon;

    @PrimaryKeyJoinColumn
    @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
    private B details;
}
@Entity
@Data
@Table(name = "B")
public class B {

    @Id
    private UUID id;

    private String someDetail;
}

Выборка данных работает нормально, за исключением того, что когда класс B не найден для некоторого экземпляра A, Hibernate делает дополнительный запрос для этого указанного c экземпляра для получения сведений о AIe в журналах. Это следующие выполненные запросы:

select a0_.id as id1_0_0_, b1_.id as id1_1_1_, a0_.some_common as some_common2_0_0_, b1_.some_detail as some_detail_2_1_1_ from a a0_ left outer join b b1_ on a0_.id=b1_.id

select b0_.id as id1_1_0_, b0_.some_detail as some_detail_2_1_0_ from b b0_ where b0_.id=?

Где во втором запросе в качестве идентификатора устанавливается идентификатор экземпляра, который выполняет не имеют подробностей.

Таким образом, похоже, что Hibernate не поддерживает необязательные отношения OneToOne эффективным способом. Любые идеи о том, как заставить Hibernate не выполнять второй запрос, а просто принять детали, являются нулевыми?

1 Ответ

1 голос
/ 14 января 2020

Нет способа избавиться от второго запроса, как вы упомянули в hibernate, потому что, если связь необязательна, Hibernate не может узнать, существует ли адрес для данного человека, не выполняя запрос. Самое близкое, что вы можете сделать, это вызвать второй запрос только тогда, когда он предназначен:

Чтобы избежать второго запроса, вы должны выбрать Ленивая загрузка :

Кому Сделайте это, измените ваше сопоставление, чтобы установить необязательное значение false, и отложенная загрузка будет включена для деталей:

@OneToOne(cascade = CascadeType.ALL,  optional = false, fetch = FetchType.LAZY)
private B details;

Ленивая загрузка гарантирует, что детали будут выбраны только тогда, когда это запланировано.

...