Jaxb and JPA: class Embeddable Could not determine type for java.util.List

Asked

Viewed 87 times

0

I’m trying to incorporate a class into another class. I’ve been able to do this in other scenarios, however, by the error shown below, I’m not getting it now.

javax.persistence.PersistenceException: [PersistenceUnit: nfse] Unable to build Hibernate SessionFactory
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.persistenceException(EntityManagerFactoryBuilderImpl.java:967)
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:892)
    at org.hibernate.jpa.HibernatePersistenceProvider.createEntityManagerFactory(HibernatePersistenceProvider.java:58)
    at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:55)
    at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:39)
    at nfse.dao.BaseDao.getEntityManager(BaseDao.java:43)
    at nfse.dao.BaseDao.insert(BaseDao.java:85)
    at nfse.service.Envio.criarNFSETeste(Envio.java:182)
    at nfse.controller.Controller.criarNotaFiscalTeste(Controller.java:260)
    at nfse.NfseVersao.main(NfseVersao.java:14)
Caused by: org.hibernate.MappingException: Could not determine type for: java.util.List, at table: LoteRps, for columns: [org.hibernate.mapping.Column(rps)]
    at org.hibernate.mapping.SimpleValue.getType(SimpleValue.java:455)
    at org.hibernate.tuple.PropertyFactory.buildStandardProperty(PropertyFactory.java:267)
    at org.hibernate.tuple.component.ComponentMetamodel.<init>(ComponentMetamodel.java:58)
    at org.hibernate.mapping.Component.getType(Component.java:169)
    at org.hibernate.mapping.SimpleValue.isValid(SimpleValue.java:422)
    at org.hibernate.mapping.Property.isValid(Property.java:226)
    at org.hibernate.mapping.PersistentClass.validate(PersistentClass.java:597)
    at org.hibernate.mapping.RootClass.validate(RootClass.java:265)
    at org.hibernate.boot.internal.MetadataImpl.validate(MetadataImpl.java:329)
    at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:451)
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:889)

Below I demonstrate my Beans that originated the error mentioned above.

package nfse.vo;

import java.io.Serializable;
import java.math.BigInteger;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import javax.persistence.AssociationOverride;
import javax.persistence.AssociationOverrides;
import javax.persistence.CascadeType;
import javax.persistence.CollectionTable;
import javax.persistence.Column;
import javax.persistence.ElementCollection;
import javax.persistence.Embeddable;
import javax.persistence.Embedded;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlSchemaType;
import javax.xml.bind.annotation.XmlTransient;
import javax.xml.bind.annotation.XmlType;

/**
 *
 * @author Administrador
 */
@Entity
@Table(name="LoteRps")
@XmlType(name = "tcLoteRps", propOrder={
    "numeroLote",
    "cnpj",
    "inscricaoMunicipal",
    "quantidadeRps",
    "listaRps"

})
public class LoteRpsV3Vo implements Serializable
{
    private String id;
    private BigInteger numeroLote;
    private String cnpj;
    private String inscricaoMunicipal;
    private Integer quantidadeRps;
    private LoteRpsV3Vo.ListaRps listaRps;
    private LocalDateTime dataRecebimento;
    private String protocolo;
    private byte situacao;
    private MensagemRetornoV3Vo mensagemRetorno;

    public LoteRpsV3Vo() {
    }

    @Override
    public String toString() {
        return "LoteRpsV3Vo{" + "id=" + id + ", numeroLote=" + numeroLote + ", cnpj=" + cnpj + ", inscricaoMunicipal=" + inscricaoMunicipal + ", quantidadeRps=" + quantidadeRps + ", listaRps=" + listaRps + ", dataRecebimento=" + dataRecebimento + ", protocolo=" + protocolo + ", situacao=" + situacao + ", mensagemRetorno=" + mensagemRetorno + '}';
    }

    @Override
    public int hashCode() {
        int hash = 5;
        hash = 29 * hash + Objects.hashCode(this.id);
        return hash;
    }

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

    // getters e setters
    @Id
    @Column(nullable = false, length = 255, unique = true)
    @XmlAttribute(name = "Id")
    public String getId() {
        return id;
    }

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

    @Column(nullable = false, length = 15, unique = true)
    @XmlElement(name = "NumeroLote", required = true)
    @XmlSchemaType(name = "nonNegativeInteger")
    public BigInteger getNumeroLote() {
        return numeroLote;
    }

