As entidades estão configuradas da seguinte forma:
Entidade Regra:
@Entity
@Table(name="regra")
public class Regra implements Serializable{
private Integer cod_regra;
private Collection<RegraProcedimento> cod_procedimento;
@OneToMany(fetch=FetchType.LAZY)
@Cascade(value={org.hibernate.annotations.CascadeType.ALL})
@OrderBy(clause = "codigo")
@JoinColumn(name="cod_regra")
public Collection<RegraProcedimento> getCod_procedimento() {
return cod_procedimento;
}
public void setCod_procedimento(Collection<RegraProcedimento> cod_procedimento) {
this.cod_procedimento = cod_procedimento;
}
//........continua..........//
}
Entidade RegraProcedimento:
public class RegraProcedimento implements Serializable {
private Integer codigo; //Sequencial
private Integer cod_procedimento; //Recebe números aleatórios
private Regra regra; //código da entidade acima
//bi-direcionalidade
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name="cod_regra",nullable = false, insertable = false, updatable = false)
public Regra getRegra() {
return regra;
}
public void setRegra(Regra regra) {
this.regra = regra;
}
//getters and setters
//........continua..........//
}
A entidade RegraProcedimento terá que persistir o código da entidade Regra(foreing key) e o atriburo cod_procedimento o qual os dois serão uma chave composta da entidade RegraProcedimento, ou seja, a chave composta será a foreing key juntamente com o campo da própria tabela.
Abaixo o código que desenvolvi conforme links acima porém não está funcionando:
package com.br.gr.model;
import java.io.Serializable;
import javax.persistence.AttributeOverride;
import javax.persistence.AttributeOverrides;
import javax.persistence.Column;
import javax.persistence.Embeddable;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
@Entity
@Table(name="regra_procedimento")
public class RegraProcedimento implements Serializable {
private Integer codigo;
private Integer cod_procedimento;
private Regra regra;
private RegraProcedimentoKey codRegra_codProcedimento;
public RegraProcedimento(){}
public RegraProcedimento (Regra regra, Integer cod_procedimento){
this.codRegra_codProcedimento = new RegraProcedimentoKey();
this.codRegra_codProcedimento.setCod_regra(regra.getCod_regra());
this.codRegra_codProcedimento.setCod_procedimento(cod_procedimento);
this.regra = regra;
this.cod_procedimento = cod_procedimento;
}
public Integer getCodigo() {
return codigo;
}
public void setCodigo(Integer codigo) {
this.codigo = codigo;
}
@Column(nullable = false, insertable = false, updatable = false)
public Integer getCod_procedimento() {
return cod_procedimento;
}
public void setCod_procedimento(Integer cod_procedimento) {
this.cod_procedimento = cod_procedimento;
}
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name="cod_regra",nullable = false, insertable = false, updatable = false)
public Regra getRegra() {
return regra;
}
public void setRegra(Regra regra) {
this.regra = regra;
}
@EmbeddedId
public RegraProcedimentoKey getCodRegra_codProcedimento() {
return codRegra_codProcedimento;
}
public void setCodRegra_codProcedimento(
RegraProcedimentoKey codRegra_codProcedimento) {
this.codRegra_codProcedimento = codRegra_codProcedimento;
}
@Embeddable
public static class RegraProcedimentoKey implements Serializable{
private Integer cod_regra;
private Integer cod_procedimento;
@Column(name="cod_regra", nullable=false)
public Integer getCod_regra() {
return cod_regra;
}
public void setCod_regra(Integer cod_regra) {
this.cod_regra = cod_regra;
}
@Column(nullable = false)
public Integer getCod_procedimento() {
return cod_procedimento;
}
public void setCod_procedimento(Integer cod_procedimento) {
this.cod_procedimento = cod_procedimento;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + cod_regra;
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
return true;
}
}
}
Ok, já havia observado essa mensagem, mas devido os testes constatei que esse código não está nulo. Abaixo irei adicionar o codigo o qual estou realizando os testes.
//Estou buscando um registro da tabela com todos os campos obrigatórios preenchidos, inclusive cod_regra, observe que o cod_regra = 28
Session s = HibernateTeste.getSession(false);
Criteria cr = s.createCriteria(Regra.class);
cr.add(Restrictions.eq("cod_regra", 28));
//Cast da retorno da consulta para o objeto em questão.
Regra regra = (Regra) cr.uniqueResult();
//Aqui estou utilizando o contrutor criado no código anterior para setar os atributos da classe @Embeddable (para criação da chave primária.
RegraProcedimento rp = new RegraProcedimento(regra,123);//Contrutor que recebe objeto regra e o código onde será a chave composta.
rp.setCodigo(1); //número sequencial qualquer.
//Por se tratar de um relacionamento @OneToMany tenho que adicionar o objeto à uma Lista conforme abaixo.
List<RegraProcedimento> list = new ArrayList<RegraProcedimento>();
list.add(rp);
//Adicionado o objeto RegraProcedimento à lista do objeto Regra.
regra.setCod_procedimento(list);
//Realizo o merge para nao ocorre problemas de objetos duplicados a Session, mas em produção utilizo saveOrUpdate();
s.beginTransaction();
s.merge(regra);
s.flush();
//Após isso ocorre o erro o qual postei anteriormente.
Tentei salvar a Entidade Regra a qual possui uma lista de RegraProcedimento não deu certo.
Teitei salvar a Entidade RegraProcedimento o qual está mapeada com a Entidade Regra e tbm não deu certo.
Havia me atentado a esse problema tbm mas nada deu certo.
qdo vc tenta salvar vc tem q passar um id q esteja cadastrado na outra tabela, e me parece q nessa pesquisa com o criteria essa id 23 não existe dai ele naum axa nd e retorna nada deixando null, saka? debug seu código pra v o q está errando ok?
A consulta que faço cm critéria é buscando justamente um registro existente para não precisar setar todos os códigos nulos.
Fiz o debug varias vezes, conferi os códigos e todos estão preenchidos, inclusive o cod_regra, o qual o banco informa que está nulo.
Googando eu achei exemplos de chave composta utilizando 2 entidades ou apenas duas chaves simples (String ou Integer), mas não achei exemplo onde a chave composta será o código de uma Entidade(cod_regra) externa e um atributo interno (cod_procedimento).
Ja fiz varios testes e nao sei mais o que fazer…hehehe Tem que rir pra não chorar…kkkkk
Se não conseguir resolver vo procurar outra abordagem e refazer o código.