Technical blog

August 21, 2010

Tweaking MySQL on Fedora

Filed under: database, linux — Tags: , — paawak @ 00:57

MySQL is installed on Fedora and most Linuxes by default. Its just about some tweaking before you can use it. I am detailing some of the rather useful commands.

To Install MySQL and start it

mysql_install_db
mysqld_safe &

Make MySQL case insensitive

This is useful when the DB Script is also expected to run on Windows server.

vi /etc/my.cnf

[mysqld]
lower_case_table_names=1

To change the root password

mysql>

update user set password=password(”newPassword”)  where user=’root’;
Query OK, 2 rows affected (0.00 sec)
Rows matched: 2  Changed: 2  Warnings: 0

grant all on *.* to ‘root’@'192.168.%’ identified by ‘newPassword’;

FLUSH PRIVILEGES;

Adding a user

mysql>

insert into user (host, user, password) values(’localhost’,'newUser’,password(’xx123′));

insert into  host(host,db,Select_priv, Insert_priv, Update_priv, Delete_priv, Create_priv, Drop_priv)  values(’localhost’,'dbName’,'Y’,'Y’,'Y’,'Y’,'Y’,'Y’);

grant all on dbName.* to ‘newUser’@'localhost’ identified by ‘xx123′;

FLUSH PRIVILEGES;

January 6, 2010

Installing postgres on Fedora

Filed under: database, postgres — Tags: , — paawak @ 14:14

In Fedora 7+, postgres is insatlled by default. Its just about a few commands to get started. First of all you have to change the password for the postgres user, postgres. I am pasting the commands below:

#passwd postgres
#chown postgres /var/lib/pgsql/data/
#su - postgres
~initdb -D /var/lib/pgsql/data/
#/etc/rc.d/init.d/postgresql start

You can also install pgadmin3, which is a nice GUI for postgres:

#yum install pgadmin3

If you do not have the repository, you can add it from here:
http://yum.pgsqlrpms.org/reporpms/repoview/letter_p.group.html

I was inspired by this blog:
http://www.postgresonline.com/journal/index.php?/archives/45-An-Almost-Idiots-Guide-to-PostgreSQL-YUM.html

August 11, 2009

Error in named query: org.hibernate.hql.ast.QuerySyntaxException: table is not mapped

Filed under: database, hibernate, java — Tags: — paawak @ 02:29

I was taking advantage of the NamedQueries feature in Hibernate annotation, when suddenly I was bombed with this queer error:

ERROR - SessionFactoryImpl.<init>(363) | Error in named query: findMaxId
org.hibernate.hql.ast.QuerySyntaxException: AccountGroup is not mapped [SELECT MAX(id) FROM AccountGroup]

My AccountGroup looks like this:

@Entity(name = "account_group")
@NamedQueries( { @NamedQuery(name = AccountGroup.NAMED_QUERY_FIND_MAX_ID, query = "SELECT MAX(acg.id) FROM AccountGroup acg") })
public class AccountGroup implements Serializable {
 
    private static final long serialVersionUID = 8651011772980546778L;
 
    public static final String NAMED_QUERY_FIND_MAX_ID = "findMaxId";
...
 
}

As is evident from the error message, the HQL compiler is not able to map any table to “AccountGroup”. But this is strange, since I have already mapped it in my hibernate.cfg.xml. After a few minutes of futile googling, the solution dawned upon me.

Solution 1:

Include an additional annotation @Table:

@Entity
@Table(name = "account_group")
@NamedQueries( { @NamedQuery(name = AccountGroup.NAMED_QUERY_FIND_MAX_ID, query = "SELECT MAX(acg.id) FROM AccountGroup acg") })
public class AccountGroup implements Serializable {
 
    private static final long serialVersionUID = 8651011772980546778L;
 
    public static final String NAMED_QUERY_FIND_MAX_ID = "findMaxId";
...
 
}

Solution 2:

Modify your query to have the fully qualified class name:

@Entity(name = "account_group")
@NamedQueries( { @NamedQuery(name = AccountGroup.NAMED_QUERY_FIND_MAX_ID, query = "SELECT MAX(acg.id) FROM com.swayam.test.AccountGroup acg") })
public class AccountGroup implements Serializable {
 
    private static final long serialVersionUID = 8651011772980546778L;
 
    public static final String NAMED_QUERY_FIND_MAX_ID = "findMaxId";
...
 
}

June 30, 2009

Recursively deleting a row in a table having Foreign Key Constraints

Filed under: database, java — Tags: — paawak @ 23:32

An oft encountered and irritating scenario while working with a database is when we come across a certain row which we want to delete, but cannot as it has recursive Foreign Key Constraints. Today I got a particularly nasty scenario as we are using Teneo. It has around four levels of Foreign Key Constraints. So, I decided to write this utility so that given a table name, column name and value, it deletes the row and all the Foreign Key Constrained data in order. I do this by making sense of the error message that I get when trying to delete a row with Foreign Key Constraints.

It looks something like this with MySQL:

Cannot delete or update a parent row: a foreign key constraint fails (`some_database/user`, CONSTRAINT `my_constraint` FOREIGN KEY (`id`) REFERENCES `employee`  (`id`))

To deal with this, I have defined this interface to extract meaningful information from the error message, so that I can delete the rogue row of the rogue table first.

package com.swayam.db.tools;
 
/**
 *@author paawak
 */
public interface ConstraintViolationExceptionInterpretor {
 
    void setExceptionMessage(String message);
 
    String getConstrainedTableName();
 
    String getForeignKeyColumnName();
 
    String getReferencedTableName();
 
    String getReferencedColumnName();
 
}

This is the implemenetation for MySQL:

package com.swayam.db.tools;
 
import java.util.regex.Matcher;
import java.util.regex.Pattern;
 
/**
 *
 * @author paawak
 */
public class MySQLConstraintViolationExceptionInterpretor implements
        ConstraintViolationExceptionInterpretor {
 
    private String message;
 
    public MySQLConstraintViolationExceptionInterpretor() {
 
    }
 
    public String getConstrainedTableName() {
 
        String match = getFirstMatch("/\w+");
 
        if (match != null) {
            match = match.substring(1);
        }
 
        return match;
 
    }
 
    public String getForeignKeyColumnName() {
 
        String match = getFirstMatch("\(`\w+`\)");
 
        if (match != null) {
            match = match.substring(2, match.length() - 2);
        }
 
        return match;
 
    }
 
    public String getReferencedColumnName() {
 
        String match = getFirstMatch("\(`\w+`\)\)");
 
        if (match != null) {
            match = match.substring(2, match.length() - 3);
        }
 
        return match;
 
    }
 
    public String getReferencedTableName() {
 
        String prefix = "REFERENCES `";
 
        String match = getFirstMatch(prefix + "\w+`");
 
        if (match != null) {
            match = match.substring(prefix.length(), match.length() - 1);
        }
 
        return match;
 
    }
 
    public void setExceptionMessage(String message) {
        this.message = message;
    }
 
    private String getFirstMatch(String regex) {
 
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(message);
 
        if (matcher.find()) {
            String match = matcher.group();
            return match;
        }
 
        return null;
 
    }
 
}

And finally the class that does the dirty job of recursively executing all the deletes:

package com.swayam.db.tools;
 
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
 
/**
 *@author paawak
 */
public class RecursiveDeleteUtil {
 
    private final Connection con;
    private final List deleteStatements;
    private final ConstraintViolationExceptionInterpretor interpretor;
    private String idColumn;
    private String idValue;
 
    public RecursiveDeleteUtil(Connection con,
            ConstraintViolationExceptionInterpretor interpretor) {
        this.con = con;
        this.interpretor = interpretor;
        deleteStatements = new ArrayList(1);
    }
 
    public void delete(String tableName, String column, String value) {
 
        if (idColumn == null) {
            idColumn = column;
            idValue = value;
        }
 
        String delQuery = "DELETE FROM " + tableName + " WHERE " + column
                + "='" + value + "'";
 
        deleteStatements.add(delQuery);
 
        try {
 
            Statement stat = con.createStatement();
            int rowsAffected = stat.executeUpdate(delQuery);
 
            if (rowsAffected > 0) {
 
                // execute all stats on the stack
                int lastIndex = deleteStatements.size() - 1;
 
                for (int count = lastIndex; count >= 0; count--) {
                    stat.executeUpdate(deleteStatements.get(count));
                }
 
            }
 
            stat.close();
 
        } catch (SQLException e) {
 
            String message = e.getMessage();
            interpretor.setExceptionMessage(message);
            String constrainedTableName = interpretor.getConstrainedTableName();
            String foreignKeyColumnName = interpretor.getForeignKeyColumnName();
            String referencedTableName = interpretor.getReferencedTableName();
            String referencedColumnName = interpretor.getReferencedColumnName();
            System.out.println("################# message = " + message
                    + "nconstrainedTableName = " + constrainedTableName
                    + ", foreignKeyColumnName = " + foreignKeyColumnName
                    + ", referencedTableName = " + referencedTableName
                    + ", referencedColumnName = " + referencedColumnName);
 
            // select the offending value
            String sel = "SELECT " + referencedColumnName + " FROM "
                    + referencedTableName + " WHERE " + idColumn + "='"
                    + idValue + "'";
 
            System.out.println("################ select = " + sel);
 
            try {
                Statement selectStat = con.createStatement();
                ResultSet res = selectStat.executeQuery(sel);
 
                while (res.next()) {
                    String constraintVal = res.getString(1);
                    delete(constrainedTableName, foreignKeyColumnName,
                            constraintVal);
                }
 
                res.close();
                selectStat.close();
 
            } catch (SQLException ex) {
                ex.printStackTrace();
            }
 
        }
 
    }
 
    public static void main(String[] args) throws Exception {
 
        Class.forName("com.mysql.jdbc.Driver").newInstance();
        String conStr = "jdbc:mysql://localhost/dummy?user=root&password=dummy";
 
        Connection con = DriverManager.getConnection(conStr);
 
        new RecursiveDeleteUtil(con,
                new MySQLConstraintViolationExceptionInterpretor()).delete(
                "some_table", "id", "118");
 
    }
 
}

I don’t claim this to be very generic, but it works pretty well for me :). A great time saver for sure.

April 2, 2009

Configuring connection pooling with Teneo

Filed under: database, hibernate, teneo — Tags: , , — paawak @ 12:38

Connection pooling is one thing that needs to be done on a production server. Spring is becoming an extremely popular choice with Hibernate for its seamless integartion. But with Teneo, its a different ball-game altogether. Fortunately for us, Hibernate provides one such hook via the property in the Environment.CONNECTION_PROVIDER configuration. It takes in the name of a class implementing the interface ConnectionProvider.

I prefer the Apache Commons DBCP. You will find the example here. When configuring Teneo, you need to set:

Properties props = new Properties();
 
//this line is the killer: delegates the ConnectionProvider to our custom implementation
//look at org.hibernate.connection.ConnectionProviderFactory.newConnectionProvider()
props.put(Environment.CONNECTION_PROVIDER, MyConnectionProvider.class
.getName());

MyConnectionProvider.java looks like:

 
package com.swayam.teneo.config;
 
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;
 
import javax.sql.DataSource;
 
import org.apache.commons.dbcp.ConnectionFactory;
import org.apache.commons.dbcp.DriverManagerConnectionFactory;
import org.apache.commons.dbcp.PoolableConnectionFactory;
import org.apache.commons.dbcp.PoolingDataSource;
import org.apache.commons.pool.ObjectPool;
import org.apache.commons.pool.impl.GenericObjectPool;
import org.hibernate.HibernateException;
import org.hibernate.cfg.Environment;
import org.hibernate.connection.ConnectionProvider;
 
/**
 * 
 * @author paawak
 */
public class MyConnectionProvider implements ConnectionProvider {
 
    private DataSource ds;
 
    public MyConnectionProvider() {
 
    }
 
    public void close() throws HibernateException {
        // TODO Auto-generated method stub
 
    }
 
    public void closeConnection(Connection conn) throws SQLException {
        conn.close();
    }
 
    public void configure(Properties props) throws HibernateException {
 
        String jdbcDriver = (String) props.get(Environment.DRIVER);
 
        if (jdbcDriver == null) {
            throw new HibernateException(
                    "Please specify the JDBC driver with the key `Environment.DRIVER`");
        }
 
        // load the driver
        try {
            Class.forName(jdbcDriver);
        } catch (ClassNotFoundException e) {
            throw new HibernateException(e);
        }
 
        String connectURI = (String) props.get(Environment.URL);
 
        if (connectURI == null) {
            throw new HibernateException(
                    "Please specify the connection URL with the key `Environment.URL`");
        }
 
        ds = setupDataSource(connectURI);
    }
 
    public Connection getConnection() throws SQLException {
        return ds.getConnection();
    }
 
    public boolean supportsAggressiveRelease() {
        // TODO Auto-generated method stub
        return false;
    }
 
    /**
     * refer to DBCP ManualPoolingDataSourceExample:
     * 
     * 
     * http://svn.apache.org/viewvc/commons/proper/dbcp/trunk/doc/ManualPoolingDataSourceExample.java?view=markup
     * 
     * 
     * This is made static for de-coupling
     * 
     */
    private static DataSource setupDataSource(String connectURI) {
        //
        // First, we'll need a ObjectPool that serves as the
        // actual pool of connections.
        //
        // We'll use a GenericObjectPool instance, although
        // any ObjectPool implementation will suffice.
        //
        ObjectPool connectionPool = new GenericObjectPool(null);
 
        //
        // Next, we'll create a ConnectionFactory that the
        // pool will use to create Connections.
        // We'll use the DriverManagerConnectionFactory,
        // using the connect string passed in the command line
        // arguments.
        //
        ConnectionFactory connectionFactory = new DriverManagerConnectionFactory(
                connectURI, null);
 
        //
        // Now we'll create the PoolableConnectionFactory, which wraps
        // the "real" Connections created by the ConnectionFactory with
        // the classes that implement the pooling functionality.
        //
        @SuppressWarnings("unused")
        PoolableConnectionFactory poolableConnectionFactory = new PoolableConnectionFactory(
                connectionFactory, connectionPool, null, null, false, true);
 
        //
        // Finally, we create the PoolingDriver itself,
        // passing in the object pool we created.
        //
        PoolingDataSource dataSource = new PoolingDataSource(connectionPool);
 
        return dataSource;
    }
 
}

July 10, 2008

Auto-start PostgreSQL in Linux

Filed under: database, linux — Tags: — paawak @ 11:37

This post is outdated. Please see this instead:

http://puretech.paawak.com/2009/05/03/fedora-getting-up-and-running-with-postgres-in-2-mins/

I had faced lot of problems starting Postgres when my system boots-up. The challenge is that the postmaster daemon should be started by the under-privileged user “postgres” and NOT “root”. This is what you must do:

In the source distribution of postgres, there is a file called linux in contrib/start-scripts/. Open this file and follow the instructions.
I will enumerate them as commands. Please note that you have to run these as root.

cp POSTGRES_SRC_DIST/contrib/start-scripts/linux /etc/rc.d/init.d/postgresql
ln -s /etc/rc.d/init.d/postgresql /etc/rc.d/rc0.d/K02postgresql
ln -s /etc/rc.d/init.d/postgresql /etc/rc.d/rc1.d/K02postgresql
ln -s /etc/rc.d/init.d/postgresql /etc/rc.d/rc2.d/K02postgresql
ln -s /etc/rc.d/init.d/postgresql /etc/rc.d/rc3.d/S98postgresql
ln -s /etc/rc.d/init.d/postgresql /etc/rc.d/rc4.d/S98postgresql
ln -s /etc/rc.d/init.d/postgresql /etc/rc.d/rc5.d/S98postgresql

You might also want to read these:

  • http://www.postgresql.org/docs/7.4/static/postmaster-start.html
  • http://www.postgresql.org/docs/8.3/static/server-start.html

Powered by WordPress