Problemas com herança

Galera, estou recebendo o seguinte erro.

AicFacade is not abstract and does not override abstract method find(Object) in AicFacadeLocal

Mas eu tenho da seguinte forma:

public class AicFacade extends AbstractFacadeSgi<Aic> implements AicFacadeLocal
public abstract class AbstractFacadeSgi<T extends Object> extends AbstractFacade
public abstract class AbstractFacade<T extends Object> **(Aqui eu tenho o find implementado)**

Esse erro está acontecendo por serem duas classes abstract?

Posta os fontes das 3 classes e também da interface AicFacadeLocal.

1 curtida

Solução 1

  1. Você não implementou o método find(Object) então o implemente!!!

Solução 2

  1. Você deve definir a class AicFacade como sendo abstrata.

Ele disse que implementou na classe AbstractFacade, que é a superclasse das outras.

Imagino que na interface AicFacadeLocal ele tenha declarado o método find sem ser genérico, aí não casa com o método definido em AbstractFacade.

Vamos esperar ele postar os códigos das classes e interface.

O problema está aqui
public abstract class AbstractFacade<T extends Object>

está faltando um implements AicFacadeLocal

Obs: Retire o
implements AicFacadeLocal
do
public class AicFacade extends AbstractFacadeSgi<Aic> implements AicFacadeLocal pós com a solução acima o AicFacade já faz ligação com o AicFacadeLocal através da AbstractFacade

Você pode ter uma encadeação de classe abstratas, ou seja, ter um classe abstrata herdando outra classe abstrata que herda outra classe abstrata …e não causará problema

Isso não é possível, pois a AbstractFacade não implementa só o AicFacadeLocal, ele faz isso com mais de 15 classes.

AicFacade:

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package br.com.celg.sessao;


import br.com.celg.entidade.Aic;
import br.com.celg.entidade.Areas;
import br.com.celg.entidade.ClassTaxonomia;
import br.com.celg.entidade.Cr;
import br.com.celg.sessao.interfaceFacade.AicFacadeLocal;
import java.util.List;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

/**
 *
 * @author Rodrigo
 */
@Stateless
public class AicFacade extends AbstractFacadeSgi<Aic> implements AicFacadeLocal {
    @PersistenceContext(unitName = "SGT-SGIPU")
    private EntityManager em;

    @Override
    protected EntityManager getEntityManager() {
        return em;
    }

    public AicFacade() {
        super(Aic.class);
    }
    
    @Override
    public int count(String consultarPor, String parametroConsulta, String dataRef, Cr cr, Areas area, ClassTaxonomia idClassTaxonomia) {

        String classe = Aic.class.getName().toString();

        String nomePuro = classe.substring(classe.lastIndexOf(".") + 1, classe.length());

        StringBuilder sb = new StringBuilder();
        sb.append("select count(").append(nomePuro.toLowerCase()).append(".codigo) from ").append(nomePuro).append(" ").append(nomePuro.toLowerCase()).append(" ");
        sb.append(" where 1 = 1 ");

        if (dataRef != null && !dataRef.isEmpty()) {
            sb.append(" and ").append(nomePuro.toLowerCase()).append(".dataRef like :valorDataRef ");
        }
        if (cr != null) {
            sb.append(" and ").append(nomePuro.toLowerCase()).append(".cr.cr = :crId ");
        }
        if (area != null) {
            sb.append(" and ").append(nomePuro.toLowerCase()).append(".cr.idArea.codigo = :areaID ");
        }
        if (idClassTaxonomia != null) {
            sb.append(" and ").append(nomePuro.toLowerCase()).append(".idClassTaxonomia.codigo = :taxonomiaID ");
        }
        if(parametroConsulta != null && !parametroConsulta.isEmpty()) {
            switch (consultarPor) {
                case "ODEX":
                    sb.append(" and ").append(nomePuro.toLowerCase()).append(".odex like '%").append(parametroConsulta).append("%'");
                    break;
                default:
                    sb.append(" and ").append(nomePuro.toLowerCase()).append(".").append(consultarPor).append(" = ").append(parametroConsulta);
                    break;
            }
        }
        
        
        javax.persistence.Query q = getEntityManager().createQuery(sb.toString());

        if (dataRef != null && !dataRef.isEmpty()) {
            q.setParameter("valorDataRef", dataRef);
        }
        if (cr != null) {
            q.setParameter("crId", cr.getCr());
        }
        if (area != null) {
            q.setParameter("areaID", area.getCodigo());
        }
        if (idClassTaxonomia != null) {
            q.setParameter("taxonomiaID", idClassTaxonomia.getCodigo());
        }
        
        
        return ((Long) q.getSingleResult()).intValue();
    }
    
    
    
