org.sonar.api.database.StatisticsEntityManager Maven / Gradle / Ivy
/*
* Sonar, open source software quality management tool.
* Copyright (C) 2009 SonarSource SA
* mailto:contact AT sonarsource DOT com
*
* Sonar is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* Sonar is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with Sonar; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
*/
package org.sonar.api.database;
import org.hibernate.ejb.EntityManagerFactoryImpl;
import org.hibernate.ejb.HibernateEntityManagerFactory;
import org.hibernate.stat.QueryStatistics;
import org.hibernate.stat.Statistics;
import org.slf4j.Logger;
import javax.persistence.*;
public class StatisticsEntityManager implements EntityManager {
private final EntityManager manager;
private final Logger logger;
private EntityTransaction transaction;
private EntityManagerFactory factory;
public StatisticsEntityManager(EntityManagerFactory factory, EntityManager manager, Logger logger) {
super();
this.manager = manager;
this.logger = logger;
this.factory = factory;
}
public void clear() {
manager.clear();
}
public void close() {
manager.close();
}
public boolean contains(Object entity) {
return manager.contains(entity);
}
public Query createNamedQuery(String name) {
return manager.createNamedQuery(name);
}
public Query createNativeQuery(String sqlString) {
return manager.createNativeQuery(sqlString);
}
public Query createNativeQuery(String sqlString, Class resultClass) {
return manager.createNativeQuery(sqlString, resultClass);
}
public Query createNativeQuery(String sqlString, String resultSetMapping) {
return manager.createNativeQuery(sqlString, resultSetMapping);
}
public Query createQuery(String qlString) {
return manager.createQuery(qlString);
}
public T find(Class entityClass, Object primaryKey) {
long start = System.currentTimeMillis();
T hit = manager.find(entityClass, primaryKey);
long stop = System.currentTimeMillis() - start;
logger.info("Find took " + stop + " ms");
return hit;
}
public void flush() {
long start = System.currentTimeMillis();
manager.flush();
long stop = System.currentTimeMillis() - start;
logger.info("Flush took " + stop + " ms");
}
public Object getDelegate() {
return manager.getDelegate();
}
public FlushModeType getFlushMode() {
return manager.getFlushMode();
}
public T getReference(Class entityClass, Object primaryKey) {
return manager.getReference(entityClass, primaryKey);
}
private String getCallerStack(int depth) {
StackTraceElement[] stack = Thread.currentThread().getStackTrace();
return stack[depth].toString();
}
public EntityTransaction getTransaction() {
if (transaction == null) {
transaction = new EntityTransaction() {
private long beginTs;
public void begin() {
beginTs = System.currentTimeMillis();
manager.getTransaction().begin();
}
public void commit() {
long start = System.currentTimeMillis();
manager.getTransaction().commit();
Long commitTimeTaken = System.currentTimeMillis() - start;
Long transactionTimeTaken = System.currentTimeMillis() - beginTs;
logger.info("{}: Commit took {} ms, global transaction took {} ms",
new Object[]{getCallerStack(5), commitTimeTaken, transactionTimeTaken});
dumpStatistics();
beginTs = 0;
}
public boolean getRollbackOnly() {
return manager.getTransaction().getRollbackOnly();
}
public boolean isActive() {
return manager.getTransaction().isActive();
}
public void rollback() {
long start = System.currentTimeMillis();
manager.getTransaction().rollback();
long rollbackTimeTaken = System.currentTimeMillis() - start;
long transactionTimeTaken = System.currentTimeMillis() - beginTs;
logger.info("Rollback took " + rollbackTimeTaken + " ms, global transaction took " + transactionTimeTaken + " ms");
beginTs = 0;
}
public void setRollbackOnly() {
manager.getTransaction().setRollbackOnly();
}
};
}
return transaction;
}
public boolean isOpen() {
return manager.isOpen();
}
public void joinTransaction() {
manager.joinTransaction();
}
public void lock(Object entity, LockModeType lockMode) {
manager.lock(entity, lockMode);
}
public T merge(T entity) {
return manager.merge(entity);
}
public void persist(Object entity) {
manager.persist(entity);
}
public void refresh(Object entity) {
manager.refresh(entity);
}
public void remove(Object entity) {
manager.remove(entity);
}
public void setFlushMode(FlushModeType flushMode) {
manager.setFlushMode(flushMode);
}
private void dumpStatistics() {
if (logger.isDebugEnabled() && factory instanceof EntityManagerFactoryImpl) {
HibernateEntityManagerFactory hibernateFactory = (HibernateEntityManagerFactory) factory;
Statistics stats = hibernateFactory.getSessionFactory().getStatistics();
for (String query : stats.getQueries()) {
QueryStatistics stat = stats.getQueryStatistics(query);
StringBuilder sb = new StringBuilder();
sb.append(stats.getQueryExecutionMaxTime());
sb.append("ms, count=");
sb.append(stat.getExecutionCount());
sb.append(", sql=");
sb.append(stat.getCategoryName());
logger.debug(sb.toString());
}
stats.clear();
}
}
}