J'ai un objet Hibernate dont les propriétés sont toutes chargées paresseuses. La plupart de ces propriétés sont d'autres objets Hibernate ou PersistentSets.
Maintenant, je veux forcer Hibernate à charger ces propriétés pour une seule fois.
Bien sûr, je pourrais "toucher" chacune de ces propriétés avec object.getSite().size()
, mais il existe peut-être un autre moyen d'atteindre mon objectif.
La documentation le dit comme ceci:
Vous pouvez forcer l'extraction habituelle De propriétés à l'aide de
fetch all properties
en HQL.
C'est une vieille question, mais je voulais aussi souligner la méthode statique Hibernate.initialize
.
Exemple d'utilisation:
Person p = sess.createCriteria(Person.class, id);
Hibernate.initialize(p.getChildren());
Les enfants sont maintenant initialisés pour pouvoir être utilisés même après la fermeture de la session.
Dozer fonctionne bien pour ce genre de chose - vous pouvez demander à Dozer de mapper l'objet à une autre instance de la même classe.
Voir cette réponse à une question similaire et ma réponse à une autre question connexe pour plus de détails.
Pour moi cela fonctionne:
Person p = (Parent) sess.get(Person.class, id);
Hibernate.initialize(p.getChildren());
Plutôt que cela:
Person p = sess.createCriteria(Person.class, id);
Hibernate.initialize(p.getChildren());
3 voies
1.HQL avec gauche rejoindre les enfants
2.SetFetchMode après createCriteria
3.Hibernate.initialize
Ceci est lent, car il effectue un aller-retour pour chaque élément à initialiser, mais le travail est fait.
private void RecursiveInitialize(object o,IList completed)
{
if (completed == null) throw new ArgumentNullException("completed");
if (o == null) return;
if (completed.Contains(o)) return;
NHibernateUtil.Initialize(o);
completed.Add(o);
var type = NHibernateUtil.GetClass(o);
if (type.IsSealed) return;
foreach (var prop in type.GetProperties())
{
if (prop.PropertyType.IsArray)
{
var result = prop.GetValue(o, null) as IEnumerable;
if (result == null) return;
foreach (var item in result)
{
RecursiveInitialize(item, completed);
}
}
else if (prop.PropertyType.GetGenericArguments().Length > 0)
{
var result = prop.GetValue(o, null) as IEnumerable;
if (result == null) return;
foreach (var item in result)
{
RecursiveInitialize(item, completed);
}
}
else
{
var value = prop.GetValue(o, null);
RecursiveInitialize(value, completed);
}
}
}