Package ch.hortis.sonar.jpa

Source Code of ch.hortis.sonar.jpa.Persistence

/*
* This program is copyright (c) 2007 Hortis-GRC SA.
*
* This file is part of Sonar.
* Sonar is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Sonar; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
package ch.hortis.sonar.jpa;

import ch.hortis.sonar.model.JdbcData;
import ch.hortis.sonar.model.SchemaInfo;
import org.hibernate.stat.EntityStatistics;
import org.hibernate.stat.QueryStatistics;
import org.hibernate.stat.SecondLevelCacheStatistics;
import org.hibernate.stat.Statistics;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.NoResultException;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.Date;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.HashMap;
import java.util.Map;

/**
* Contains all functions to setup the database.
*/
public class Persistence {

  public static final int MODEL_VERSION = 9;

  protected final JdbcData jdbcData;
  protected final Logger log;
  private EntityManagerFactory factory = null;

  protected Persistence( JdbcData jdbcData ) {
    this.jdbcData = jdbcData;
    this.log = LoggerFactory.getLogger( this.getClass().getName() );
  }

  public static Persistence create( JdbcData jdbcData ) throws PersistenceException {
    Persistence persistence = new Persistence( jdbcData );
    persistence.install();
    return persistence;
  }

  public static boolean databaseExists( JdbcData jdbcData ) throws SQLException, WrongDatabaseVersionException {
    Connection jdbcConn;
    if ( jdbcData.getDatasource() != null ) {
      DataSource ds;
      try {
        Context ctx = new InitialContext();
        ds = (DataSource) ctx.lookup( jdbcData.getDatasource() );
      } catch (Exception ex) {
        SQLException sqlEx = new SQLException( "Error during datasource JNDI lookup" );
        sqlEx.initCause( ex );
        throw sqlEx;
      }
      jdbcConn = ds.getConnection();
    } else {
      try {
        Class.forName( jdbcData.getDriverClassName() );
      } catch (ClassNotFoundException e) {
        throw new SQLException( "Cannot found sql driver " + jdbcData.getDriverClassName() );
      }
      jdbcConn = DriverManager.getConnection( jdbcData.getUrl(), jdbcData.getUsername(), jdbcData.getPassword() );
    }
    Statement stmt = null;
    ResultSet rs = null;
    try {
      stmt = jdbcConn.createStatement();
      rs = stmt.executeQuery( "SELECT version FROM " + SchemaInfo.TABLE_NAME );
      while ( rs.next() ) {
        int version = rs.getInt( 1 );
        if ( version == MODEL_VERSION ) {
          return true;
        }
        throw new WrongDatabaseVersionException( "Database required model version (" + MODEL_VERSION + ") does not match current version (" + version + ")" );
      }
    } catch (SQLException ex) {
      // don't care

    } finally {
      if ( rs != null ) rs.close();
      if ( stmt != null ) stmt.close();
      jdbcConn.close();
    }
    return false;
  }

  private void install() throws PersistenceException {
    try {
      factory = JPAUtil.getEntityManagerFactory( jdbcData, null );
    } catch (javax.persistence.PersistenceException ex) {
      log.debug( "Persistence exception " + ex.getMessage() );
      // if an error exists trace should look like : org.hibernate.HibernateException: Missing table:
      throw new PersistenceException( ex );
      //createDatabase("create");
    }
   
    EntityManager manager = factory.createEntityManager();
    try {
      SchemaInfo schemaInfo = manager.find( SchemaInfo.class, MODEL_VERSION );
      if ( schemaInfo == null ) {
        throw new WrongDatabaseVersionException( "Database required model version (" + MODEL_VERSION + ") not found" );
      }
    } catch (NoResultException exception) {
      throw new PersistenceException( exception.getMessage() );
    } finally {
      manager.close();
    }
  }

  protected final void createDatabase( String creationMode, int version ) throws PersistenceException {
    SchemaInfo schemaInfo = new SchemaInfo();
    schemaInfo.setVersion( version );
    Map<String, String> configuration = new HashMap<String, String>();
    configuration.put( "hibernate.hbm2ddl.auto", creationMode );
    try {
      factory = JPAUtil.getEntityManagerFactory( jdbcData, configuration );
      EntityManager manager = factory.createEntityManager();
      manager.getTransaction().begin();
      manager.persist( schemaInfo );
      manager.getTransaction().commit();
      manager.close();
      log.info( "Database created" );
    } catch (javax.persistence.PersistenceException exception) {
      throw new PersistenceException( exception );
    }
  }

