Monday, November 7, 2016

Hooking into or extends the GormStaticApi methods of the GORM API for Grails

Main class defination

package com.autobill.enhancer

import org.codehaus.groovy.grails.commons.DefaultGrailsDomainClass
import org.codehaus.groovy.grails.orm.hibernate.HibernateDatastore
import org.codehaus.groovy.grails.orm.hibernate.HibernateGormStaticApi
/**
 * Created by pritom on 17/10/2016.
 */
class MyCustomStaticApi<D> extends HibernateGormStaticApi<D> {
    private HibernateGormStaticApi gormStaticApi

    MyCustomStaticApi(HibernateGormStaticApi gormStaticApi) {
        super(gormStaticApi.persistentClass, gormStaticApi.datastore as HibernateDatastore, gormStaticApi.gormDynamicFinders, gormStaticApi.classLoader, gormStaticApi.transactionManager)
        this.gormStaticApi = gormStaticApi
    }

    @Override
    D read(Serializable id) {
        println("Reading-${id}")
        super.read(id)
    }

    static void init(servletContext) {
        servletContext.grailsApplication.domainClasses.each { DefaultGrailsDomainClass domainClass ->
            def gormStaticApi = domainClass.clazz.currentGormStaticApi()
            domainClass.clazz.setStaticGormStaticApi(new MyCustomStaticApi(gormStaticApi))
        }
    }
}

And invoke MyCustomStaticApi.init(servletContext) from Bootstrap.groovy


Hooking into or extends the GormInstanceApi methods of the GORM API for Grails

Main class defination


package com.autobill.enhancer

import org.codehaus.groovy.grails.commons.DefaultGrailsDomainClass
import org.codehaus.groovy.grails.orm.hibernate.HibernateDatastore
import org.codehaus.groovy.grails.orm.hibernate.HibernateGormInstanceApi
/**
 * Created by pritom on 17/10/2016.
 */
class MyCustomInstanceApi<D> extends HibernateGormInstanceApi<D> {
    private HibernateGormInstanceApi gormInstanceApi

    MyCustomInstanceApi(HibernateGormInstanceApi gormInstanceApi) {
        super(gormInstanceApi.persistentClass, gormInstanceApi.datastore as HibernateDatastore, gormInstanceApi.classLoader)
        this.gormInstanceApi = gormInstanceApi
    }

    @Override
    D save(D instance) {
        println("Saving-${instance}")
        super.save(instance)
    }

    static void init(servletContext) {
        servletContext.grailsApplication.domainClasses.each { DefaultGrailsDomainClass domainClass ->
            def gormInstanceApi = domainClass.clazz.currentGormInstanceApi()
            domainClass.clazz.setInstanceGormInstanceApi(new MyCustomInstanceApi(gormInstanceApi))
        }
    }
}

And invoke MyCustomInstanceApi.init(servletContext) from Bootstrap.groovy

Get caller class name from inherited static method using java

Base class to test caller call name extractor


package com.pritom.kumar;

/**
 * Created by pritom on 10/10/2016.
 */
abstract class StaticMethodCallerClassName {
    static String returnCallerClassNameUsingThreadStackTrace() {
        StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace();
        return stackTraceElements[2].getClassName();
    }

    static String returnCallerClassNameUsingThrowable() {
        return new Throwable().getStackTrace()[2].getClassName();
    }

    static String returnCallerClassNameUsingSecurityManager() {
        Class[] classes = CallingClassManager.INSTANCE.getCallingClasses();
        return classes[classes.length - 2].getCanonicalName();
    }

    private static class CallingClassManager extends SecurityManager {
        static final CallingClassManager INSTANCE = new CallingClassManager();

        Class[] getCallingClasses() {
            return getClassContext();
        }
    }

    static void printElapsedTime(String title, Long startTime, String className) {
        startTime = System.nanoTime() - startTime;
        System.out.println(title + " took=" + ((double) startTime) / 1000000D + " ms and class_name=" + className);
    }
}

Example class 1

package com.pritom.kumar;

/**
 * Created by pritom on 10/10/2016.
 */
public class StaticMethodCallerClassNameTest1 extends StaticMethodCallerClassName {
    public static void main(String[] args) {
        x1();
    }

    static void x1() {
        long startTime = System.nanoTime();
        String className = null;
        for (int i = 0; i < 10000; i++) {
            className = returnCallerClassNameUsingThreadStackTrace();
        }
        printElapsedTime("ThreadStackTrace", startTime, className);

        startTime = System.nanoTime();
        className = null;
        for (int i = 0; i < 10000; i++) {
            className = returnCallerClassNameUsingThrowable();
        }
        printElapsedTime("Throwable", startTime, className);

        startTime = System.nanoTime();
        className = null;
        for (int i = 0; i < 10000; i++) {
            className = returnCallerClassNameUsingSecurityManager();
        }
        printElapsedTime("SecurityManager", startTime, className);
    }
}


Example class 2

package com.pritom.kumar;

