-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 8 posts ] 
Author Message
 Post subject: deleting with query
PostPosted: Sat Aug 21, 2004 1:49 pm 
Newbie

Joined: Wed Jul 28, 2004 11:16 am
Posts: 6
Location: Australian in Ireland
Is it possible to use a NamedQuery from the mapping files as a delete

I have seen examples like
Code:
session.delete("from Cat cat where cat.name = ?",name, Hibernate.STRING);


but how do i use this query as a delete

<query name="Cat,name" >
from Cat as cat where cat.name = :name
</query>

Code:
Query query = getQuery("Cat,name", params);
query.??? delete


I guess i could do something like
Code:
session.delete(query.getQueryString(), name, Hibernate.STRING);
and generalise it for more parameters and probably even get the query as string directly fromt he mapping document.
However i would prefer to treat the delete in the same manner as my other queries, looking them up as a NamedQuery using the same populate code for the parameters.

am i missing something obvious?

thanks
Simon

Hibernate version:2.1.4

Mapping documents:Cat

Code between sessionFactory.openSession() and session.close():

Full stack trace of any exception that occurs:na

Name and version of the database you are using:MySQL

Debug level Hibernate log excerpt:na


Top
 Profile  
 
 Post subject: Re: deleting with query
PostPosted: Sat Aug 21, 2004 6:42 pm 
Beginner
Beginner

Joined: Mon Jul 26, 2004 4:29 pm
Posts: 45
Location: TX, USA
spettlar wrote:
Is it possible to use a NamedQuery from the mapping files as a delete


Check the javadocs for:
Code:
session.delete(namedQuery.getQueryString());


Top
 Profile  
 
 Post subject: Re: deleting with query
PostPosted: Sat Aug 21, 2004 6:51 pm 
Beginner
Beginner

Joined: Mon Jul 26, 2004 4:29 pm
Posts: 45
Location: TX, USA
mojarrell wrote:
Check the javadocs for:
Code:
session.delete(namedQuery.getQueryString());


Sorry, I posted without catching the last part of your question. Couldn't you set the value of the parameter with:

Code:
namedQuery.setString(0, "Smith");


before issuing the
Code:
session.delete(namedQuery.getQueryString())


I'm not where I can verify this, but it seems reasonable.

Sorry if I'm still misunderstanding your question,
Maury


Top
 Profile  
 
 Post subject:
PostPosted: Sun Aug 22, 2004 7:16 am 
Newbie

Joined: Wed Jul 28, 2004 11:16 am
Posts: 6
Location: Australian in Ireland
nah
Code:
query.getQueryString()
just returns the string from the mapping document ie

from Cat as cat where cat.name = :name

so just adding the query string is not enough. I looked at

Code:
session.delete(query.getQueryString(), query.getNamedParameters(), query.getXXX())


but i dont know how to get the types back from the query. Anyway it seems a bit counter productive to go to the trouble of firstly extracting the query to configuration, then creating the Query instance, populating the query with parameters, then have to parse it back to a string and getting the parameters and types back out. So thats why i posted to the forum, i am sure im just missing something simple??

Simon


Top
 Profile  
 
 Post subject:
PostPosted: Mon Aug 23, 2004 6:00 pm 
Proxool Developer
Proxool Developer

Joined: Tue Aug 26, 2003 10:42 am
Posts: 373
Location: Belgium
My two cents... (not tested ;) - why don't you just do:

Code:
query.uniqueResult()


and don't care about the returned value... wondering if this won't do the trick...


Top
 Profile  
 
 Post subject:
PostPosted: Tue Aug 24, 2004 3:14 pm 
Beginner
Beginner

Joined: Mon Jul 26, 2004 4:29 pm
Posts: 45
Location: TX, USA
bertrand wrote:
My two cents... (not tested ;) - why don't you just do:

Code:
query.uniqueResult()


Bertrand, you'll have to show me what you mean; I tried 2 or 3 variations of query.uniqueResult() and couldn't get it to work.

Simon,

This has been on my mind because I'm trying to get my head around what Hibernate is all about. Coming from a database world and learning Java, it's been great to be able to manipulate data with Java idioms, but I still want to revert to database and sql at times. I set up an Oracle8i table with basically a number ID and a varchar2 description.

