É comum mapeamos, objetos do mundo real ou entidades de negócio em classes Java, essas classes, onde normalmente essas classes representam tabelas em nosso banco objeto relacional. O Java possui uma especificação que nos ajuda a fazer esse link entre nossas classes, o JPA, ele define as regras de implementação e uso, o Hibernate, por exemplo, é uma das bibliotecas e implementa a especificação
O Hibernate também possui uma implementação própria, que diverge da especificação JPA ,mas que foi usada como base para a especificação JPA.
Nesse post, veremos a implementação de um mapeamento um-para-um, faremos o mapeamento do relacionamento
de User
para UserProfile
, onde, cada usuário pode ter apenas um perfil, já que não faz sentido
um usuário possuir múltiplos perfis. Não veremos a parte de configuração de conexão, já que estamos usando
Spring Boot
, e essa parte está
sendo tratada na auto-configuração.
Começaremos mapeando a classe User
@Entity
public class User implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Column(length = 20, nullable = false)
private String username;
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "user_profile_id")
private UserProfile userProfile;
public User() {
}
//getters... setters
}
Usamos a anotação @Entity
para marcar a classe como uma entidade gerenciada pelo JPA, toda entidade
, também deve conter uma @Id
, onde mapeamos para o atributo id
, dizemos também
que esse atributo terá o valor gerado pelo próprio JPA, assim, não precisamos gerenciar esses valores na mão.
Para o relacionamento um-para-um, usamos a anotação @OneToOne
no atributo userProfile
, adicionamos o atributo cascade
da anotação, com o valor ALL
, para que quando persistimos
o objeto de User
, também irá persistir o UserProfile
, automaticamente.
Também marcamos o atributo userProfile
, com a anotação @JoinColumn
, para sinalizar,
que a chave estrangeira, será salva na tabela de User
Por fim, temos o mapeamento da classe UserProfile
@Entity
public class UserProfile implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String name;
private String surName;
private String email;
public UserProfile() {
}
}
Aqui, nenhuma novidade, não precisamos referenciar a classe User
aqui, pois estamos usando um mapeamento
uni-direcional, ou sejá, apenas a classe User
vai referenciar UserProfile
Podemos testar se está tudo corretamente mapeado, com o seguinte teste
@RunWith(SpringRunner.class)
@DataJpaTest
public class UniDirectionalIT {
@Autowired
TestEntityManager entityManager;
@Test
public void doesCreateUserAndUserProfile(){
User user = new User("testname", new UserProfile("FirstName" , "SecondName"));
Object userId = entityManager.persistAndGetId(user);
entityManager.flush();
entityManager.clear();
//clean first level cache, to guarantee that will hit the database again
User user1 = entityManager.find(User.class, userId);
assertThat(user1).isNotNull();
assertThat(user1.getUserProfile()).isNotNull();
}
}
Fontes no link.