JPA - Mapamento de duas ou mais tabelas

Olá pessoal,

Como faço pra mapear duas ou mais tabelas em uma única entidade?

Ex.:

tbConta (id, descricao)
tbPessoaFisica(CPF)
tbPessoaJuridica(CNPJ)

Então quero criar uma entidade PessoaFisica.

PessoaFisica (ID, Descricao e CPF)

E ao persistir, salvar nas suas respectivas tabelas.

Grato,

veja sobre SecondaryTable

http://www.java2s.com/Tutorial/Java/0355__JPA/MapOneEntityToMoreThanOneTable.htm

Pozzo,

Já vi, n consegui implementar, mas ainda acho q algo com herança
seria bom, mas tb n consegui implementar.

Mas vou olhar o tutorial, parece um exemplo bem prático.

Retorno…

Então,

Acho q aquele realmente n é o modelo, pois eu estaria alterando minha entidade Conta
para ter os campos de PessoaJuridica.

Mas eu queria fazer o inverso, PessoaJuridica assumir os campos básicos de Conta,
lembrando q q Conta é q tem a chave primária (auto incrementa), a chave em PessoaJuridica
é apenas a extrangeira.

Certo, entendi. Neste caso é melhor herança mesmo. Qual problema ocorreu? Você conhece as três formas?

*  SINGLE_TABLE: Single-table-per-class inheritance hierarchy
* JOINED: Common base table, with joined subclass tables
* TABLE_PER_CLASS: Single-table-per-outermost concrete entity class

Então, sou zero bala em JPA, Java…, mas acho q o Joined era a melhor solução.

