Université de Nice Sophia-Antipolis

Cours Modèles pour la persistance des objets

Contrôle final session 1

Durée : 2h.

Seuls documents autorisés : photocopies des transparents distribués en cours ; en particulier, les énoncés et corrections des TP sont interdits. Éteignez les téléphones portables.

Important : la présentation et la lisibilité du code compteront dans la note finale. Vous êtes autorisé à écrire le code (et seulement le code) avec un crayon à papier si c'est parfaitement lisible (pas de crayon trop clair).

Ajoutez des commentaires quand vous pensez que ça peut être utile au correcteur. Ne mettez pas de commentaires évidents qui n'ajoutent rien à votre code.

Respectez le découpage en questions et l'ordre des questions. Les numéros des questions devront apparaître clairement sur votre feuille.

Exercice 1 (6 points)

Vous venez d'être engagé comme "Monsieur Persistance" par une entreprise. Votre chef de service vous demande de résoudre 2 gros problèmes qui sont apparus avec deux applications écrites par des stagiaires qui n'avaient pas votre qualification dans le domaine de la persistance. L'application utilise une base de données relationnelle et y accède par des programmes en Java.

  1. La première application utilise JPA pour gérer la persistance. Une méthode accède à une base de données pour récupérer des données. Un traitement complexe et automatisé modifie ces données et enregistre le résultat de toutes ces modifications dans la base de données.
    Le problème est que la récupération des données est très longue, beaucoup plus longue qu'elle ne devrait.
    Qu'allez-vous regarder en premier dans la méthode pour essayer de résoudre le problème ? Citez au moins 2 situations qui pourraient générer ce type de problème. Pour chaque situation, indiquez le problème possible et comment il serait possible de le corriger. Pour chaque situation, donnez un exemple concret pour bien vous faire comprendre (avec un minimum de code, par exemple le code d'une requête JPA).
  2. Une deuxième application utilise JDBC pour gérer la persistance. L'entreprise a remarqué que certains traitements ne peuvent parfois pas être lancés 2 fois de suite (disons à quelques minutes d'intervalle). La première fois semble se passer correctement mais si on relance ensuite le même traitement (mais avec des données différentes), l'application se bloque et doit être stoppée de l'extérieur, par le système d'exploitation. Ce problème semble aléatoire ; parfois les traitements peuvent être lancés plusieurs fois sans blocage et parfois un blocage survient. Vous supposerez que cette entreprise est très généreuse et peut augmenter ses employés plusieurs fois dans une journée (en fait elle les augmente en fin de mois quand ils ont accompli une certaine tâche et plusieurs traitements différents lancés en fin de mois peuvent donc les augmenter pour des tâches différentes).
    Expliquez la raison de ce comportement et dites précisément ce qu'il faudra faire pour résoudre le problème.
    Voici le code de la méthode qui lance le traitement :
  /**
   * Modification du salaire d'employés
   * @param matricules matricules des employés dont on modifie les salaires
   * @param pourcentage pourcentage d'augmentation des salaires
   * @throws SQLException si un matricule n'existe pas ou si autre erreur SQL.
   */
  public static void modifieSalaire(List<Integer> matricules, int pourcentage) 
      throws SQLException {
    String commande = "update emp set sal = sal * (1 + ? / 100) where matr = ?";
    String url = "jdbc:oracle:thin:@sirocco.unice.fr:1521:INFO";
    Connection c = DriverManager.getConnection(url, "toto", "toto");
    c.setAutoCommit(false);
    PreparedStatement stmt = c.prepareStatement(commande);
    for (Integer matricule : matricules) {
      stmt.setInt(1, 5);
      stmt.setInt(2, matricule);
      int n = stmt.executeUpdate();
      if (n != 1) {
        throw new SQLException("Aucun employé n'a le matricule " + matricule);
      }
    }
    c.commit();
    c.close();
  }

Cette méthode est lancée depuis une interface graphique par ce type de code (la récupération de la liste des matricules et du pourcentage d'augmentation a été simplifiée pour les besoins de l'exercice) :

    List<Integer> matricules = new ArrayList<Integer>();
matricules.add(7369);
matricules.add(7499);
matricules.add(8036);
try {
modifieSalaire(matricules, 5);
}
catch(SQLException e) {
e.printStackTrace();
// Affiche un message d'erreur à l'utilisateur . . . }

Exercice 2 (5 points)

Votre application utilise db4o pour la persistance.

  1. Vous donnerez le code des 2 classes Departement et Employe ; vous écrirez le code le plus simple possible pour permettre d'ajouter un employé avec un certain nom dans un département ayant un certain nom (aucune autre propriété que les noms). Inutile de donner le code de la méthode toString.
    Vous supposerez qu'un département peut avoir plusieurs employés mais qu'un employé ne peut avoir qu'un seul département. Vous supposerez que l'association entre les deux classes est bidirectionnelle. Il devra être possible d'avoir tous les employés d'un département ou le département d'un employé.
    Vous fournirez une méthode pour que le développeur puisse gérer facilement les deux bouts de l'association. N'oubliez pas le cas où un employé change de département.
  2. La base de données contient déjà le département "Comptabilité" et vous voulez ajouter un nouvel employé nommé "Dupond" dans ce département. Donnez le code Java pour cela dans la méthode main d'une classe Main.

Exercice 3 (9 points)

  1. Mêmes questions (1 et 2) que l'exercice précédent mais cette fois votre application utilise JPA pour la persistance. Pour la question 1 de l'exercice précédent vous pouvez indiquer ce qu'il faudra changer par rapport à l'exercice précédent (mais vos explications devront être très claires et sans ambiguïtés) ou redonner tout le code.
  2. Donnez les ordres SQL pour créer les tables qui contiendront les données sur les employés et les départements.
  3. Ecrivez une méthode dans la classe Main qui affiche les noms des employés dont le nom commence par un "D". Syntaxe de la méthode substring de JPA :
    substring(chaîne, début, longueur) retourne une portion de la chaîne qui commence au caractère de numéro début et de la longueur indiquée. La numérotation des caractères commence à 1.

Annexe :

Méthodes de l'interface Collection<E> :

boolean add(E e)

boolean remove(Object o)