Como posso representar muitos para muitos relação à mesma tabela / entidade em hibernação?

votos
0

Isso é possível? Quero dizer, possa ambas as extremidades do ponto de muitos para muitos relação à mesma tabela?

Publicado 10/12/2008 em 04:49
fonte usuário
Em outras línguas...                            


2 respostas

votos
1

Eu não sei como você faria isso sem um enorme redundância, horrível. A forma padrão para lidar com uma relação de n para n entre duas mesas é através de uma terceira tabela que contém dois valores primários chave, uma para o primeiro quadro, um para a segunda tabela, com uma restrição única (li 'índice') sobre a combinação de todas as colunas, e, possivelmente, com um ou dois duplicados índices (não-exclusivos) sobre as chaves primárias separadas. Em linhas gerais:

CREATE TABLE Table1 (pkcol1 ... PRIMARY KEY, ...);
CREATE TABLE Table2 (pkcol2 ... PRIMARY KEY, ...);
CREATE TABLE MtoM_Table1_Table2
(
     pkcol1 ... REFERENCES Table1,
     pkcol2 ... REFERENCES Table2,
     PRIMARY KEY (pkcol1, pkcol2)
);
-- CREATE INDEX fk1_mtom_table1_table2 ON MtoM_Table1_Table2(pkcol1);
-- CREATE INDEX fk2_mtom_table1_table2 ON MtoM_Table1_Table2(pkcol2);

Se o seu DBMS é inteligente, você pode pular o índice separado na coluna à esquerda da chave principal desde que o índice na chave primária também pode ser usada para buscar o justo valor de liderança.

Suponha Table1 e Table2 são a mesma tabela (que, na verdade, temos apenas Tabela 1), como na questão; isso normalmente ainda exigem o mapeamento da tabela MtoM_Table1_Table1 - uma tabela separada da mesa principal. A tabela de mapeamento deve ter nomes separados para a coluna de PK (chave primário), mas ambas as colunas (ou conjuntos de colunas) na tabela de mapeamento irá referir-se à coluna (s) de PK em Tabela 1.

CREATE TABLE Table1 (pkcol1 ... PRIMARY KEY, ...);
CREATE TABLE MtoM_Table1_Table1
(
     pkcol1 ... REFERENCES Table1(pkcol1),
     akcol1 ... REFERENCES Table1(pkcol1),
     PRIMARY KEY (pkcol1, akcol1)
);
-- CREATE INDEX fk1_mtom_table1_table1 ON MtoM_Table1_Table1(pkcol1);
-- CREATE INDEX fk2_mtom_table1_table1 ON MtoM_Table1_Table1(akcol1);

Se você queria eliminar a tabela de mapeamento também, então você teria que ter uma segunda coluna na tabela 1 para segurar o outro valor PK - chamá-lo FKcol1 (para a coluna de chave estrangeira). Isso, então, deixa-o com um dilema: o que é a chave primária? Tem que ser a combinação de PKCol1 e FKCol1. Mas FKCol1 é suposto fazer referência a chave primária de outra linha - então você tem uma contradição. Mesmo supondo que você conseguiu evitar isso como um problema (como, exatamente?), Para ter 'muitas linhas' no lado de referência do relacionamento muitos-para-muitos, você deve ter várias linhas na tabela principal com os mesmos dados em todas as colunas, com excepção FKcol, mas estes irão fazer referência a um número (mais do que um, em geral) outras linhas da tabela. Isto é uma contradição mais um pesadelo de redundância, além de você perdeu sua chave primária simples,

CREATE TABLE Table1
(
    pkcol1 ... /* PRIMARY KEY */,
    fkcol1 ... /* FOREIGN KEY REFERENCES Table1(pkcol1) */,
    ...
);
-- CREATE INDEX fk1_table1 ON Table1(pkcol1);
-- CREATE INDEX fk2_table1 ON Table1(fkcol1);

Então, eu estou convencido de que a única resposta sensata é "Não - você não pode representar ambas as extremidades de um relacionamento muitos-para-muitos na mesma tabela, você deve usar uma tabela de mapeamento para reter muita chance de nada de trabalho 'como de costume' no sistema".

Respondeu 10/12/2008 em 05:49
fonte usuário

votos
0

Se você estiver usando hibernate-anotações, há uma @ManyToMany, não tenho certeza sobre o equivalente XML. Ele deve aparecer na documentação da API da sua distribuição

Respondeu 10/12/2008 em 04:50
fonte usuário

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more