Comment puis-je accéder aux champs chargés paresseux après la session a fermé, à l'aide mise en veille prolongée?

StackOverflow https://stackoverflow.com/questions/1069310

  •  21-08-2019
  •  | 
  •  

Question

envisager ce scénario:

  • Je l'ai chargé une entité mère par mise en veille prolongée
  • Parent contient une collection d'enfants qui est grand et paresseux chargé
  • La séance de mise en veille prolongée est fermée après cette charge initiale alors que l'utilisateur visualise les données parent
  • L'utilisateur peut choisir d'afficher le contenu de la collection enfants paresseux
  • Je voudrais maintenant charger cette collection

Quels sont les moyens / meilleure façon de le chargement de cette collection?

  • On suppose session en vue n'est pas une option que l'extraction de la collection Les enfants ne se produirait après que l'utilisateur a vu le parent et a décidé de voir les enfants.
  • Ceci est un service qui sera accessible à distance par le client sur le Web et de bureau.

Merci.

Était-ce utile?

La solution

Je fais des suppositions sur ce que l'utilisateur regarde, mais il semble que vous voulez seulement récupérer les enfants si l'utilisateur a déjà vu le parent et veut vraiment voir les enfants.

Pourquoi essayer de ne pas ouvrir une nouvelle session et aller chercher les enfants par leurs parents? Quelque chose le long des lignes de ...

criteria = session.createCriteria(Child.class);
criteria.add(Restrictions.eq("parent", parent));
List<Child> children = criteria.list();

Autres conseils

La collection paresseux peut être chargé à l'aide de Hibernate.initialize (parent.getCollection ()), sauf que l'objet parent doit être fixé à une session active.

Cette solution prend l'entité mère et le nom du champ chargé paresseux et retourne l'entité avec la collection complètement chargée.

Malheureusement, comme le parent doit être remis en place à la nouvelle session ouverte, je ne peux pas utiliser une référence à la collection paresseuse car cela renverrait la version détachée de l'entité; d'où le fieldName et la réflexion. Pour la même raison, il doit retourner l'entité mère ci-joint.

Ainsi, dans le scénario OP, cet appel peut être fait lorsque l'utilisateur choisit de voir la collection paresseuse:

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

La méthode:

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;
}

Hibernate gère les collections d'une manière différente que les champs normaux.

A mon travail, nous contourner ce problème en tout initialisant les champs de la charge initiale que nous avons besoin au cas par cas. Par exemple, dans une méthode de charge de façade qui est entouré par une transaction que vous pourriez avoir:

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

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

et nous avons un appel de façade différente pour chaque intention. Cela permet d'atteindre essentiellement ce que vous avez besoin parce que vous seriez chargement de ces champs spécifiques lorsque vous avez besoin de quelque façon, ce qui les met juste à la session au moment de la charge.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top