Se estamos trabalhando em qualquer aplicação hibernate ou estamos planejando trabalhar em qualquer no futuro, então você pode facilmente entender as relações um-a-um entre várias entidades na aplicação. Neste exemplo de mapeamento de hibernação um-para-um, vamos discutir 4 variações diferentes.
Table of ContentsVarious supported techniques for one to one mapping1. Using foreign key association2. Using join table3. Using shared primary key4. @MapsId
Para este exemplo de mapeamento de hibernação um-para-um, estou estendendo o exemplo escrito para o exemplo de hibernação olá mundo. Nós temos duas entidades aqui: Employee
e Account
.
Um empregado pode ter apenas uma conta. Da mesma forma, uma conta será associada a apenas um funcionário. É uma relação de um para um para este exemplo.
Várias técnicas suportadas
Em hibernar existem 3 formas de criar relações de um para um entre duas entidades. De qualquer forma temos de usar a anotação @OneToOne.
- A primeira técnica é mais usada e usa uma coluna de chave estrangeira em uma das tabelas.
- Segunda técnica usa uma solução bastante conhecida de ter uma terceira tabela para armazenar mapeamento entre as duas primeiras tabelas.
- Terceira técnica é algo novo que usa um valor de chave primária comum em ambas as tabelas.
Hibernar um para um mapeamento com associação de chave estrangeira
Neste tipo de associação, uma coluna de chave estrangeira é criada na entidade proprietária. Por exemplo, se nós fizermos EmployeeEntity owner, então uma coluna extra "ACCOUNT_ID"
será criada em Employee
tabela. Esta coluna irá armazenar a chave estrangeira para Account
tabela.
Table structure will be like this:
Para fazer tal associação, consulte a entidade Account
em EmployeeEntity
classe como segue:
@OneToOne@JoinColumn(name="ACCOUNT_ID")private AccountEntity account;
A coluna join é declarada com a anotação @JoinColumn que se parece com a anotação @Column. Ela tem mais um parâmetro chamado referencedColumnName
. Este parâmetro declara a coluna na entidade alvo que será usada para o join.
Se não @JoinColumn
for declarado no lado do dono, os padrões se aplicam. Uma(s) coluna(s) de join será(ão) criada(s) na tabela do dono e seu nome será a concatenação do nome da relação no lado do dono, _ (sublinhado), e o nome da(s) coluna(s) de chave primária(s) no lado do dono.
Numa relação bidirecional, um dos lados (e apenas um) tem que ser o dono. O proprietário é responsável pela atualização da(s) coluna(s) da associação. Para declarar um lado como não responsável pela relação, é utilizado o atributo mappedBy. O atributo ‘mappedBy’ refere-se ao nome da propriedade da associação no lado do proprietário.
@OneToOne(mappedBy="account")private EmployeeEntity employee;
Acima de "mappedBy
” declara que é dependente da entidade proprietária para o mapeamento.
Vamos testar os mapeamentos acima no código em execução:
Executar código acima cria o esquema desejado no banco de dados e executa estas consultas SQL.
Pode verificar os dados e mapeamentos em ambas as tabelas quando correr acima do programa.
Hibernar um para um mapeamento com a tabela comum de join
Esta abordagem não é nova para todos nós. Vamos começar com a estrutura de BD alvo nesta técnica.
Nesta técnica, a anotação principal a ser usada é @JoinTable. Esta anotação é usada para definir o novo nome da tabela (obrigatório) e chaves estrangeiras de ambas as tabelas. Vamos ver como é usada:
@JoinTable a anotação é usada em EmployeeEntity
classe. Ela declara que uma nova tabela EMPLOYEE_ACCOUNT
será criada com duas colunas EMPLOYEE_ID
(chave primária da tabela EMPLOYEE) e ACCOUNT_ID
(chave primária da tabela ACCOUNT).
Teste acima das entidades gera as seguintes consultas SQL em arquivos de log:
Hibernar um a um mapeamento com chave primária compartilhada
Nesta técnica, hibernar garantirá que ele usará um valor de chave primária comum em ambas as tabelas. Desta forma a chave primária de EmployeeEntity
pode ser assumida com segurança a chave primária de AccountEntity
também.
Estrutura de tabela será assim:
Nesta abordagem, @PrimaryKeyJoinColumn é a anotação principal a ser usada. Vamos ver como usá-la.
@OneToOne(cascade = CascadeType.ALL)@PrimaryKeyJoinColumnprivate AccountEntity account;
Em AccountEntity
lado, ela permanecerá dependente da entidade proprietária para o mapeamento.
@OneToOne(mappedBy="account", cascade=CascadeType.ALL)private EmployeeEntity employee;
Testar as entidades acima gera as seguintes consultas SQL em arquivos de log:
Hibernar um a um mapeamento com @MapsId
Nesta técnica, hibernar assume que tanto o fonte quanto o alvo compartilham os mesmos valores chave primários.
Nesta abordagem, @MapsId é a anotação principal a ser usada. Vamos ver como utilizá-la.
Em AccountEntity
lado, ela permanecerá dependente da entidade proprietária para o mapeamento.
@Idprivate Integer accountId;
Testar as entidades acima gera as seguintes consultas SQL em arquivos de log: