Solucionado (ver solução)
Solucionado
(ver solução)
1
resposta

Mapeamento Jpa em interface

Tenho uma determinada classe cliente. Nesta classe existe o atributo documento que pode ser CNPJ ou CPF. Este documento é declarado por uma interface uma vez que somente em tempo de execução teria a definição.

No banco de dados tenho o campo indicando o numero do documento e um campo indicando se eh pessoa fisica ou juridica ("IDETIPPSA").

O problema: o EntityManager .find sempre retorna o objeto cliente mas sua propriedade documento vem nulo. Se trocar o tipo da propriedade documento de IDocumento para String o mesmo retorna corretamente o numero do documento.

Existe algum erro na anotacao? Ou seria outro problema?

@DiscriminatorColumn(name="IDETIPPSA", discriminatorType = DiscriminatorType.STRING)
public interface IDocumento {
    public String getNumero();
    public boolean isValido();
}

@Entity
public class Cliente {
    @Id
    private int id;
    private String nome;
    private IDocumento documento;

        ...etc
}

@DiscriminatorValue("J")
public class Cnpj implements IDocumento{

    private String numero;

    public Cnpj(String numero) {
        this.numero = numer;
    }

    public String getNumero() {
        return numero;
    }

    public boolean isValido() {
        .. implementacao do metodo

    }
}


@DiscriminatorValue("F")
public class Cpf implements IDocumento{

    private String numero;

    public Cpf(String numero) {
        this.numero = numero;
    }

    public String getNumero() {
        return numero;
    }

    public boolean isValido() {
        .. implementacao do metodo

    }
}
1 resposta
solução!

Oi Rui,

Atributos como interface não são suportados pela JPA =/

Uma alternativa seria você utilizar herança para fazer esse mapeamento. Algo como:

@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(discriminatorType = DiscriminatorType.STRING, name = "IDETIPPSA")
public abstract class Cliente {
    //atributos comuns para todos os tipos de cliente
    @Id
    private int id;
    private String nome;
    private String documento;

    //cada classe filha devera sobrescrever esse metodo:
    public abstract boolean isDocumentoValido();
}

@Entity
@DiscriminatorValue("F")
public class PessoaFisica extends Cliente {
    //atributos especificos de PF

    public boolean isDocumentoValido() {
        //validacao de CPF
    }
}

@Entity
@DiscriminatorValue("J")
public class PessoaJuridica extends Cliente {
    //atributos especificos de PJ

    public boolean isDocumentoValido() {
        //validacao de CNPJ
    }
}

E nas suas consultas você consegue diferenciar quando quiser PF ou PJ ou ambos. Exemplo:

List<PessoaFisica> pfs = em.createQuery(“SELECT pf FROM PessoaFisica pf”, PessoaFisica.class).getResultList();

List<PessoaJuridica> pjs = em.createQuery(“SELECT pj FROM PessoaJuridica pj”, PessoaJuridica.class).getResultList();

List<Cliente> todos = em.createQuery(“SELECT c FROM Cliente c”, Cliente.class).getResultList();