Вопрос по java – Как я могу получить доступ к загруженным ленивым полям после закрытия сеанса, используя спящий режим?

8

рассмотрим этот сценарий:

I have loaded a Parent entity through hibernate Parent contains a collection of Children which is large and lazy loaded The hibernate session is closed after this initial load while the user views the Parent data The user may choose to view the contents of the lazy Children collection I now wish to load that collection

Какие способы / лучший способ загрузки этой коллекции?

Assume session-in-view is not an option as the fetching of the Children collection would only happen after the user has viewed the Parent and decided to view the Children. This is a service which will be accessed remotely by web and desktop based client.

Благодарю.

Ваш Ответ

3   ответа
7

(parent.getCollection ()) за исключением того, что родительский объект должен быть присоединен к активному сеансу.

Это решение берет родительский объект и имя лениво загруженного поля и возвращает объект с полностью загруженным набором.

К сожалению, так как родитель должен быть присоединен к недавно открытому сеансу, я не могу использовать ссылку на отложенную коллекцию, поскольку это будет ссылаться на отдельную версию сущности; отсюда fieldName и отражение. По той же причине, это должно вернуть присоединенный родительский объект.

Таким образом, в сценарии OP этот вызов может быть сделан, когда пользователь выбирает просмотр отложенной коллекции:

Parent parentWithChildren = dao.initialize(parent,"lazyCollectionName");

Метод:

public Entity initialize(Entity detachedParent,String fieldName) {
    // ...open a hibernate session...
    // reattaches parent to session
    Entity reattachedParent = (Entity) session.merge(detachedParent); 

    // get the field from the entity and initialize it
    Field fieldToInitialize = detachedParent.getClass().getDeclaredField(fieldName);
    fieldToInitialize.setAccessible(true);
    Object objectToInitialize = fieldToInitialize.get(reattachedParent);

    Hibernate.initialize(objectToInitialize);
    return reattachedParent;
}
0

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

public Parent loadParentWithIntent1(Long parentId)
{
  Parent parent = loadParentFromDAO();

  for (Child c : parent.getChildren())
  {
    c.getField1();
  }
}

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

Error: User Rate Limit Exceeded Paul Adamson
3

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

Почему бы не попробовать открыть новую сессию и получить детей от их родителей? Что-то вроде ...

criteria = session.createCriteria(Child.class);
criteria.add(Restrictions.eq("parent", parent));
List<Child> children = criteria.list();
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded Paul Adamson

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