    @Override
    public List findRange(int[] range, String consultarPor, String parametroConsulta, String dataRef, Cr cr, Areas area, ClassTaxonomia idClassTaxonomia){

        String classe = Aic.class.getName().toString();

        String nomePuro = classe.substring(classe.lastIndexOf(".") + 1, classe.length());

        StringBuilder sb = new StringBuilder();
        sb.append("select ").append(nomePuro.toLowerCase()).append(" from ").append(nomePuro).append(" ").append(nomePuro.toLowerCase()).append(" ");
        sb.append(" where 1 = 1 ");

        if (dataRef != null && !dataRef.isEmpty()) {
            sb.append(" and ").append(nomePuro.toLowerCase()).append(".dataRef like :valorDataRef ");
        }
        if (cr != null) {
            sb.append(" and ").append(nomePuro.toLowerCase()).append(".cr.cr = :crId ");
        }
        if (area != null) {
            sb.append(" and ").append(nomePuro.toLowerCase()).append(".cr.idArea.codigo = :areaID ");
        }
        if (idClassTaxonomia != null) {
            sb.append(" and ").append(nomePuro.toLowerCase()).append(".idClassTaxonomia.codigo = :taxonomiaID ");
        }
        if(parametroConsulta != null && !parametroConsulta.isEmpty()) {
            switch (consultarPor) {
                case "ODEX":
                    sb.append(" and ").append(nomePuro.toLowerCase()).append(".odex like '%").append(parametroConsulta).append("%'");
                    break;
                default:
                    sb.append(" and ").append(nomePuro.toLowerCase()).append(".").append(consultarPor).append(" = ").append(parametroConsulta);
                    break;
            }
        }
        
        sb.append(" order by ").append(nomePuro.toLowerCase()).append(".dataRef ");
        
        javax.persistence.Query q = getEntityManager().createQuery(sb.toString());

        if (dataRef != null && !dataRef.isEmpty()) {
            q.setParameter("valorDataRef", dataRef);
        }
        if (cr != null) {
            q.setParameter("crId", cr.getCr());
        }
        if (area != null) {
            q.setParameter("areaID", area.getCodigo());
        }
        if (idClassTaxonomia != null) {
            q.setParameter("taxonomiaID", idClassTaxonomia.getCodigo());
        }

        q.setMaxResults(range[1] - range[0]);
        q.setFirstResult(range[0]);
        return q.getResultList();
    }

}

AicFacadeLocal:

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package br.com.celg.sessao.interfaceFacade;

import br.com.celg.entidade.Aic;
import br.com.celg.entidade.Areas;
import br.com.celg.entidade.ClassTaxonomia;
import br.com.celg.entidade.Cr;
import java.util.List;
import javax.ejb.Local;

/**
 *
 * @author Rodrigo
 */
@Local
public interface AicFacadeLocal {

    void create(Aic aic);

    void edit(Aic aic);

    void remove(Aic aic);

    Aic find(Object id);

    List<Aic> findAll();

    List<Aic> findRange(int[] range);

    List<String> findByDataGroup();
    
    int count();

    public int count(String consultarPor, String parametroConsulta, String dataRef, Cr cr, Areas area, ClassTaxonomia taxonomia);

    public List findRange(int[] i, String consultarPor, String parametroConsulta, String dataRef, Cr cr, Areas area, ClassTaxonomia taxonomia);

    public List<String> consultarClassePorStringDistinct(String dataRef, String query);
    
}

Tem certeza de que o find da classe AbstractFacade tem a mesma assinatura como você declarou na interface AicFacadeLocal ?

Aic find(Object id);

AbstractFacadeSgi:

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package br.com.celg.sessao;

import facade.AbstractFacade;
import java.util.Collection;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.ParameterExpression;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import javax.persistence.NoResultException;
import javax.persistence.Query;

