¿Cuándo es útil trabajar con la carga lazy?

Cuando existen grandes volúmenes de datos, ya que evita cargarlos todos al mismo tiempo, lo que puede afectar el rendimiento de la aplicación. Los datos se cargan solo cuando se necesita, como al cambiar de página o aplicar filtros.

Se deben proporcionar métodos de carga lazy (load y count) en el bean de respaldo para manejar la carga de datos según las necesidades de la tabla.

Fundeweb ya proporciona una librería con parte de esta funcionalidad implementada (FundeWebLazyDataModel)


¿Cómo se le indica a la datatable que usamos la carga perezosa?

Se debe configurar el atributo lazy a true y valor debe ser un modelo de datos lazy ‘LazyDataModel’ (que se gestiona en su servicio correspondiente). Activamos la paginación y establecemos las filas iniciales para utilizarlo en la carga del modelo.

Implementación

Realizaremos una consulta a la entidad de la base de datos con todos los registros a obtener (sin filtros = sin where).

@NamedQuery( name = "obtenerEntities", query = "SELECT entity FROM Entity entity" )

Le impondremos las condiciones a filtrar en la implementación del DAS.


public ResultQuery<Entity> obtenerEntities( Map<String, Object> filters, int first, int pageSize, String multiSortMeta ) {
        List<String> restricciones = new ArrayList<>();

        if (filters != null) {
               restricciones = filters.keySet().stream().filter( filtro -> filters.get( filtro ) != null ).map( <<<<<<condiciones a filtrar>>>>>> ).collect( Collectors.toList() );
        }
        return this.resultsByEntityNamedQueryWithDinamicFilter( "obtenerEntities", restricciones, null, first, pageSize, multiSortMeta, null, null );
}


Creamos o añadimos a un servicio para manejar la lógica y actuar como intermediario entre el DAS y la capa de presentación con su @Name correspondiente y @Stateles. (@Name( EntityService.ID )@Stateless)

Y se añade el método implementado en el DAS


public ResultQuery<Entity> obtenerEntity( Map<String, Object> filters, int first, int pageSize, String multiSortMeta ) {

               return entityDAS.obtenerEntity( filters, first, pageSize, multiSortMeta );

        }


Crearemos un nuevo  modelo de datos lazy (LazyDataModel)  que extienda FundeWebLazyDataModel<Entity> y se valga del servicio creado anteriormente.

Es en este modelo donde se proporcionan los métodos de carga lazy, donde se realiza la carga de datos según los parámetros de paginación, ordenamiento y filtros y se establece la cantidad total de registros para la paginación.

Como no tiene ni @Name ni @Stateless (no es un EJB) hay que inyectar el servicio en el modelo de datos de la siguiente manera:


EntityService entityService;

private EntityService getEntityService() {
               if ( this.entityService == null ) {
                       this. entityService = ( EntityService) Component.getInstance( EntityService.class, true );
               }
               return this.entityService;
        }




protected List<Entity> loadPage( int first, int pageSize, List<SortMeta> multiSortMeta, Map<String, Object> filters ) {
               ResultQuery<Entity> resultQuery = getEntityService().obtenerEntity( filters, first, pageSize, null );
               setRowCount( resultQuery.getResultCount().intValue() );
               return resultQuery.getResultList();
        }



Configuramos el bean de respaldo e inicializamos el modelo de datos lazy. (Aquí el servicio si se puede inyectar a través del @name)


private LazyDataModel<Entity> lazyModel;

@In( value = EntityService.ID, create = true )

EntityService entityService;

 

lazyModel = new LazyDataModel( entityService);