Hibernate Configuration / Hibernate Session

My Server part also has a hibernate configuration and hibernate session.
Is there any way to give that hibernate session to the HibernateDataSource ?

The main reason is that i need to “encrypt” the password of the hibernate.cfg.xml and therefore the HibernateDataSource fails on startup (as it is not included in the hibernate.cfg.xml)

Within my server code - the password is decrypted and then added to the Hibernate Configuration on runtime - so i need a method to “forward” my configuration to the HibernateDataSource - before this starts loading.

Is there any way ?

What are you doing, rewriting hibernate.cfg.xml at runtime? There are other approaches to making sure the password isn’t on disk, such as having Hibernate use a JNDI DataSource, which are probably preferable.

That said, if you must stick with your current approach, you should be able to have everything run in the right order if you modify hibernate.cfg.xml before you reference any of your HibernateDataSources. For example, have a servlet that you install that has load-on-startup set, similar to the Init servlet that comes with SmartGWT.

i am not rewriting the hibernate.cfg.xml as this would mean - again the password is on the disk - i am changing the Hibernate Configuration Object on runtime !

What i am doing is to (in more simple form -see below) - adding the parameters needed by hibernate at runtime (but not to the config file) - only to the hibernate Configuration object.

Now i need a way to pass that Configuration object to the HibernateDataSource - somehow like it is possible with the Spring – in the server.properties (i am not using spring)

hibernateConfig = new Configuration();
EncryptionReader reader = new EncryptionReader();
SecuredHibernateSettings settings = reader.getSecuredHibernateConfig();

Properties externalProperties= new Properties();
externalProperties.put("hibernate.connection.password", settings.getPassword());
externalProperties.put("hibernate.connection.username", settings.getUsername());

Ah, that makes sense. Use the “configBean” approach described here - this allows you to register your Configuration object as a Spring bean and have the HibernateDataSource look it up from Spring.

Thanks - that seems to be a solution !
Is there an example - or something - as i am actually not using spring !

Only to be shure - i have to configure in the server.properties (if my bean is called sessionFactory)

hibernate.config.lookupStyle: spring
hibernate.config.bean: sessionFactory

and additionally i need to add the “beanClass” into the datasource definition - right ??

br
johannes

i am now getting the following error - i am actually totaly wrong ??

i specified the credentials needed in the server.properties and in the DataSource !

java.lang.IllegalStateException: No WebApplicationContext found: no ContextLoaderListener registered?
	at org.springframework.web.context.support.WebApplicationContextUtils.getRequiredWebApplicationContext(WebApplicationContextUtils.java:70)
	at com.isomorphic.spring.SpringBeanFactory.getBeanFactory(SpringBeanFactory.java:45)
	at com.isomorphic.spring.SpringBeanFactory.getBean(SpringBeanFactory.java:51)
	at com.isomorphic.rpc.ServerObject.<init>(ServerObject.java:232)
	at com.isomorphic.rpc.ServerObject.<init>(ServerObject.java:70)
	at com.isomorphic.hibernate.HibernateDataSource.initStaticConfigAndSessionFactory(HibernateDataSource.java:351)

br
johannes

I actually tried it with the spring bean as follows:

i created the application context and used a PropertyPlaceholderConfigurer to configure the properties.

The SessionFactory is can be retrieved (i tried it within a servlet)!

But when i try to configure the smartclient package with - it seems that only the configuration is taken from the LocalSessionFactoryBean as the error that appears is that the jdbc.url is not set - which is not true - it is only set by the properties.

It seems that the smartclient - HibernateDataSource only gets the Configuration and then tries to build its own session - and does not load the Properties for the bean - can that be ??

br
johannes

Right, the session is not retrieved via Spring, only the Configuration is retrieved.

I tried it now and it is not working as expected:

i have a “normal” LocalSessioNFactoryBean and a datasource attached to it.
the datasource gets the information thru a PropertyPlaceholderConfigurer (which has an override for the password - to make it encrypted).

