194 lines
6.0 KiB
Java
194 lines
6.0 KiB
Java
package dev.lions.repositories;
|
|
|
|
import jakarta.persistence.EntityManager;
|
|
import jakarta.persistence.PersistenceContext;
|
|
import jakarta.persistence.TypedQuery;
|
|
import jakarta.persistence.criteria.CriteriaBuilder;
|
|
import jakarta.persistence.criteria.CriteriaQuery;
|
|
import jakarta.transaction.Transactional;
|
|
import jakarta.validation.Valid;
|
|
import jakarta.validation.constraints.NotNull;
|
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
|
import dev.lions.exceptions.RepositoryException;
|
|
|
|
import java.lang.reflect.ParameterizedType;
|
|
import java.util.List;
|
|
import java.util.Optional;
|
|
|
|
/**
|
|
* Repository générique fournissant les opérations CRUD de base.
|
|
* Cette classe abstract implémente les fonctionnalités communes à tous les repositories
|
|
* de l'application en assurant une gestion cohérente des entités.
|
|
*
|
|
* @param <T> Type de l'entité
|
|
* @param <ID> Type de l'identifiant de l'entité
|
|
*/
|
|
@Slf4j
|
|
public abstract class BaseRepository<T, ID> {
|
|
|
|
@PersistenceContext
|
|
protected EntityManager entityManager;
|
|
|
|
private final Class<T> entityClass;
|
|
|
|
/**
|
|
* Constructeur initialisant la classe d'entité via réflexion.
|
|
*/
|
|
@SuppressWarnings("unchecked")
|
|
public BaseRepository() {
|
|
Class<?> currentClass = getClass();
|
|
while (!(currentClass.getGenericSuperclass() instanceof ParameterizedType)) {
|
|
currentClass = currentClass.getSuperclass();
|
|
}
|
|
this.entityClass = (Class<T>) ((ParameterizedType) currentClass.getGenericSuperclass())
|
|
.getActualTypeArguments()[0];
|
|
|
|
log.debug("Repository initialisé pour l'entité : {}", entityClass.getSimpleName());
|
|
}
|
|
|
|
/**
|
|
* Persiste une nouvelle entité.
|
|
*
|
|
* @param entity Entité à persister
|
|
* @return Entité persistée
|
|
*/
|
|
@Transactional
|
|
public T save(T entity) {
|
|
try {
|
|
log.debug("Sauvegarde d'une nouvelle entité : {}", entityClass.getSimpleName());
|
|
entityManager.persist(entity);
|
|
entityManager.flush();
|
|
log.info("Entité sauvegardée avec succès : {}", entity);
|
|
return entity;
|
|
} catch (Exception e) {
|
|
throw new RepositoryException("Erreur lors de la sauvegarde de l'entité", e);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Met à jour une entité existante.
|
|
*
|
|
* @param entity Entité à mettre à jour
|
|
* @return Entité mise à jour
|
|
*/
|
|
@Transactional
|
|
public T update(T entity) {
|
|
try {
|
|
log.debug("Mise à jour d'une entité : {}", entityClass.getSimpleName());
|
|
T updatedEntity = entityManager.merge(entity);
|
|
entityManager.flush();
|
|
log.info("Entité mise à jour avec succès : {}", entity);
|
|
return updatedEntity;
|
|
} catch (Exception e) {
|
|
throw new RepositoryException("Erreur lors de la mise à jour de l'entité", e);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Recherche une entité par son identifiant.
|
|
*
|
|
* @param id Identifiant de l'entité
|
|
* @return Entité trouvée (Optional)
|
|
*/
|
|
public Optional<T> findById(ID id) {
|
|
try {
|
|
log.debug("Recherche de l'entité {} avec l'id : {}",
|
|
entityClass.getSimpleName(), id);
|
|
return Optional.ofNullable(entityManager.find(entityClass, id));
|
|
} catch (Exception e) {
|
|
throw new RepositoryException("Erreur lors de la recherche de l'entité", e);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Récupère toutes les entités.
|
|
*
|
|
* @return Liste des entités
|
|
*/
|
|
public List<T> findAll() {
|
|
try {
|
|
log.debug("Récupération de toutes les entités : {}",
|
|
entityClass.getSimpleName());
|
|
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
|
|
CriteriaQuery<T> cq = cb.createQuery(entityClass);
|
|
cq.from(entityClass);
|
|
TypedQuery<T> query = entityManager.createQuery(cq);
|
|
return query.getResultList();
|
|
} catch (Exception e) {
|
|
throw new RepositoryException("Erreur lors de la récupération des entités", e);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Supprime une entité.
|
|
*
|
|
* @param entity Entité à supprimer
|
|
*/
|
|
@Transactional
|
|
public void delete(T entity) {
|
|
try {
|
|
log.debug("Suppression de l'entité : {}", entity);
|
|
if (!entityManager.contains(entity)) {
|
|
entity = entityManager.merge(entity);
|
|
}
|
|
entityManager.remove(entity);
|
|
entityManager.flush();
|
|
log.info("Entité supprimée avec succès : {}", entity);
|
|
} catch (Exception e) {
|
|
throw new RepositoryException("Erreur lors de la suppression de l'entité", e);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Supprime une entité par son identifiant.
|
|
*
|
|
* @param id Identifiant de l'entité à supprimer
|
|
*/
|
|
@Transactional
|
|
public void deleteById(ID id) {
|
|
try {
|
|
log.debug("Suppression de l'entité {} avec l'id : {}",
|
|
entityClass.getSimpleName(), id);
|
|
findById(id).ifPresent(this::delete);
|
|
} catch (Exception e) {
|
|
throw new RepositoryException("Erreur lors de la suppression de l'entité", e);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Vérifie l'existence d'une entité par son identifiant.
|
|
*
|
|
* @param id Identifiant à vérifier
|
|
* @return true si l'entité existe
|
|
*/
|
|
public boolean existsById(ID id) {
|
|
try {
|
|
log.debug("Vérification de l'existence de l'entité {} avec l'id : {}",
|
|
entityClass.getSimpleName(), id);
|
|
return findById(id).isPresent();
|
|
} catch (Exception e) {
|
|
throw new RepositoryException(
|
|
"Erreur lors de la vérification de l'existence de l'entité", e);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Compte le nombre total d'entités.
|
|
*
|
|
* @return Nombre total d'entités
|
|
*/
|
|
public long count() {
|
|
try {
|
|
log.debug("Comptage des entités : {}", entityClass.getSimpleName());
|
|
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
|
|
CriteriaQuery<Long> cq = cb.createQuery(Long.class);
|
|
cq.select(cb.count(cq.from(entityClass)));
|
|
return entityManager.createQuery(cq).getSingleResult();
|
|
} catch (Exception e) {
|
|
throw new RepositoryException(
|
|
"Erreur lors du comptage des entités", e);
|
|
}
|
|
}
|
|
} |