java - paneles - Fuerza la carga impaciente de propiedades cargadas de otra manera perezosas
table swing java (7)
Tengo un objeto Hibernate cuyas propiedades están cargadas perezosamente. La mayoría de estas propiedades son otros objetos Hibernate o PersistentSets.
Ahora quiero forzar a Hibernate a cargar ansiosamente estas propiedades por una sola vez.
Por supuesto, podría "tocar" cada una de estas propiedades con object.getSite().size()
pero tal vez haya otra manera de lograr mi objetivo.
De acuerdo con los documentos de hibernación , debería poder deshabilitar la carga perezosa de propiedades al establecer el atributo lazy
en sus asignaciones de propiedades particulares:
<class name="Document">
<id name="id">
<generator class="native"/>
</id>
<property length="50" name="name" not-null="true"/>
<property lazy="false" length="200" name="summary" not-null="true"/>
<property lazy="false" length="2000" name="text" not-null="true"/>
</class>
Esta es una pregunta antigua, pero también quería señalar el método estático Hibernate.initialize
.
Ejemplo de uso:
Person p = sess.createCriteria(Person.class, id);
Hibernate.initialize(p.getChildren());
Los niños ahora están inicializados para ser utilizados incluso después de que se cierre la sesión.
Esto es lento, ya que hace un viaje de ida y vuelta para cada elemento que necesita inicializar, pero hace el trabajo.
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);
}
}
}
La documentación lo pone así:
Puede forzar la
fetch all properties
impaciente habitual de las propiedades mediante lafetch all properties
en HQL.
Referencias
- Guía de referencia del núcleo de Hibernate
Para mi esto funciona:
Person p = (Parent) sess.get(Person.class, id);
Hibernate.initialize(p.getChildren());
En vez de esto:
Person p = sess.createCriteria(Person.class, id);
Hibernate.initialize(p.getChildren());
Dozer funciona bien para este tipo de cosas: puede pedirle a Dozer que asigne el objeto a otra instancia de la misma clase, y Dozer visitará todos los objetos accesibles desde el objeto actual.
Vea esta respuesta a una pregunta similar y mi respuesta a otra pregunta relacionada para obtener más detalles.
3 maneras
1.HQL con hijos a la izquierda
2.SetFetchMode después de createCriteria
3.Hibernar.inicializar