Paginação com criteria.distinct_root_entity

Estou desenvolvendo aplicação Java web e deparei com um problema. Tenho um relacionamento n:n entre AgendaTriados e Indicacao e está retornando dados duplicados quando realizo uma consulta… consigo retornar a situação usando o criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY), mas quando coloca paginação a quantidade por pagina de dados acabam ficando errada, ou seja, não realiza a paginação correta…em uma pagina fica com maior quantidade que a outra. por exemplo, se for 5 por pagina dependendo da quantidade de procedimento de indicação salvo em uma agenda ficará só um dado mostra na pagina. Se não fui claro o suficiente coloca a pergunta que explico.

Class AgendaTriados

@Entity
@Table(name = "agenda_triados")
public class AgendaTriados implements Serializable {

	private static final long serialVersionUID = 1L;

	private Long id;
	private String observacao;
	private Date dataAtendimento;
	private Aluno aluno;
	private Aluno aluno2;
	private Disciplina disciplina;
	private AgendaMarcacao agenda_marcacao;
	private List<Indicacao> indicacoes = new ArrayList<>();

	@Id
	@GeneratedValue
	public Long getId() {
		return id;
	}

	public void setId(Long id) {
		this.id = id;
	}

	@Column(columnDefinition = "text")
	public String getObservacao() {
		return observacao;
	}

	public void setObservacao(String observacao) {
		this.observacao = observacao;
	}

	@NotNull
	@Column(name = "data_atendimento")
	@Temporal(TemporalType.DATE)
	public Date getDataAtendimento() {
		return dataAtendimento;
	}

	public void setDataAtendimento(Date dataAtendimento) {
		this.dataAtendimento = dataAtendimento;
	}

	@NotNull
	@ManyToOne
	@JoinColumn(name = "id_aluno")
	public Aluno getAluno() {
		return aluno;
	}

	public void setAluno(Aluno aluno) {
		this.aluno = aluno;
	}

	@NotNull
	@ManyToOne
	@JoinColumn(name = "id_aluno2")
	public Aluno getAluno2() {
		return aluno2;
	}

	public void setAluno2(Aluno aluno2) {
		this.aluno2 = aluno2;
	}

	@NotNull
	@ManyToOne
	@JoinColumn(name = "id_disciplina")
	public Disciplina getDisciplina() {
		return disciplina;
	}

	public void setDisciplina(Disciplina disciplina) {
		this.disciplina = disciplina;
	}


	@NotNull
	@ManyToOne(cascade = { CascadeType.PERSIST, CascadeType.MERGE })
	@JoinColumn(name = "id_agenda_marcacao")
	public AgendaMarcacao getAgenda_marcacao() {
		return agenda_marcacao;
	}

	public void setAgenda_marcacao(AgendaMarcacao agenda_marcacao) {
		this.agenda_marcacao = agenda_marcacao;
	}

	@NotNull
	@ManyToMany
	@JoinTable(name = "triado_indicacao", joinColumns = @JoinColumn(name = "agenda_triados_id"),
		inverseJoinColumns = @JoinColumn(name = "indicacao_id"))
	public List<Indicacao> getIndicacoes() {
		return indicacoes;
	}

	public void setIndicacoes(List<Indicacao> indicacoes) {
		this.indicacoes = indicacoes;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((id == null) ? 0 : id.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		AgendaTriados other = (AgendaTriados) obj;
		if (id == null) {
			if (other.id != null)
				return false;
		} else if (!id.equals(other.id))
			return false;
		return true;
	}

	public void completarCampo() {
		Disciplina disciplina = new Disciplina();
		AgendaTriados triado = new AgendaTriados();

		triado.setDisciplina(disciplina);

	}

}

Class Indicacao

@Entity
@Table(name = "indicacao")
public class Indicacao implements Serializable {

	private static final long serialVersionUID = 1L;

	private Long id;
	private String nome;

	@Id
	@GeneratedValue
	public Long getId() {
		return id;
	}

	public void setId(Long id) {
		this.id = id;
	}

	@Column(nullable = false)
	public String getNome() {
		return nome;
	}