/**
 * Created by pritom on 10/10/2016.
 */
public class StaticMethodCallerClassNameTest2 extends StaticMethodCallerClassNameTest1 {
    public static void main(String[] args) {
        x2();
    }

    static void x2() {
        long startTime = System.nanoTime();
        String className = null;
        for (int i = 0; i < 10000; i++) {
            className = returnCallerClassNameUsingThreadStackTrace();
        }
        printElapsedTime("ThreadStackTrace", startTime, className);

        startTime = System.nanoTime();
        className = null;
        for (int i = 0; i < 10000; i++) {
            className = returnCallerClassNameUsingThrowable();
        }
        printElapsedTime("Throwable", startTime, className);

        startTime = System.nanoTime();
        className = null;
        for (int i = 0; i < 10000; i++) {
            className = returnCallerClassNameUsingSecurityManager();
        }
        printElapsedTime("SecurityManager", startTime, className);
    }
}

Example class 3

package com.pritom.kumar;

/**
 * Created by pritom on 10/10/2016.
 */
public class StaticMethodCallerClassNameTest3 extends StaticMethodCallerClassNameTest2 {
    public static void main(String[] args) {
        x3();
    }

    static void x3() {
        long startTime = System.nanoTime();
        String className = null;
        for (int i = 0; i < 10000; i++) {
            className = returnCallerClassNameUsingThreadStackTrace();
        }
        printElapsedTime("ThreadStackTrace", startTime, className);

        startTime = System.nanoTime();
        className = null;
        for (int i = 0; i < 10000; i++) {
            className = returnCallerClassNameUsingThrowable();
        }
        printElapsedTime("Throwable", startTime, className);

        startTime = System.nanoTime();
        className = null;
        for (int i = 0; i < 10000; i++) {
            className = returnCallerClassNameUsingSecurityManager();
        }
        printElapsedTime("SecurityManager", startTime, className);
    }
}

Cannot change column used in a foreign key constraint


Disabling foreign key check using following SQL:
SET FOREIGN_KEY_CHECKS=0;

Enabling foreign key check:
SET FOREIGN_KEY_CHECKS=1;

If you want it globally then:
SET GLOBAL FOREIGN_KEY_CHECKS=0;
SET GLOBAL FOREIGN_KEY_CHECKS=1;

Alter all table of a mysql database using java

package com.pritom.kumar;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by pritom on 18/10/2016.
 */
public class StoredProcedureUtils {
    static Connection connection = null;

    public static void main(String[] args) throws Exception {
        alterTableSchema("some_db_name");
    }

    static void alterTableSchema(String databaseName) throws Exception {
        /* Query for retrieve table names from database */
        String query = "SELECT table_name FROM information_schema.tables " +
                "WHERE table_schema='" + databaseName + "' ORDER BY table_name;";

        /* Create statement */
        Statement statement = getConnection().createStatement();

        /* Retrieving all table names */
        ResultSet resultSet = statement.executeQuery(query);
        List<String> tableList = new ArrayList<String>();
        while (resultSet.next()) {
            tableList.add(resultSet.getString(1));
        }

        /* Set database not to check foreign key constraints */
        statement.execute("SET FOREIGN_KEY_CHECKS=0;");

        /* Alter table structure */
        for (Integer index = 0; index < tableList.size(); index++) {
            String tableName = tableList.get(index);
            try {
                statement.execute("ALTER TABLE " + databaseName + "." + tableName + " MODIFY id BIGINT(20) AUTO_INCREMENT;");
                pl(formatAsLength("Done Alter Table=" + tableName, 70, "") + (index + 1) + " Of " + tableList.size());
            }
            catch (Exception ex) {
                pl(formatAsLength("Error Alter Table=" + tableName, 70, "") + "Error=" + ex.getMessage());
            }
        }

        /* Set database mode to check foreign key constraints again */
        statement.execute("SET FOREIGN_KEY_CHECKS=1;");

        /* Close statement */
        statement.close();
    }

    static Connection getConnection() throws Exception {
        if (connection != null) {
            return connection;
        }
        connection = DriverManager.getConnection("jdbc:mysql://localhost/some_db_name?user=root&password=");
        return connection;
    }

    static void pl(Object o) {
        System.out.println("" + o);
    }

    static String formatAsLength(String number, Integer minLength, String replaceEmptyWith) {
        number = String.format("%-" + minLength + "s", number);
        return replaceEmptyWith.length() > 0 ? number.replace(" ", replaceEmptyWith) : number;
    }
}

How to pass the entire model to a template in Grails


<g:render template="/layouts/view_name" model="${pageScope.variables}"/>

java - JDBC connection error : unrecognized timezone

java.sql.SQLException: The server time zone value is unrecognized or represents more than one time zone

Have to add "serverTimezone" parameter to connect url.

jdbc:mysql://localhost/db?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC

Apparently, to get version 5.1.33 of MySQL JDBC driver to work with UTC time zone, one has to specify the serverTimezone explicitly in the connection string