    public void setNumeroLote(BigInteger numeroLote) {
        this.numeroLote = numeroLote;
    }

    @Column(nullable = false, length = 14)
    @XmlElement(name = "Cnpj", required = true)
    public String getCnpj() {
        return cnpj;
    }

    public void setCnpj(String cnpj) {
        this.cnpj = cnpj;
    }

    @Column(nullable = false, length = 15)
    @XmlElement(name = "InscricaoMunicipal", required = true)
    public String getInscricaoMunicipal() {
        return inscricaoMunicipal;
    }

    public void setInscricaoMunicipal(String inscricaoMunicipal) {
        this.inscricaoMunicipal = inscricaoMunicipal;
    }

    @Column(nullable = false, length = 4)
    @XmlElement(name = "QuantidadeRps")
    public Integer getQuantidadeRps() {
        return quantidadeRps;
    }

    public void setQuantidadeRps(Integer quantidadeRps) {
        this.quantidadeRps = quantidadeRps;
    }

    @XmlElement(name = "ListaRps", required = true)
    @Embedded
    @AssociationOverride(name = "listaRps.rps",
            joinColumns = @JoinColumn(name = "loteRpsId")
    )
    public ListaRps getListaRps() {
        return listaRps;
    }

    public void setListaRps(ListaRps listaRps) {
        this.listaRps = listaRps;
    }

    @Column
    @XmlTransient
    public LocalDateTime getDataRecebimento() {
        return dataRecebimento;
    }

    public void setDataRecebimento(LocalDateTime dataRecebimento) {
        this.dataRecebimento = dataRecebimento;
    }

    @Column
    @XmlTransient
    public String getProtocolo() {
        return protocolo;
    }

    public void setProtocolo(String protocolo) {
        this.protocolo = protocolo;
    }

    @Column
    @XmlTransient
    public byte getSituacao() {
        return situacao;
    }

    public void setSituacao(byte situacao) {
        this.situacao = situacao;
    }

    @OneToOne(mappedBy = "loteRps", cascade = CascadeType.PERSIST, fetch = FetchType.LAZY, orphanRemoval = true)
    @XmlTransient
    public MensagemRetornoV3Vo getMensagemRetorno() {
        return mensagemRetorno;
    }

    public void setMensagemRetorno(MensagemRetornoV3Vo mensagemRetorno) {
        this.mensagemRetorno = mensagemRetorno;
    }

    @XmlAccessorType(XmlAccessType.FIELD)
    @XmlType(name = "", propOrder = {
        "rps"
    })
    @Embeddable
    public static class ListaRps
    {
        @XmlElement(name = "Rps", required = true)
        @OneToMany(cascade = CascadeType.PERSIST)
        @JoinColumn(name = "loteRpsId")
        protected List<RpsV3Vo> rps;

        public List<RpsV3Vo> getRps() {
            if (rps == null)
            {
                rps = new ArrayList<>();
            }
            return rps;
        }   
    }
}


package nfse.vo;

import java.io.Serializable;
import java.util.Objects;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Embedded;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.ForeignKey;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;
import javax.xml.bind.annotation.XmlType;

/**
 *
 * @author Administrador
 * Representa a estrutura do Recibo Provisório de Serviço (RPS)
 */
@Entity
@Table(name="Rps")
@XmlType(name = "tcRps", propOrder={
    "infRps"
})
public class RpsV3Vo implements Serializable
{
    // atributos
    private Integer id;
    private InfRpsV3Vo infRps;

    // construtor padrão
    public RpsV3Vo() {
    }

    // métodos
    @Override
    public String toString() {
        return "RpsV3Vo{" + "id=" + id + ", infRps=" + infRps + '}';
    }

    @Override
    public int hashCode() {
        int hash = 5;
        hash = 37 * hash + Objects.hashCode(this.id);
        return hash;
    }

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

    // getters e setters
    @Id
    @Column
    @GeneratedValue(strategy = GenerationType.AUTO)
    @XmlTransient
    public Integer getId() {
        return id;
    }

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

    @OneToOne(cascade = CascadeType.PERSIST, fetch = FetchType.LAZY)
    @JoinColumn(name = "infRpsId", referencedColumnName = "id",
            nullable = false, foreignKey = @ForeignKey(name = "fkRpsInfRps"))
    @XmlElement(name = "InfRps", required = true)
    public InfRpsV3Vo getInfRps() {
        return infRps;
    }