	public void setNome(String nome) {
		this.nome = nome;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((id == null) ? 0 : id.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Indicacao other = (Indicacao) obj;
		if (id == null) {
			if (other.id != null)
				return false;
		} else if (!id.equals(other.id))
			return false;
		return true;
	}

	@Override
	public String toString() {
		return nome;
	}
}

Repository Triados

public class Triados implements Serializable {

	private static final long serialVersionUID = 1L;

	@Inject
	private EntityManager manager;

	public AgendaTriados guardar(AgendaTriados triado) {

		return manager.merge(triado);

	}

	@Transactional
	public void remover(AgendaTriados triado) {
		try {
			triado = porId(triado.getId());
			manager.remove(triado);
			manager.flush();
		} catch (PersistenceException e) {
			throw new NegocioException("A agenda não pode ser excluída.");
		}
	}

	public AgendaTriados porId(Long id) {
		return manager.find(AgendaTriados.class, id);
	}


	@SuppressWarnings("unchecked")
	public List<AgendaTriados> filtrados(AgendaTriadosFilter filtro) {
		Criteria criteria = criarCriteriaParaFiltro(filtro);

		criteria.setFirstResult(filtro.getPrimeiroRegistro());
		criteria.setMaxResults(filtro.getQuantidadeRegistros());

		return criteria.addOrder(Order.asc("dataAtendimento")).list();
	}

	public int quantidadeFiltrados(AgendaTriadosFilter filtro) {
		Criteria criteria = criarCriteriaParaFiltro(filtro);

		criteria.setProjection(Projections.rowCount());
		return ((Number) criteria.uniqueResult()).intValue();
	}

	private Criteria criarCriteriaParaFiltro(AgendaTriadosFilter filtro) {
		Session session = this.manager.unwrap(Session.class);

		Criteria criteria = session.createCriteria(AgendaTriados.class, "tr");
		// criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
		criteria.createAlias("tr.agenda_marcacao", "trag");
		criteria.createAlias("trag.lista_espera", "agenda");
		criteria.createAlias("agenda.paciente", "triado");
		criteria.createAlias("tr.disciplina", "trd");
		criteria.createAlias("tr.aluno", "tral");
        criteria.createAlias("indicacoes", "indi");
		

		if (filtro.getDataAtenderDe() != null) {
			criteria.add(Restrictions.ge("tr.dataAtendimento", filtro.getDataAtenderDe()));
		}

		if (filtro.getDataAtenderAte() != null) {
			criteria.add(Restrictions.le("tr.dataAtendimento", filtro.getDataAtenderAte()));
		}

		if (StringUtils.isNotBlank(filtro.getNomeDisc())) {

			criteria.add(Restrictions.ilike("trd.nome", filtro.getNomeDisc(), MatchMode.ANYWHERE));
		}

		if (StringUtils.isNotBlank(filtro.getCodigo())) {
			criteria.add(Restrictions.ilike("trd.codigo", filtro.getCodigo(), MatchMode.EXACT));
		}

		if (filtro.getPraticas() != null && filtro.getPraticas().length > 0) {
			criteria.add(Restrictions.in("trd.pratica", filtro.getPraticas()));

		}
		if (filtro.getTurnos() != null && filtro.getTurnos().length > 0) {
			criteria.add(Restrictions.in("trd.turno", filtro.getTurnos()));

		}

		if (StringUtils.isNotBlank(filtro.getNomeAl())) {

			criteria.add(Restrictions.ilike("tral.nomeAluno", filtro.getNomeAl(), MatchMode.ANYWHERE));
		}
		if (StringUtils.isNotBlank(filtro.getNomePaciente())) {

			criteria.add(Restrictions.ilike("triado.nome", filtro.getNomePaciente(), MatchMode.ANYWHERE));
		}

		if (filtro.getIndicacoes() != null && filtro.getIndicacoes().length > 0) {
			criteria.add(Restrictions.in("indi.nome", filtro.getIndicacoes()));
		}

		return criteria;
	}

}

Eu pesquisei sobre criteria.setProjection(Projections.distinct(Projections.id())), mas não estou conseguindo fazer funcionar…