Monday, October 5, 2009

Passing array as a parameter to PL/SQL stored procedure using Spring Jdbc Api

Passing an array as parameter into orcle pl/sql stored procedure is a little tricky. We are going to use “Spring Way” to do this. First of all we need access to the underlying connection.

There is an abstract implementation of the SqlTypeValue interface named AbstractSqlTypeValue , for convenient creation of type values that are supposed to be passed into the PreparedStatement.setObject method. The createTypeValue callback method has access to the underlying Connection, if that should be needed to create any database-specific objects.


PassArray.java


import java.sql.Connection;

import java.sql.SQLException;

import java.util.ArrayList;

import java.util.HashMap;

import java.util.List;

import java.util.Map;

import org.springframework.jdbc.core.JdbcTemplate;

import org.springframework.jdbc.core.SqlParameter;

import org.springframework.jdbc.core.simple.SimpleJdbcCall;

import org.springframework.jdbc.core.support.AbstractSqlTypeValue;



public class PassArray {

protected JdbcTemplate jdbcTemplate;

private String schemaName="T_SCHEMA";

public class MyArray extends AbstractSqlTypeValue {

private List values;

public MyArray(List values) {

this.values = values;

}

public Object createTypeValue(Connection con, int sqlType,

String typeName) throws SQLException {

oracle.sql.ArrayDescriptor desc =

new oracle.sql.ArrayDescriptor(typeName, con);

return new oracle.sql.ARRAY(desc, con, (Long[]) values

.toArray(new Long[values.size()]));

}

}

public void callProcedureWithArrayParameter() {

List values = new ArrayList();

values.add(1L);

values.add(2L);

SimpleJdbcCall jdbcCall = new SimpleJdbcCall(jdbcTemplate)

.withSchemaName(schemaName)

.withProcedureName("PCK_TEST.SP_WITH_ARRAY_PARAMETER")

.withoutProcedureColumnMetaDataAccess().declareParameters(new SqlParameter("P_ARRAY", java.sql.Types.ARRAY,schemaName + ".PARAMETER_ARRAY_TYPE"));

Map map = new HashMap();

map.put("P_ARRAY", new MyArray(values));

jdbcCall.execute(map);

}

}


PL/SQL Code:

CREATE OR REPLACE TYPE T_SCHEMA.PARAMETER_ARRAY_TYPE IS TABLE OF NUMBER(19);

/

CREATE OR REPLACE PACKAGE T_SCHEMA."PCK_TEST" AS

PROCEDURE sp_with_array_parameter(p_array IN PARAMETER_ARRAY_TYPE);

END PCK_TEST;

/

CREATE OR REPLACE PACKAGE BODY T_SCHEMA."PCK_TEST" AS

PROCEDURE sp_with_array_parameter (p_array IN PARAMETER_ARRAY_TYPE) IS

CURSOR c_records (p_array PARAMETER_ARRAY_TYPE) IS SELECT * FROM MY_TABLE WHERE id IN (SELECT * FROM TABLE (CAST (p_array AS PARAMETER_ARRAY_TYPE)));

BEGIN

FOR r_record IN c_records (p_array)

LOOP

--some biz logic here

END LOOP;

END;

END PCK_TEST;

/

Tuesday, June 2, 2009

My first appspot project :)

okahraman.appspot.com

Tuesday, February 26, 2008

Implementing a naming strategy in Toplink

We can implement a naming strategy in Toplink like Hibernate naming strategy via using DescriptorCustomizer interface of Toplink.

Descriptors describe how a Java class relates to a data source representation. They relate object classes to the data source at the data model level. For example, persistent class attributes may map to database columns. TopLink uses descriptors to store the information that describes how an instance of a particular class can be represented in a data source.

You can customize a descriptor at run time by specifying a descriptor customizer–a Java class that implements the oracle.toplink.tools.sessionconfiguration.DescriptorCustomizer interface and provides a default (zero-argument) constructor.


NamingStrategyCustomizer.java

import java.util.Vector;

import oracle.toplink.descriptors.ClassDescriptor;
import oracle.toplink.internal.helper.DatabaseTable;
import oracle.toplink.tools.sessionconfiguration.DescriptorCustomizer;


/**
*
* @author Okan Kahraman
*
*/
public class NamingStrategyCustomizer implements DescriptorCustomizer {

public static final String PROJECT_TABLE_PREFIX="Project_X_";


public void customize(ClassDescriptor classDescriptor) throws Exception {

Vector<DatabaseTable> tables = classDescriptor.getTables();

for (DatabaseTable table : tables) {
//adds the project prefix to the table name
table.setName(PROJECT_TABLE_PREFIX + table.getName());
//returns the schema name
table.getTableQualifier();
//returns the schema and table name together
table.getQualifiedName();
}
}
}

