Problemas com herança

16 respostas Resolvido
java
R

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?

16 Respostas

S

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

H

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.
S

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.

H

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

H

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

R

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

R

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);
    
}
S

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

Aic find(Object id);

R

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();
}

	
	
	
	

}
R

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>
}
S

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

R

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

S

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);
R

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)**
S
Solucao aceita

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?

R

É 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.

Criado 8 de fevereiro de 2018
Ultima resposta 9 de fev. de 2018
Respostas 16
Participantes 3