package ufe.jpa;

import java.math.BigDecimal;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;
import javax.persistence.Query;

public class Test3 {

  public static void main(String[] args) {
    EntityManagerFactory emf = null;
    EntityManager em = null;
    EntityTransaction tx = null;
    try {
      emf = Persistence.createEntityManagerFactory("employes");
      em = emf.createEntityManager();
      String s = "select e from Employe e where upper(e.departement.nom) = :nomDept";
      Query q = em.createQuery(s);
      String nomDept = "DIRECTION";
      q.setParameter("nomDept", nomDept);
      List<Employe> employes = q.getResultList();
      for (Employe employe : employes) {
        System.out.println(employe.getNom() + " gagne " + employe.getSalaire());
      }

      // Version 2
      s = "select e.nom, e.salaire from Employe e where upper(e.departement.nom) = :nomDept";
      Query q2 = em.createQuery(s);
      q2.setParameter("nomDept", nomDept);
      List<Object[]> infosEmployes = q2.getResultList();
      for (Object[] infoEmploye : infosEmployes) {
        System.out.println(infoEmploye[0] + " gagne " + infoEmploye[1]);
      }

      // Version 3 avec requête nommée
      Query q3 = em.createNamedQuery("findNomsEmployes");
      q3.setParameter("nomDept", nomDept);
      List<String> noms = (List<String>) q3.getResultList();
      for (String nom : noms) {
        System.out.println(nom);
      }

      // Augmentation des employés récupérés
      for (Employe employe : employes) {
        BigDecimal salaire = employe.getSalaire();
        if (salaire != null) {
          employe.setSalaire(salaire.multiply(new BigDecimal("1.05")));
          System.out.println("Salaire de " + employe.getNom() 
                  + " passé en mémoire à " + employe.getSalaire());
        } else {
          System.out.println("salaire null pour " + employe.getNom() );
        }
      }
      // Enregistrer les modifications
      tx = em.getTransaction();
      tx.begin();
      tx.commit();

      // Modifications en volume
      tx.begin();
      String ordre = "update Employe e "
              + "set e.salaire = e.salaire * 1.05 "
              + "where upper(e.departement.nom) = :nomDept";
      Query q4 = em.createQuery(ordre);
      q4.setParameter("nomDept", nomDept);
      int nbEntitesModif = q4.executeUpdate();
      System.out.println("Nombre entités modifiées par modification en volume :" 
              + nbEntitesModif);
      tx.commit();

      // Vérifie qu'une requête en volume ne modifie pas les entités en mémoire
      if (employes.size() > 0) {
        Employe emp = employes.get(0);
        System.out.println("Après modification en volume, salaire de " 
                + emp.getNom() + " = " + emp.getSalaire());

        // Synchronisation entité en mémoire avec la base de donnée
        em.refresh(emp);
        System.out.println("Après synchronisation, salaire de " 
                + emp.getNom() + " = " + emp.getSalaire());
      }
    } catch (Exception e) {
      // En "vrai" il faudrait affiner un peu plus...
      e.printStackTrace();
    } finally {
      if (em != null) {
        em.close();
      }
      if (emf != null) {
        emf.close();
      }
    }
  }
}