    public void setInfRps(InfRpsV3Vo InfRps) {
        this.infRps = InfRps;
    }

}

Below my method that inserts the objects in the database

public Object insert (Object obj)
{
    this.em = getEntityManager();
    EntityTransaction et = this.em.getTransaction();
    et.begin();
    try {
        this.em.merge(obj);
        this.em.flush();
        et.commit();
        return obj;
    } catch(Throwable e) {
        e.printStackTrace();
        et.rollback();
    } finally {
        this.em.close();
    }
    throw new UnsupportedOperationException("Not supported yet.");
}

Below the controller method that makes the necessary calls to carry out your task.

public EnvioLREV3Vo criarNFSETeste() throws DatatypeConfigurationException
{

    BaseDao dao = new LoteRpsDao();

    // crio o lote
    LoteRpsV3Vo loteRps = new LoteRpsV3Vo();
    loteRps.setId("002457");
    loteRps.setNumeroLote(new BigInteger("002457"));
    loteRps.setCnpj("07331220000147");
    loteRps.setInscricaoMunicipal("1981905");
    loteRps.setQuantidadeRps(1);

    // crio o rps
    RpsV3Vo rps = new RpsV3Vo();

    // crio InfRps
    InfRpsV3Vo infRps = new InfRpsV3Vo();
    infRps.setId("002457");
    // crio IdentificacaoRps
    IdentificacaoRpsV3Vo identificacaoRps = new IdentificacaoRpsV3Vo();
    identificacaoRps.setNumero(new BigInteger("002457"));
    identificacaoRps.setSerie("A");
    byte t = 1;
    identificacaoRps.setTipo(t);
    infRps.setIdentificacaoRps(identificacaoRps);

    infRps.setDataEmissao(LocalDateTime.now());
    byte no = 1;
    infRps.setNaturezaOperacao(no);
    byte ret = 6;
    infRps.setRegimeEspecialTributacao(ret);
    byte osn = 1;
    infRps.setOptanteSimplesNacional(osn);
    byte ic = 2;
    infRps.setIncentivadorCultural(ic);
    byte s = 1;
    infRps.setStatus(s);

    // crio DadosServico
    DadosServicoV3Vo servico = new DadosServicoV3Vo();
    // crio Valores
    ValoresV3Vo valores = new ValoresV3Vo();
    valores.setValorServicos(new BigDecimal("70.00"));
    valores.setValorDeducoes(new BigDecimal("0.00"));
    valores.setValorPis(new BigDecimal("0.00"));
    valores.setValorCofins(new BigDecimal("0.00"));
    valores.setValorInss(new BigDecimal("0.00"));
    valores.setValorIr(new BigDecimal("0.00"));
    valores.setValorCsll(new BigDecimal("0.00"));
    byte ir = 2;
    valores.setIssRetido(ir);
    valores.setValorIss(new BigDecimal("0.00"));
    valores.setBaseCalculo(new BigDecimal("70.00"));
    valores.setAliquota(new BigDecimal("0.0423"));
    valores.setValorLiquidoNfse(new BigDecimal("70.00"));
    valores.setDescontoCondicionado(new BigDecimal("0.00"));
    valores.setDadosServico(servico);

    servico.setValores(valores);
    servico.setItemListaServico("1.03");
    servico.setCodigoTributacaoMunicipio("631190001");
    servico.setDiscriminacao("Comissao IATA R$ 50,00");
    servico.setCodigoMunicipio(3133808);

    infRps.setServico(servico);

    // crio IdentificacaoPrestador
    IdentificacaoPrestadorV3Vo identificacaoPrestador = new IdentificacaoPrestadorV3Vo();
    identificacaoPrestador.setCnpj("07331220000147");
    identificacaoPrestador.setInscricaoMunicipal("1981905");
    infRps.setPrestador(identificacaoPrestador);

    // cria DadosTomador
    DadosTomadorV3Vo tomador = new DadosTomadorV3Vo();
    // add uma IdentificacaoTomador para DadosTomador
    IdentificacaoTomadorV3Vo identificacaoTomador = new IdentificacaoTomadorV3Vo();
    // add CpfCnpj em IdentificacaoTomador
    CpfCnpjV3Vo cpfCnpj = new CpfCnpjV3Vo();
    cpfCnpj.setCnpj("17609594000801");

    identificacaoTomador.setCpfCnpj(cpfCnpj);

    tomador.setIdentificacaoTomador(identificacaoTomador);
    tomador.setRazaoSocial("ALJA HOTELARIA E SERVIçOS LTDA - EPP");
    // cria Endereco para o Tomador
    EnderecoV3Vo tendereco = new EnderecoV3Vo();
    tendereco.setEndereco("Avenida 1");
    tendereco.setNumero("926");
    tendereco.setBairro("CENTRO");
    tendereco.setCodigoMunicipio(3543907);
    tendereco.setUf("SP");
    tendereco.setCep(37800000);
    tomador.setEndereco(tendereco);

    // cria Contato para o Tomador
    ContatoV3Vo tcontato = new ContatoV3Vo();
    tcontato.setTelefone("3587205239");
    tcontato.setEmail("[email protected]");
    tomador.setContato(tcontato);
    infRps.setTomador(tomador);

    rps.setInfRps(infRps);

    RpsV3Vo mRps = (RpsV3Vo) dao.insert(rps);

    LoteRpsV3Vo.ListaRps listaRps =new  LoteRpsV3Vo.ListaRps();
    listaRps.getRps().add(mRps);
    loteRps.setListaRps(listaRps);

    LoteRpsV3Vo mLoteRps = (LoteRpsV3Vo) dao.insert(loteRps);

    // crio o envio
    EnvioLREV3Vo envio = new EnvioLREV3Vo();
    envio.setLoteRps(mLoteRps);

    return envio;
}