this starts and works perfectly in spring !

	<bean id="dataSource"
		class="org.springframework.jdbc.datasource.DriverManagerDataSource">
		<property name="driverClassName" value="${db.driver}" />
		<property name="url" value="${db.url}" />
		<property name="username" value="${db.username}" />
		<property name="password" value="${db.password}" />
	</bean>

	<bean id="sessionFactory"
		class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
		<property name="dataSource" ref="dataSource" />
		<property name="configLocation">
			<value>classpath:hibernate.cfg.xml</value>
		</property>
	</bean>

if i now set in the server.properties

hibernate.config.lookupStyle: spring
hibernate.config.bean: sessionFactory

i at the end get the following error (and nothing works) - which seems that the hiberante datasource is not loading the connection settings correctly - or do i have a mistake in my setup ??


org.hibernate.HibernateException: JDBC URL was not specified by property hibernate.connection.url
	at org.hibernate.connection.DriverManagerConnectionProvider.configure(DriverManagerConnectionProvider.java:98)
	at org.hibernate.connection.ConnectionProviderFactory.newConnectionProvider(ConnectionProviderFactory.java:143)
	at org.hibernate.connection.ConnectionProviderFactory.newConnectionProvider(ConnectionProviderFactory.java:84)
	at org.hibernate.cfg.SettingsFactory.createConnectionProvider(SettingsFactory.java:459)
	at org.hibernate.cfg.SettingsFactory.buildSettings(SettingsFactory.java:91)
	at org.hibernate.cfg.Configuration.buildSettingsInternal(Configuration.java:2831)
	at org.hibernate.cfg.Configuration.buildSettings(Configuration.java:2827)
	at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1838)
	at com.isomorphic.hibernate.HibernateDataSource.initStaticConfigAndSessionFactory(HibernateDataSource.java:396)
	at com.isomorphic.hibernate.HibernateDataSource.initConfigAndSessionFactory(HibernateDataSource.java:308)
	at com.isomorphic.hibernate.HibernateDataSource.init(HibernateDataSource.java:148)
	at com.isomorphic.datasource.BasicDataSource.fromConfig(BasicDataSource.java:134)
	at com.isomorphic.datasource.DataSource.fromConfig(DataSource.java:164)
	at com.isomorphic.datasource.FileSystemDSRepo.loadDS(FileSystemDSRepo.java:110)
	at com.isomorphic.datasource.DataSource.forName(DataSource.java:147)
	at com.isomorphic.datasource.DataSource.forName(DataSource.java:144)
	at com.isomorphic.datasource.DataSource.forName(DataSource.java:141)
	at com.isomorphic.datasource.PoolableDataSourceFactory.makeUnpooledObject(PoolableDataSourceFactory.java:89)
	at com.isomorphic.datasource.PoolableDataSourceFactory.makeObject(PoolableDataSourceFactory.java:96)
	at com.isomorphic.pool.PoolManager.borrowObject(PoolManager.java:76)
	at com.isomorphic.datasource.DataSourceManager.getDataSource(DataSourceManager.java:56)
	at com.isomorphic.servlet.DataSourceLoader.processRequest(DataSourceLoader.java:80)
	at com.isomorphic.servlet.DataSourceLoader.doGet(DataSourceLoader.java:64)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
	at com.isomorphic.servlet.BaseServlet.service(BaseServlet.java:152)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
	at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:487)
	at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:362)
	at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
	at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:181)
	at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:729)
	at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:405)
	at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
	at org.mortbay.jetty.handler.RequestLogHandler.handle(RequestLogHandler.java:49)
	at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
	at org.mortbay.jetty.Server.handle(Server.java:324)
	at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:505)
	at org.mortbay.jetty.HttpConnection$RequestHandler.headerComplete(HttpConnection.java:829)
	at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:513)
	at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:211)
	at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:380)
	at org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:395)
	at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:488)
