Tengo una relación OneToOne entre las tablas Usuario y Perfil definida así:
@Entity
@Builder
@Data
@NoArgsConstructor
@AllArgsConstructor
@Table(name="users", uniqueConstraints = {
@UniqueConstraint(columnNames = "username"),
@UniqueConstraint(columnNames = "email")
}
)
public class User implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int idUser;
private String username;
private String email;
private String password;
@OneToOne(cascade=CascadeType.ALL, orphanRemoval=true)
@JoinColumn(name="id_profile", referencedColumnName="idProfile")
private Profile profile;
@ManyToMany(fetch = FetchType.EAGER)
private Set<Role> roles = new LinkedHashSet<Role>();
}
@Entity
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Table(name="profile",
uniqueConstraints = @UniqueConstraint(columnNames = "discordId")
)
public class Profile implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int idProfile;
private Date birthday;
private String discordId;
private String description;
@ElementCollection(fetch=FetchType.EAGER)
private Set<String> spokenLanguages = new LinkedHashSet<String>();
@OneToMany(fetch=FetchType.EAGER)
private Set<ProfileGame> profileGames = new LinkedHashSet<>();
@OneToOne(mappedBy="profile")
private User user;
@ManyToOne
private TimeSlot timeSlot;
}
Luego ejecuto una prueba para crear algunos elementos fijos en mi base de datos:
Profile profile = this.profileRepository.save(Profile.builder()
.birthday(new Date())
.discordId("discord-" + i)
.description("Description de user-" + i)
.spokenLanguages(spokenLanguages)
.timeSlot(timeSlot)
.build());
user.setProfile(profile);
System.err.println(user);
Todo funciona bien aquí, System.err.println(usuario) devuelve valores correctos.
El problema proviene de la base de datos, que no "aplica" el id_profile en mi tabla de Usuarios:
¿Qué me perdí?
¿Las entidades son la misma tabla o una tabla diferente?
-code_mechanic
28/03/2021 a las 15:32
Diferentes tablas
- Zabón
28/03/2021 a las 15:39
Entonces, ¿por qué el campo id_profile está en la tabla de usuarios? Debe haber un campo user_id FK en el perfil, ¿no?
-code_mechanic
28/03/2021 a las 15:51
No sé cómo hacer eso... ¡Soy novato en Spring! :-/
- Zabón
28/03/2021 a las 16:08
1
Te recomiendo que leas un poco sobre el mapeo OneToOne, consulta este artículo
-code_mechanic
28/03/2021 a las 16:30
------------------------------------
Intenta hacer algo como esto:
Profile profile = Profile.builder()
.birthday(new Date())
.discordId("discord-" + i)
.description("Description de user-" + i)
.spokenLanguages(spokenLanguages)
.timeSlot(timeSlot)
.user(user)
.build();
user.setProfile(profile);
profile = this.profileRepository.save(profile);
Utiliza una asociación @OneToOne bidireccional, por lo que debe asegurarse de que ambas partes esténEstamos sincronizados en todo momento.
Además, como necesita propagar el estado persistente al usuario, debe agregar cascade = CascadeType.ALL al Profile.user como se muestra a continuación:
@Entity
public class Profile implements Serializable {
// ...
@OneToOne(mappedBy="profile", cascade=CascadeType.ALL)
private User user;
}
1
En realidad, no cambió nada.
- Zabón
28/03/2021 a las 16:20
------------------------------------
Usuario de clase:
@OneToOne(mappedBy = "user", cascade = CascadeType.ALL,
fetch = FetchType.LAZY, optional = false)
private Profile profile;
Perfil de clase:
@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name="id_user")
private User user;