Javier Leyba | 1 Sep 2006 13:03
Picon

Parameters to store procedure

Hi

I´ve a store procedure that receive two parameters: one input and one
output with the result of the operation.

I'm in nightmare trying to set up a map for this.

I don't want to create a class to pass parameters so I tried to pass
inline parameters but I really couldn´t understand how ti works with
iBatis.

I did:

----------
public class GenericResult implements Serializable {
	private Integer result;

	public Integer getResult() {
		return result;
	}

	public void setResult(Integer result) {
		this.result = result;
	}		
}
----------
<procedure id="deleteNotification"
	resultClass="Notification.genericResult" parameterClass="java.util.Map">
	<![CDATA[
                {call
(Continue reading)

Ralf Assmann | 1 Sep 2006 14:21
Picon
Favicon

Bad Performance Using Ibatis?


Hi there,

making a performance test with ibatis, we got a very slow runtime. 
Inserting 100000 rows into a table, we took more than twice the time 
than using own-written prepared statements. The time was definitely  
lost during the transaction time writing the data to the database, 
calling sqlMap.insert(...).

Does anyone know if this runtime is normal while using ibatis or is 
there any xml-parameter to optimize it?

Many thanx,

Ralf

Gareth Moorst | 1 Sep 2006 15:16
Picon
Favicon

Creating SQLMaps at runtime

For those interested in creating modular sql map applications (a single sqlmapclient with sqlmaps loaded dynamically from multiple jars) here's how I went about it:

I have a Spring/Ibatis application in which I wanted to load Spring Beans/Ibatis DAOs from jars present on the classpath. To accomplish this, I created a new Spring bean, extending the existing org.springframework.orm.ibatis.SqlMapClientFactoryBean.
This bean takes additional properties templateLocation and sqlmapLocation, where templateLocation is a single filename and sqlmapLocation is a path pattern, such as "/config/*sqlmap.xml".

In this bean, I searched the classpath f or a template SQL-map-config.xml and for any *sqlmap.xml files.
I then wrote a new temporary sql-map-config.xml file and inserted <sqlMap url="blah"/> entries for all the sqlmap.xml files on the classpath.
I then build the sqlmap client using the new sql-map-config.xml file via the SqlMapBuilder and delete the temporary file.

In my initial tests, it's working fine - I have a core DAO jar file and an extension DAO jar file both running inside a web application, and Spring/Ibatis seem to be working happily.

It doesn't stand much chance of working without Spring however, as it is tightly coupled to the SqlMapClientFactoryBean and makes use of Spring utility classes to search the classpath.

It's also a bit ugly in places - writing a temporary xml file to build the sqlmapclient from smells bad to me, but I don't know of any other way to get an sqlmapclient...

Questions, ideas, comments?

Cheers,
Gareth Moorst.

----- Original Message ----
From: Gareth Moorst <gazj2ee <at> yahoo.co.uk>
To: user-java <at> ibatis.apache.org
Sent: Wednesday, 30 August, 2006 4:45:00 PM
Subject: Re: Creating SQLMaps at runtime

Clinton,

The classpath scanning code is much simpler than I expected - in Spring, it just boils down to:

[classLoader].getResources("folder/filename.xml");

which returns an Enumeration of URLs.
The javadoc notes that there must be a folder for the method call to work reliably when searching inside jar files.

Allowing wildcards in the filename is a bit more complex and involves finding the classpath roots and iterating through the entries in classpath jars or folders to see if they match the pattern.

The code is all in org.springframework.core.io.support.PathMatchingResourcePatternResolver for the interested.

So scanning the classpath for named files is pretty easy to do... shall I expect it in the next release? ;)

What remains is for me to figure out a way to mung the retrieved sql map files into an sql map client.

Can anyone point me in the right direction?

Cheers,
Gareth.

----- Original Message ----
From: Gareth Moorst <gazj2ee <at> yahoo.co.uk>
To: user-java <at> ibatis.apache.org
Sent: Wednesday, 30 August, 2006 3:16:46 PM
Subject: Fw: Creating SQLMaps at runtime



----- Forwarded Message ----
From: Gareth Moorst <gazj2ee <at> yahoo.co.uk>
To: Clinton Begin <clinton.begin <at> gmail.com>
Sent: Wednesday, 30 August, 2006 3:16:03 PM
Subject: Re: Creating SQLMaps at runtime

Cheers for the quick reply..

As for searching the classpath, I'm not sure yet.
I only found out earlier today that Spring allows you to do just that - you can create an ApplicationContext using a string like 'classpath*:context.xml' to find all the context.xml files on the classpath - that's how I was going to sort out the spring side of things.

I'll take a look at the spring source and see how they do it.

Cheers,
Gareth

----- Original Message ----
From: Clinton Begin <clinton.begin <at> gmail.com>
To: user-java <at> ibatis.apache.org; Gareth Moorst <gazj2ee <at> yahoo.co.uk>
Sent: Wednesday, 30 August, 2006 3:09:02 PM
Subject: Re: Creating SQLMaps at runtime


>> search the classpath

How are you going to do that?  If that were an easy thing to do reliably, we'd probably just do it for you by allowing:  <sqlMap resource="/*.xml" />

Any ideas?

Cheers,
Clinton

On 8/30/06, Gareth Moorst <gazj2ee <at> yahoo.co.uk> wrote:
Hi,


What I'm trying to achieve is a way to have a set of 'core' sqlmaps, which are always loaded, and a further set of optional sqlmaps, which are only loaded if present.
In particular, I want to search the classpath for sqlmap files at startup and 'inject' them all into a running Spring configured sql map client.





Chris Lamey | 1 Sep 2006 15:59
Favicon

Re: Bad Performance Using Ibatis?

Are you batching the inserts?  If not, then a commit is done after each
insert, which is very slow.

On Fri, 2006-09-01 at 14:21 +0200, Ralf Assmann wrote:
> Hi there,
> 
> making a performance test with ibatis, we got a very slow runtime. 
> Inserting 100000 rows into a table, we took more than twice the time 
> than using own-written prepared statements. The time was definitely  
> lost during the transaction time writing the data to the database, 
> calling sqlMap.insert(...).
> 
> Does anyone know if this runtime is normal while using ibatis or is 
> there any xml-parameter to optimize it?
> 
> Many thanx,
> 
> 
> Ralf
> 

Poitras Christian | 1 Sep 2006 16:09
Picon

RE: bug in javabeans setter (ComplexBeanProbe.java)?

This is a good question.
I didn't notice that your HashMap was intialized with the original
HashMap from iBatis when calling new. 

I guess your right about it, but it is valid to call 13 at the end (for
simple getter/setter).
Then to correct the problem, the setObject method should be like this.

(1) if (name.indexOf('.') > -1) {
      StringTokenizer parser = new StringTokenizer(name, ".");
(2)   String property = parser.nextToken();
(3)   Object child = object;
(4)   while (parser.hasMoreTokens()) {
(5)     Class type = getPropertyTypeForSetter(child, property);
(6)     Object parent = child;
(7)     child = getProperty(parent, property);
(8)     if (child == null) {
(9)       if (value == null) {
            return; // don't instantiate child path if value is null
          } else {
            try {
(10)          child = type.newInstance();
              if (!parser.hasMoreTokens()) {
(13)            setProperty(child, property, value);
              }
(11)          setObject(parent, property, child);
            } catch (Exception e) {
			...
            }
          }
        }
        property = parser.nextToken();
      }
    } else {
      setProperty(object, name, value);
    }

I can't say this will work for sure, but it is a workaround to test.
If your not dependent on null testing, you could also change the getter
to initialize an empty HashMap. You can also change null testing with
isEmpty(). This is more convenient since it cannot raise unwanted
NullPointerException.

I know iBatis does not handle these types of getter/setter very easilly.
iBatis believes that your gettes/setters are returning/setting the
property without doing any validation or copying or anything else...

Hope this will help.
Christian

-----Original Message-----
From: Adam Klein [mailto:Adam.Klein <at> aqr.com] 
Sent: Thursday, 31 August 2006 14:34
To: user-java <at> ibatis.apache.org
Subject: RE: bug in javabeans setter (ComplexBeanProbe.java)?

I don't think solves it.  Check out the setObject(...) function in
ComplexBeanProbe.java, listed below, followed by my analysis.  

public void setObject(Object object, String name, Object value) {
(1) if (name.indexOf('.') > -1) {
      StringTokenizer parser = new StringTokenizer(name, ".");
(2)   String property = parser.nextToken();
(3)   Object child = object;
(4)   while (parser.hasMoreTokens()) {
(5)     Class type = getPropertyTypeForSetter(child, property);
(6)     Object parent = child;
(7)     child = getProperty(parent, property);
(8)     if (child == null) {
(9)       if (value == null) {
            return; // don't instantiate child path if value is null
          } else {
            try {
(10)          child = type.newInstance();
(11)          setObject(parent, property, child);
            } catch (Exception e) {
			...
            }
          }
        }
        property = parser.nextToken();
      }
(13)  setProperty(child, property, value);
    } else {
      setProperty(object, name, value);
    }
  }

Here is what happens.  Ibatis calls:

	setObject(myClass, "myHashMap.key1", "value1")

with myClass = new MyClass(), myHashMap == null, and then:

1.  true condition, "myHashMap.key1" has "." in it
2.  property = "myHashMap"	
3.  child = myClass
4.  true condition, parser has more tokens 5.  type =
"java.util.HashMap"
6.  parent = myClass
7.  child = myHashMap
8.  true condition, child (myHashMap) IS null 9.  false condition, value
== "value1", not null 10. child = new HashMap() 11. setObject(parent,
property, child), ie, myClass.myHashMap =
COPY(child)
12. ...
13. setProperty(child, property, value), ie, child.key1 = "value1"

Note that child != myHashMap at step 13 due to the setter's deep
copying.  Shouldn't it call setProperty(child, property, value) BEFORE
step 11?

Best,
  Adam

-----Original Message-----
From: Poitras Christian [mailto:Christian.Poitras <at> ircm.qc.ca]
Sent: Thursday, August 31, 2006 1:58 PM
To: user-java <at> ibatis.apache.org
Subject: RE: bug in javabeans setter (ComplexBeanProbe.java)?

Ok. I have an answer for this type of problem.

For your resultMap, iBatis will generate objects by calling the
following.
MyClass myClass = new MyClass(); <- iBatis calls instantiate but the
result is the same.
myClass.setMyDouble(value0);
myClass.setMyHashMap(new HashMap()); <- I think this is done.
myClass.getMyHashMap().setKey1(value1);
myClass.getMyHashMap().setKey2(value2);

To get pass your problem, you should change the setter with this.
	public void setMyHashMap(HashMap<String, String> h) {
            if (myHashMap == null) {
			myHashMap = new HashMap<String,String>(h);
		}
		// create COPY of h
		if (h == null)
            	myHashMap = null;
        	else {
            	myHashMap.clear();
	            myHashMap.putAll(h);
        	}
	}	

-----Original Message-----
From: Adam Klein [mailto:Adam.Klein <at> aqr.com]
Sent: Thursday, 31 August 2006 09:32
To: user-java <at> ibatis.apache.org
Subject: RE: bug in javabeans setter (ComplexBeanProbe.java)?

My class looks like this:

Public class MyClass {
	HashMap<String,String> myHashMap;
	...		     

	MyClass() {
		// Uncomment to fix bad iBATIS behavior:
		// myHashMap = new HashMap<String,String>();
	}

	public void setMyHashMap(HashMap<String, String> h) {
		// create COPY of h
		if (h == null)
            	myHashMap = null;
	      else if (myHashMap == null)
            	myHashMap = new HashMap<String,String>(h);
        	else {
            	myHashMap.clear();
	            myHashMap.putAll(h);
        	}
	}	

	Public HashMap<String, String> getMyHashMap() {
		return myHashMap;
	}
}

Now, if I use the result map below to generate a List of MyClass
objects, if myHashMap is not initialized to a non-null value in the
constructor (see commented-out line above), the value Key1 is not
assigned value1, because what happens is the code creates a new HashMap
object, say X, and before calling X.put(Key1, Value1), the code calls
setMyHashMap(X), and THEN it calls X.put(Key1, value1), but by this time
X no longer refers to the same object as myHashMap.

Hope this makes sense.

Regards,
  Adam

-----Original Message-----
From: Poitras Christian [mailto:Christian.Poitras <at> ircm.qc.ca]
Sent: Wednesday, August 30, 2006 2:01 PM
To: user-java <at> ibatis.apache.org
Subject: RE: bug in javabeans setter (ComplexBeanProbe.java)?

Can you post a copy of your setters?
I'm not sure what you're trying to ask or to do.

Christian

-----Original Message-----
From: Adam Klein [mailto:Adam.Klein <at> aqr.com]
Sent: Tuesday, 29 August 2006 16:41
To: user-java <at> ibatis.apache.org
Subject: bug in javabeans setter (ComplexBeanProbe.java)?

Apologies if this is posted twice, I don't think my first one made it.

I had implemented defensive copying on my javabean setter methods - ie,
so the value of the bean would be set to a COPY of the parameter  -
while the getter would return a direct reference.  Then, when I was
trying to set keys in an (uninitiailized) HashMap object to values like
this:

<resultMap id="myResultMap" class="MyClass">
	 <result property = myDouble 		column="value0" />
       <result property = myHashMap.Key1 	column="value1" />
       <result property = myHashMap.Key2 	column="value2" />
</resultMap>

I got a very strange result: of the values in myHashMap, only the value
of myHashMap.key2 would be set; in general, the first key of an
(uninitialized) HashMap would never be assigned a value. I traced the
reason to the ComplexBeanProbe.java file, in the setObject method: it
called the method setObject(parent, property, child) prior to calling
setProperty(child, property, value), which meant that the parent.child
object no longer referenced the child object by the time the code
attempted to set values on the child object (due specifically to my
defensive copying).  If myHashMap is initialized to an empty HashMap
value on creation of MyClass, there are no problems.

The question is, is this just a symptom of defensive copying, or is this
a bug, where setProperty(child, property, value) should be called first?

Regards,
  Adam

 

 

Disclaimer: This e-mail may contain confidential and/or privileged
information.  If you are not the intended recipient or have received
this e-mail in error, please notify the sender immediately and
destroy/delete this e-mail.  You are hereby notified that any
unauthorized copying, disclosure or distribution of the material in this
e-mail is strictly prohibited.

This communication is for informational purposes only.  It is not
intended as an offer or solicitation for the purchase or sale of any
financial instrument or as an official confirmation of any transaction.
All information contained in this communication is not warranted as to
completeness or accuracy and is subject to change without notice.  Any
comments or statements made in this communication do not necessarily
reflect those of AQR Capital Management, LLC and its affiliates.

Larry Meadors | 1 Sep 2006 16:17
Picon
Favicon

Re: Bad Performance Using Ibatis?

...and if you do batch it, you may still want to commit after ever
100-200 inserts to keep the database from creating a massive rollback
segment.

Also, if you are inserting 100,000 rows, you may want to look into
using a native data loader tool. It'll be WAAY faster.

Larry

On 9/1/06, Chris Lamey <clamey <at> localmatters.com> wrote:
> Are you batching the inserts?  If not, then a commit is done after each
> insert, which is very slow.
>
> On Fri, 2006-09-01 at 14:21 +0200, Ralf Assmann wrote:
> > Hi there,
> >
> > making a performance test with ibatis, we got a very slow runtime.
> > Inserting 100000 rows into a table, we took more than twice the time
> > than using own-written prepared statements. The time was definitely
> > lost during the transaction time writing the data to the database,
> > calling sqlMap.insert(...).
> >
> > Does anyone know if this runtime is normal while using ibatis or is
> > there any xml-parameter to optimize it?
> >
> > Many thanx,
> >
> >
> > Ralf
> >
>

Zsolt | 1 Sep 2006 16:45

RE: Bad Performance Using Ibatis?

You probably need bulk insert.

insert into ... values(...),(...)

That is very fast.

Zsolt

>-----Original Message-----
>From: Ralf Assmann [mailto:ralf.assmann <at> innovations.de]
>Sent: Friday, September 01, 2006 2:22 PM
>To: user-java <at> ibatis.apache.org
>Subject: Bad Performance Using Ibatis?
>
>
>Hi there,
>
>making a performance test with ibatis, we got a very slow runtime.
>Inserting 100000 rows into a table, we took more than twice the time
>than using own-written prepared statements. The time was definitely
>lost during the transaction time writing the data to the database,
>calling sqlMap.insert(...).
>
>Does anyone know if this runtime is normal while using ibatis or is
>there any xml-parameter to optimize it?
>
>Many thanx,
>
>
>Ralf

Clinton Begin | 1 Sep 2006 16:55
Picon

Re: Bad Performance Using Ibatis?


Yay!  It's our monthly performance concern! 

Rest assured, for 99% of cases, iBATIS is within milliseconds of JDBC performance.

This comes  up once a month, where someone creates a couple of for{} loops with JDBC vs. iBATIS....

9 times out of 10 the code is the problem -- inappropriate transaction handling, is the most common mistake.

In any case, you might want to read this thread.

http://www.mail-archive.com/user-java <at> ibatis.apache.org/msg04760.html

The key point:  "When I excluded the
startTransaction/commitTransaction/endTransaction...my process took 5
minutes to run. When I included it, I got my full process to run under 1
minute. This is directly equal to the speed I found when using straight
Jdbc and/or Spring Jdbc Templates."

Batching and reflection optimization are icing on the cake.  Even without them, iBATIS should be nearly as fast as JDBC ( i.e. not noticably slower).

Cheers,
Clinton

On 9/1/06, Ralf Assmann <ralf.assmann <at> innovations.de > wrote:

Hi there,

making a performance test with ibatis, we got a very slow runtime.
Inserting 100000 rows into a table, we took more than twice the time
than using own-written prepared statements. The time was definitely
lost during the transaction time writing the data to the database,
calling sqlMap.insert(...).

Does anyone know if this runtime is normal while using ibatis or is
there any xml-parameter to optimize it?

Many thanx,


Ralf


Ralf Assmann | 1 Sep 2006 20:13
Picon
Favicon

Re: Bad Performance Using Ibatis?

No, I am not batching the insert. This will not work with the 
application we want to use ibatis for ... If a make the test with 
batching, ibatis is also slower than jdbc-statements (prepared 
statements), but not twice the time.

Therefore, autocommitting is false. The commit will be done by 
sqlMap.commitTransaction(). This works, because without using this in 
the test, no data are in the database table.

Chris Lamey schrieb:
> Are you batching the inserts?  If not, then a commit is done after each
> insert, which is very slow.
>
> On Fri, 2006-09-01 at 14:21 +0200, Ralf Assmann wrote:
>   
>> Hi there,
>>
>> making a performance test with ibatis, we got a very slow runtime. 
>> Inserting 100000 rows into a table, we took more than twice the time 
>> than using own-written prepared statements. The time was definitely  
>> lost during the transaction time writing the data to the database, 
>> calling sqlMap.insert(...).
>>
>> Does anyone know if this runtime is normal while using ibatis or is 
>> there any xml-parameter to optimize it?
>>
>> Many thanx,
>>
>>
>> Ralf
>>
>>     

Ralf Assmann | 1 Sep 2006 20:14
Picon
Favicon

Re: Bad Performance Using Ibatis?

A commit will be done every 1000 inserts. Also, there are not 
differences in doing that with ibatis and "plain jdbc-statements". Both 
will do the same, but ibatis needs twice the time.

Larry Meadors schrieb:
> ...and if you do batch it, you may still want to commit after ever
> 100-200 inserts to keep the database from creating a massive rollback
> segment.
>
> Also, if you are inserting 100,000 rows, you may want to look into
> using a native data loader tool. It'll be WAAY faster.
>
> Larry
>
>
> On 9/1/06, Chris Lamey <clamey <at> localmatters.com> wrote:
>> Are you batching the inserts?  If not, then a commit is done after each
>> insert, which is very slow.
>>
>> On Fri, 2006-09-01 at 14:21 +0200, Ralf Assmann wrote:
>> > Hi there,
>> >
>> > making a performance test with ibatis, we got a very slow runtime.
>> > Inserting 100000 rows into a table, we took more than twice the time
>> > than using own-written prepared statements. The time was definitely
>> > lost during the transaction time writing the data to the database,
>> > calling sqlMap.insert(...).
>> >
>> > Does anyone know if this runtime is normal while using ibatis or is
>> > there any xml-parameter to optimize it?
>> >
>> > Many thanx,
>> >
>> >
>> > Ralf
>> >
>>


Gmane