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

0

I'm trying to embed a class inside another class. I've already been able to do this in other scenarios, but for the error shown below, I'm not getting it right 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 show my beans that caused 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 objects into 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 accomplish 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;
}
JAXB creates this class "@Embeddable public static class ListRps" within the scope of the class "public class LoteRpsV3Vo implements Serializable" command line.

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

In this context, parsing an XML for a system object or a system object for an XML is trivial.

    
asked by anonymous 18.12.2017 / 20:58

1 answer

0

You are merging different AccessType into the same class. At the top-level class LoteRpsV3Vo you're using annotated% getters , so Hibernate expects to find annotations in getters from < in> nested class AccessType.PROPERTY , 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 ListaRps with the value @Access (indicates that the attributes are annotated) in your AccessType.FIELD class:

@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;
        }
    }
}
    
19.12.2017 / 12:37