Showing posts with label hibernate. Show all posts
Showing posts with label hibernate. Show all posts

Tuesday, October 23, 2012

Stop Hibernate info level logging to Console in WebSphere

Keywords:
websphere hibernate logging info commons logging log4j info SystemOut.log Console stdout WAS7 WAS8.5

Problem:
The application is packaged with hibernate and configured with log4j logging (to a rolling, application-specific file - hibernate set to WARN level logging) and deployed to WebSphere with parent last class loading.

Despite all this info-level messages are being output to the WebSphere system-out/console log (in WAS_HOME\profiles\[profile_name]\logs\[server_name]\SystemOut.log).

Why is the application log4j configuration (in log4j.properties) being ignored and how can the application's hibernate logging be diverted away from the console?

Solution:
Various resources on the web describe configuring WebSphere logging or hibernate logging but the bottom of this post on Hibernate and Logging specifically describes this 'leaking' of log configuration/output and how to resolve it.

Create a commons-logging.properties with the content:
org.apache.commons.logging.Log=org.apache.commons.logging.impl.Log4JLogger
... and put this file in the application's classpath (WEB-INF/classes for example).



Notes:
By default, WebSphere Application Server is installed to use info level tracing (for all loggers that it knowns about). In WAS 8.5 you'll see this in the SystemOut.log:
[22/10/12 12:00:00:000 EST] 00000001 ManagerAdmin  I   TRAS0017I: The startup trace state is *=info.

You can edit this by going to (in WAS 8.5) Application Servers > [server_name] > Troubleshooting | Change log detail levels. You can specify the logging definition in plain text. For example, turning default logging to audit-level and disabling logging for the verbose com.ibm.ws.webcontainer.annotation module (this is a ':' delimited list):
*=audit: com.ibm.ws.webcontainer.annotation=off

Alternatively, use the "Components and Groups" section of the interface to expand items of the "tree" and right-click to select custom logging levels for a given "node" (NB for log4j users, the log levels may not match log4j - eg "audit" and "warning" instead of "warn").

Also interesting to note is that without the commons-logging.properties file defined in your web-app you will see every package from your application(s) and their libraries (where classes include logging definitions) included in this "Components and Groups" interface. Therefore if you see org.hibernate.* disappear from this interface you can be certain the configuration has worked.



Friday, April 20, 2012

Running Native SQL deletes or updates via Hibernate

Keywords:
hibernate manual native SQL update delete bulkUpdate child table spring

Problem:
Probably not the best idea but for performance, limitations in hibernate mappings or errors in the objects you find it'd be much easier to just run some manual SQL. Can you do this via hibernate?

Solution:
Yes you can, hibernate call this "Native SQL". This is fairly well document, but I noticed its missing an example of doing a manual update/delete - where the result is not going to give you a list() of anything.

For Query you make via createSQLQuery(...), use executeUpdate() which returns the number of rows effected.

Here an example (using the CATS/DOGS table names from the hibernate document):
Query deleteQuery = session.createSQLQuery(
    "delete from CATS "
    + "where DOG_ID in ( "
        + "select d.ID from DOGS d "
        + "where d.STATUS = ?)");
deleteQuery.setString(0, "VICIOUS");
int updated = deleteQuery.executeUpdate();

If you're integrating with hibernate via spring, the same can be done via the template-callback mechanism (where your DAO extends org.springframework.orm.hibernate3.support.HibernateDaoSupport):
Integer deletedData = (Integer)getHibernateTemplate().execute(new HibernateCallback () {
    public Object doInHibernate(Session session) throws HibernateException, SQLException {
        // delete the data
        Query deleteQuery = session.createSQLQuery(
            "delete from CATS "
            + "where DOG_ID in ( "
                + "select d.ID from DOGS d "
                + "where d.STATUS = ?)");
        deleteQuery.setString(0, "VICIOUS");
        int updated = deleteQuery.executeUpdate();
    }
});
if (log.isDebugEnabled()) {
    log.debug("rows deleted from CATS: " + deletedData);
}

Notes:
If you're wondering if you can avoid hard coding the table references by asking hibernate for the table-name mapping, this does seem possible - Get the table name from the model in Hibernate - but this approach doesn't seem to be "public" so may disappear.


Tuesday, September 08, 2009

Is Eclipse deleting XML resources from my build path?

Keywords:
eclipse 3.4.0 ganymede FileNotFoundException xml properties build classpath filtered resources deleted excluded "class path resource cannot be resolved"

Problem:
I have a project where configuration resources (mostly hibernate - hibernate.cfg.xml & *.hbm.xml) exist in the same folders as the java source and it's expected that these are copied to the build output so they can be loaded from the classpath.

It seems eclipse is "cleaning up" the XML files from the build output folder. Check the include/exclude settings on the project and Included is set to (All). Adding *.xml explicitly to the included list makes no difference.

Out of curiosity, manually copying an XML file to the build output folder and refreshing the project causes the XML to be deleted. Why?

Solution:
I'm not sure if it was an update or plugin that caused this, but the problem is with the Filtered Resources setting.

In Window -> Preferences:
go to: Java > Compiler > Building
in Output folder section:
  • check the Filtered resources value
  • if *.xml is in the comma separated list, this is the cause.
    Remove from the list and allow the Project rebuild.

As mentioned, even if you explicitly add *.xml to be included in your Project settings the above global setting will cause it to be excluded.