[/CODE

i think there is a problem as - i found those lines in the logs, which seems that it still tries to load the cfg.xml file !

XML - Parsed XML from (in memory stream): 3ms
INFO  Configuration - configuring from XML document
DEBUG Configuration - hibernate.bytecode.use_reflection_optimizer=false
DEBUG Configuration - hibernate.connection.autocommit=true
DEBUG Configuration - hibernate.connection.provider_class=org.hibernate.connection.DriverManagerConnectionProvider
DEBUG Configuration - hibernate.connection.release_mode=auto

If you’ve got a hibernate.cfg.xml lying around as well (possibly the one from the SDK) remove that first if you intend to use Spring instead.

If you need further assistance, post the entire server-side log for the attempt to load Hibernate/Spring configuration, don’t trim it.

help would be nice as i work with that part now for several days not getting forward…

the hibernate.cfg.xml is there because - i have the configuration in it !
in the applicationContext (of spring) i have a datasource - which provides the “other” information - missing in the hibernate.cfg.xml !
so the hibernate.cfg.xml misses some parameters (the datasource) which are injected by the spring framework.

so my spring beans look like that:

	<bean id="dataSource"
		class="org.springframework.jdbc.datasource.DriverManagerDataSource">
		<property name="driverClassName" value="${db.driver}" />
		<property name="url" value="${db.url}" />
		<property name="username" value="${db.username}" />
		<property name="password" value="${db.password}" />
	</bean>

	<bean id="sessionFactory"
		class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
		<property name="dataSource" ref="dataSource" />
		<property name="configLocation">
			<value>classpath:hibernate.cfg.xml</value>
		</property>
	</bean>

therefore the connection informations like (url, driver, username, password) is seperated from the hibernate.cfg.xml (and missing in there)

the LocalSessionFactoryBean reads the hibernate.cfg.xml and gets the settings for the datasource (url, driver, username, password) - which then combines it into the “real” Configuration Object !

in my own servlet i tried to connect thru that SessionFactory and everything seems fine.

if i call that bean in my test servlet like

ctx.getBean("&sessionFactory");
and then issue a getConfiguration(); i get the config - and can build a SessionFactory out of that

my server.properties has those entries

hibernate.config.lookupStyle: spring
hibernate.config.bean: sessionFactory

but something goes wrong - as it seems that the SmartClient package gets not the “combined” Configuration out of the spring bean.

attached is the serverside log

smartClientServerLog.txt (12.9 KB)

i now tried to remove the “datasource” from the spring bean and place all the properties into the sessionFactory bean.

	<bean id="sessionFactory"
		class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
		<property name="configLocation">
			<value>classpath:hibernate.cfg.xml</value>
		</property>
		<property name="hibernateProperties">
			<props>
				<prop key="hibernate.dialect">com.amergy.cmt.server.mssql.MSDialect</prop>
				<prop key="hibernate.show_sql">true</prop>
				<prop key="hibernate.generate_statistics">true</prop>
				<prop key="hibernate.connection.url">jdbc:sqlserver://testserver:1433;databaseName=test</prop>
				<prop key="hibernate.connection.username">${db.username}</prop>
				<prop key="hibernate.connection.password">${db.password}</prop>
				<prop key="hibernate.connection.driver_class">com.microsoft.sqlserver.jdbc.SQLServerDriver</prop>	
			</props>
		</property>
	</bean>

i made a servlet which is loaded on startup and executes that code

			ctx = WebApplicationContextUtils.getRequiredWebApplicationContext(config.getServletContext());
			LocalSessionFactoryBean bean = (LocalSessionFactoryBean) ctx.getBean("&sessionFactory");
			Configuration dbConfig = bean.getConfiguration();
			SessionFactory factory = dbConfig.buildSessionFactory();
			Session session = factory.openSession();

then i even execute a query with it - and everything works fine.

i then “again” tried to change the settings in the server.properties to

hibernate.config.lookupStyle: spring
hibernate.config.bean: sessionFactory

i then get the error that the URL is not specified in the config (see below) !!!
why - it is in - and it even works, whats wrong - i have no idea any more ??
what can i test to find it out - can someone help - someone who made that with spring already ?

thanks

org.hibernate.HibernateException: JDBC URL was not specified by property hibernate.connection.url
	at org.hibernate.connection.DriverManagerConnectionProvider.configure(DriverManagerConnectionProvider.java:98)
	at org.hibernate.connection.ConnectionProviderFactory.newConnectionProvider(ConnectionProviderFactory.java:143)
	at org.hibernate.connection.ConnectionProviderFactory.newConnectionProvider(ConnectionProviderFactory.java:84)
	at org.hibernate.cfg.SettingsFactory.createConnectionProvider(SettingsFactory.java:459)
	at org.hibernate.cfg.SettingsFactory.buildSettings(SettingsFactory.java:91)
	at org.hibernate.cfg.Configuration.buildSettingsInternal(Configuration.java:2831)
	at org.hibernate.cfg.Configuration.buildSettings(Configuration.java:2827)
	at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1838)
	at com.isomorphic.hibernate.HibernateDataSource.initStaticConfigAndSessionFactory(HibernateDataSource.java:396)
	at com.isomorphic.hibernate.HibernateDataSource.initConfigAndSessionFactory(HibernateDataSource.java:308)
	at com.isomorphic.hibernate.HibernateDataSource.init(HibernateDataSource.java:148)
	at com.isomorphic.datasource.BasicDataSource.fromConfig(BasicDataSource.java:134)
	at com.isomorphic.datasource.DataSource.fromConfig(DataSource.java:164)
	at com.isomorphic.datasource.FileSystemDSRepo.loadDS(FileSystemDSRepo.java:110)
	at com.isomorphic.datasource.DataSource.forName(DataSource.java:147)
	at com.isomorphic.datasource.DataSource.forName(DataSource.java:144)
	at com.isomorphic.datasource.DataSource.forName(DataSource.java:141)
	at com.isomorphic.datasource.PoolableDataSourceFactory.makeUnpooledObject(PoolableDataSourceFactory.java:89)
	at com.isomorphic.datasource.PoolableDataSourceFactory.makeObject(PoolableDataSourceFactory.java:96)
	at com.isomorphic.pool.PoolManager.borrowObject(PoolManager.java:76)
	at com.isomorphic.datasource.DataSourceManager.getDataSource(DataSourceManager.java:56)
	at com.isomorphic.servlet.DataSourceLoader.processRequest(DataSourceLoader.java:80)
	at com.isomorphic.servlet.DataSourceLoader.doGet(DataSourceLoader.java:64)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
	at com.isomorphic.servlet.BaseServlet.service(BaseServlet.java:152)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
	at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:487)
	at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:362)
	at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
	at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:181)
	at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:729)
	at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:405)
	at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
	at org.mortbay.jetty.handler.RequestLogHandler.handle(RequestLogHandler.java:49)
	at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
	at org.mortbay.jetty.Server.handle(Server.java:324)
	at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:505)
	at org.mortbay.jetty.HttpConnection$RequestHandler.headerComplete(HttpConnection.java:829)
	at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:513)
	at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:211)
	at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:380)
	at org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:395)
	at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:488)

