Traitement des incidents liés aux applications JPA
Utilisez ces informations pour identifier et résoudre les problèmes les plus courants liés aux applications utilisant l'API JPA (Java™ Persistence API).
Procédure
- Traitez les incidents liés aux classes NoClassDefFoundError for org.apache.openjpa.* ou com.ibm.websphere.persistence.* lorsque vous utilisez le fichier JAR de client léger JPA.
A compter de WebSphere Application Server version 9.0, deux fichiers JAR de client léger JPA sont disponibles. com.ibm.ws.jpa-2.1.thinclient_9.0.jar : inclut les interfaces de spécification JPA 2.1, ainsi que les interfaces et classes EclipseLink. com.ibm.ws.jpa-2.0.thinclient_9.0.jar : inclut les interfaces de spécification JPA 2.0, ainsi que les interfaces et classes WSJPA et OpenJPA. Avant la version 9, ce fichier JAR s'appelait com.ibm.ws.jpa_X.X.jar.
Eviter les incidents:
Si votre application dépend de classes ou d'un comportement OpenJPA ou WSJPA spécifiques et que vous avez ajouté com.ibm.ws.jpa-2.1.thinclient_9.0.jar à votre chemin d'accès aux classes, vous devez plutôt utiliser com.ibm.ws.jpa-2.0.thinclient_9.0.jar sur le chemin d'accès aux classes de votre client léger.
gotcha - Traitez les incidents liés aux classes NoClassDefFoundError for org.apache.openjpa.* ou com.ibm.websphere.persistence.* à partir d'une application qui s'exécute sur un serveur d'applications WebSphere. Dans WebSphere Application Server version 9.0, le fournisseur de persistance par défaut pour les nouveaux profils, OpenJPA, a été remplacé par EclipseLink. Si vous exécutez une application OpenJPA alors que WebSphere est configuré pour utiliser EclipseLink, une erreur NoClassDefFoundError est générée, car les classes OpenJPA ne sont pas disponibles sur le contexte d'exécution du serveur lorsqu'elles sont configurées pour utiliser JPA 2.1.Remarque : Si vous utilisez l'outil de migration de WebSphere Application Server version 8.5.5 pour effectuer une migration vers WebSphere Application Server version 9.0, votre niveau JPA prend automatiquement la valeur 2.0, et le fournisseur JPA utilisé sera le même que celui de WebSphere Application Server version 8.5.5.
Pour résoudre ce problème, reconfigurez votre serveur ou cluster pour qu'il utilise JPA 2.0. Cette action définit OpenJPA comme fournisseur de persistance par défaut.
- Troubleshoot NoClassDefFoundError: org.apache.openjpa.enhance.PersistenceCapable. Les applications qui utilisent OpenJPA peuvent exécuter des outils d'amélioration de temps de génération sur des entités de classe. L'utilisation de l'amélioration OpenJPA ajoute des références à des classes, telles que org.apache.openjpa.enhance.PersistenceCapable, à la classe compilée. Dans WebSphere Application Server version 9.0, le fournisseur de persistance par défaut pour les nouveaux profils, OpenJPA, a été remplacé par EclipseLink. Si vous tentez d'exécuter une application OpenJPA alors que WebSphere Application Server est configuré pour utiliser EclipseLink, une erreur NoClassDefFoundError est générée, car les classes OpenJPA ne sont pas disponibles sur le contexte d'exécution du serveur lorsqu'il est configuré pour utiliser JPA 2.1.Remarque : Si vous utilisez l'outil de migration de WebSphere Application Server version 8.5.5 pour effectuer une migration vers WebSphere Application Server version 9.0, votre niveau JPA prend automatiquement la valeur 2.0, et le fournisseur JPA utilisé sera le même que celui de WebSphere Application Server version 8.5.5.Pour résoudre le problème, vous pouvez :
- Reconfigurer votre serveur ou cluster pour qu'il utilise JPA 2.0. Cette action définit OpenJPA comme fournisseur de persistance par défaut.
- Recompilez l'application et étendez les entités à l'aide de l'extension EclipseLink au lieu de l'extension OpenJPA.
- Passez en revue les messages relatifs aux transactions.
Dans certains cas, un message semblable au message suivant peut être consigné : Impossible d'exécuter {0} sur une transaction gérée par WebSphere. WebSphere ne prend pas en charge la manipulation directe des transactions gérées.
Cette erreur est probablement due au fait qu'une source de données n'a pas été correctement configurée en tant que <non-jta-data-source>. Consultez la rubrique du centre de documentation relative à l'association des fournisseurs de persistance et des sources de donnée pour savoir comment configurer une source de données à utiliser comme élément <non-jta-data-source>.
- Résolvez les problèmes relatifs aux classes qui n'ont pas été étendues avant la phase d'exécution.
Il est difficile de diagnostiquer ces situations. L'origine de l'incident peut parfois correspondre à un manque d'extension OpenJPA au niveau des classes entité. Des exemples de ces situations peuvent consister à détecter les entités qui ne sont pas persistence capable. Recherchez un message semblable au message suivant dans le journal : Cette configuration interdit l'optimisation effectuée pendant la phase d'exécution, mais les types répertoriés ci-après n'ont pas été étendus lors de la génération ou lors du chargement des classes avec un agent Java : "{0}".
Ce message indique que l'extension attendue lors la phase d'exécution n'a pas été effectuée sur les types d'entité répertoriés. Dans plupart des cas, cela correspond à un échec lors de la génération, et la classe PCEnhancer doit être exécutée sur les classes répertoriées. Ce message peut également indiquer un problème plus important, particulièrement si vous vous attendez à ce que la transformation du chargeur de classe du conteneur effectue l'extension de l'entité.
- Résolvez les problèmes liés aux curseurs fermés. Voici une exception de DB2 consignée dans le journal org.apache.openjpa.persistence.PersistenceException :
[ibm][db2][jcc][10120][10898] Opération non valide : un ensemble de résultats fermé peut correspondre à un problème de configuration de WebSphere Application Server.
Par défaut, le serveur d'applications attribue la valeur 2 (CLOSE_CURSORS_AT_COMMIT) à la propriété personnalisée resultSetHoldability. Lorsque cette propriété est définie, DB2 ferme resultSet/cursor au niveau des limites de transaction. Même si la valeur par défaut de DB2 resultSetHoldability est 1 (HOLD_CURSORS_OVER_COMMIT), le serveur d'applications retient la valeur 2 par défaut afin d'éviter des problèmes de compatibilité avec des versions précédentes du serveur d'applications. Vous pouvez modifier la valeur par défaut.Avertissement : S'il s'agit d'une source de données XA, définissez une nouvelle propriété personnalisée sur la source de données où nom_propriété = downgradeHoldCursorsUnderXa et valeur booléenne = true.Eviter les incidents: Dans la version 8.0, si une source de données XA DB2 est utilisée, la configuration suivante est obligatoire pour résoudre le problème d'ensemble de résultats fermé :
- Utilisez DB2 version 9.1 FP4 (pour l'APAR IZ18072) ou une version ultérieure.
- Ajoutez la propriété personnalisée name="downgradeHoldCursorsUnderXa", value="true" et type="java.lang.Boolean"
- Ajoutez la propriété personnalisée name="resultSetHoldability", value="1", et type="java.lang.Integer"
- Evitez l'utilisation du composant EntityManager sur plusieurs unités d'exécution. Si vous rencontrez une exception avec le texte de message ci-après, vous pourriez, par mégarde, favoriser l'utilisation du
composant EntityManager sur plusieurs unités d'exécutions.Pour chaque spécification JPA, un composant EntityManager ne doit être utilisé que par une seule unité d'exécution. Un message d'exception similaire au message ci-après peut s'afficher (dans ce contexte, les courtiers et les composants EntityManager sont essentiellement la même chose) :Il existe plusieurs façons de résoudre ce problème :
Plusieurs unités d'exécution ont tenté d'accéder à un seul courtier. Par défaut, les courtiers ne respectent pas le cloisonnement des unités d'exécution ; si vous voulez que plusieurs unités d'exécution puissent accéder à un courtier, définissez la propriété openjpa.Multithreaded sur true afin d'annuler le comportement par défaut.
Pratiques recommandées: Utilisez un modèle de type get-use-close (obtention/utilisation/fermeture) dans des contextes de persistance gérée par application (étendues). N'oubliez pas de fermer l'élément EntityManager avant de quitter la méthode ayant utilisé cet élément. Laisser l'élément EntityManager ouvert peut permettre à d'autres unités d'exécution d'utiliser la même instance EntityManager au même moment et peut consommer des ressources système.bprac
- Modifiez l'application pour utiliser des contextes de persistance gérée par conteneur en injectant l'instance EntityManager via l'annotation @PersistenceContext, si le modèle de programmation de l'application est compatible avec cette modification. Cela respecte le modèle de type get-use-close en permettant au conteneur d'effectuer la gestion.
- Comme indiqué dans ce texte de l'exception, une solution palliative rapide consiste à configurer OpenJPA pour demander un
accès à unités d'exécution multiples vers les composants EntityManager via la propriété openjpa.Multithreaded. Le fait d'activer cette propriété peut augmenter inutilement le temps système.
Eviter les incidents: Les variables d'instance pour les servlets sont automatiquement partagées par toutes les instances du servlet. L'utilisation de l'annotation @PersistenceContext sur une variable d'instance de servlet peut générer accidentellement un accès à unités d'exécutions multiples au même composant EntityManager. En outre, les composants EntityManagers injectés de cette manière ne sont pas nettoyés par le conteneur tant que l'application n'est pas arrêtée. Pour les servlets, il est préférable d'utiliser l'annotation @PersistenceUnit pour injecter un composant EntityManagerFactory. gotcha
- Si vous utilisez le verrouillage optimiste, tenez compte des conditions de version.
Dans l'architecture JPA, le fournisseur de persistance utilise la propriété des versions pour effectuer le verrouillage optimiste et les sémantiques de concurrence d'une entité persistante ; par exemple :
@Entity public class VersionedTimestampEntity { @Id private int id; @Version private java.sql.Timestamp version; .... }
Le fournisseur effectue un mise jour de la propriété de version en lui attribuant une nouvelle valeur lorsqu'une entité est inscrite dans la base de données. Lors d'une opération de fusion d'entités, le fournisseur de persistance analyse cette propriété de version afin de déterminer si l'entité fusionnée correspond à une copie périmée de cette entité. Si l'opération échoue à cause d'une condition de version périmée, une exception OptimisticLockException est générée. Les types de propriété de version sont les suivants :- integer
- Entierr
- short
- Short
- long
- Long
- Timestamp.
Si une entité est conservée et qu'elle est ensuite récupérée et mise à jour dans un autre contexte de persistance figurant dans la fenêtre de précision de la plateforme, le fournisseur de persistance ne peut pas détecter le verrouillage optimiste ni la condition simultanée. Par conséquent, il se peut qu'une exception OptimisticLockException ne soit pas générée et que l'intégrité des données soit compromise.Eviter les incidents: Si vous utilisez correctement le type Timestamp pour la propriété de version, l'application doit prendre en compte le comportement qui peut résulter de la précision de l'implémentation utilisée pour la création de l'objet Timestamp. L'implémentation standard utilise la méthode System.currentTimeMills. La précision de temps de cette méthode est spécifique à la plateforme. Par exemple, elle est de 15 ms pour Windows 32 bits et de 2 ms pour z/OS.gotcha
- Résolution des violations de contrainte de la base de données lorsque l'on travaille avec des entités
Les fournisseurs JPA inclus avec WebSphere Application Server utilisent un gestionnaires de mise à jour des contraintes afin de déterminer l'ordre des requêtes SQL dans la base de données en fonction de la configuration de chaque entité. Ce gestionnaire de mise à jour peut réorganiser l'ordre des requêtes SQL dans la base de données. Cela évite à une application de connaître l'ordre des opérations du gestionnaire d'entités nécessaire pour réaliser sa logique applicative et optimiser les performances de la base de données à l'aide de la prise en charge des lots sous-jacente.
Comme le fournisseur JPA ne suppose pas qu'il existe des contraintes implicites de la base de données pour les relations entre les entités, s'il y a des contraintes dans la base de données (par exemple, une contrainte de clé étrangère), le fournisseur JPA peut ne pas émettre d'instructions SQL dans l'ordre souhaité. Dans ces conditions, on peut observer l'exception suivante ou une exception similaire :com.ibm.db2.jcc.b.SqlException: DB2 SQL error: SQLCODE: -530, SQLSTATE: 23503, SQLERRMC: xxxxxx
Il existe plusieurs façons de résoudre ce problème :- Le fournisseur OpenJPA peut être configuré pour lire les informations relatives aux contraintes à partir de la base de
données et les appliquer au gestionnaire de mise à jour lors de la phase d'exécution en ajoutant la propriété de
configuration suivante à l'unité de persistance :
<property name="openjpa.jdbc.SchemaFactory" value="native(ForeignKeys=true)" />
- L'application peut étendre l'entité pour utiliser l'annotation @ForeignKey et indiquer au fournisseur
JPA quelles relations ont des contraintes de clés étrangères.
public class Person { @ManyToOne @ForeignKey private Address address; .... }
- Pour les applications OpenJPA, l'application peut prendre la responsabilité d'organiser les instructions SQL
en ajoutant la propriété de configuration suivante à l'unité de persistance :
<property name="openjpa.jdbc.UpdateManager" value="operation-order" />
Avec cette option de configuration, le fournisseur JPA exécute les instructions SQL dans le même ordre que celui qui était requis pour les opérations d'entités. L'application doit connaître toute interdépendance entre les entités.
Eviter les incidents: Il peut être tentant d'utiliser plusieurs de ces propriétés mais vous devez uniquement utiliser celle la plus adaptée à votre situation. Si vous pensez que vous devez utiliser plusieurs propriétés, gardez à l'esprit que les propriétés openjpa.jdbc.UpdateManager et openjpa.jdbc.SchemaFactory utilisées conjointement peuvent générer un ordre de requête SQL différent de celui requis pour résoudre l'exception. Le paramètre operation-order de la propriété openjpa.jdbc.UpdateManager indique au fournisseur JPA que vous souhaitez que les requêtes SQL soient exécutées dans l'ordre spécifié dans une application. Même si vous indiquez la propriété openjpa.jdbc.SchemaFactory avec la commande openjpa.jdbc.UpdateManager, le fournisseur JPA respecte l'ordre des requêtes SQL défini dans une application au lieu de trier automatiquement les requêtes SQL afin de respecter une contrainte détectée, telle une contrainte de clé externe. Lorsque la propriété openjpa.jdbc.UpdateManager est indiquée, le développeur d'application doit s'assurer que les requêtes SQL sont indiquées dans l'ordre correct au sein d'une application.gotcha
- Supprimez les contraintes de la base de données.
- Le fournisseur OpenJPA peut être configuré pour lire les informations relatives aux contraintes à partir de la base de
données et les appliquer au gestionnaire de mise à jour lors de la phase d'exécution en ajoutant la propriété de
configuration suivante à l'unité de persistance :
- Traitement des incidents à l'aide de la tâche OpenJPA MappingTool ANT.
La ANT tâche MappingTool fournie par OpenJPA utilise un chargeur de classe temporaire pour charger les classes de pilotes JDBC. Ce chargeur de classe temporaire peut rencontrer des problèmes lors du chargement de certains pilotes JDBC tels que DB2.
Lorsque vous exécutez la tâche ANT MappingTool, vous observez une erreur similaire à celle présentée ci-dessous :
[mappingtool] java.lang.UnsatisfiedLinkError: com/ibm/jvm/Trace.initTrace([Ljava/lang/String;[Ljava/lang/String;)V [mappingtool] at com.ibm.jvm.Trace.initializeTrace(Trace.java:94) [mappingtool] at com.ibm.jvm.Trace.<clinit>(Trace.java:59) [mappingtool] at java.lang.J9VMInternals.initializeImpl(Native Method) [mappingtool] at java.lang.J9VMInternals.initialize(J9VMInternals.java:200) [mappingtool] at java.lang.Class.forNameImpl(Native Method) [mappingtool] at java.lang.Class.forName(Class.java:136) [mappingtool] at com.ibm.db2.jcc.a.o.n(o.java:577) [mappingtool] at com.ibm.db2.jcc.a.o.<clinit>(o.java:329)Pour utiliser l'outil de mappage, vous pouvez désactiver le chargeur de classe temporaire en ajoutant l'argument tmpClassLoader=false à la tâche ANT. Voici deux exemples de script ANT :
Cet exemple présente le problème :
<taskdef name="mapping" classname="org.apache.openjpa.jdbc.ant.MappingToolTask" classpathref="jpa.cp"/> . . . <target name="map.broken"> <mapping> <!-- this exhibits the problem --> . . . </mapping> </target>
Cet exemple évite le problème :
<taskdef name="mapping" classname="org.apache.openjpa.jdbc.ant.MappingToolTask" classpathref="jpa.cp"/> . . . <target name="map.fixed"> <mapping tmpClassLoader="false"> <!-- this will work --> . . . </mapping> </target>
- Impact de DataCache sur les modèles de domaines incohérents
Lorsqu'une application conserve un modèle de domaine incohérent et extrait plus tard les entités dans un contexte de persistance séparé, les entités extraites sont différentes, selon que DataCache est actif ou non.
Par exemple, prenez en compte une relation de type un-à-un bidirectionnelle entre deux entités mappées par une colonne de clé étrangère unique dans la base de données. Une application peut définir les zones de relations dans les entités de manière incohérente. Lorsque ce genre de valeurs incohérentes est mappé vers la base de données, les enregistrements des bases de données deviennent cohérents uniquement parce qu'une colonne de clé étrangère unique indique que la DataCache des relations bidirectionnelles est active, pourtant, DataCache capture ensuite les états d'entité de la mémoire incohérents. Par conséquent, lorsqu'une application conserve une paire d'entités liées dans une relation bidirectionnelle mais que leurs zones de relations sont définies comme valeurs incohérentes et qu'elle extrait ensuite les entités dans un contexte de persistance différent, la relation bidirectionnelle reste incohérente ou devient cohérente selon que DataCache est utilisé ou non.
Des zones multiples sont mappées vers la même colonne mais définies sur des valeurs différentes : voici un autre exemple où un état d'entité incohérente est conservé mais extrait en tant qu'entité cohérente dans un contexte de persistance séparé. Dans ce cas, l'introduction de DataCache a aussi pour conséquence qu'une entité réalisée dans un contexte de persistance séparé conserve des valeurs incohérentes et différentes alors que sans un DataCache, une entité garde la même valeur pour les deux zones.
Pratiques recommandées: Evitez de remplir le modèle du domaine de l'application de manière incohérente. Pour OpenJPA, il est également possible de configurer la propriété openjpa.InverseManager afin de détecter certaines incohérences, telles qu'une relation bidirectionnelle.bprac
- Corrigez les incidents avec les annotations MappingTool et @ForeignKey
avec Sybase.
L'outil de mappage OpenJPA est incapable de créer des contraintes ForeignKey lorsqu'il est utilisé avec Sybase Adaptive Server. En conséquence, les contraintes de clé externe doivent être créées manuellement.
- Procédez à l'identification et à la résolution des problèmes liés aux options de configuration de DB2 Optim pureQuery Runtime. Si vous utilisez DB2 Optim pureQuery Runtime avec le fournisseur JPA de WebSphere Application Server (WSJPA), vous devez définir la propriété suivante dans le fichier persistence.xml :
<property name="openjpa.Compatibility" value="StrictIdentityValues=true"/>
Si vous devez définir une option de compatibilité différente, par exemple, ReloadOnDetach=false, les deux options doivent être spécifiées en tant que paramètres de la même instruction de propriété dans le fichier persistence.xml. Par exemple :
<property name="openjpa.Compatibility" value="StrictIdentityValues=true,ReloadOnDetach=false"/>
Eviter les incidents: La propriété de compatibilité OpenJPA ne supprime pas les types de proxy qu'OpenJPA génère pour certains types de données, plus particulièrement les types de données, tels GregorianCalendar. Cette omission peut provoquer des problèmes de désérialisation. Le cas échéant, un message d'erreur du type suivant est émis :gotcha
Error Message is:org.codehaus.jackson.map.JsonMappingException: Can not construct instance of org.apache.openjpa.util.java$util$GregorianCalendar$proxy, problem: no suitable creator method found at [Source: org.apache.http.conn.EofSensorInputStream@d83fbd5; line: 1, column: 4094]
- Procédez à l'identification et la résolution des incidents liés aux attributs de type temporels dans une entité lorsque vous utilisez une base de données avec DB2 for z/OS. Si une entité comporte un attribut de type temporel et que la colonne mappée correspondante destinée à la base de données n'est pas compatible, l'exception suivante peut apparaître dans certaines situations :
Cette exception peut se produire dans les cas suivants :org.apache.openjpa.lib.jdbc.ReportingSQLException: THE DATE, TIME, OR TIMESTAMP VALUE 1 IS INVALID. SQLCODE=-18x, SQLSTATE=22007
- Votre base de données exécute DB2 for z/OS.
- Vous utilisez une requête nommée et accédez à la base de données à l'aide d'un SQL natif.
- La requête native utilise la zone temporelle sous la forme d'un paramètre SQL, mais la requête n'est pas compatible avec la définition de colonne de la table de base de données. Pour plus d'informations sur la compatibilité, reportez-vous à la rubrique Supported data conversions dans le centre de documentation DB2 9.7.
Sous-rubriques
Journalisation d'applications avec JPA
La journalisation permet de visualiser, de tracer et de résoudre le comportement de l'environnement d'exécution d'une application. JPA (Java Persistence API) fournit un système de journalisation flexible intégré dans le serveur d'applications pour vous aider à résoudre certains problèmes.Identification et résolution des problèmes liés à l'expiration de transactions et aux interblocages JPA
Les interblocages de base de données et l'expiration de transactions résultent de conflits entre deux clients ou plus qui tentent d'accéder à la même ressource de base de données. L'interblocage est un cas particulier où une condition de blocage circulaire se produit entre deux clients ou plus, chacun étant bloqué par les autres, mais aucun ne peut fonctionner. En règle générale, ces phénomènes ne constituent pas des erreurs de programmation. Ils sont provoqués par une logique métier qui accède à des ressources de base de données de façon complexe et interdépendante.Journalisation d'applications avec JPA
La journalisation permet de visualiser, de tracer et de résoudre le comportement de l'environnement d'exécution d'une application. JPA (Java Persistence API) fournit un système de journalisation flexible intégré dans le serveur d'applications pour vous aider à résoudre certains problèmes.Identification et résolution des problèmes liés à l'expiration de transactions et aux interblocages JPA
Les interblocages de base de données et l'expiration de transactions résultent de conflits entre deux clients ou plus qui tentent d'accéder à la même ressource de base de données. L'interblocage est un cas particulier où une condition de blocage circulaire se produit entre deux clients ou plus, chacun étant bloqué par les autres, mais aucun ne peut fonctionner. En règle générale, ces phénomènes ne constituent pas des erreurs de programmation. Ils sont provoqués par une logique métier qui accède à des ressources de base de données de façon complexe et interdépendante.


http://www14.software.ibm.com/webapp/wsbroker/redirect?version=cord&product=was-nd-mp&topic=tejb_jpatroubleshoot
Nom du fichier : tejb_jpatroubleshoot.html