Return-Path: Delivered-To: apmail-ibatis-user-java-archive@www.apache.org Received: (qmail 88616 invoked from network); 26 Sep 2006 12:20:55 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (209.237.227.199) by minotaur.apache.org with SMTP; 26 Sep 2006 12:20:55 -0000 Received: (qmail 10827 invoked by uid 500); 26 Sep 2006 12:20:46 -0000 Delivered-To: apmail-ibatis-user-java-archive@ibatis.apache.org Received: (qmail 10756 invoked by uid 500); 26 Sep 2006 12:20:45 -0000 Mailing-List: contact user-java-help@ibatis.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: user-java@ibatis.apache.org Delivered-To: mailing list user-java@ibatis.apache.org Received: (qmail 10745 invoked by uid 99); 26 Sep 2006 12:20:45 -0000 Received: from idunn.apache.osuosl.org (HELO idunn.apache.osuosl.org) (140.211.166.84) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 26 Sep 2006 05:20:45 -0700 Authentication-Results: idunn.apache.osuosl.org smtp.mail=jeffgbutler@gmail.com; spf=pass Authentication-Results: idunn.apache.osuosl.org header.from=jeffgbutler@gmail.com; domainkeys=good X-ASF-Spam-Status: No, hits=2.5 required=5.0 tests=DNS_FROM_RFC_ABUSE,HTML_MESSAGE Received-SPF: pass (idunn.apache.osuosl.org: domain gmail.com designates 66.249.82.230 as permitted sender) DomainKey-Status: good X-DomainKeys: Ecelerity dk_validate implementing draft-delany-domainkeys-base-01 Received: from [66.249.82.230] ([66.249.82.230:63841] helo=wx-out-0506.google.com) by idunn.apache.osuosl.org (ecelerity 2.1.1.8 r(12930)) with ESMTP id 0C/50-10462-71B19154 for ; Tue, 26 Sep 2006 05:20:40 -0700 Received: by wx-out-0506.google.com with SMTP id h30so2437512wxd for ; Tue, 26 Sep 2006 05:20:36 -0700 (PDT) DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=beta; d=gmail.com; h=received:message-id:date:from:to:subject:in-reply-to:mime-version:content-type:references; b=V8xBCfEjUqMFJqXMRizWGB1M5732zroMogOJYyJyXPJzaZ6ZIDqfx9a/NdC23Uc2yPfxYrkGnI2v1HCSU3GAXTiKJbUW8boUaa9TU9aCmFtjeGUB/2hbjexyDYOonMtnaEWzexaz/tJpjoXDq/+8hP4ujtsvd3hOjcN5a0QUXCY= Received: by 10.90.25.3 with SMTP id 3mr92808agy; Tue, 26 Sep 2006 05:20:36 -0700 (PDT) Received: by 10.90.118.17 with HTTP; Tue, 26 Sep 2006 05:20:36 -0700 (PDT) Message-ID: Date: Tue, 26 Sep 2006 07:20:36 -0500 From: "Jeff Butler" To: user-java@ibatis.apache.org Subject: Re: Custom Type Handler for Oracle DATE In-Reply-To: <4518E1CA.8090405@agilemovement.it> MIME-Version: 1.0 Content-Type: multipart/alternative; boundary="----=_Part_5503_16837413.1159273236798" References: <4518E1CA.8090405@agilemovement.it> X-Spam-Rating: minotaur.apache.org 1.6.2 0/1000/N ------=_Part_5503_16837413.1159273236798 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Content-Disposition: inline Here are a couple of thoughts: 1. Oracle's DATE type can be DATE, TIME. or TIMESTAMP depending on how it's configured. But I think their JDBC driver always reports it as TIMESTAMP - so that's why Abator generated it as TIMESTAMP. If it really is a DATE then use a to force the field to jdbcType DATE. 2. Upgrade to Abator 1.0 and regenerate your objects. I made a change in the select by example clauses regarding DATE/TIME/TIMESTAMP that also may fix the probem. I don't think you need to resort to a custom type handler for this. Jeff Butler On 9/26/06, aris wrote: > > Hi all, > I'm new to this mailing list and to Ibatis too. > > Today I wrote my first type handler callback class to solve a problem > with the Oracle jdbc driver (from version 9). > > I've a table with a column of type DATE and an index is defined on this > column. The table is mapped from a domain object with the related field > of type java.util.Date. > > The portion of resultMap for the field is: > > > The domain object and the resultMap have been generated with Abator for > Eclipse 0.6.5. > > I search on that table using a selectByExample. Using the field > columnDate as parameter in the where clause the execution of the query > became slower beacause the index wasn't used. > > This is the problem: IBatis adds a parameter of type a java.util.Date on > a prepared statement with a setTimestamp(...). This is correct because a > setDate(...) truncates information about hours, minutes and seconds. But > when a setTimestamp is used the query optimizer generates a query that > doesn't use the index and perform a full table scan. > > Solution 1: write a query using the to_date function and change the type > of the field to String; > > Solution 2: wrap the value of the field in a oracle.sql.DATE and prepare > the statement using the method setObject(...). > > Rewrite the query with the to_date implied to change the Abator > generated code (the dynamic sql for the where clause) so I tried to > implement the 2nd solution. > > I wrote a custom type handler to convert a java.util.Date in an > oracle.sql.DATE and back. I've tested it and now the query uses the > index but I'd like a hint about my implementation from other users with > more experience. > > I appreciate any comments. > > Best regards, > aris. > > > > package com.yourpackage; > > import java.sql.SQLException; > import java.sql.Timestamp; > import java.util.Date; > > import oracle.sql.DATE; > > import com.ibatis.sqlmap.client.extensions.ParameterSetter; > import com.ibatis.sqlmap.client.extensions.ResultGetter; > import com.ibatis.sqlmap.client.extensions.TypeHandlerCallback; > > public class OracleDateTypeHandler implements TypeHandlerCallback { > > public void setParameter(ParameterSetter setter, Object parameter) > throws SQLException { > if (parameter == null) { > setter.setNull(oracle.jdbc.OracleTypes.DATE); > } else { > Date date = (Date) parameter; > DATE oracleDate = new DATE(new Timestamp(date.getTime())); > setter.setObject(oracleDate); > } > } > > public Object getResult(ResultGetter getter) throws SQLException { > Timestamp value = getter.getTimestamp(); > if (getter.wasNull()) { > return null; > } > return new Date(value.getTime()); > > } > > public Object valueOf(String s) { > return s; > } > > } > > > > ------=_Part_5503_16837413.1159273236798 Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Content-Disposition: inline
Here are a couple of thoughts:
 