i am a little but further - i got the problem solved as the movement between the spring and the hibernate.cf.xml has to be done “only” on some points and some hibernate properties need to stay in the xml file while others need to be in the spring configuration.

so the actual spring config is

	<bean id="sessionFactory"
		class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
		<property name="configLocation">
			<value>classpath:hibernate.cfg.xml</value>
		</property>
		<property name="hibernateProperties">
			<props>
				<prop key="hibernate.dialect">com.amergy.cmt.server.mssql.MSDialect</prop>
				<prop key="hibernate.show_sql">true</prop>
				<prop key="hibernate.generate_statistics">true</prop>
				<prop key="hibernate.connection.url">jdbc:sqlserver://testserver:1433;databaseName=cmt</prop>
				<prop key="hibernate.connection.username">test</prop>
				<prop key="hibernate.connection.password">test</prop>
				<prop key="hibernate.connection.driver_class">com.microsoft.sqlserver.jdbc.SQLServerDriver</prop>
				<prop key="hibernate.connection.provider_class">org.hibernate.connection.DriverManagerConnectionProvider</prop>
			</props>
		</property>
	</bean>

and the hibernate.cfg.xml holds the mapped classes and the dialect settings.

now the isomorphic packages are starting up - but when i try to acess a datasource - i get the error that the entity “test” cannot be found ??

