「J2EE」カテゴリーのアーカイブ
1.発行SQLのログ出力方法
デバッグおよびテストを行う場合などで、JPQLの変換後のSQLの情報が必要なる場合があります。persistence.xmlに2行追加するだけです。
persistence.xmlに10行目と、11行目を追加します。10行目は、JPQLの発行したSQL文をログ出力するために、「eclipselink.logging.level.sql」の項目を「FINE」に設定します。また11行目は、ホスト変数をログ出力するかどうかの設定です。
図 1. persistence.xmlファイル例
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="testPU" transaction-type="JTA">
<jta-data-source>jdbc/db2</jta-data-source>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<properties>
<property name="eclipselink.logging.level.sql" value="FINE"/>
<property name="eclipselink.logging.parameters" value="true"/>
</properties>
</persistence-unit>
</persistence>
図 2. 実行JPQL
Query query = em.createQuery("SELECT p FROM Product p WHERE p.id = :id and p.productName = :productName");
query.setParameter("id", 10);
query.setParameter("productName", "パソコン");
query.getResultList();
図 3. 出力ログ
詳細レベル (低): SELECT ID, CREATE_PROGRAM_ID, CREATE_TIMESTAMP, CREATE_USER_ID, MAKER, PRODUCT_NAME, PRODUCT_SPECIFICATION_CONTENT, PRODUCT_SPECIFICATION_DIV, RELEASE_DATE, UPDATE_PROGRAM_ID, UPDATE_TIMESTAMP, UPDATE_USER_ID FROM PRODUCT WHERE ((ID = ?) AND (PRODUCT_NAME = ?))
bind => [10, パソコン]
2.総評
プログラム上でホスト変数のログ出力を行わずに、EclipseLinkのLogging設定を行うだけで、ホスト変数の確認ができるのがとても便利です。使用するフレームワークによりますが、ホスト変数のログ出力を、コーディングしなければならないこともあるので、とても便利です。
お手数ですが、この記事が、あなたのお役に立った場合は、ぜひ、「いいね」ボタンを押してくれるとうれしいです。自分自身のモチベーションの維持と、このブログを読んでくださる、他の読者にも参考になると思います。
3.参照
EclipseLink/Examples/JPA/Logging Log Level Configuration
©中條勝徳 and okulejp.com, 2012.
EclipseLinkを利用した、DB2の拡張クライアント情報の設定方法がなかったので、設定方法をブログに載せます。
1.SessionEventAdapterの実装
postAcquireConnectionメソッドは、DBコネクションを取得した後に呼び出されます。preReleaseConnectionメソッドは、DBコネクションを開放するときに呼び出されます。postAcquireConnectionメソッドの24~26行目で、拡張クライアント情報を設定しています。preReleaseConnectionの39~41行目で、拡張クライアント情報を初期化しています。
図 1. SessionEventAdapterの実装例(CustomSessionEventAdapter.java)
package com.wordpress.okulejp.sesstion;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Map;
import java.util.logging.Logger;
import javax.faces.context.FacesContext;
import javax.servlet.http.HttpServletRequest;
import org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor;
import org.eclipse.persistence.sessions.SessionEvent;
import org.eclipse.persistence.sessions.SessionEventAdapter;
public class CustomSessionEventAdapter extends SessionEventAdapter {
@Override
public void postAcquireConnection(SessionEvent event) {
Logger logger = Logger.getLogger(this.getClass().getName());
logger.fine("postAcquireConnection start");
try {
FacesContext fc = FacesContext.getCurrentInstance();
Map<String,Object> sessionMap = fc.getExternalContext().getSessionMap();
Connection con= ((DatabaseAccessor) event.getResult()).getConnection();
HttpServletRequest request = (HttpServletRequest) fc.getExternalContext().getRequest();
con.setClientInfo("ApplicationName", (String) sessionMap.get("ApplicationName"));
con.setClientInfo("ClientUser", request.getRemoteUser());
con.setClientInfo("ClientHostname", request.getRemoteAddr());
} catch(SQLException ex) {
throw new RuntimeException(ex.getMessage());
}
logger.fine("postAcquireConnection end");
}
@Override
public void preReleaseConnection(SessionEvent event) {
Logger logger = Logger.getLogger(this.getClass().getName());
logger.fine("preReleaseConnection start");
try {
java.sql.Connection con= ((DatabaseAccessor) event.getResult()).getConnection();
con.setClientInfo("ApplicationName", null);
con.setClientInfo("ClientUser", null);
con.setClientInfo("ClientHostname", null);
} catch(SQLException ex) {
throw new RuntimeException(ex.getMessage());
}
logger.fine("preReleaseConnection end");
}
}
2.persistence.xmlの設定
9行目で、実装したSessionEventAdapterを呼び出す設定をしています。
図 2. persistence.xml
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="ngsPU" transaction-type="JTA">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<jta-data-source>jdbc/db2</jta-data-source>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<properties>
<property name="eclipselink.session-event-listener" value="com.wordpress.okulejp.sesstion.CustomSessionEventAdapter"/>
<property name="eclipselink.logging.level" value="FINE"/>
<property name="eclipselink.logging.level.sql" value="FINE"/>
<property name="eclipselink.logging.parameters" value="true"/>
</properties>
</persistence-unit>
</persistence>
3.DB2監査ログ
12~14行目で、CustomSessionEventAdapter.javaで設定した拡張クライアント情報が出力されています。またDB2監査ログの設定しだいで、42~52行目のようにSQLパラメータの出力も可能です。
(※注意10,13行目で、IPアドレスを「*」でマスキングしてありますが、実際に監査ログには値が出力されます。)
図 3. DB2監査ログ出力結果
timestamp=2012-12-19-10.50.32.423000;
category=EXECUTE;
audit event=STATEMENT;
event correlator=55;
event status=0;
database=MYDB;
userid=OKULE;
authid=ADMIN;
session authid=ADMIN;
application id=192.168.*.*.54300.121219013706;
application name=db2jcc_application;
client userid=test_id;
client workstation name=192.168.*.*;
client application name=test_appName;
package schema=OKULE;
package name=SYSSH200;
package section=1;
local transaction id=0xd7064d0000000000;
global transaction id=0x0000000000000000000000000000000000000000;
uow id=25;
activity id=1;
statement invocation id=0;
statement nesting level=0;
activity type=WRITE_DML;
statement text=UPDATE DB2_AUDIT_TEST SET UPDATE_PROGRAM_ID = ? , UPDATE_USER_ID = ? , UPDATE_TIMESTAMP = SYSDATE WHERE ID = ?;
statement isolation level=CS;
Compilation Environment Description
isolation: CS
query optimization: 5
min dec div 3: NO
degree: 1
SQL rules: DB2
refresh age: +00000000000000.000000
resolution timestamp: 2012-12-19-10.50.30.000000
federated asynchrony: 0
temporal business time: 0000-00-00-00.00.00.000000000000
temporal system time: 0000-00-00-00.00.00.000000000000
schema: OKULE
maintained table type: SYSTEM;
rows modified=1;
rows returned=0;
value index = 1
type = VARCHAR
data = MA0304;
extended indicator = 0;
value index = 2
type = VARCHAR
data = admin;
extended indicator = 0;
value index = 3
type = VARCHAR
data = k3;
extended indicator = 0;
local start time=2012-12-19-10.50.30.772729;
4.参考URL
IBM Data Server Driver for JDBC and SQLJ によるクライアント情報プロパティーのサポート
Java Persistence API (JPA) Extensions Reference for EclipseLink session-event-listener
©中條勝徳 and okulejp.com, 2012.