@Entity(name=“conta”)
@Inheritance(strategy=InheritanceType.JOINED)
public class Conta implements Serializable {

@Id
@Column(name="conta_id", insertable=false)
private int contaId;
private String descricao;

… e seus respectivos gets/sets

@Entity(name=“conta_pessoa_juridica”)
@Inheritance(strategy=InheritanceType.JOINED) //este n tinha aqui, vi num exemplo e coloquei
public class PessoaJuridica extends Conta implements Serializable {

@Column(name="pessoa_juridica_fantasia")
private String fantasia;

E dah o seguinte erro ao persistir:

[TopLink Warning]: 2008.12.06 11:47:32.166–UnitOfWork(31817359)–Exception [TOPLINK-4002] (Oracle TopLink Essentials - 2.0.1 (Build b09d-fcs (12/06/2007))): oracle.toplink.essentials.exceptions.DatabaseException
Internal Exception: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column ‘DTYPE’ in 'field list’
Error Code: 1054
Call: INSERT INTO CONTA (conta_id, DESCRICAO, DTYPE) VALUES (?, ?, ?)
bind => [0, Descrição conta…, PessoaJuridica]

Query: InsertObjectQuery(teste.PessoaJuridica@2200d5)
Exception [TOPLINK-4002] (Oracle TopLink Essentials - 2.0.1 (Build b09d-fcs (12/06/2007))): oracle.toplink.essentials.exceptions.DatabaseException
Internal Exception: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column ‘DTYPE’ in 'field list’
Error Code: 1054
Call: INSERT INTO CONTA (conta_id, DESCRICAO, DTYPE) VALUES (?, ?, ?)
bind => [0, Descrição conta…, PessoaJuridica]
Query: InsertObjectQuery(teste.PessoaJuridica@2200d5)
CONSTRUÍDO COM SUCESSO (tempo total: 5 segundos)

Pq DTYPE? :slight_smile:

Ops… faltou completar, dá erro ao tentar persistir!

faltam as anotações @DiscriminatorColumn.
veja este link para mais detalhes:

http://download.oracle.com/docs/cd/B31017_01/web.1013/b28221/cmp30cfg016.htm

Agora me perdi.

With the join table strategy there is a table per class in the hierarchy, but the subclass tables only have the extra attribute they define in their subclass. A discriminator column is NOT required to differentiate between which class type is persisted in a particular row unlike the single table mapping. The persistence manager does not need a discrimiator column to figure out the type.

This is what the annotations look like for Pet.

@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public class Pet implements java.io.Serializable
{

@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public class Dog extends Pet
{

Curioso, na verdade eu também acho desnecessário o uso de discriminator neste caso, pois você pode descobrir o tipo da entidade através do join.

Bom, talvez seja uma particularidade do TopLink, já que o trecho que você citou acima é da JBoss (Hibernate).

Mas faça um teste adicionando discriminator. Um outro teste bacana é habilitar a impressão de sqls e substituir o Toplink pelo Hibernate, e ver se continua funcionando.

Eu n to conseguindo nem usar o TopLink… quem dirá o Hibernate *rrr, pelo q vi há configurações a mais.

Tá f… se eu conseguir fazer isso sem muitos problemas e conseguir usar o jComboBox com duas colunas
(sem problemas), faço o projeto q tenho pra fazer em Java, se não, volto pro C#, fico preso em coisas q
só consegui um pouco de ajuda aqui no forum mesmo, mas acho q ainda falta material na net. Isso que
me preocupa, mas vamos lah… tô aqui desde as 6 da manha pra fazer isso e n saí do lugar, nossa!

Por enqto, obrigado pela atenção dispensada.

Olha, discordo sobre a quantidade de material. Na verdade, acho que até tem bastânte material por ai. Mas é necessário um certo tempo para absorver. Agora, se você conhece melhor C# do que Java e tem pressa para finalizar este projeto, talvez seja a melhor opção mesmo.
Se tem tiver tempo e paciência, talvez Java seja uma boa opção também.

Poste seus problemas. Aliás, o discriminator funcionou?

Olá pozzo,

Desculpa a demora em responder, funcionou sim, brigadão!
Tô apanhando agora no passo seguitne:

//ENTIDADE PRINCIPAL
@Entity
@Table(name = “cad_conta”)
@Inheritance(strategy=InheritanceType.JOINED)
@DiscriminatorColumn(name=“pj”, discriminatorType=DiscriminatorType.STRING,length=1)
@DiscriminatorValue(“0”)
public class Conta implements Serializable {

//ENTIDADES SECUNDARIA…
@Entity
@Table(name=“cad_conta_pessoa_fisica”)
@DiscriminatorValue(“F”)
public class PessoaFisica extends Conta implements Serializable {

@Entity
@Table(name = “cad_conta_pessoa_juridica”)
@DiscriminatorValue(“J”)
public class PessoaJuridica extends Conta implements Serializable

Ele criou e as tabelas ok e a persistencia tb foi blz.

Agora n consigo recuperar os dados:

Tento puxar todos de Contas (Select c FROM Conta c) e o erro é este:

Exception Description: Missing class for indicator field value [O] of type [class java.lang.String].
Descriptor: RelationalDescriptor(br.com.yeld.phenix.entidade.Conta --> [DatabaseTable(cad_conta)])
Exception in thread “main” Local Exception Stack:
Exception [TOPLINK-43] (Oracle TopLink Essentials - 2.0.1 (Build b09d-fcs (12/06/2007))): oracle.toplink.essentials.exceptions.DescriptorException
Exception Description: Missing class for indicator field value [O] of type [class java.lang.String].
Descriptor: RelationalDescriptor(br.com.yeld.phenix.entidade.Conta --> [DatabaseTable(cad_conta)])

Tô me batendo aqui… já tinha visto algo assim?

Sobre material Java, tem muito sim, mas pelo tamanho da comunidade, eu esperava um tikin mais, muita
gente fala mal da MS, mas pelo menos nesse ponto *r eles são bem bons.
Sobre a decisão, realmente ainda tô em dúvida. Tenho tempo bastante, o projeto q estamos fazendo não é sob
encomenda, apesar de já ter perdido algumas oportunidades, a pressa seria nossa mesmo. Daí realmente ainda
tenho dúvidas, pq tô passando por problemas que eu n teria no C#, pela experiência q tenho nele. Com C# eu
sei q o desenvolvimento seria mais rápido e tb sei q a execução do programa é em uma velocidade agradável.
Em java, pra mim tudo é novo, vou gastar mais tempo pra desenvolver, isso eu sei, n sei ainda a questão da
performance, o quão mais lento ele pode ser, já q estou usando JPA e ao contrário do EntityFramework (.net),
ele não trabalha com Stored Procedures (até onde sei), então sei q se eu fosse usá-las em C#, teria um ganho
de performance considerável e independente disso, ele executa bem legal…
Mas mesmo com “tudo” isso, há uma coisa q me atrai no java, e que tem pesado muito, que é o fato de
ser multiplataforma, é justamente isso q me fez me interessar por ele, pois gostei muito do Ubuntu.
O que pretendo é passar mais uns 30 a 40 dias tentando java e fazer alguns testes depois, se eu perceber que
não vai ser muita vantagem pra mim, continuo o que já tinha feito no C#, caso contrário, adoto o Java para pelo
menos esse projeto.

Grande abraço.

Opa, foi vacilo meu, o código está certo, o problema foi que eu tinha preenchido a tabela não mão mesmo,
e tinha colocado “o” ao invés de “O”.

Tah funcionando bala, esbarrei num outro prob, mas vou futucar um pouco mais.

Falew!