web-dev-qa-db-fra.com

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

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

entityManager.find(Customer.class, customerID);

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

134
Sajee

Les options de journalisation sont spécifiques au fournisseur. Vous devez savoir quelle implémentation JPA utilisez-vous.

  • 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éfinissez la catégorie de journal DataNucleus.Datastore.Native sur un niveau tel que DEBUG.

301
axtavt

De même, si vous utilisez EclipseLink et souhaitez générer les valeurs de paramètre SQL, vous pouvez ajouter cette propriété à votre fichier persistence.xml:

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

Si vous utilisez hibernate et logback comme enregistreur, vous pouvez utiliser ce qui suit (affiche uniquement les liaisons et pas 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 affiche la requête

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

org.hibernate.type = TRACE affiche les liaisons et normalement les résultats, qui seront supprimés via 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>
15
Kuhpid

Dans EclipseLink pour obtenir le code 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? pour les paramètres. Pour que le code SQL soit traduit avec les arguments, vous avez besoin d'un DatabaseRecord avec les valeurs de paramètre.

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

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

Source: Comment obtenir le SQL pour une requête

14
Tomasz

Afin de visualiser tout le SQL et les paramètres dans OpenJPA, placez ces deux paramètres dans le fichier persistence.xml:

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

Exemple utilisant log4j ( src\log4j.xml ):

<?xml version="1.0" encoding="UTF-8" ?>

<appender name="CA" class="org.Apache.log4j.AsyncAppender">
    <param name="BufferSize" value="512"/>
    <appender-ref ref="CA_OUTPUT"/>
</appender>
<appender name="CA_OUTPUT" class="org.Apache.log4j.ConsoleAppender">
    <layout class="org.Apache.log4j.PatternLayout">
        <param name="ConversionPattern" value="[%p] %d %c %M - %m%n"/>
    </layout>
</appender>

<logger name="org.hibernate.SQL" additivity="false">
    <level value="DEBUG"/>
    <appender-ref ref="CA"/>
</logger>

<root>
    <level value="WARN"/>
    <appender-ref ref="CA"/>
</root>

4
Marcus Becker

Si vous voulez voir les requêtes exactes avec les valeurs de paramètre et les valeurs de retour, vous pouvez utiliser un pilote proxy jdbc. Il interceptera tous les appels jdbc et enregistrera leurs valeurs. Quelques procurations:

  • log4jdbc
  • jdbcspy

Ils peuvent également fournir des fonctionnalités supplémentaires, telles que la mesure du temps d'exécution des requêtes et la collecte de statistiques.

4
mateusz.fiolka

De plus, si vous utilisez WildFly/JBoss, définissez le niveau de journalisation de org.hibernate sur DEBUG.

 Hibernate Logging in WildFly

1
Αλέκος

Avec Spring Boot, ajoutez simplement: spring.jpa.show-sql = true à application.properties . Cela affichera la requête, mais sans les paramètres réels (vous verrez? À la place de chaque paramètre).

0
Elhanan Mishraky

Il y a un fichier appelé persistence.xml Appuyez sur Ctrl + Maj + R et trouvez-le, puis, il y a un endroit écrit quelque chose comme showSQL.

Il suffit de le dire comme vrai

Je ne sais pas si le serveur doit être démarré en mode débogage . Vérifiez les instructions SQL créées sur la console.

0
pringlesinn

Une autre bonne option si vous avez trop de journaux et que vous voulez uniquement mettre une System.out.println() temporelle, vous pouvez, selon votre fournisseur:

CriteriaBuilder criteriaBuilder = getEntityManager().getCriteriaBuilder();
CriteriaQuery<ExaminationType> criteriaQuery = criteriaBuilder.createQuery(getEntityClass()); 

/* For Hibernate */
System.out.println(getEntityManager().createQuery(criteriaQuery).unwrap(org.hibernate.Query.class).getQueryString());

/* For OpenJPA */ 
System.out.println(getEntityManager().createQuery(criteriaQuery).unwrap(org.Apache.openjpa.persistence.QueryImpl.class).getQueryString());

/* For EclipseLink */
System.out.println(getEntityManager().createQuery(criteriaQuery).unwrap(JpaQuery.class).getSQLString());
0
King Midas
0
btiernay

Si vous utilisez le framework Spring. Modifiez votre fichier application.properties comme suit

#Logging JPA Queries, 1st line Log Query. 2nd line Log parameters of prepared statements 
logging.level.org.hibernate.SQL=DEBUG  
logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE  

#Logging JdbcTemplate Queries, 1st line Log Query. 2nd line Log parameters of prepared statements 
logging.level.org.springframework.jdbc.core.JdbcTemplate=DEBUG  
logging.level.org.springframework.jdbc.core.StatementCreatorUtils=TRACE  
0
thyzz