nie jest kompletna odpowiedź, ale tylko wskaźnik ...
QueryCounter
public class QueryCounter {
private static long COUNTER = 0;
private static long next() {
return ++COUNTER;
}
private static String getHintValue() {
return "/*Query No. " + next() + " */";
}
public static void setQueryCount(Query query) {
/* EclipseLink */
//query.setHint(QueryHints.HINT, getHintValue());
query.setHint("eclipselink.sql.hint", getHintValue());
/* OpenJPA + Oracle */
//query.setHint("openjpa.hint.OracleSelectHint", getQueryHint());
/* OpenJPA + MySQL */
//query.setHint("openjpa.hint.MySQLSelectHin", getQueryHint());
}
}
Wykorzystanie
Organization sun = new Organization("Sun");
em.persist(sun);
tx.commit();
Assert.assertNotNull(sun.getEntityId());
Query query = em.createQuery("SELECT org.entityId FROM Organization org WHERE org.entityId = " + sun.getEntityId());
QueryCounter.setQueryCount(query);
query.getResultList();
/*ServerSession does NOT log ReadObjectQuery??*/
query = em.createQuery("SELECT org FROM Organization org WHERE org.entityId = " + sun.getEntityId());
QueryCounter.setQueryCount(query);
query.getResultList();
query = em.createQuery("SELECT org.entityId FROM Organization org WHERE org.entityId = " + sun.getEntityId());
QueryCounter.setQueryCount(query);
query.getResultList();
Konsola
[EL Finest]: 2010-11-20 19:06:16.45--UnitOfWork(717879615)--Thread(Thread[main,5,main])--Execute query ReportQuery(referenceClass=Organization sql="SELECT entity_id FROM organization_tt WHERE (entity_id = ?)")
[EL Fine]: 2010-11-20 19:06:16.475--ServerSession(699542937)--Connection(1949550475)--Thread(Thread[main,5,main])--SELECT /*Query No. 1 */ entity_id FROM organization_tt WHERE (entity_id = ?)
bind => [1]
[EL Finest]: 2010-11-20 19:06:23.372--UnitOfWork(717879615)--Thread(Thread[main,5,main])--Execute query ReadObjectQuery(referenceClass=Organization sql="SELECT entity_id, name FROM organization_tt WHERE (entity_id = ?)")
[EL Finest]: 2010-11-20 19:06:35.916--UnitOfWork(717879615)--Thread(Thread[main,5,main])--Execute query ReportQuery(referenceClass=Organization sql="SELECT entity_id FROM organization_tt WHERE (entity_id = ?)")
[EL Fine]: 2010-11-20 19:06:35.92--ServerSession(699542937)--Connection(1949550475)--Thread(Thread[main,5,main])--SELECT /*Query No. 3 */ entity_id FROM organization_tt WHERE (entity_id = ?)
bind => [1]
OpenJPA ma podobną koncepcję 1.8.7. Database-Specific Hints. Sprawdź, czy te konkretne wskazówki mogą rozwiązać Twój cel.
AKTUALIZACJA ODPOWIEDŹ
@Eddie, sprawdzić, czy to może pomóc ...........
CustomLogFactory
public class MyLogFactory extends org.apache.openjpa.lib.log.LogFactoryImpl {
/* copied from LogFactoryImpl.NEWLINE */
private static final String NEWLINE = J2DoPrivHelper.getLineSeparator();
private boolean sqlLogger;
@Override
public Log getLog(String channel) {
if("openjpa.jdbc.SQL".equals(channel)) { // OR equalsIgnoreCase(channel) ???
sqlLogger = true;
}
return super.getLog(channel);
}
@Override
protected LogImpl newLogImpl() {
if(sqlLogger) {
sqlLogger = false; /* once an SQL Logger is created, we dont't need any more instances */
return new LogImpl() {
private long sqlCounter = 0;
@Override
protected String formatMessage(short level, String message, Throwable t) {
if(isSQLString(message)) {
StringBuffer formattedMessage = new StringBuffer(super.formatMessage(level, message, t));
StringBuffer queryNo = new StringBuffer();
queryNo.append(" [Query # ").append(++sqlCounter).append("]").append(NEWLINE);
formattedMessage.delete(formattedMessage.length() - NEWLINE.length(), formattedMessage.length());
formattedMessage.append(queryNo);
return formattedMessage.toString();
}
return super.formatMessage(level, message, t);
}
/* just a sample implementation; checks whether message contains the word "executing"
* more concrete implementation should check the message for SELECT, UPDATE, INSERT INTO, ALTER.... clauses */
private boolean isSQLString(String message) {
if(message.contains("executing")) {
return true;
}
return false;
}
};
}
return super.newLogImpl();
}
}
peristence.xml
<property name="openjpa.Log" value="org.opensource.logger.MyLogFactory(DefaultLevel=WARN, Runtime=INFO, Tool=INFO, SQL=TRACE)"/>
test
EntityManager em = Persistence.createEntityManagerFactory("default").createEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin();
Person person = new Person();
person.setName("Bond-OO7");
person.setAge(22);
em.persist(person);
tx.commit();
em.close();
Konsola
............
2084 default TRACE [main] openjpa.jdbc.SQL - <t 346613126, conn 1551158018> executing prepstmnt 556472773 SELECT SEQUENCE_OWNER AS SEQUENCE_SCHEMA, SEQUENCE_NAME FROM ALL_SEQUENCES [Query # 1]
2136 default TRACE [main] openjpa.jdbc.SQL - <t 346613126, conn 1551158018> [52 ms] spent
2305 default TRACE [main] openjpa.jdbc.SQL - <t 346613126, conn 2026561073> executing prepstmnt 6637010 INSERT INTO Person (id, age, name) VALUES (?, ?, ?) [params=?, ?, ?] [Query # 2]
2306 default TRACE [main] openjpa.jdbc.SQL - <t 346613126, conn 2026561073> [1 ms] spent
............
+ 1 JPA2 nadal potrzebuje niektórych funkcji out-of-box;) – dira
zobacz część UPDATED ANSWER w mojej poprzedniej odpowiedzi. – dira
@ becomputer06 - Myślę, że nie wyrażam jasno mojej potrzeby. To drugie rozwiązanie dotyczy tylko rejestrowania i nie jest wysyłane do bazy danych. QUERYNO jest specjalną klauzulą, podobnie jak WHERE lub OPTIMIZE FOR X ROWS. http://publib.boulder.ibm.com/infocenter/dzichelp/v2r2/index.jsp?topic=/com.ibm.db29.doc.sqlref/db2z_sql_querynoclause.htm – Eddie