I'm trying to map the following template 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
Attendance 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:
Company:
@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;
}
}
HomeGroup:
@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 Enterprise and GroupAtendance 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 to 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 naming problems, and I made this implementation based on this Hebert's blog post .
Does anyone have any ideas? Thank you in advance.