Showing posts with label database. Show all posts
Showing posts with label database. Show all posts

Thursday, December 27, 2012

Hibernate CLOB to String Conversion AliasToEntityMapResultTransformer not working

Hibernate Clob conversion is little tricky especially when we use with JPA. There is no predefined Transformer for this in Hibernate due to some reason.
Code to retirive records as List of map
org.hibernate.Query query=((Session) em.getDelegate() )
  .createSQLQuery(sql);
query
  .setResultTransformer( AliasToEntityMapResultTransformer.INSTANCE);
List<Map<String,Object>> aliasToValueMapList=query.list();
return aliasToValueMapList; 
which will return non-blob and non clob type columns as it is. those are readable in the viewing end. but for Clob types it will store the object notation like org.hibernate.type.ClobType@2311
reason is AliasToEntityMapResultTransformer class does not have mechanism to convert clob to string as it may lead memory issue.
AliasToEntityMapResultTransformer.java
..{
.........
...

public Object transformTuple(Object[] tuple, String[] aliases) {
  Map result = new HashMap(tuple.length);
  for ( int i=0; i<tuple.length; i++ ) {
   String alias = aliases[i];
   if ( alias!=null ) {
    result.put( alias, tuple[i] );
   }
  }
  return result;
 } 
...
.........
..} 

Solution is we can write our own result transformer.
MyResultTransformer.java
package com.util;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.sql.Clob;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.io.IOUtils;
import org.hibernate.transform.BasicTransformerAdapter;

public class MyResultTransformer extends BasicTransformerAdapter {

 public final static MyResultTransformer INSTANCE;
 static {
  INSTANCE = new MyResultTransformer();
 }

 private MyResultTransformer() {

 }
 private static final long serialVersionUID = 1L;

 @Override
 public Object transformTuple(Object[] tuple, String[] aliases) {
  Map<String, Object> map = new HashMap<String, Object>();
  for (int i = 0; i < aliases.length; i++) {
   Object t = tuple[i];
   if (t != null && t instanceof Clob) {
    Clob c = (Clob) tuple[i];
    try {
     ByteArrayOutputStream bos = new ByteArrayOutputStream();
     IOUtils.copy(c.getAsciiStream(), bos);
     t = new String(bos.toByteArray());
    } catch (SQLException e) {
     e.printStackTrace();
    } catch (IOException e) {
     e.printStackTrace();
    }
   }
   map.put(aliases[i], t);
  }
  return map;
 }
}


now,

...
query
  .setResultTransformer( MyResultTransformer.INSTANCE);
...
will return list of maps with Clob types as Converted String.

Note: Considerable thing here is memory. ex. for 100 records if each record has 1mb of data in a clob type attribute, the total size is >100 mb

Oracle XE Startup Problem : ORA-01034: ORACLE not available ORA-27101: shared memory realm does not exit | ORA-12631 (Username retrieval failed)

Oracle eXpressEdition a compact and nice to use for development purpose.
But after i installed Oracle XE 11g in my machine it gave me a heavy headache to get it up and run correctly.

Problems i got are as below
  • ORA-01034: ORACLE not available ORA-27101: shared memory realm does not exit
  • ORA-12631 (Username retrieval failed) 
  • http://127.0.0.1:8080/apex/ is not opening
  • listener.ora changes does not help
  • ....

I was Googling for more than a week for the problems and each solution leads to another problem for example if i solve ORA-27101 then the next gate will be ORA-12631(it goes one..).  

Finally i got relief from the headache.

  • To install Oracle XE user should have System Admin privilege.  
    so i got Admin privilege from my network admin.
  • I am able to install now, but still it makes problem.
  • XE service is not running or oracle Apex is not opening @ http://127.0.0.1:8080/apex/
  •  My account is actually networked (Windows NT user).
  • I uninstalled XE, then i logged in with the Local System Administrator account (not in NT domain).
  • I installed Oracle XE.
Now its up and running oracle Apex is also running well.

So careful, while installing Oracle XE be logged in the system as local Administrator.

Thursday, September 15, 2011

Postgres DBlink Example

dblink is one of the features available with postgres to do something by connecting remote pgdatabase from pg-sql.

To enable dblink execute the file located @ \share\contrib with the name of dblink.sql in to the required DB.

Following example function is to extract remote db's data and migrate it to local. Structure of the both tables vary is the notable one.

-- Function: extractobudata()

-- DROP FUNCTION extractobudata();

CREATE OR REPLACE FUNCTION extractobudata()
  RETURNS void AS
$BODY$
DECLARE
    last_extracted_data numeric;
BEGIN
    select max(packetid) into last_extracted_data from obuperiodicdata;

    INSERT INTO
        obuperiodicdata
        (packetid,
        obuserialnumber,
        companysign,
        gpsspeed,
        lat,
        lon,
        alt,
        heading,
        storedon,
        distance,
        enginerpm,
        receivedon,
        poiid)
                SELECT *
        FROM dblink('dbname= port=5432 host= user= password=', 'select
        af_sno,
  af_obu_serial_no ,
af_company_sign,
  af_gps_speed,
  af_lat,
  af_lon,
  af_alt,
  af_heading,
  af_timestamp,
  af_distance,
  af_engine_rpm,
  af_received_time,
  poi_id
        from at_obu_periodic_data where af_sno > '|| last_extracted_data  )
        AS t1(packetid numeric ,
        obuserialnumber character(100),
        companysign character(100) ,
        gpsspeed numeric,
        lat numeric,
        lon numeric,
        alt numeric,
        heading numeric,
        storedon timestamp,
        distance numeric,
        enginerpm numeric,
        receivedon timestamp,
        poiid integer );
   
END
$BODY$
  LANGUAGE 'plpgsql' VOLATILE
  COST 100;
ALTER FUNCTION extractobudata() OWNER TO postgres;

Installing & Enabling PostGIS in Postgres

  1. Check with the stack builder for PostGIS spatial Extension is installed.
  2. Enable to install(if not) and click next. 
  3. Download and install postGIS extension.
     
  4. Once it is installed check for the database postgis/template_postgis. If any of the above databases is there then that can be used.
  5. Otherwise create a new database manually and execute the sql file which should be located @ <c:\postgresinstallationlocation>\share\contrib\ with the name of postgis.sql.
  6. That database will have two tables called geometry_columns & spatial_ref_sys, some 100s of functions and some trigger functions.
  7. Now using that database as a template, any number of databases can be created with PostGIS enabled.