Exception org.hibernate.Propertyaccessexception: could not set a field value by Reflection Setter

Asked

Viewed 2,235 times

2

I’m trying to map the following model in JPA with Hibernate:

Company table:

CREATE TABLE empresa (
  id_empresa INT(11) NOT NULL AUTO_INCREMENT ,
  PRIMARY KEY (id_empresa) )
ENGINE = InnoDB
DEFAULT CHARACTER SET = latin1
ROW_FORMAT = FIXED

Contact group table:

CREATE TABLE grupo_atendimento` (
  id_grupo_atendimento INT(11) NOT NULL AUTO_INCREMENT ,
  ddd VARCHAR(2) NOT NULL ,
  PRIMARY KEY (id_grupo_atendimento) )
ENGINE = InnoDB

N-N associative table with extra field:

CREATE TABLE grupo_atendimento_empresa (
  `id_grupo_atendimento` INT(11) NOT NULL ,
  `id_empresa` INT(11) NOT NULL ,
  `contador` INT(11) UNSIGNED NOT NULL DEFAULT 0 ,
  PRIMARY KEY (`
id_grupo_atendimento`, `id_empresa`) ,
  INDEX `fk_tbl_fises_ddd_empresa_tbl_fises_ddd1` (`id_grupo_atendimento` ASC) ,
  INDEX `fk_tbl_fises_ddd_empresa_tbl_empresa1` (`id_empresa` ASC) ,
  CONSTRAINT `fk_tbl_fises_ddd_empresa_tbl_fises_ddd1`
    FOREIGN KEY (`id_grupo_atendimento` )
    REFERENCES `infolog`.`tbl_fises_grupo_atendimento` (`id_grupo_atendimento` )
    ON DELETE NO ACTION
    ON UPDATE NO ACTION,
  CONSTRAINT `fk_tbl_fises_ddd_empresa_tbl_empresa1`
    FOREIGN KEY (`id_empresa` )
    REFERENCES `infolog`.`tbl_empresa` (`id_empresa` )
    ON DELETE NO ACTION
    ON UPDATE NO ACTION)
ENGINE = InnoDB

To reflect this model in Java, I created the classes below:

Enterprise:

@Entity
@Table(name="empresa")
public class Empresa {

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY) 
    @Column(name="id_empresa")
    private Integer id;

    @OneToMany(mappedBy = "empresa")
    private List<GrupoAtendimentoEmpresa> gruposAtendimento;

    public Integer getId() {
        return this.id;
    }

    public List<GrupoAtendimentoEmpresa> getGruposAtendimento() {
        return gruposAtendimento;
    }

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

    public void setGruposAtendimento(List<GrupoAtendimentoEmpresa> gruposAtendimento) {
        this.gruposAtendimento = gruposAtendimento;
    }
}

Groupbuilding:

@Entity
@Table(name = "grupo_atendimento")
public class GrupoAtendimento {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id_grupo_atendimento")
    private Integer id;

    @Column(name = "ddd")
    private String ddd;

    @OneToMany(mappedBy = "grupoAtendimento")
    private List<GrupoAtendimentoEmpresa> representantesTecnicos;

    public Integer getId() {
        return id;
    }

    public String getDdd() {
        return ddd;
    }

    public List<GrupoAtendimentoEmpresa> getRepresentantesTecnicos() {
        return representantesTecnicos;
    }

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

    public void setDdd(String ddd) {
        this.ddd = ddd;
    }

    public void setTechnicalRepresentatives(
            List<GrupoAtendimentoEmpresa> representantesTecnicos) {
        this.representantesTecnicos = representantesTecnicos;
    }
}

Association between Company and Group with the extra field, using another class as Idclass:

@Entity
@Table(name = "grupo_atendimento_empresa")
@IdClass(GrupoAtendimentoEmpresaId.class)
public class GrupoAtendimentoEmpresa {

    @Id
    @ManyToOne
    @JoinColumn(name = "id_grupo_atendimento")
    private GrupoAtendimento grupoAtendimento;

    @Id
    @ManyToOne
    @JoinColumn(name = "id_empresa")
    private Empresa empresa;

    @Column(name = "contador")
    private Integer contador;

    public GrupoAtendimento getGrupoAtendimento() {
        return grupoAtendimento;
    }

    public Empresa getEmpresa() {
        return empresa;
    }

    public Integer getContador() {
        return contador;
    }

    public void setGrupoAtendimento(GrupoAtendimento grupoAtendimento) {
        this.grupoAtendimento = grupoAtendimento;
    }

    public void setEmpresa(Empresa empresa) {
        this.empresa = empresa;
    }

    public void setContador(Integer contador) {
        this.contador = contador;
    }
}

And finally the Idclass:

public class GrupoAtendimentoEmpresaId implements Serializable {
    private static final long serialVersionUID = -3138856182021663633L;

    @Column(name = "id_grupo_atendimento")
    private int grupoAtendimento;

    @Column(name = "id_empresa")
    private int empresa;

    public int getGrupoAtendimento() {
        return grupoAtendimento;
    }

    public int getEmpresa() {
        return empresa;
    }

    public void setGrupoAtendimento(int grupoAtendimento) {
        this.grupoAtendimento = grupoAtendimento;
    }

    public void setEmpresa(int empresa) {
        this.empresa = empresa;
    }

    @Override
    public int hashCode() {
        return grupoAtendimento + empresa;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj instanceof GrupoAtendimentoEmpresaId) {
            GrupoAtendimentoEmpresaId grupoAtendimentoEmpresaId = (GrupoAtendimentoEmpresaId) obj;
            return grupoAtendimentoEmpresaId.grupoAtendimento == grupoAtendimento
                    && grupoAtendimentoEmpresaId.empresa == empresa;
        }

        return false;
    }
}

With the database populated, I tried to run the code below:

GrupoAtendimentoEmpresaId id = new GrupoAtendimentoEmpresaId();
        id.setEmpresa(15513);
        id.setGrupoAtendimento(1);

        GrupoAtendimentoEmpresa grupoEmpresa = entityManager.find(
                GrupoAtendimentoEmpresa.class, id);

And I get the following exception:

javax.persistence.PersistenceException: org.hibernate.PropertyAccessException: could not set a field value by reflection setter of x.y.z.model.GrupoAtendimentoEmpresa.grupoAtendimento

I spent yesterday afternoon scouring the code and found no nomenclature problems, and carried out this implementation based on this blog post do Hebert.

Anyone have any ideas? Thanks in advance.

1 answer

3


Bruno,

In his class GrupoAtendimentoEmpresa, instead of using the @Id annotation in your group and company attributes, add two new attributes (whole type) that represent the ids of these entities and write them down with @Id. Keep going as your class should go below:

@Entity
@Table(name = "grupo_atendimento_empresa")
@IdClass(GrupoAtendimentoEmpresaId.class)
public class GrupoAtendimentoEmpresa {

    @Id
    @Column(name = "id_grupo_atendimento", insertable = false, updatable = false)
    private int grupoAtendimentoId;

    @Id
    @Column(name = "id_empresa", insertable = false, updatable = false)
    private int empresaId;

    @ManyToOne
    @JoinColumn(name = "id_grupo_atendimento")
    private GrupoAtendimento grupoAtendimento;

    @ManyToOne
    @JoinColumn(name = "id_empresa")
    private Empresa empresa;

    @Column(name = "contador")
    private Integer contador;

    // Getters e Setters

}

I found this solution in this link: http://www.java2s.com/Code/Java/JPA/SetIdClassforCompoundKey.htm

  • 1

    I implemented as proposed and worked perfectly, populated the new attributes int and the objects empresa and grupoAtendimento as expected. The only detail is that unlike the link example, I had to leave the annotations @Column in GrupoAtendimentoEmpresaId, I tried to remove and ended up giving SQL syntax error "Unknown column".

Browser other questions tagged

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