[Resolvido -Sem Spring Data] Spring Data vs Lazy Loading (Primefaces)

Galera,

estou meio impacado ao juntar essas duas tecnologias
(Spring Data) com o LazyDataModel do Primefaces…

O negócio é o seguinte, com o Spring Data eu tenho o seguinte método:

	public Page<T> findAll(int page, int page_size){
		PageRequest pageRequest = new PageRequest(page, page_size);		
	
		return this.getBaseRepository().findAll(pageRequest);
		
	}

Como podem ver, eu recebo a pagina e o tamanho da página e este é o filtro :slight_smile:
Tudo bem até aí…

O problema é que agora, no LazyLoading eu tenho que sobrescrever este método:

			public List<T> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String,String> filters) {

Que como vocês também notaram, eu só recebo “first” e “pageSize”.
Não recebo a pagina!

Bom, vi umas integrações com o Hibernate que vc faz um “setFirstResult” e algo assim e funciona.
Mas agora pro Spring Data, eu não consigo contornar.

O que vcs acham que deve ser feito?

Abraços!

Bom dia Amigo, estou passando o mesmo problema com essa integração voce conseguiu resolver o prolema ? Se conseguir pode me passar a solução desde já agradeço!!

Bom dia,

meu amigo, resolvi este problema há muito tempo. Por sorte, ainda tenho o código aqui.

Infelizmente eu não resolvi o problema com o Spring Data. De qualquer maneira, segue o código que eu fiz. Espero que te ajude:


	@SuppressWarnings("unchecked")
	@Override
	public List<T> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String, String> filters) {
			
		// filters
		List<FilterCriteria> myFilters = new ArrayList<FilterCriteria>();

		List<FilterCriteria> filter = JSFUtil.getFilters();

		if (filter != null) {
			myFilters.addAll(filter);
		}

		int rowCount = hibernateService.executeDatatablePaginationPageCount(myFilters, entityClass);

		// pageCount
		setRowCount(rowCount);

		List<T> data = (List<T>) hibernateService.executeDatatablePaginationQuery(pageSize, first, sortField, sortOrder, myFilters, entityClass);

		// Query :)
		return data;
	}

Isto delega pro HibernateService, que delega para o HibernateDAO:

	/**
	 * Query Dinâmica utilizado nos filtros e nas Datatables (LazyDataModel)
	 * @param pageSize Tamanho da página
	 * @param first Primeiro elemento da página
	 * @param sortField Campo a ser Ordenado
	 * @param sortOrder Tipo de Ordenação (Crescente ou Decrescente)
	 * @param myFilters Lista de filtros utilizados
	 * @param entityClass Classe alvo
	 * @return Lista do tipo entityClass.
	 */
	public List<?> executeDatatablePaginationQuery(int pageSize, int first, String sortField, SortOrder sortOrder, List<FilterCriteria> myFilters, Class<?> entityClass) {

		EntityManager entityManager = entityManagerFactory.createEntityManager();
		entityManager.getTransaction().begin();

		// For the root alias
		String root = entityClass.toString().substring(entityClass.toString().lastIndexOf(".") + 1).toLowerCase();

		Session hibernateSession = entityManager.unwrap(Session.class);
		Criteria criteria = hibernateSession.createCriteria(entityClass, root);

		List<Alias> alias = new ArrayList<Alias>();

		tratarFiltros(myFilters);
		
		for (FilterCriteria filter : myFilters) {			
			for (Alias al : filter.getAlias()) {
				if (!alias.contains(al)) {
					alias.add(al);
					criteria.createAlias(al.getField(), al.getAlias());
				}
			}
			criteria.add(filter.getCriterion());
		}		

		// order
		if (!ObjectUtil.nullOrEmpty(sortField)) {
			sortField = sortField.toLowerCase();
			criteria.addOrder(sortOrder == SortOrder.ASCENDING ? Order.asc(sortField) : Order.desc(sortField));
		}

		// pagination
		criteria.setFirstResult(first);
		criteria.setMaxResults(pageSize);
		
		//evitar registros duplicados
		 criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);

		 List<?> lista = criteria.list();
		
		entityManager.getTransaction().commit();
		entityManager.close();
		
		return lista;
	}

Espero que te ajude.

Voce criou um LazyModel generico nesse caso? E nesse lazy vc recebe a interface HibernateService que possui os metodos de consulta?

Sim segue a implementação completa:


/**
 * 
 * Dependência do Primefaces
 * Classe utilizada para carregar lista de objetos para a datatable por meio de Lazy Loading e paginação.
 * 
 * @author Marco Noronha
 *
 * @param <T> Entidade 
 * @param <PK> Chave Primária da Entidade
 */
public class BaseLazyModelJPA<T, PK extends Serializable> extends LazyDataModel<T> {

	private static final long serialVersionUID = -1575756081953492198L;

	/**
	 * Classe da Entidade
	 */
	private Class<T> entityClass;

	/**
	 * Serviço genérico que irá delegar as operações com a base de dados
	 */
	private BaseService<T, PK> baseService;

	/**
	 * Utilizado para as consultas dinâmicas contemplando os filtros
	 */
	private HibernateService hibernateService;

	private static final Logger log = Logger.getLogger(BaseLazyModelJPA.class);
	
	public BaseLazyModelJPA(BaseService<T, PK> baseService, Class<T> entityClass, HibernateService hibernateService) {
		this.entityClass = entityClass;
		this.baseService = baseService;
		this.hibernateService = hibernateService;
	}


	@SuppressWarnings("unchecked")
	@Override
	public List<T> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String, String> filters) {
			
		// filters
		List<FilterCriteria> myFilters = new ArrayList<FilterCriteria>();

		List<FilterCriteria> filter = JSFUtil.getFilters();

		if (filter != null) {
			myFilters.addAll(filter);
		}

		int rowCount = hibernateService.executeDatatablePaginationPageCount(myFilters, entityClass);

		// pageCount
		setRowCount(rowCount);

		List<T> data = (List<T>) hibernateService.executeDatatablePaginationQuery(pageSize, first, sortField, sortOrder, myFilters, entityClass);

		// Query :)
		return data;
	}

	@SuppressWarnings("unchecked")
	@Override
	public T getRowData(String key) {
		if(!ObjectUtil.nullOrEmpty(key))
			return getBaseService().findOne((PK) new SimpleTypeConverter().convertIfNecessary(key, ReflectUtil.getPrimaryKeyField(entityClass).getType()));
		
		return null;
	}

	@Override
	public Object getRowKey(T entity) {
		Object id = null;

		try {
			id = ReflectUtil.getFieldValue(entity, ReflectUtil.getPrimaryKeyField(entityClass).getName());
		} catch (Exception e) {
			log.error("Erro ao pegar chave primária da classe "+entityClass.getName(), e);
			e.printStackTrace();
		}

		return id;
	}

	public BaseService<T, PK> getBaseService() {
		return baseService;
	}

}