Спящий ленивый объект без отношений

У меня есть объект Hibernate следующим образом:

@Entity
@Table(name="SOME_TABLE")
public class SomeEntity {

private Long id;
private String someInfo;

@Id
@Column(name = "ID")
public Long getId() {
    return id;
}

public void setId(Long id) {
    this.id = id;
}

@Column(name = "SOME_INFO")
public String getSomeInfo() {
    return someInfo;
}

public void setSomeInfo(String someInfo) {
    this.someInfo = someInfo;
}
}

При загрузке объекта с помощью следующего кода:

sessionFactory.getCurrentSession().load(getEntityClass(), id);

Поля объекта не загружаются, вместо этого возвращается прокси-объект, а фактические поля загружаются только тогда, когда я явно вызываю их с помощью их метода получения. Насколько мне известно, простые поля (примитивы, строки) должны загружаться с готовностью. Почему поля, которые не являются отношениями или коллекциями, загружаются лениво? есть ли способ попросить Hibernate загрузить их с нетерпением? Это проблематично для меня, поскольку я использую этот объект в качестве возвращаемого значения приложения Spring REST, а затем получаю исключение could not initialize proxy - no Session.


person zuckermanori    schedule 31.01.2017    source источник
comment
afaik, спящий режим по умолчанию загружает свойства с нетерпением. Это поведение можно изменить с помощью улучшения байт-кода. Может быть, это как-то установлено по умолчанию в вашем проекте? проверьте этот ответ, чтобы включить ленивую загрузку свойств .com/questions/19610085/.   -  person Mustafa    schedule 31.01.2017
comment
Нет, мое приложение не настраивает улучшение байт-кода   -  person zuckermanori    schedule 31.01.2017


Ответы (1)


Причина, по которой вы получаете прокси, заключается в том, что контракту Session#load разрешено возвращать прокси в качестве заполнителя, даже не запрашивая базу данных для указанного объекта. Вот почему так важно, чтобы предоставленный идентификатор, для которого вы хотите загрузить, существовал, так как позже вы столкнетесь с непредвиденными ошибками ObjectNotFoundException, если это так.

То, что вы хотите использовать, это Session#get, который гарантированно будет запрашивать базу данных и не будет возвращать прокси, поэтому упомянутые вами базовые атрибуты будут загружены с готовностью, как вы и ожидали.

Например:

final Comment comment = new Comment( "This is a comment" );
comment.setOwner( session.load( Product.class, productId ) );
session.save( comment );

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

person Naros    schedule 31.01.2017
comment
Спасибо @Naros, это то, что я пропустил - person zuckermanori; 31.01.2017