The JAXB creates this class "@Embeddable public Static class Listarps" within the scope of the class "public class Loterpsv3vo Implements Serializable" per command line.

These classes were handwritten, but based on these generated classes. If I remove this class "@Embeddable public static class ListaRps" and migrate your attribute "protected List<RpsV3Vo> rps;" for the class "public class LoteRpsV3Vo implements Serializable" I can insert the persistent objects into the database, but I want to do it this way, because these classes are created by the command line by JAXB based on archives .XSD provided by a API.

In this context, the parse of a XML to a system object or a system object to a XML is trivial.

1 answer

0

You are mixing different AccessType in the same class. In the top level class LoteRpsV3Vo you are using AccessType.PROPERTY (getters annotated), so Hibernate expects to find the annotations in getters of nested class ListaRps, as it does not find, it throws this exception.

To solve this, you could add getters and setters in your class ListaRps and write them down.

@Entity
@Table(name="LoteRps")
@XmlType(name = "tcLoteRps", propOrder={
    "numeroLote",
    "cnpj",
    "inscricaoMunicipal",
    "quantidadeRps",
    "listaRps"

})
public class LoteRpsV3Vo {

    //Resto da sua classe LoteRpsV3Vo

    @Embeddable
    public static class ListaRps {

        protected List<RpsV3Vo> rps;

        @XmlElement(name = "Rps", required = true)
        @OneToMany(cascade = CascadeType.PERSIST)
        @JoinColumn(name = "loteRpsId")
        public List<RpsV3Vo> getRps() {
            if (rps == null) {
                rps = new ArrayList<>();
            }
            return rps;
        }

        public void setRps(List<RpsV3Vo> rps) {
            this.rps = rps;
        }
    }
}

Or add the annotation @Access with the value AccessType.FIELD (indicates that attributes are annotated) in your class ListaRps:

@Entity
@Table(name="LoteRps")
@XmlType(name = "tcLoteRps", propOrder={
    "numeroLote",
    "cnpj",
    "inscricaoMunicipal",
    "quantidadeRps",
    "listaRps"

})
public class LoteRpsV3Vo {

    //Resto da sua classe LoteRpsV3Vo

    @Embeddable
    @Access(AccessType.FIELD)
    public static class ListaRps {

        @XmlElement(name = "Rps", required = true)
        @OneToMany(cascade = CascadeType.PERSIST)
        @JoinColumn(name = "loteRpsId")
        protected List<RpsV3Vo> rps;

        public List<RpsV3Vo> getRps() {
            if (rps == null) {
                rps = new ArrayList<>();
            }
            return rps;
        }
    }
}

Browser other questions tagged

You are not signed in. Login or sign up in order to post.