-->
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.  [ 3 posts ] 
Author Message
 Post subject: HQL to SQL Transation Solution - for JDBC queries
PostPosted: Thu Jan 20, 2005 1:23 pm 
Regular
Regular

Joined: Tue Nov 30, 2004 4:23 pm
Posts: 62
So I ran the API through the debugger and had quite a few methods on how I thought I could solve the ability to translate HQL to SQL, but classes like the SessionImpl and SessionFactoryImpl are all final, so I could not successfully implement a Decorator Pattern or any clear extension of their functionality. Essentially the find method did most of what I need to do. It submitted all queries into the QueryTranslator and returned an array of QueryTranslators, which contains the SQL String. This is all I needed, but of course the code continues to process those QueryTranslators against the database in the list command. So unfortunately, my only solution was to utilize QueryTranslator as a utility class. This is the following code that I am testing/implementing:

Code:
    public static String translateHQLtoSQL( Session hibernateSession,
        String hqlString, boolean scalar ) throws HibernateException
    {
         //We jave a helper class to load the Hibernate Configurations
        Properties props =
            HibernateHelper.getHibernateConfigurationProperties(  );
        String sqlQuery = "";

        try
        {
            //Take the loaded Hibernate Configuration and create a Settings class
            Settings hibernateSettings = SettingsFactory.buildSettings( props );
            //The SessionImpl stores a SessionFactoryImpl but returns it as a SessionFactoryImplementor
            //SessionFactoryImpl implements SessionFactoryImplementor
            SessionFactoryImpl sessionFactory =
                ( SessionFactoryImpl )hibernateSession.getSessionFactory(  );
            //Then pass the HQL query into the creation of a QueryTranslator
            QueryTranslator queryTranslator = new QueryTranslator( hqlString );
            //Compile the HQL with the sessionFactory and hibernateSettings
            queryTranslator.compile( sessionFactory,
                hibernateSettings.getQuerySubstitutions(  ), scalar );
            //Retrieve the SQL statement from the SQL String
            sqlQuery = queryTranslator.getSQLString(  );
        }
        catch ( HibernateException he )
        {
            ArchTracer.exitScope( he );

            HibernateHelper.handleHibernateException( he );
        }

        return sqlQuery;
    }

    public int getGovernedSearchConstantResult( String sqlQuery, List paramaters )
      throws MaximumResultsExceededException, DatabaseException
    {
        int rowCount = 0;
        String selectConstant = "";
        PreparedStatement statement = null;
        Connection connection = null;
        ResultSet resultSet = null;

        try
        {
            //Use a utility class to remove the select statement from the SQL
            //May seem odd but the utility class was created for parsing HQL,
            //But works the same for HQL and SQL
            String excludeSelect =
                HQLStringParser.getHQLFragmentAfter( sqlQuery, FROM_CLAUSE );

       //Add the "select 1" string to the beginning and the "read only"
            //for performance
            selectConstant =
                SELECT_CONSTANT_CLAUSE + excludeSelect + READ_ONLY_CLAUSE;

            connection = getConnection(  );
            statement = connection.prepareStatement( selectConstant );

            //Use a private method that loops through a list of parameters and
            //sets them as Objects to the PreparedStatement
       //This is the next hook that I have to create into Hibernate
            //because their no functionality to pass in a HQL type
            //and retrieve the matching Java Type.  I need this
            //to correctly create the PreparedStatement
            this.setQueryParameters( statement, paramaters );

            //Execute the SQL
            resultSet = statement.executeQuery(  );

            //For speed, looping through the resultset is faster than using
   
            while ( ( rowCount <= ABSOLUTE_MAX_RESULTS ) && resultSet.next(  ) )
            {
                rowCount++;
            }

            if ( rowCount > ABSOLUTE_MAX_RESULTS )
            {
                ArchTracer.high( "Search query returned more than " +
                    ABSOLUTE_MAX_RESULTS + " results." );
                throw new MaximumResultsExceededException( "Returned too many rows: ",
                    "error.technical.persistence.MaximumResultsExceeded",
                    new Object[] { String.valueOf( ABSOLUTE_MAX_RESULTS ) } );
            }
        }
        catch ( SQLException sqle )
        {
            throw new DatabaseException( "The governed search query for max results limit failed",
                sqle, "error.database.QueryFailed" );
        }
        finally
        {
            JdbcHelper.closeAll( connection, statement, resultSet );
        }

        return rowCount;
    }



Thanks for the help...It would be nice if in Hibernate 3, there was extensibility to SessionImpl or SessionFactoryImpl that way I could have allowed the Hibernate architecture to work properly, just decorate or over the Find method in the SessionImpl to only return the list of QueryTranslators and not actually hit the database.

-jay


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jan 20, 2005 2:21 pm 
Hibernate Team
Hibernate Team

Joined: Mon Aug 25, 2003 9:11 pm
Posts: 4592
Location: Switzerland
Nobody knows what you want to do and why.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jan 20, 2005 2:33 pm 
Regular
Regular

Joined: Tue Nov 30, 2004 4:23 pm
Posts: 62
Sorry Christian...I had a previous post that talked about a website search strategy ( goverened strategy ) that was mentioned in a book you promote. The SQL Tuning book by O'Reilly. In there, they discuss when you have too many results being returned from a search, to propose a new search strategy. This strategy would run a purely optimized query to the database ( preferably using something like a select constant ) to see if the query would retrieve +1 record past the maximum allowable records. If so, you can send something to the user to let them know to specify more criteria. The benefit being that you did not have to do a full blown query of the data tables, only to find out you are returning too many rows...This is described in this post:

http://forum.hibernate.org/viewtopic.php?t=936975

The point being is that Hibernate does not have functionality to do a select constant and this is necessary for database performance of testing the maximum allowable search results.

In my situation, a developer is submitting one HQL statement, and I need to create two statements from it. One to test for the maximum results returned. And one to run the actual HQL statement, as long as the possible results is less then the maximum allowable results. This search page is totally general and searching millions of records, so if I sent through a normal select statement just to check the maximum allowable results, Hibernate would do a significant amount of object creation along with how the database would respond to retrieving results, possibly by creating temporary tables to construct the results. Then if there are too many results, I would inform the user and the process would start all over again when the put in new criteria.

Many databases, such as DB2 are optimized when running select constant type functionality. We have an architect on the project who has already performanced tested and published specs on the speed of implementing this purely in Java. I am trying to implement that type of search functionality in Hibernate. But without a select constant functionality, I need to translate HQL queries to SQL queries and HQL types to SQL types in order to run a JDBC query for the select constant.

Hope that makes sense...I really am enjoying using Hibernate, I am just trying to find the correct hook into the architecture.

Thanks

-jay


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