First I wondered if doing the deletes from Hibernate using a session.delete(Object) would be waaaay slower than using sql. I inserted 10000 rows into the table and ran a sql delete. The delete consistantly takes about 10 seconds. Then I iterated over the objects and deleted them one at time and it took over a minute:

Code:
    Transaction t = session.beginTransaction();
    Iterator masterIterator = session.iterate("from MasterTable as m where m.masterId >= 5");
    while (masterIterator.hasNext()) {
      session.delete((MasterTable)masterIterator.next());
    }
    t.commit();


But here's the interesting part: I then created and deleted the rows in one session so that the objects would still be cached. The delete time dropped to about 14 seconds:

Code:
    lgr.info("before create in makeThenDelete");
    Session session = sessionFactory.openSession();
    Transaction t = session.beginTransaction();
    for (int i=5; i<=10005; i++) {
      MasterTable m = new MasterTable();
      m.setMasterId(new BigDecimal(i));
      m.setMasterDescription("Master Record" + i);
      session.save(m);
    }
    t.commit();
    lgr.info("after create in makeThenDelete");
    // now delete them
    session.delete("from MasterTable as m where m.masterId >= 5");
    t.commit();
    session.close();
    lgr.info("after delete in makeThenDelete");


Then I tried doing a session.delete(String) with a hard coded string, again in the same session. Now were down to 11 or 12 seconds:

Code:
    lgr.info("before create in makeThenDeleteWithSql");
    Session session = sessionFactory.openSession();
    Transaction t = session.beginTransaction();
    for (int i=5; i<=10005; i++) {
      MasterTable m = new MasterTable();
      m.setMasterId(new BigDecimal(i));
      m.setMasterDescription("Master Record" + i);
      session.save(m);
    }
    t.commit();
    lgr.info("after create in makeThenDeleteWithSql");
    Query q = session.createSQLQuery("delete from master_table {masterTable} where {masterTable}.master_id >=5", "masterTable", MasterTable.class );
    q.uniqueResult();
    // now delete them
    t.commit();
    lgr.info("after delete in makeThenDeleteWithSql");
    session.close();


So, I guess what I'm saying that Hibernate would do a pretty good job unless you're talking about large batch type operations that DBA's or integrators encounter.


Back to your question. I can really see a use for a delete using a named query. I started playing around with it and well, I don't know if this is overkill, but what about the following:

First I wrote a method like this:
Code:
  private Type [] toTypeArray(Object [] object) {
    Type [] type = new Type[object.length];
    for (int i=0; i<object.length; i++) {
      type[i] = (Type)object[i];
    }
    return type;
  }


With this handy method in hand I can then do something like:

Code:
    List params = new ArrayList();
    List types = new ArrayList();
    Query q = session.createQuery("from MasterTable as m where m.masterId >= :masterId");
    q.setParameter("masterId", new Integer(50), Hibernate.INTEGER);
    // populate my lists when I set the parameters
    params.add(new Integer(50));
    types.add(Hibernate.INTEGER);
    session.delete(q.getQueryString(), params.toArray(), toTypeArray(types.toArray()));
    t.commit();


What do you think? Just for reference this method took 13-16 seconds to delete 10,000 rows.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Aug 24, 2004 3:26 pm 
Beginner
Beginner

Joined: Mon Jul 26, 2004 4:29 pm
Posts: 45
Location: TX, USA
Somehow I cut and pasted the wrong examples into my post:

The iterative delete looks like this:
Code:
    Transaction t = session.beginTransaction();
    Iterator masterIterator = session.iterate("from MasterTable as m where m.masterId >= 5");
    while (masterIterator.hasNext()) {
      session.delete((MasterTable)masterIterator.next());
    }
    t.commit();


The hard coded delete looks like this:
Code:
    session.delete("from MasterTable as m where m.masterId >= 5");
    t.commit();


Sorry about that...


Top
 Profile  
 
 Post subject:
PostPosted: Tue Aug 24, 2004 7:17 pm 
Newbie

Joined: Wed Jul 28, 2004 11:16 am
Posts: 6
Location: Australian in Ireland
this looks good, esp the performance measures, im off for three days on a boat, but ill give this a go in my tests when i get back

- thanks


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 8 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.