Skip to content

Latest commit

 

History

History
107 lines (97 loc) · 3.93 KB

README.md

File metadata and controls

107 lines (97 loc) · 3.93 KB

#tenant Build Status

Possibilita adicionar Tenant as consultas JPA através do criteria builder, fazendo uso do CDI.

Supondo que Temos dois modelos, Recurso e Aplicação, onde uma aplicação possui vários recursos, mas só iremos mostrar aquelas aplicações que não se chamam "AplicaçãoQueNãoDeveAparecerNaConsulta", em um exemplo real poderiamos mostrar para o usuário logado só os recursos da aplicação em que ele está relacionado. Mas enfim, montamos então um tenant para aplicação.

package br.eti.clairton.tenant;

import javax.enterprise.context.Dependent;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.From;
import javax.persistence.criteria.Path;
import javax.persistence.criteria.Predicate;
import javax.validation.constraints.NotNull;

@Dependent// para ser geneciado pelo CDI
//Qualificando ele com um Tenant para o Tipo Aplicacação
@TenantType(Aplicacao.class)
public class AplicacaoTenant extends Tenantable<Aplicacao> {
	
	//Contrato que adicionara o Predicado que desejamos
	@Override
	public Predicate add(CriteriaBuilder builder, From<?, Aplicacao> from, Object value) {
		final Path<String> path = from.get(Aplicacao_.nome);
		final Predicate predicate = builder.notEqual(path, value);
		return predicate;
	}
}

O tenant de Recurso, somente irá chamar o tenant relacionado a Aplicação, fica dessa forma:

package br.eti.clairton.tenant;

import javax.enterprise.context.Dependent;
import javax.inject.Inject;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.From;
import javax.persistence.criteria.Join;
import javax.persistence.criteria.Predicate;
import javax.validation.constraints.NotNull;

@Dependent//Para ser Gerenciado pelo CDI
//Qualificado como tenant para o tipo recurso
@TenantType(Recurso.class)
public class RecursoTenant extends Tenantable<Recurso> {
	private final TenantBuilder builder;
	/*
     	 * Deve injetar o Tenant Builder e Chamar o Super, isso fará com que ele
         * possa se chamar recursivamente
     	 */
	@Inject
	public RecursoTenant(final TenantBuilder builder) {
		this.builder = builder;
	}

	//Contrato que adicionara o Predicado que desejamos
	@Override
	public Predicate addCriteriaBuilder criteriaBuilder, From<?, Recurso> from, Object value) {
       /*
        * não temos um predicado diretamente os atributos de Recurso, para
        * sim temos que pegar os Recurso relacionados a Aplicação que
        * queremos, por isso faremos o join de Recurso com Aplicação
        */
		final Join<Recurso, Aplicacao> join = from.join(Recurso_.aplicacao);
		/*
	     * e chamaremos o TenantBuilder que irá fazer a de AplicacaoTenant#add
	     * atravé do CDI e retornar o predicado necessário
	     */
		return builder.run(criteriaBuilder, join, value);
	}
}

Finalmente podemos fazer a consulta:

@Inject EntityManager entityManager;
@Inject TenantBuilder tenant;
final String nome = "OutroTesteQueNãoDeveAparecerNaConsulta";
// cortamos o código aqui, para não ficar muito extenso
final CriteriaBuilder builder = entityManager.getCriteriaBuilder();
final CriteriaQuery<Recurso> query = builder.createQuery(Recurso.class);
final Root<Recurso> from = query.from(Recurso.class);
//recurpera os predicados
final Predicate predicate = tenant.run(builder, from, nome);
//aplicaca os predicados
query.where(predicate);
final TypedQuery<Recurso> typedQuery = entityManager.createQuery(query);
/*
 * Retornara somente os Recursos que estão relacionados as Aplicações com nome
 * diferente de "AplicaçãoQueNãoDeveAparecerNaConsulta"
 */
final List<Recurso> result = typedQuery.getResultList();

Para usar será necessário adicionar os repositórios maven adicionar as depêndencias:

<dependency>
    <groupId>br.eti.clairton</groupId>
	<artifactId>tenant</artifactId>
	<version>${latest}</version>
</dependency>