/**
   * Lit un pret.
   *
   * @param idPret L'ID du pret à lire
   * @return Le pret lu
   * @throws DAOException S'il y a une erreur dans la base de données
   */
  public PretDTO read(int idPret) throws DAOException {

    PretDTO pretDTO = null;

    try (PreparedStatement readPreparedStatement =
        getConnection().prepareStatement(PretDAO.READ_REQUEST)) {
      readPreparedStatement.setInt(1, idPret);
      try (ResultSet resultSet = readPreparedStatement.executeQuery()) {
        if (resultSet.next()) {

          pretDTO = new PretDTO();
          pretDTO.setIdPret(resultSet.getInt(1));

          final MembreDTO membreDTO = new MembreDTO();
          membreDTO.setIdMembre(resultSet.getInt(2));
          pretDTO.setMembreDTO(membreDTO);

          final LivreDTO livreDTO = new LivreDTO();
          livreDTO.setIdLivre(resultSet.getInt(3));
          pretDTO.setLivreDTO(livreDTO);

          pretDTO.setDatePret(resultSet.getTimestamp(4));
          pretDTO.setDateRetour(resultSet.getTimestamp(5));
        }
      }

    } catch (final SQLException sqlException) {
      throw new DAOException(sqlException);
    }
    return pretDTO;
  }
  /**
   * Trouve les prêts non terminés à partir d'une date de retour.
   *
   * @param dateRetour La date de retour à utiliser
   * @return La liste des prets correspondants; une liste vide sinon
   * @throws DAOException S'il y a une erreur avec la base de données
   */
  public List<PretDTO> findByDateRetour(Timestamp dateRetour) throws DAOException {

    List<PretDTO> listePrets = Collections.EMPTY_LIST;
    PretDTO pretDTO = null;

    try (PreparedStatement findByDateRetourPreparedStatement =
        getConnection().prepareStatement(PretDAO.FIND_BY_DATE_RETOUR); ) {
      findByDateRetourPreparedStatement.setTimestamp(1, dateRetour);
      try (ResultSet resultSet = findByDateRetourPreparedStatement.executeQuery(); ) {
        if (resultSet.next()) {
          listePrets = new ArrayList<>();
          do {
            pretDTO = new PretDTO();
            pretDTO.setIdPret(resultSet.getInt(1));
            final MembreDTO membreDTO = new MembreDTO();
            membreDTO.setIdMembre(resultSet.getInt(2));
            pretDTO.setMembreDTO(membreDTO);
            // pretDTO.getMembreDTO().setIdMembre(resultSet.getInt(2));
            final LivreDTO livreDTO = new LivreDTO();
            livreDTO.setIdLivre(resultSet.getInt(3));
            pretDTO.setLivreDTO(livreDTO);
            // pretDTO.getLivreDTO().setIdLivre(resultSet.getInt(3));
            pretDTO.setDatePret(resultSet.getTimestamp(4));
            pretDTO.setDateRetour(resultSet.getTimestamp(5));
            listePrets.add(pretDTO);
          } while (resultSet.next());
        }
      }
    } catch (final SQLException sqlException) {
      throw new DAOException(sqlException);
    }
    return listePrets;
  }
  /**
   * Trouve tous les livres.
   *
   * @return La liste des livres; une liste vide sinon
   * @throws DAOException S'il y a une erreur avec la base de données
   */
  public List<LivreDTO> getAll() throws DAOException {

    List<LivreDTO> listeDTO = Collections.EMPTY_LIST;

    LivreDTO livreDTO = null;
    try (PreparedStatement getAllPreparedStatement =
            getConnection().prepareStatement(LivreDAO.GET_ALL_REQUEST);
        ResultSet resultSet = getAllPreparedStatement.executeQuery(); ) {

      if (resultSet.next()) {
        listeDTO = new ArrayList<>();
        do {
          livreDTO = new LivreDTO();
          livreDTO.setIdLivre(resultSet.getInt(1));
          livreDTO.setTitre(resultSet.getString(2));
          livreDTO.setAuteur(resultSet.getString(3));
          livreDTO.setDateAcquisition(resultSet.getTimestamp(4));
          listeDTO.add(livreDTO);
        } while (resultSet.next());
      }

    } catch (final SQLException sqlException) {
      throw new DAOException(sqlException);
    }
    return listeDTO;
  }
  /**
   * Ajoute un nouveau livre.
   *
   * @param livreDTO Le livre à ajouter
   * @throws DAOException S'il y a une erreur avec la base de données
   */
  public void add(LivreDTO livreDTO) throws DAOException {
    try (PreparedStatement addPreparedStatement =
        getConnection().prepareStatement(LivreDAO.ADD_REQUEST)) {

      addPreparedStatement.setString(1, livreDTO.getTitre());
      addPreparedStatement.setString(2, livreDTO.getAuteur());
      addPreparedStatement.setTimestamp(3, livreDTO.getDateAcquisition());

      addPreparedStatement.executeUpdate();
    } catch (final SQLException sqlException) {
      throw new DAOException(sqlException);
    }
  }
  /** {@inheritDoc} */
  @Override
  public List<PretDTO> getAll(Connexion connexion, String sortByPropertyName)
      throws DAOException, InvalidHibernateSessionException, InvalidSortByPropertyException {
    if (connexion == null) {
      throw new InvalidHibernateSessionException("La connexion ne peut être null");
    }
    if (sortByPropertyName == null) {
      throw new InvalidSortByPropertyException("La propriété ne peut être null");
    }
    List<PretDTO> prets = Collections.<PretDTO>emptyList();

    try (PreparedStatement statementGetAllLivres =
        (connexion.getConnection().prepareStatement(PretDAO.GET_ALL_REQUEST))) {
      try (ResultSet resultSet = statementGetAllLivres.executeQuery()) {
        PretDTO pretDTO = null;
        if (resultSet.next()) {
          prets = new ArrayList<>();
          do {

            pretDTO = new PretDTO();
            pretDTO.setIdPret(resultSet.getString(1));

            MembreDTO membre = new MembreDTO();
            membre.setIdMembre(resultSet.getString(2));

            LivreDTO livre = new LivreDTO();
            livre.setIdLivre(resultSet.getString(3));

            pretDTO.setMembreDTO(membre);
            pretDTO.setLivreDTO(livre);
            pretDTO.setDatePret(resultSet.getTimestamp(4));
            pretDTO.setDateRetour(resultSet.getTimestamp(5));

            prets.add(pretDTO);

          } while (resultSet.next());
        }
        return prets;
      } catch (SQLException sqlException) {
        throw new DAOException(
            Integer.toString(sqlException.getErrorCode()) + " " + sqlException.getMessage(),
            sqlException);
      }
    } catch (SQLException sqlException) {
      throw new DAOException(
          Integer.toString(sqlException.getErrorCode()) + " " + sqlException.getMessage(),
          sqlException);
    }
  }
  /** {@inheritDoc} */
  @Override
  public List<PretDTO> findByDatePret(
      Connexion connexion, Timestamp datePret, String sortByPropertyName)
      throws DAOException, InvalidHibernateSessionException, InvalidCriterionException,
          InvalidSortByPropertyException {
    if (connexion == null) {
      throw new InvalidHibernateSessionException("La connexion ne peut être null");
    }
    if (datePret == null) {
      throw new InvalidCriterionException("La date de pret ne peut être null");
    }
    if (sortByPropertyName == null) {
      throw new InvalidSortByPropertyException("La propriété ne peut être null");
    }
    List<PretDTO> pret = Collections.<PretDTO>emptyList();
    try (
    // TODO passer d'un timestamp exact à une date???
    PreparedStatement stmtGetPretsByMembre =
        (connexion.getConnection().prepareStatement(PretDAO.FIND_BY_DATE_PRET)); ) {
      stmtGetPretsByMembre.setTimestamp(1, datePret);
      try (ResultSet rset = stmtGetPretsByMembre.executeQuery()) {

        pret = new ArrayList<>();

        while (rset.next()) {

          PretDTO tempPret = new PretDTO();
          tempPret.setIdPret(rset.getString(1));

          MembreDTO membre = new MembreDTO();
          membre.setIdMembre(rset.getString(2));

          LivreDTO livre = new LivreDTO();
          livre.setIdLivre(rset.getString(3));

          tempPret.setMembreDTO(membre);
          tempPret.setLivreDTO(livre);
          tempPret.setDatePret(rset.getTimestamp(4));
          tempPret.setDateRetour(rset.getTimestamp(5));
        }
      }
    } catch (SQLException sqlException) {
      throw new DAOException(
          Integer.toString(sqlException.getErrorCode()) + " " + sqlException.getMessage(),
          sqlException);
    }
    return pret;
  }
  /**
   * Met à jour un livre.
   *
   * @param livreDTO Le livre à mettre à jour
   * @return Le nombre de lignes affectées par la modification
   * @throws DAOException S'il y a une erreur dans la base de données
   */
  public int update(LivreDTO livreDTO) throws DAOException {
    int result = 0;
    try (PreparedStatement updatePreparedStatement =
        getConnection().prepareStatement(LivreDAO.UPDATE_REQUEST)) {

      updatePreparedStatement.setString(1, livreDTO.getTitre());
      updatePreparedStatement.setString(2, livreDTO.getAuteur());
      updatePreparedStatement.setTimestamp(3, livreDTO.getDateAcquisition());
      updatePreparedStatement.setInt(4, livreDTO.getIdLivre());

      result = updatePreparedStatement.executeUpdate();
    } catch (final SQLException sqlException) {
      throw new DAOException(sqlException);
    }

    return result;
  }
  /** {@inheritDoc} */
  @Override
  public List<PretDTO> findByDateRetour(
      Connexion connexion, Timestamp dateRetour, String sortByPropertyName)
      throws InvalidHibernateSessionException, InvalidCriterionException,
          InvalidSortByPropertyException, DAOException {

    if (connexion == null) {
      throw new InvalidHibernateSessionException("La connexion ne peut être null");
    }
    if (dateRetour == null) {
      throw new InvalidCriterionException("La dateRetour ne peut être null");
    }
    if (sortByPropertyName == null) {
      throw new InvalidSortByPropertyException(
          "La propriété utilisée pour classer les prets ne peut être null");
    }

    List<PretDTO> listePrets = Collections.EMPTY_LIST;
    PretDTO pretDTO = null;

    try (PreparedStatement findByDateRetourPreparedStatement =
        connexion.getConnection().prepareStatement(PretDAO.FIND_BY_DATE_RETOUR); ) {
      findByDateRetourPreparedStatement.setTimestamp(1, dateRetour);
      try (ResultSet resultSet = findByDateRetourPreparedStatement.executeQuery(); ) {
        if (resultSet.next()) {
          listePrets = new ArrayList<>();
          do {
            pretDTO = new PretDTO();
            pretDTO.setIdPret(resultSet.getString(1));
            final MembreDTO membreDTO = new MembreDTO();
            membreDTO.setIdMembre(resultSet.getString(2));
            pretDTO.setMembreDTO(membreDTO);
            final LivreDTO livreDTO = new LivreDTO();
            livreDTO.setIdLivre(resultSet.getString(3));
            pretDTO.setLivreDTO(livreDTO);
            pretDTO.setDatePret(resultSet.getTimestamp(4));
            pretDTO.setDateRetour(resultSet.getTimestamp(5));
            listePrets.add(pretDTO);
          } while (resultSet.next());
        }
      }
    } catch (final SQLException sqlException) {
      throw new DAOException(sqlException);
    }
    return listePrets;
  }
  /**
   * Supprime un livre.
   *
   * @param livreDTO Le livre à supprimer
   * @throws DAOException S'il y a une erreur dans la base de données
   */
  public void delete(LivreDTO livreDTO) throws DAOException {
    try (PreparedStatement deletePreparedStatement =
        getConnection().prepareStatement(LivreDAO.DELETE_REQUEST)) {

      deletePreparedStatement.setInt(1, livreDTO.getIdLivre());

      deletePreparedStatement.executeUpdate();
    } catch (final SQLException sqlException) {
      throw new DAOException(sqlException);
    }
  }
  /** {@inheritDoc} */
  @Override
  public PretDTO get(Connexion connexion, Serializable primaryKey)
      throws InvalidHibernateSessionException, InvalidPrimaryKeyException, DAOException {

    PretDTO pretDTO = null;

    if (connexion == null) {
      throw new InvalidHibernateSessionException("La connexion ne peut être null");
    }
    if (primaryKey == null) {
      throw new InvalidPrimaryKeyException("Le DTO ne peut être null");
    }

    final String idMembre = (String) primaryKey;
    try (PreparedStatement readPreparedStatement =
        connexion.getConnection().prepareStatement(PretDAO.READ_REQUEST)) {
      readPreparedStatement.setString(1, idMembre);
      try (ResultSet resultSet = readPreparedStatement.executeQuery()) {
        if (resultSet.next()) {

          pretDTO = new PretDTO();
          pretDTO.setIdPret(resultSet.getString(1));

          final MembreDTO membreDTO = new MembreDTO();
          membreDTO.setIdMembre(resultSet.getString(2));
          pretDTO.setMembreDTO(membreDTO);

          final LivreDTO livreDTO = new LivreDTO();
          livreDTO.setIdLivre(resultSet.getString(3));
          pretDTO.setLivreDTO(livreDTO);

          pretDTO.setDatePret(resultSet.getTimestamp(4));
          pretDTO.setDateRetour(resultSet.getTimestamp(5));
        }
      }

    } catch (final SQLException sqlException) {
      throw new DAOException(sqlException);
    }
    return pretDTO;
  }
  /**
   * Trouve les livres à partir d'un titre.
   *
   * @param livreDTO Le livre qui a le titre à utiliser
   * @return La liste des livres correspondants; une liste vide sinon
   * @throws DAOException S'il y a une erreur avec la base de données
   */
  public List<LivreDTO> findByTitre(LivreDTO livreDTO) throws DAOException {

    List<LivreDTO> listeLivres = Collections.EMPTY_LIST;
    LivreDTO livreAvecTitre = null;

    try (PreparedStatement findByTitrePreparedStatement =
        getConnection().prepareStatement(LivreDAO.FIND_BY_TITRE_REQUEST); ) {
      findByTitrePreparedStatement.setString(1, "%" + livreDTO.getTitre() + "%");
      try (ResultSet rset = findByTitrePreparedStatement.executeQuery(); ) {
        if (rset.next()) {
          listeLivres = new ArrayList<>();
          do {
            livreAvecTitre = new LivreDTO();
            livreAvecTitre.setIdLivre(rset.getInt(1));
            livreAvecTitre.setTitre(rset.getString(2));
            livreAvecTitre.setAuteur(rset.getString(3));
            livreAvecTitre.setDateAcquisition(rset.getTimestamp(4));
            listeLivres.add(livreAvecTitre);
          } while (rset.next());
        }
      }
    } catch (final SQLException sqlException) {
      throw new DAOException(sqlException);
    }
    return listeLivres;
  }
  /**
   * Lit un livre.
   *
   * @param idLivre L'ID du livre à lire
   * @return Le livre lu
   * @throws DAOException S'il y a une erreur dans la base de données
   */
  public LivreDTO read(int idLivre) throws DAOException {

    LivreDTO livreDTO = null;

    try (PreparedStatement readPreparedStatement =
        getConnection().prepareStatement(LivreDAO.READ_REQUEST)) {
      readPreparedStatement.setInt(1, idLivre);
      try (ResultSet resultSet = readPreparedStatement.executeQuery()) {
        if (resultSet.next()) {
          livreDTO = new LivreDTO();
          livreDTO.setIdLivre(resultSet.getInt(1));
          livreDTO.setTitre(resultSet.getString(2));
          livreDTO.setAuteur(resultSet.getString(3));
          livreDTO.setDateAcquisition(resultSet.getTimestamp(4));
        }
      }

    } catch (final SQLException sqlException) {
      throw new DAOException(sqlException);
    }
    return livreDTO;
  }
  /** {@inheritDoc} */
  @Override
  public PretDTO get(Connexion connexion, Serializable primaryKey)
      throws DAOException, InvalidHibernateSessionException, InvalidPrimaryKeyException {
    if (connexion == null) {
      throw new InvalidHibernateSessionException();
    }
    if (primaryKey == null) {
      throw new InvalidPrimaryKeyException();
    }
    String idPret = (String) primaryKey;
    PretDTO tempPret = null;
    try (PreparedStatement statementRead =
        (connexion.getConnection().prepareStatement(PretDAO.READ_REQUEST))) {
      statementRead.setString(1, idPret);

      try (ResultSet rset = statementRead.executeQuery()) {
        if (rset.next()) {

          tempPret = new PretDTO();
          tempPret.setIdPret(rset.getString(1));
          MembreDTO membre = new MembreDTO();
          membre.setIdMembre(rset.getString(2));
          tempPret.setMembreDTO(membre);
          LivreDTO livre = new LivreDTO();
          livre.setIdLivre(rset.getString(3));
          tempPret.setLivreDTO(livre);
          tempPret.setDatePret(rset.getTimestamp(4));
          tempPret.setDateRetour(rset.getTimestamp(5));
          rset.close();
        }
      }
    } catch (SQLException sqlException) {
      throw new DAOException(
          Integer.toString(sqlException.getErrorCode()) + " " + sqlException.getMessage(),
          sqlException);
    }
    return tempPret;
  }