/**
 *
 * @author Rodrigo
 */
public abstract class AbstractFacadeSgi<T> extends AbstractFacade{

    public AbstractFacadeSgi(Class entityClass) {
        super(entityClass);
    }

    	/**
     *
     * caso n?o seja informado parametro de busca n?o realiza busca vazia no
     * banco
     *
     * @param propriedade
     * @param valor
     * @param limite
     * @return
     */
    
    public List<String> findByDataGroup() {
        javax.persistence.criteria.CriteriaQuery cq = getEntityManager().getCriteriaBuilder().createQuery();
        cq.select(cq.from(getClass()).get("dataRef"));
        cq.distinct(true);
        return getEntityManager().createQuery(cq).getResultList();
    }
	
    public List consultarClassePorStringDistinct(String propriedade, String valor) {
        CriteriaBuilder builder = getEntityManager().getCriteriaBuilder();
        CriteriaQuery criteria = builder.createQuery(getClass());
        Root root = criteria.from(getClass());
        criteria.select(root.get(propriedade));
        criteria.distinct(true);

        ParameterExpression<String> parametro = builder.parameter(String.class);
    criteria.where(builder.like(builder.lower(root.get(propriedade)), builder.lower(parametro)));

    criteria.orderBy(getEntityManager().getCriteriaBuilder().asc(root.get(propriedade)));
    TypedQuery query = getEntityManager().createQuery(criteria);
    query.setParameter(parametro, "%" + valor + "%");
//        query.setHint(QueryHints.CACHE_USAGE, CacheUsage.CheckCacheThenDatabase);
    return query.getResultList();
}

	
	
	
	

}

Sim, o código do AbstractFacade ultrapassa o limite permitido aqui, vou postar apenas o find:

public T find(Object id) {
    // <editor-fold defaultstate="collapsed" desc="Compiled Code">
    /* 0: aload_0
     * 1: invokevirtual facade/AbstractFacade.getEntityManager:()Ljavax/persistence/EntityManager;
     * 4: aload_0
     * 5: getfield      facade/AbstractFacade.entityClass:Ljava/lang/Class;
     * 8: aload_1
     * 9: invokeinterface javax/persistence/EntityManager.find:(Ljava/lang/Class;Ljava/lang/Object;)Ljava/lang/Object;
     * 14: areturn
     *  */
    // </editor-fold>
}

Então

// AbstractFacade
public T find(Object id)

É diferente de

// AicFacadeLocal
public Aic find(Object id)

Sugiro modificar sua interface AicFacadeLocal para ser genérica e também retornar o tipo genérico ao invés de Aic

Mas tipo, quando eu herdo a AbstractFacade direto, sem precisar passar pela AbstractFacadeSgi, ela funciona normal.
Exatamente como está o código ai.

O problema não é o extends
O problema é o implements AicFacadeLocal

Nessa interface o método find tem retorno definido como sendo um Aic

public Aic find(Object id);

Acontece que na sua superclasse o find tá implementado com retorno de tipo genérico

public T find(Object id);

Tenha em mente que os tipos genéricos só existem em tempo de compilação, no bytecode gerado os tipos genéricos viram tudo Object, esse processo é chamado de Erasure.

Então o que acontece é que quando você implementa AicFacadeLocal, o compilador espera que você tenha um método com a seguinte assinatura:

public Aic find(Object id);

mas na verdade você tem um método com essa assinatura:

public Object find(Object id);

Mas porque então está funcionando dessa forma quando eu utilizo da seguinte forma:

public class AicFacade extends AbstractFacade<Aic> implements AicFacadeLocal

public abstract class AbstractFacade<T extends Object> **(Aqui eu tenho o find implementado)**

Pq dessa forma você está especificando que você estende um AbstractFacade<Aic>

Eu não havia reparado que no AbstractFacadeSgi você esqueceu de pôr o extends AbstractFacade<T>.

Você só pôs extends AbstractFacade

Corrige o extends que vai funcionar.

Uma pergunta:
Qual a necessidade de tantos níveis hierárquicos?

1 curtida

É porque na empresa se utiliza um “framework” criado que realiza a maioria das consultas que precisamos, mas quando precisamos de algo especifico daquele sistema, colocamos mais um nível e é implementado apenas nesse sistema.

1 curtida