-->
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.  [ 7 posts ] 
Author Message
 Post subject: Get SQL for Session?
PostPosted: Thu Oct 15, 2009 2:23 pm 
Newbie

Joined: Thu Oct 15, 2009 12:08 pm
Posts: 3
Location: Buffalo, NY, USA
Hello,

Short story:
Is there a way for me to get the SQL that Hibernate generates when I save a pojo to a Session?

Long story:
I am using Hibernate to integrate 2 different databases with my Java application. On the one hand, I have a MySQL database on a particular server. On the other hand, each distribution of my application has its own embedded Derby database. The application mainly works with the Derby database. However, the Derby database needs to be updated often with new data from the MySQL database. This needs to be able to happen in two ways:

Method 1.) Via 2 connections, one to each database: in this scenario, my hbm2java-generated pojos act as the middle ground between the databases (i.e., I get pojos from a MySQL session, detach them, and save them to a Derby session.) This part works!

Method 2.) Via an update file. Here, it seems I have 2 choices: I can either serialize the MySQL pojos into a file, and then inflate them at a later date (or another application instance) to save them to a Derby session (as in Method 1 above); OR I can *somehow* get the SQL that Hibernate is using in Method 1, and just save all the required SQL into the file, which can then be read later and executed to update the Derby database. This is what I would prefer to do, but need help with.

So my question then is, how can I retrieve the SQL statements that Hibernate is executing when I save pojos to my Derby Session? Any help is appreciated...

-RN


Top
 Profile  
 
 Post subject: Re: Get SQL for Session?
PostPosted: Thu Oct 15, 2009 9:32 pm 
Newbie

Joined: Thu Oct 15, 2009 9:30 pm
Posts: 4
Put the following line in your log4j.properties file.

log4j.logger.org.hibernate.SQL=debug


Top
 Profile  
 
 Post subject: Re: Get SQL for Session?
PostPosted: Fri Oct 16, 2009 9:23 am 
Newbie

Joined: Thu Oct 15, 2009 12:08 pm
Posts: 3
Location: Buffalo, NY, USA
aykroyd, thanks for your post. Actually, I am already getting the SQL feedback from log4j because I am using
Code:
org.apache.log4j.Logger.getRootLogger().setLevel(org.apache.log4j.Level.ALL);
What I am really hoping for is a method or class that I can use to get the impending SQL at runtime. Otherwise, I think I would have to catch my debug log and parse it at runtime... which I would like to avoid.


Top
 Profile  
 
 Post subject: Re: Get SQL for Session?
PostPosted: Fri Oct 16, 2009 9:28 am 
Newbie

Joined: Fri Oct 16, 2009 7:12 am
Posts: 3
Hi,

another way would be imlementing an Interceptor. The method prepareStatement() would be the right place where every statement walks through.
Possible this is a option for you?


Top
 Profile  
 
 Post subject: Re: Get SQL for Session?
PostPosted: Fri Oct 16, 2009 12:10 pm 
Newbie

Joined: Thu Oct 15, 2009 9:30 pm
Posts: 4
Raybernator,

Sorry I didn't read the full text of your original post closely enough. Yeah, I actually had to do something somewhat similar several years ago. In my case, I wanted to take a query, and send it to several databases and then aggregate the responses. The way that I did it was to subclass the DataSource, Connection, Statement, and PreparedStatement classes that we used...

So DataSource would return one of my special Connection classes with several actual connections in it. From there you will get calls from hibernate preparing statements etc with the actual SQL. At this point, you can re-write it or return statement that have statements to go to both your derby and MySQL database.

Hope that helps,

Pete


Top
 Profile  
 
 Post subject: Re: Get SQL for Session?
PostPosted: Fri Oct 16, 2009 12:50 pm 
Newbie

Joined: Thu Oct 15, 2009 12:08 pm
Posts: 3
Location: Buffalo, NY, USA
Thanks for the responses.

