Last active
February 24, 2024 19:24
-
-
Save lgzarturo/6db62a1af60a6d4cf621317fad85dd49 to your computer and use it in GitHub Desktop.
Relación OneToMany para obtener la lista de elementos de la relación con JPA o EntityManager
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Clase Usuario | |
@Entity | |
@Table(name = "usuarios") | |
public class Usuario { | |
@Id | |
@GeneratedValue(strategy = GenerationType.IDENTITY) | |
private Long id; | |
private String nombre; | |
// El fetch es opcional pero es una buena práctica definir la relación @OneToMany como lazy para optimizar las consultas. | |
// Esto significa que los roles asociados a un usuario no se cargarán automáticamente cuando se recupere un usuario | |
// de la base de datos, sino que se cargarán solo cuando se acceda explícitamente a ellos. | |
// Esto puede mejorar el rendimiento al evitar la recuperación innecesaria de datos. | |
// Al establecer fetch = FetchType.LAZY, estás indicando que los roles asociados a un usuario se cargarán de manera perezosa. | |
// Sin embargo, ten en cuenta que cuando accedas a los roles después de recuperar un usuario, puede generar una consulta | |
// adicional si aún no se han cargado los roles. | |
// Para evitar esto, puedes utilizar la técnica de carga perezosa anticipada (eager fetching) en ciertos casos | |
// donde sepas que siempre necesitarás los roles asociados. | |
@OneToMany(mappedBy = "usuario", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY) | |
private List<Rol> roles = new ArrayList<>(); | |
// Constructor, getters y setters | |
} | |
// Clase rol | |
@Entity | |
@Table(name = "roles") | |
public class Rol { | |
@Id | |
@GeneratedValue(strategy = GenerationType.IDENTITY) | |
private Long id; | |
private String nombre; | |
@ManyToOne | |
@JoinColumn(name = "usuario_id") | |
private Usuario usuario; | |
// Constructor, getters y setters | |
} | |
// Para obtener lo usuarios con el Entity Manager | |
@Service | |
public class UsuarioService { | |
@Autowired | |
private EntityManager entityManager; | |
@Transactional(readOnly = true) | |
public List<Usuario> obtenerUsuariosConRoles() { | |
// En esta consulta JPQL, utilizamos LEFT JOIN FETCH para traer los roles asociados con cada usuario | |
// en una sola consulta, evitando así consultas adicionales por cada usuario. | |
// Luego es necesario iterar sobre la lista de usuarios y sus roles asociados para imprimir la información deseada. | |
// Pero eso ya se hace en otra capa, ya que la responsabilidad de esta función solo es obtener los datos. | |
return entityManager.createQuery( | |
"SELECT DISTINCT u FROM Usuario u LEFT JOIN FETCH u.roles", | |
Usuario.class | |
).getResultList(); | |
} | |
} | |
// Usando repository, un service y un rest controller | |
// Asegúrate de tener las dependencias de Spring Data JPA en tu proyecto. | |
// Con este código, cuando hagas una solicitud GET a /usuarios/con-roles, | |
// el controlador llamará al servicio, | |
// que a su vez ejecutará la consulta HQL para obtener la lista de usuarios con sus roles asociados. | |
// Luego, el controlador devolverá esta lista como respuesta HTTP. | |
// Recuerda ajustar los paquetes y las configuraciones según la estructura de tu proyecto. | |
@Repository | |
public interface UsuarioRepository extends JpaRepository<Usuario, Long> { | |
// Puedes definir la consulta en el repositorio usando la anotación @Query junto con la consulta HQL. | |
// Con esto, defines un método findAllWithRoles() en el repositorio que ejecuta la consulta HQL | |
// para obtener todos los usuarios con sus roles asociados. | |
@Query("SELECT DISTINCT u FROM Usuario u LEFT JOIN FETCH u.roles") | |
List<Usuario> findAllWithRoles(); | |
} | |
@Service | |
public class UsuarioService { | |
@Autowired | |
private UsuarioRepository usuarioRepository; | |
@Transactional(readOnly = true) | |
public List<Usuario> obtenerUsuariosConRoles() { | |
return usuarioRepository.findAllWithRoles(); | |
} | |
} | |
@RestController | |
@RequestMapping("/usuarios") | |
public class UsuarioController { | |
@Autowired | |
private UsuarioService usuarioService; | |
@GetMapping("/con-roles") | |
public List<Usuario> obtenerUsuariosConRoles() { | |
return usuarioService.obtenerUsuariosConRoles(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment