Alguém possui algum exemplo de JPA com chave composta?
Estou tendo vários problemas com isso.
gostaria de um exemplo de um CRUD com chave-composta, já pesquisei e nao achei…
(JPA) Algum exemplo real (Chave-Composta)
20 Respostas
Segue o exemplo :
Omiti os getters and setters.
@Entity
@Table(name="adm03_hierarquia")
public class Hierarquia implements Serializable {
private static final long serialVersionUID = 1L;
@Id
private HierarquiaId id;
@Column(name="hier_visualizacao",length=11,nullable=false)
private String visualizacao;
@Column(name="hier_sn_possui_inferior",length=1,nullable=false)
private String possuiInferior;
Chave composta
@Embeddable
public class HierarquiaId implements Serializable {
private static final long serialVersionUID = 1L;
@Column(name="hier_id_local_referencia",nullable=false)
private int idLocalReferencia;
@Column(name="hier_id_estrutura",nullable=false)
private int idEstrutura;
Este codigo está ligado a logica do sistema que estou desenvolvendo , mas se tiver dúvidas , coloque aí que eu o pessoal vai respondendo.
Marco Aurélio
é pq nao tem lógica os erros que estão dando aqui.
Como você está fazendo para inserir os dados e para a busca?
Para salvar eu uso assim:
manager.persist(hierarquia);
Porém o id tem que estar preenchido.
Lembre que a minha chave é de tipo primitivo, se sua chave for objeto , também precisará preecher antes de mandar persistir.
Para pesquisar a chave composta:
hierarquia = manager.find(Hierarquia.class, id);
Marco Aurélio
Você preencha dessa mesma forma?
Portador portador = new Portador();
PortadorPK pk = new PortadorPK();
pk.setConvenio(998);
pk.setPortador(19668);
portador.setPk(pk);
manager.persist(portador);
??
A chave é assim mesmo.
Porém nao estou vendo na sua classe portador atributos que nao sao chave composta.
Veja o meu codigo para salvar com mais informações
// cria o id
HierarquiaId id = new HierarquiaId();
id.setIdLocalReferencia(idLocalReferencia);
id.setIdEstrutura(idEstrutura);
id.setIdLocalSuperior(idLocalReferencia);
Instancia o objeto
Hierarquia hierarquia = new Hierarquia();
Informa o id para ser persistido
hierarquia = manager.find(Hierarquia.class, id);
Qualquer coisa coloque o erro para tentarmos identificar.
Marco Aurélio
é pq eu omiti os outros atributos da Classe portador, coloquei apenas a chave compsota.
Não da nenhum erro, o problema é que o registro vai corrompido na tabela, ou as vezes grava e nao mostra o registro, eu passo um valor e chega um valor todo estranho…
é pq eu omiti os outros atributos da Classe portador, coloquei apenas a chave compsota.
Não da nenhum erro, o problema é que o registro vai corrompido na tabela, ou as vezes grava e nao mostra o registro, eu passo um valor e chega um valor todo estranho…
Verifique se a chave compostá é com tipo de dado primitivo.
Caso nao seja é preciso navegar até localizar o id da chave.
Exemplo
class Pessoa{
@Id
private id;
}
chave composta
class PessoaPK
private LocalTrabalho local;
private Cargo cargo.
}
Como prencher a chave
PessoaPK pk =new PessoaPK();
pk.setLocalTrabalho.setId(1);
pk.setCargo.setId(32);
Veja este codigo pode conter alguns erros mas olhe o conceito , a navegação que usei para localizar os ids da chave composta.
É necessario localizar a chave.
Verifique se é isso.
Marco Aurélio
é pq eu omiti os outros atributos da Classe portador, coloquei apenas a chave compsota.
Não da nenhum erro, o problema é que o registro vai corrompido na tabela, ou as vezes grava e nao mostra o registro, eu passo um valor e chega um valor todo estranho…
E tem uma classe que nao grava uma coluna da chave composta
Por favor coloque seu código aqui.
public static Comercios populaComercios(){
Comercios comercios = new Comercios();
ComerciosPK pk = new ComerciosPK();
pk.setConvenio(998); //TODO Verificar pq nao está gravando aqui direito.
pk.setComercio(17896);
comercios.setPk(pk);
comercios.setCnpj("99999999999999");
comercios.setRazaoSocial("GUSTAVO TESTE");
comercios.setNomeFantasia("teste");
return comercios;
}
@Embeddable
public class ComerciosPK implements Serializable {
@Column(name="CONVENIO")
private Integer convenio;
@Column(name="COMERCIO")
private long comercio;
private static final long serialVersionUID = 1L;
public ComerciosPK() {
super();
}
public Integer getConvenio() {
return this.convenio;
}
public void setConvenio(Integer convenio) {
this.convenio = convenio;
}
public long getComercio() {
return this.comercio;
}
public void setComercio(long comercio) {
this.comercio = comercio;
}
@Override
public boolean equals(Object o) {
if (o == this) {
return true;
}
if ( ! (o instanceof ComerciosPK)) {
return false;
}
ComerciosPK other = (ComerciosPK) o;
return (this.convenio == other.convenio)
&& (this.comercio == other.comercio);
}
@Override
public int hashCode() {
final int prime = 31;
int hash = 17;
hash = hash * prime + ((int) (this.convenio ^ (this.convenio >>> 32)));
hash = hash * prime + ((int) (this.comercio ^ (this.comercio >>> 32)));
return hash;
}
}
Entity
@Table(name="convenio.comercios")
public class Comercios extends Comercio implements Serializable {
@Id
private ComerciosPK pk;
@ManyToOne
@JoinColumns(
@JoinColumn(name="EMPRESA",referencedColumnName="EMPRESA", insertable=false, updatable=false)
)
private Empresa empresa;
public Empresa getEmpresa() {
return empresa;
}
public void setEmpresa(Empresa empresa) {
this.empresa = empresa;
}
@Column(name="EMPRESA")
private long nroEmpresa;
@Column(name="TIPO_COMERCIO", length=1)
private int tipoComercio;
public int getTipoComercio() {
return tipoComercio;
}
public ComerciosPK getPk() {
return this.pk;
}
public void setPk(ComerciosPK pk) {
this.pk = pk;
}
facade.persist(populaComercios());
omiti alguns get e set…
Esse código não está setando no banco a coluna CONVENIO
Guga , existe algumas coisas que JPA faz em relação a herança , inclusive há bastante discussões sobre assunto no blog da Caelum.
Sinceramente não concordo do jeito JPA faz, e acredito que os DBA’s devem ficar loucos.
Quando estou com um problema parecido com o seu na modelagem dos Entity, eu copio as classes e vou reescrevendo tudo novamente para verificar onde está dando o erro.
Veja, há uma complexidade na sua classe “class Comercios” :
- ela herda “extends Comercio” (verificar a criação do entity comercio)
- acessa Empresa empresa (verificar a criação do entity Empresa)
- tem uma chave composta ComerciosPK pk.
Sugiro que faça passo a passo, para verificar onde está emperrando, pelo menos assim você terá controle, e saberá onde está o erro.
Marco Aurélio
[email removido]
Não há complexidade aonde vc citou, porque as heranças são só classes abstratas, não sao Entidades.
o único problema mesmo é somente a chave composta.
]Guga , existe algumas coisas que JPA faz em relação a herança , inclusive há bastante discussões sobre assunto no blog da Caelum.Sinceramente não concordo do jeito JPA faz, e acredito que os DBA’s devem ficar loucos.
Quando estou com um problema parecido com o seu na modelagem dos Entity, eu copio as classes e vou reescrevendo tudo novamente para verificar onde está dando o erro.
Veja, há uma complexidade na sua classe “class Comercios” :
- ela herda “extends Comercio” (verificar a criação do entity comercio)
- acessa Empresa empresa (verificar a criação do entity Empresa)
- tem uma chave composta ComerciosPK pk.
Sugiro que faça passo a passo, para verificar onde está emperrando, pelo menos assim você terá controle, e saberá onde está o erro.
Marco Aurélio
[email removido]
Ok , me manda a classe empresa , estou simulando aqui.
@Entity
@Table(name="convenio.empresa")
public class Empresa extends br.com.cabal.entity.Empresa implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@NotFound(action=NotFoundAction.IGNORE)
private long empresa;
private Integer convenio;
private String cnpj;
@Column(name="RAZAO_SOCIAL")
private String razaoSocial;
@Column(name="NOME_CARTAO")
private String nomeCartao;
@Column(name="DIA_CORTE")
private Integer diaCorte;
@Column(name="DIA_PAGAMENTO")
private Integer diaPagamento;
...//Tem mais outras propriedades. encapsulamento omitido.
extends br.com.cabal.entity.Empresa
@Entity
@Table(name="convenio.empresa")
@Entity
@Table(name="empresa")
Fiz a mesma coisa da classe comercios tirei o schema "convenio":
@Entity
@Table(name="convenio.comercios")
Segue as classes e a chave composta:
CLASSE EMPRESA ( sem getters e setters)@Entity
@Table(name="empresa")
public class Empresa implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@NotFound(action=NotFoundAction.IGNORE)
private long empresa;
private Integer convenio;
private String cnpj;
@Column(name="RAZAO_SOCIAL")
private String razaoSocial;
@Column(name="NOME_CARTAO")
private String nomeCartao;
@Column(name="DIA_CORTE")
private Integer diaCorte;
@Column(name="DIA_PAGAMENTO")
private Integer diaPagamento;
@Embeddable
public class ComerciosPK implements Serializable {
private static final long serialVersionUID = 1L;
@Column(name="CONVENIO")
private Integer convenio;
@Column(name="COMERCIO")
private long comercio;
@Entity
@Table(name="comercios")
public class Comercios implements Serializable {
private static final long serialVersionUID = 1L;
@Id
private ComerciosPK pk;
//@ManyToOne
//@JoinColumns(
// @JoinColumn(name="EMPRESA",referencedColumnName="EMPRESA", insertable=false, updatable=false)
//)
/**TODO
* Há algum problema com este mapeamento
* favor verificar*/
@Column(name="EMPRESA")
private long nroEmpresa;
@Column(name="TIPO_COMERCIO", length=1)
private int tipoComercio;
BASE DE DADOS
Empresa criada
[code]
# Table "empresa" DDL
CREATE TABLE `empresa` (
`empresa` bigint(20) NOT NULL,
`convenio` int(11) default NULL,
`cnpj` varchar(255) default NULL,
`RAZAO_SOCIAL` varchar(255) default NULL,
`NOME_CARTAO` varchar(255) default NULL,
`DIA_CORTE` int(11) default NULL,
`DIA_PAGAMENTO` int(11) default NULL,
PRIMARY KEY (`empresa`)
) ENGINE=InnoDB DEFAULT CHARSET=latin
# Table "comercios" DDL
CREATE TABLE `comercios` (
`CONVENIO` int(11) NOT NULL,
`COMERCIO` bigint(20) NOT NULL,
`EMPRESA` bigint(20) default NULL,
`TIPO_COMERCIO` int(11) default NULL,
PRIMARY KEY (`CONVENIO`,`COMERCIO`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
´
Marco Aurélio
[email removido]
[/code]
Tentei te mandar um e-mail e nao consegui…
Bom, nao consegui ver diferença do seu código para o meu…
Em relação ao mapeamento, aqui está tudo correto, não aconteceu nenhum erro nada.
Estou tendo alguns probleminhas com a JPA, tem algum e-mail que eu possa te mandar?