We have a web application running in a production enviroment and at some point the client complained about how slow the application got.
When we checked what was goi
As pointed out by @BalusC, this query is performed during schema validation. But validation is usually done once for all when creating the SessionFactory
(if activated). Do you call the following method explicitely: Configuration#validateSchema(Dialect, DatabaseMetadata)
?
Now, is that correct? It's there a way for me to configure the OC4J for it to instantiate filters only once?
Your implementation of the Open Session In View looks fine (and is very close to the one suggested in this page). And according to the Servlet specification only one instance per <filter>
declaration in the deployment descriptor is instantiated per Java Virtual Machine (JVMTM) of the container. Since it is very unlikely that this isn't the case with OC4J, I'm tempted to say that there must something else.
Can you put some logging in the filter? What about making the SessionFactory
static (in a good old HibernateUtil
class)?
Specifically what happens is that folks who write software that support different databases package their software in a database neutral way. ie. when an override isn't present what they do is use jdbc db metadata getTables call to check if the connection is still valid. Typically you override with select * from dual etc but when that's not done or you don't specifically say what kind of database you are using the software is written to run something that will work with any JDBC driver. jdbc db metadatabase getTables will do that.
I just wanted to put in the workaround I used to get around this problem. We typically have lots of schemas in our databases and this would take hours to finish in the application we were trying to use which used hibernate because of the large number of objects that it ended up checking (the query itself would execute fast but it just did so many of them).
What I did is overrode the ALL_OBJECTS view in the schema being connected to so that it only brought back it's own objects and not all objects in the db.
e.g.
CREATE OR REPLACE VIEW ALL_OBJECTS AS SELECT USER OWNER, O.* FROM USER_OBJECTS O;
It's not the greatest solution but for this application there is nothing else that would be using the ALL_OBJECTS view so it works fine and starts up substantially faster.
Had the same problem, the cause was exactly the one described by Bob Breitling, C3P0 uses by default JDBC API for connection testing :
java.sql.DatabaseMetaData#getTables(....)
In order to change this behavior the preferredTestQuery must be set, or if C3P0 is used through hibernate - hibernate.c3p0.preferredTestQuery
I believe this query is coming from the Oracle JDBC driver to implement a Hibernate request to retrieve database object info through DatabaseMetaData.
This query shouldn't be too expensive, or at least isn't on a system I have handy. What's your count of all_objects and more importantly, what do you see in the rows/bytes total for the explain plan?
It's indeed coming from Hibernate and specifically org.hibernate.tool.hbm2ddl.TableMetadata
. It's under each been used to validate the schema (table and column mapping). Apparently it's unnecessarily been executed on every spawned request or session instead of only once during application's startup. Are you for example not unnecessarily calling the Hibernate Configurator on every request or session?