Pete, I think I understand the gist of what you are saying; however, I'm not currently using any DataSource, Connection, Statement, and PreparedStatement classes... so I'm not sure how to relate it to my work. Below is the code I am using.

First, my method to get the databases set up (configs, sessionFactories, etc.):
Code:
public static void initializeDatabases()
{       
   try {
      // Create Configurations from configuration files.
      Configuration mysqlConfig = new Configuration().configure("/hibernate_mysql.cfg.xml");
      Configuration derbyConfig = new Configuration().configure("/hibernate_derby.cfg.xml");           
      
      // Check to see if the Derby database is already present.
      File dbLoc = new File("db/msjdb");
      if (!dbLoc.exists()) {
         
         // Change the connection URL to create a new database.
         String prop = "hibernate.connection.url";
         String url = derbyConfig.getProperty(prop);
         derbyConfig.setProperty(prop, url + ";create=true");
         
         // Export the schema to Derby.
         SchemaExport se = new SchemaExport(derbyConfig);
         se.create(false, true);
         
         // Change the connection URL back to the original.
         derbyConfig.setProperty(prop, url);
      }
      // Create SessionFactories from configurations.
      ourMysqlSessionFactory = mysqlConfig.buildSessionFactory();
      ourDerbySessionFactory = derbyConfig.buildSessionFactory();           
      
   } catch (Throwable ex) {
      // Log the exception.
      System.err.println("Initial SessionFactory creation failed." + ex);
      throw new ExceptionInInitializerError(ex);
   }
}

And here is the method I use to transfer the result of an HQL query from MySQL to Derby:
Code:
public static void transferHqlResults(String hqlQuery)
{
   // Open the MySQL session.
   Session mysqlSession = getMysqlSessionFactory().openSession();       

   // Query the MySQL database for pojos.
   Query q = mysqlSession.createQuery(hqlQuery);       
   List<MsjHbPojo> result = q.list();

   // Recursively build a list of objects that will be persisted.
   List<Object> reqdObjects = new Vector<Object>();
   for (int i = 0; i < result.size(); i++)
   {
      importWithPrereqs(result.get(i), reqdObjects, mysqlSession);
   }

   // Close the MySQL session.
   mysqlSession.close();       

   // Open the Derby session.
   Session derbySession = getDerbySessionFactory().openSession();

   // Begin the Derby transaction.
   Transaction t = derbySession.beginTransaction();

   // Save all the pojos that have been loaded.
   for (int p = 0; p < reqdObjects.size(); p++)
   {
      if (reqdObjects.get(p) instanceof MsjHbPojo)
      {
         MsjHbPojo pojo = (MsjHbPojo)reqdObjects.get(p);
         Class c = ClassHelper.getNormalizedClass(pojo.getClass());
         MsjHbPojo loadPojo = (MsjHbPojo)derbySession.get(c, pojo.getId());
         if (loadPojo==null)                   
         {
            derbySession.save(reqdObjects.get(p));
         }
      }
   }

   // Commit to Derby.
   t.commit(); // ***THE SQL THAT I WANT TO CAPTURE GETS PRINTED HERE FROM LOG4J***

   // Close the Derby session.
   derbySession.close();
}

I'm pretty much a newbie when it comes to Hibernate. This is my first project... and it took me forever to get this working the way I wanted it. Do you have any suggestions that would be straightforward with my current code? Thanks...

-RN


Top
 Profile  
 
 Post subject: Re: Get SQL for Session?
PostPosted: Fri Oct 16, 2009 4:29 pm 
Newbie

Joined: Thu Oct 15, 2009 9:30 pm
Posts: 4
So... I think that you can set the property:

hibernate.connection.provider_class to a class of your choosing. Then hibernate will call that to get its jdbc connection. So then you return your custom connection type from there.

There's an example of how that might work here: http://wiki.apache.org/jakarta-commons/DBCP/Hibernate.

Pete


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 7 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.