i have no entity with that name - only the datasoure .ds file is named that way !

do i also need to change the datasource.ds file ??

Using Smart GWT Pro 3.0.

Have a question similar to original poster, but it sounds like he or she ended up using Spring.

To make a long story short, I have an external JAR I’m including in my project that requires Hibernate and is currently creating its own SessionFactory and Session using a hibernate config file included in the JAR.

I’m using Smart GWT hibernate Datasources and they require having a Hibernate configuration file in the class path.

What I’d like to do is instruct Smart GWT to use the hibernate config file in the included external JAR. I’ve read in various places that if you are using Spring you can set properties in server.properties to inject the hibernate configuration file from Spring, but we are not using Spring and I don’t think it makes sense to move towards Spring just for this purpose.

Is anybody aware of a way to overcome this situation?

It’s not quite clear where the perceived problem is.. take a look at the Hibernate Integration docs - config can come from .cfg.xml, annotations, or a Spring-provided bean.

If you don’t want to use one of these methods, can you suggest some (fictitious for now) settings that would help you solve your current problem?

First off, thanks for the reply. I’m impressed with the responsiveness of Isomorphic staff and it’s one of the reasons we’ve talked so highly about Smart GWT to our customers.

Second, I read the Hibernate Integration previously and this is the documentation I believe you were referring to:

You can provide Hibernate configuration to the Smart GWT server in three ways:     

   You can place a traditional hibernate.cfg.xml file somewhere on the classpath
    You can have Smart GWT look up a Hibernate Configuration to use. This works in the same way as a ServerObject, and in fact makes use of the ServerObject code. To do this, add ServerObject-compliant properties to your server.properties file, prefixed with hibernate.config. For example:

             hibernate.config.lookupStyle: spring
             hibernate.config.bean: mySessionFactory
      

    You can provide a Hibernate configuration at the level of individual DataSources, by specifying a configBean on the dataSource (this is only applicable if you are using Spring; see below)

Perhaps, I’m mis-interpreting this section, but it sounds like there are three ways to configure hibernate, but the last two both require Spring. So that leaves only the first option of placing a hibernate.cfg.xml file on the build path.

There is a hibernate.cfg.xml file in one of the jars included in the web app and available on the class path and we could use that, but when I remove the ‘SmartGWT-specific’ hibernate.cfg.xml file from the webapp/WEB-INF classes directory, I get the following exception:

java.io.FileNotFoundException: /Users/v3ventures/Documents/Projects/Blackpoint/WizardSleeve/Code/V3/WizardSleeveV3/gwt/src/main/webapp/WEB-INF/classes/hibernate.cfg.xml (No such file or directory)
	at java.io.FileInputStream.open(Native Method)

So although we do have a valid .cfg.xml file on the classpath, it appears SmartGWT expects it to be in webapp/WEB-INF/classes and not say in WEB-INF/lib or even a jar in webapp/WEB-INF/classes.

Ideally, what we’d like is to be able to use the Smart GWT hibernate configuration lookup style, but point it to a class on the classpath that has the standard Hibernate Factory methods (getSessionFactory(), getConfiguration() etc.) implemented.

So something like:

             hibernate.config.lookupStyle: bean (or maybe classpath)
             hibernate.config.bean: com.blah.blah.HibernateUtil

And HibernateUtil implements a getConfiguration() and getSessionFactory() that the Smart GWT components can then use.

Perhaps this is currently feasible but I’m configuring things incorrectly. Thoughts?

The rationale behind this is we have a web-app where several libraries need database/hibernate access. So instead of having to manage and control 3 or 4 different hibernate configurations and have multiple sessionFactories running around it would be nice to just point everything to a single hibernate configuration file.

That facility (looking up Hibernate configuration from some class available on the classpath) is exactly what our Spring-based lookup achieves. We would just recommend using Spring to do this. It doesn’t imply that you need to change anything about how any other parts of your app behave.