  public void dumpStats( Logger logger ) {
    if ( factory instanceof org.hibernate.ejb.EntityManagerFactoryImpl ) {
      org.hibernate.ejb.EntityManagerFactoryImpl hibernateFactory = (org.hibernate.ejb.EntityManagerFactoryImpl) factory;
      Statistics stats = hibernateFactory.getSessionFactory().getStatistics();
      if ( !stats.isStatisticsEnabled() ) {
        logger.info( "DB statistics computation are disabled, enable them using sonar.db.statistics=true system property" );
        return;
      }
      double cacheHitCount = stats.getSecondLevelCacheHitCount();
      Date statsDate = new Date( stats.getStartTime() );
      logger.info( "DB Statistics computed since " + statsDate );
      logger.info( "" );
      logger.info( "Cache hit count:" + cacheHitCount );
      double cacheMissCount = stats.getSecondLevelCacheMissCount();
      logger.info( "Cache miss count:" + cacheMissCount );
      double cachePutCount = stats.getSecondLevelCachePutCount();
      logger.info( "Cache put count:" + cachePutCount );
      double cacheHitRatio = cacheHitCount / ( cacheHitCount + cacheMissCount );
      logger.info( "Cache Hit ratio:" + cacheHitRatio );
      logger.info( "" );
      logger.info( "Cache regions statistics :" );
      logger.info( "" );
      String[] cacheRegions = stats.getSecondLevelCacheRegionNames();
      for (String region : cacheRegions) {
        SecondLevelCacheStatistics cacheStats = stats.getSecondLevelCacheStatistics( region );
        logger.info( "Cache region:" + cacheStats.getCategoryName() );
        logger.info( "Elements in memory:" + cacheStats.getElementCountInMemory() );
        logger.info( "Hits count:" + cacheStats.getHitCount() );
        logger.info( "Miss count:" + cacheStats.getMissCount() );
        logger.info( "Put count:" + cacheStats.getPutCount() );
        logger.info( "" );
      }

      logger.info( "Entites statistics :" );
      logger.info( "" );
      String[] entities = stats.getEntityNames();
      for (String entity : entities) {
        EntityStatistics stat = stats.getEntityStatistics( entity );
        logger.info( "Entity name:" + stat.getCategoryName() );
        logger.info( "Entity delete count:" + stat.getDeleteCount() );
        logger.info( "Entity fetch count:" + stat.getFetchCount() );
        logger.info( "Entity insert count:" + stat.getInsertCount() );
        logger.info( "Entity load count:" + stat.getLoadCount() );
        logger.info( "Entity update count:" + stat.getUpdateCount() );
        logger.info( "" );
      }

      logger.info( "Queries statistics :\n" );
      logger.info( "Queries execution count :" + stats.getQueryExecutionCount() );
      logger.info( "Queries max time :" + stats.getQueryExecutionMaxTime() );
      logger.info( "Queries max time sql:" + stats.getQueryExecutionMaxTimeQueryString() );
      logger.info( "" );
      String[] queries = stats.getQueries();
      for (String query : queries) {
        QueryStatistics stat = stats.getQueryStatistics( query );
        logger.info( "Query name:" + stat.getCategoryName() );
        logger.info( "Query cache hit count:" + stat.getCacheHitCount() );
        logger.info( "Query cache miss count:" + stat.getCacheMissCount() );
        logger.info( "Query cache put count:" + stat.getCachePutCount() );
        logger.info( "Query exec count:" + stat.getExecutionCount() );
        logger.info( "Query avg time:" + stat.getExecutionAvgTime() );
        logger.info( "Query max time:" + stat.getExecutionMaxTime() );
        logger.info( "Query min time:" + stat.getExecutionMinTime() );
        logger.info( "Query row count:" + stat.getExecutionRowCount() );
        logger.info( "" );
      }
      stats.clear();
    }
  }

  public EntityManager getNewEntityManager() {
    return factory.createEntityManager();
  }
 
  public void close() {
    if ( factory.isOpen() ) {
      factory.close();
    }
  }

}
TOP

Related Classes of ch.hortis.sonar.jpa.Persistence

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.