Friday, May 31, 2013

Installation Postgres service

The following script will install Postgres as a service in a specific port in Windows. The .bat file should be placed in the same folder as bin folder of Postgres
 @ECHO ON  
 REM The script sets environment variables helpful for PostgreSQL  
 @ECHO "%~dp0"  
 @SET PATH="%~dp0\bin";%PATH%  
 @SET PGDATA=%~dp0\data  
 @SET PGDATABASE=postgres  
 @SET PGUSER=postgres  
 @SET PGPORT=5439  
 @SET PGLOCALEDIR=%~dp0\share\locale  
 "%~dp0\bin\initdb" -U postgres -A trust   
 "%~dp0\bin\pg_ctl" -l logfile register -N Postgres_Service -o "-F -p %PGPORT%"  
 NET START Postgres_Service  

Monday, May 20, 2013

hibernate/JPA annotation for byte[] + blob in oracle + bytea in postgres

After reading this http://stackoverflow.com/questions/3677380/proper-hibernate-annotation-for-byte and try everything that I found over Internet .
Problem : I want to have a JPA/Hibernate annotation that stores byte[] as blob in Oracle and as bytea in postgres.
Answer there is no such annotation ! So annoying to be real !
It is a similar problem with boolean storage http://vthanhvinh.blogspot.fi/2013/05/orgpostgresqlutilpsqlexception-error.html. However, there is no annotation that can help in this case.
Luckily, we can override annotation mapping with xml file, my great discovery. I have a entity like this
 package com.wapice.example;  
 import javax.persistence.Column;  
 import javax.persistence.Entity;  
 import javax.persistence.Table;  
 import javax.persistence.TableGenerator;  
 @Entity  
 @Table(name ="SMMBINRESOURCE")  
 @TableGenerator(name = "BINRESOURCEID", table = "SMMID", pkColumnName = "SERIES", valueColumnName = "NEXTVAL", pkColumnValue = "BINRESOURCEID", initialValue = 0, allocationSize = 1)  
 public class BinaryResource extends ProjectSpecificObject<Long> {  
      private String _name;  
      private String _mimetype;  
      private byte[] _data;  
      // logged object fields  
      /**  
       *   
       */  
      private static final long serialVersionUID = 8989926469766677944L;  
      @Column(name="DATA",columnDefinition="BLOB")  
      public byte[] getData() {  
           return _data;  
      }  
      public void setData(byte[] data) {  
           _data = data;  
      }  
      @Column(name="NAME", columnDefinition="nvarchar2")  
      public String getName() {  
           return _name;  
      }  
      public void setName(String name) {  
           _name = name;  
      }  
      @Column(name="MIMETYPE", columnDefinition="nvarchar2")  
      public String getMimetype() {  
           return _mimetype;  
      }  
      public void setMimetype(String mimetype) {  
           _mimetype = mimetype;  
      }  
 }  

By using @Column(name="DATA",columnDefinition="BLOB") , it will work with Oracle and correctly map byte[] to blob. But that would not work with Postgres.
So I have a xml mapping file for postgres as follow:
 <?xml version="1.0" encoding="UTF-8" ?>  
 <entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm"  
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
    xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm    
 http://java.sun.com/xml/ns/persistence/orm_2_0.xsd"  
   version="2.0">  
   <description>SMM extended mapping</description>  
   <package>entity</package>   
   <entity class="com.wartsila.smm.model.BinaryResource" name="SMMBINRESOURCE">      
     <table name="SMMBINRESOURCE"/>  
     <attributes>  
       <basic name="name">  
         <column name="NAME" length="100"/>  
       </basic>  
       <basic name="mimetype">  
            <column name="MIMETYPE"/>  
       </basic>  
       <basic name="data">  
             <column name="DATA" column-definition="bytea"/>  
       </basic>  
     </attributes>  
   </entity>  
 </entity-mappings>  
then I define Hibernate sessionFactory for Postgres SQL as :
 <?xml version="1.0" encoding="UTF-8"?>  
 <beans xmlns="http://www.springframework.org/schema/beans"  
  xmlns:context="http://www.springframework.org/schema/context"  
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jdbc="http://www.springframework.org/schema/jdbc"  
  xmlns:jee="http://www.springframework.org/schema/jee" xmlns:p="http://www.springframework.org/schema/p"  
  xsi:schemaLocation="  
  http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd  
    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd  
  http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd  
  http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd  
  http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.0.xsd  
  ">  
   <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">  
  <property name="dataSource">  
   <ref bean="smmDataSource" />  
  </property>  
  <!--   
  <property name="entityInterceptor">  
       <bean class="com.wartsila.smm.hibernate.interceptors.CutomEntityInterceptor"></bean>  
     </property>  
  -->  
  <property name="hibernateProperties">  
   <props>  
   <prop key="hibernate.connection.defaultNChar">true</prop>  
   <prop key="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</prop>  
   <prop key="hibernate.show_sql">false</prop>  
   <prop key="hibernate.hbm2ddl.auto">validate</prop>  
   </props>  
  </property>  
  <property name="packagesToScan">  
       <list>  
         <value>com.wapice.example/value>  
       </list>  
     </property>  
     <property name="mappingResources">  
         <list>  
      <value>com/wapice/example/orm-postgres.xml</value>  
       </list>  
      </property>  
  </bean>  
 </beans>  

This will correctly map byte[] to bytea in Postgres. Moreover, as we can see BinaryResource extends from ProjectSpecificObject which is a @MappedSuperclass. But we do not need to re-define ProjectSpecificObject in xml mapping AGAIN. Therefore, in my opinion, this is quite nice solution.

Sunday, May 19, 2013

Keep sorting order in Vaadin table after clear container datasource / set new container datasource

When we reset the container datasource or clear the container datasource of the table, the sorting order of the table is reset.
The work around could be using
setSortAscending(!isSortAscending()); setSortAscending(isSortAscending()); setSortAscending(!isSortAscending());
to retain the sorting order settings like before the clear/reset of datasource.

Thursday, May 16, 2013

org.postgresql.util.PSQLException: ERROR: column "xxx" is of type smallint/integer/numeric but expression is of type boolean + Hibernate

I am implementing a synchronize solution between DB nodes : Oracle vs Postgres. Same J2EE web application will run on those 2 databases and a background process will synch those database with each other.
. One problem is Oracle stores boolean Hibernate mapping value as 1 or 0. In contrast, Postgres stores Hibernate boolean as 'y' or 'n' which is very annoying and troublesome when doing DB synch. So I would like to force Postgres to map Hibernate boolean type to numeric/integer/smallint by trying to implement a custom Dialect extends from PostgreSQLDialect. I tried to override
public String toBooleanValueString(boolean bool)
and register type mappings as well. But , sadly, after many trials , it seems that it does not work.
At the end, I needed to use the ugly solution by adding :
@Type(type="org.hibernate.type.NumericBooleanType")
to all boolean attributes in my mapped class. It is ugly because it adds dependency to Hibernate in my Model Project. However, I can live with it for now.
You may try to add columnDefinition="smallint" of JPA to mapped boolean atribute instead of using ugly @Type. However, to me, for several reasons, it is not an option.