BaseEntity.java

import javax.persistence.Column;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.MappedSuperclass;

import oracle.toplink.annotations.Customizer;

@MappedSuperclass
@Customizer(value = NamingStrategyCustomizer.class)
public class BaseEntity {

@Id
@GeneratedValue
@Column(name="ID")
private Long id = null;

public void setId(Long id) {
this.id = id;
}

public Long getId() {
return id;
}
}

Wednesday, February 6, 2008

Eclipse Plug-in for ZK: ZK Studio

ZK Studio is an Eclipse plug-in to quickstart our ZK project. Every time we start a new Dynamic project in Eclipse, we always need to do the same routines. ZK Studio handles these routines with ease and saves our time.

Download ZK Studio from the following link:
ZK Sudio 0.5.0 (Eclipse plug-in)

The installation of ZK Studio is just like any other eclipse plug-ins. Copy the "org.zkoss.eclipse.setting_0.5.0.vxxx.jar" file into your "ECLIPSE_HOME/plugins" folder and restart your Eclipse workbench. Configuration of ZK Studio is quite easy:

  1. In your Eclipse IDE, click toolbar "Window" and select "Preferences...".
  2. At preference tree, select "ZK" category then chose "Installed ZKs".
  3. Currently there's no installed ZKs, so we need to prepare one. Preparing a ZK package is very simple:
    1. Download ZK's binary distribution from SourceForge.net
    2. Unpack it as a folder, put it in a proper place like: "D:\work\libraries\zk\zk-bin-3.0.3"
    3. Thats all you need to do.
  4. Back to Eclipse IDE's preference dialog. In "Installed ZKs" click "Add..." button and chose the package you prepared.
  5. Press "apply", "ok" to quit preference dialog.



Now create a new Dynamic Web Project and add ZK to your project configutaion.

Click "Next" and select ZK WebApp facet to enable ZK for current project.

Select the ZK version you want to use in current project.

Click "Finish" and Eclipse will create a new ZK-enabled project.

Yea, simple but useful plug-in...

Saturday, February 2, 2008

ZK 3.0.3 released

Over 8 new features and 22 bugs fixed, ZK 3.0.3 focuses mainly on fixing bugs and improving performance. More languages are supported for messages, and more formats are supported to JasperReports.

www.zkoss.org

Wednesday, January 23, 2008

ZK 3.0.2 released

ZK 3.0.2 focuses mainly on fixing bugs and improving performance. In addition to over 44 bug fixes, there are 30 new features.

In this release, more components are introduced and enhanced. jasperreports component is supported. ListModel and databind supports combobox. Datebox supports valid range of date. Moreover, the performance of live data of listbox and grid is improved. JpaUtil and OpenEntityManagerInView allow you to integrate with J2EE more easily. You can retrieve EntityManager and EntityManagerFactory by using newly added JpaUtil.

Great work again! Thanks ZK team!

www.zkoss.org

Accessing spring managed beans from outside the container

Sometimes we have to leave the container and need to access beans that managed by Spring. Spring has an interface named AplicationContextAware. Implementing this interface is discouraged by the springframework team, because it tightly couples our code to spring. There are no many ways to overcome this problem and we want to use the same context across different tiers, without re-instantianting the context. So we created our own singleton bean named SpringUtils which implements AplicationContextAware.


import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.util.Assert;

/**
*
* @author Okan Kahraman
*
*/
public class SpringUtils implements ApplicationContextAware {

private static ApplicationContext applicationContext;

@Override
public void setApplicationContext(ApplicationContext applicationContext)
throws BeansException {
this.applicationContext = applicationContext;
}

public static Object getBean(String beanRefName, Class beanClass) {
Object object = null;
Assert.notNull(applicationContext, "ApplicationContext must not be null!");
try {
BeanFactory factory = (BeanFactory) applicationContext;
object = factory.getBean(beanRefName, beanClass);
} catch (NoSuchBeanDefinitionException ex) {
// ignore
}
return object;

}

public static Object getBean(String beanRefName) {
Object object = null;
Assert.notNull(applicationContext, "ApplicationContext must not be null!");
try {
BeanFactory factory = (BeanFactory) applicationContext;
object = factory.getBean(beanRefName);
} catch (NoSuchBeanDefinitionException ex) {
// ignore
}
return object;
}
}