185 votes

Comment visualiser les requêtes SQL émises par JPA ?

Quand mon code émet un appel comme celui-ci :

entityManager.find(Customer.class, customerID);

Comment puis-je voir la requête SQL pour cet appel ? En supposant que je n'aie pas accès au serveur de base de données pour profiler/surveiller les appels, existe-t-il un moyen d'enregistrer ou de visualiser dans mon IDE les requêtes SQL correspondantes émises par les appels JPA ? Je travaille avec SQL Server 2008 R2 en utilisant le pilote jTDS.

10 votes

Quel est le fournisseur JPA ? Je pense que ce paramètre est spécifique au fournisseur.

0 votes

@Sajee, pourriez-vous marquer la réponse de axtavt comme acceptée afin de diriger les visiteurs de votre question directement vers cette réponse ?

365voto

axtavt Points 126632

Les options de journalisation sont propres à chaque fournisseur. Vous devez savoir quelle implémentation de JPA vous utilisez.

  • Hibernate ( voir ici ) :

    <property name = "hibernate.show_sql" value = "true" />
  • EclipseLink ( voir ici ) :

    <property name="eclipselink.logging.level" value="FINE"/>
  • OpenJPA ( voir ici ) :

    <property name="openjpa.Log" value="DefaultLevel=WARN,Runtime=INFO,Tool=INFO,SQL=TRACE"/>
  • DataNucleus ( voir ici ) :

    Définir la catégorie du journal DataNucleus.Datastore.Native à un niveau, comme DEBUG .

4 votes

@Sajee : Vous devriez donner à cette réponse une coche pour indiquer qu'il s'agit de la réponse acceptée. Cela fonctionne très bien pour moi, avec Hibernate. Si vous approuvez cette réponse, vous et le répondant obtiendrez plus de points et plus de permissions sur stackoverflow.com.

79 votes

Vous devriez mettre cette ligne dans votre persistence.xml pour tout corps qui est curieux. Elle serait sous le nœud <properties>... Désolé si c'est évident, j'étais juste confus sur l'endroit où le mettre moi-même.

5 votes

Lorsque vous utilisez Hibernate et log4j, vous pouvez également définir le logger "org.hibernate.SQL" sur DEBUG ( javalobby.org/java/forums/t44119.html )

36voto

ThePizzle Points 368

En outre, si vous utilisez EclipseLink et que vous souhaitez afficher les valeurs des paramètres SQL, vous pouvez ajouter cette propriété à votre fichier persistence.xml :

<property name="eclipselink.logging.parameters" value="true"/>

0 votes

Existe-t-il une alternative pour obtenir les valeurs de liaison dans intellij ?

15voto

Tomasz Points 1678

Dans EclipseLink, pour obtenir le SQL d'une requête spécifique au moment de l'exécution, vous pouvez utiliser l'API DatabaseQuery :

Query query = em.createNamedQuery("findMe"); 
Session session = em.unwrap(JpaEntityManager.class).getActiveSession(); 
DatabaseQuery databaseQuery = ((EJBQueryImpl)query).getDatabaseQuery(); 
databaseQuery.prepareCall(session, new DatabaseRecord());

String sqlString = databaseQuery.getSQLString();

Ce SQL contiendra des ? pour les paramètres. Pour obtenir le SQL traduit avec les arguments, vous avez besoin d'un DatabaseRecord avec les valeurs des paramètres.

DatabaseRecord recordWithValues= new DatabaseRecord();
recordWithValues.add(new DatabaseField("param1"), "someValue");

String sqlStringWithArgs = 
         databaseQuery.getTranslatedSQLString(session, recordWithValues);

Source : Comment obtenir le SQL d'une requête

0 votes

Qu'est-ce que recordWithValues ? Est-il possible de l'obtenir à partir de DatabaseQuery ou EJBQueryImpl ?

1 votes

L'argument Record est l'un de (Record, XMLRecord) qui contient les arguments de la requête.

0 votes

Si j'ai quelque chose comme Query myQuery = entityManager.createNamedQuery("MyEntity.findMe") ; myQuery.setParameter("param1", "someValue) ; Comment obtenir recordWithValues de myQuery ?

15voto

Kuhpid Points 355

Si vous utilisez hibernate et logback comme enregistreur, vous pouvez utiliser la méthode suivante (qui ne montre que les liaisons et non les résultats) :

<appender
    name="STDOUT"
    class="ch.qos.logback.core.ConsoleAppender">
    <encoder>
        <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} -
            %msg%n</pattern>
    </encoder>
    <filter class="ch.qos.logback.core.filter.EvaluatorFilter">
        <evaluator>
            <expression>return message.toLowerCase().contains("org.hibernate.type") &amp;&amp;
                logger.startsWith("returning");</expression>
        </evaluator>
        <OnMismatch>NEUTRAL</OnMismatch>
        <OnMatch>DENY</OnMatch>
    </filter>
</appender>

org.hibernate.SQL=DEBUG imprime la requête

<logger name="org.hibernate.SQL">
    <level value="DEBUG" />
</logger>

org.hibernate.type=TRACE imprime les liens et normalement les résultats, qui seront supprimés par le filtre personnalisé.

<logger name="org.hibernate.type">
    <level value="TRACE" />
</logger>

Vous avez besoin de la dépendance janino (http://logback.qos.ch/manual/filters.html#JaninoEventEvaluator) :

<dependency>
    <groupId>org.codehaus.janino</groupId>
    <artifactId>janino</artifactId>
    <version>2.6.1</version>
</dependency>

8voto

jfcorugedo Points 328

Afin d'afficher tout le SQL et les paramètres dans OpenJPA, mettez ces deux paramètres dans le persistence.xml :

<property name="openjpa.Log" value="DefaultLevel=WARN, Runtime=INFO, Tool=INFO, SQL=TRACE"/>
<property name="openjpa.ConnectionFactoryProperties" value="PrintParameters=true" />

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X