1. Oracle's DATE type can be DATE, TIME. or TIMESTAMP depending on how it's configured.  But I think their JDBC driver always reports it as TIMESTAMP - so that's why Abator generated it as TIMESTAMP.  If it really is a DATE then use a <columnOverride> to force the field to jdbcType DATE.
 
2. Upgrade to Abator 1.0 and regenerate your objects.  I made a change in the select by example clauses regarding DATE/TIME/TIMESTAMP that also may fix the probem.
 
I don't think you need to resort to a custom type handler for this.
 
Jeff Butler

 
On 9/26/06, aris <aris@agilemovement.it> wrote:
Hi all,
I'm new to this mailing list and to Ibatis too.

Today I wrote my first type handler callback class to solve a problem
with the Oracle jdbc driver (from version 9).

I've a table with a column of type DATE and an index is defined on this
column. The table is mapped from a domain object with the related  field
of type java.util.Date .

The portion of resultMap for the field is:
<result column="COLUMN_DATE" property="columnDate" jdbcType="TIMESTAMP"/>

The domain object and the resultMap have been generated with Abator for
Eclipse 0.6.5.

I search on that table using a selectByExample. Using the field
columnDate as parameter in the where clause the execution of the query
became slower beacause the index wasn't used.

This is the problem: IBatis adds a parameter of type a java.util.Date on
a prepared statement with a setTimestamp(...). This is correct because a
setDate(...) truncates information about hours, minutes and seconds. But
when a setTimestamp is used the query optimizer generates a query that
doesn't use the index and perform a full table scan.

Solution 1: write a query using the to_date function and change the type
of the field to String;

Solution 2: wrap the value of the field in a oracle.sql.DATE and prepare
the statement using the method setObject(...).

Rewrite the query with the to_date implied to change the Abator
generated code (the dynamic sql for the where clause) so I tried to
implement the 2nd solution.

I wrote a custom type handler to convert a java.util.Date in an
oracle.sql.DATE and back. I've tested it and now the query uses the
index but I'd like a hint about my implementation from other users with
more experience.

I appreciate any comments.

Best regards,
aris.



package com.yourpackage;

import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.Date;

import oracle.sql.DATE;

import com.ibatis.sqlmap.client.extensions.ParameterSetter;
import com.ibatis.sqlmap.client.extensions.ResultGetter;
import com.ibatis.sqlmap.client.extensions.TypeHandlerCallback;

public class OracleDateTypeHandler implements TypeHandlerCallback {

   public void setParameter(ParameterSetter setter, Object parameter) throws SQLException {
       if (parameter == null) {
           setter.setNull (oracle.jdbc.OracleTypes.DATE);
       } else {
           Date date = (Date) parameter;
           DATE oracleDate = new DATE(new Timestamp(date.getTime()));
           setter.setObject(oracleDate);
       }
   }

   public Object getResult(ResultGetter getter) throws SQLException {
       Timestamp value = getter.getTimestamp();
       if (getter.wasNull()) {
           return null;
       }
       return new Date( value.getTime());

   }

   public Object valueOf(String s) {
       return s;
   }

}




------=_Part_5503_16837413.1159273236798--