Skip to content

Instantly share code, notes, and snippets.

@lgzarturo
Last active February 24, 2024 19:24
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lgzarturo/6db62a1af60a6d4cf621317fad85dd49 to your computer and use it in GitHub Desktop.
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
// 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