PDA

View Full Version : Issues: XML Application Context with / vs hibernate.cfg.xml



wfarnaby
Sep 27th, 2004, 03:11 PM
Consider the following:

<!-- Hibernate SessionFactory -->
<bean
id="sessionFactory"
class="org.springframework.orm.hibernate.LocalSessionFact oryBean">
<property name="dataSource"><ref local="dataSource"/></property>
<property name="mappingResources">
<value>petclinic.hbm.xml</value>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
</props>
</property>
</bean>

Don't we also have to be able (if we want) to specify Hibernate "class-cache" and "collection-cache" elements (for any number of classes) here in this session factory bean definition... otherwise we'd still need an external Hibernate configuration file, e.g., "hibernate.config.xml"?

This brings me to my next question. Above, we declare a session factory as a Spring bean, named "sessionFactory". If I want/need to reference a separate Hibernate configuration file, e.g., ...

(Spring XML App Context):

<!-- Hibernate SessionFactory -->
<bean
id="sessionFactory"
class="org.springframework.orm.hibernate.LocalSessionFact oryBean">
<property name="dataSource"><ref local="dataSource"/></property>
<property name="configLocation">
<value>classpath:hibernate.cfg.xml</value>
</property>
</bean>

hibernate.config.xml:

<hibernate-configuration>
<session-factory name="hibernate/SomeSessionFactory">
...
</session-factory>
</hibernate-configuration>

... then, how can I end up with the one session factory ("sessionFactory", reified as a Spring bean) that I actually want, when, by using hibernate.cfg.xml, I have to declare another, JNDI-bound, session factory?

Thanks for any help that you can offer for these questions.

irbouho
Sep 27th, 2004, 10:08 PM
Don't we also have to be able (if we want) to specify Hibernate "class-cache" and "collection-cache" elements (for any number of classes) here in this session factory bean definition... otherwise we'd still need an external Hibernate configuration file, e.g., "hibernate.config.xml"?
You can define cache properties at the class level (inside petclinic.hbm.xml)
Take a look at 14.3. The Second Level Cache (http://www.hibernate.org/hib_docs/reference/en/html/performance.html#performance-cache)


... then, how can I end up with the one session factory ("sessionFactory", reified as a Spring bean) that I actually want, when, by using hibernate.cfg.xml, I have to declare another, JNDI-bound, session factory?
Spring LocalSessionFactoryBean creates a hibernate Configuration and passes it the configuration attributes you define in your applicationContext.xml. So if you provide a configLocation, LocalSessionFactoryBean will pass its value to Configuration and retrieves the resulting Hibernate SessionFactory to make it available to your application.

wfarnaby
Sep 28th, 2004, 12:55 AM
Thanks for your response.

So, the situation as I understand it is, there's only one SessionFactory created by Spring and available via ' <bean id="sessionFactory"...', and, if I supply the optional "name" attribute of the "session-factory" element in hibernate.cfg.xml, then that same SessionFactory singleton instance is also bound by Hibernate in the JNDI registry at "name"... correct?

wfarnaby
Sep 28th, 2004, 01:02 AM
Also, regarding the first point, as you say one can "define cache properties at the class level" in each mapping file. But it's nice to do everything for every class in one spot (in hibernate.cfg.xml, as the author mentions in Hibernate in Action) and currently Spring will not support this; i.e. Spring application context lets you specify Hibernate properties and mappings (so if these are the only things you want to do, you can dispense with hibernate.cfg.xml), but not class and collection cache configuration.

Juergen Hoeller
Sep 28th, 2004, 09:41 AM
Indeed, Spring does currently not support cache definitions at the SessionFactory level. Note that you can easily combine properties defined on LocalSessionFactoryBean with ones defined in hibernate.cfg.xml, provided that you load the latter via "configLocation" (as you've done above), so that shouldn't be a big issue.

That said, I do consider adding support for such cache definitions to LocalSessionFactoryBean. However, this will happen for Spring 1.1.2 at the earliest (not for 1.1.1 which is scheduled for release tomorrow).

For the time being, simply keep your hibernate.cfg.xml as minimal as possible in such a scenario. Or alternatively, put as much as possible in hibernate.cfg.xml and define a LocalSessionFactoryBean with just "configLocation" and possibly "dataSource".

If you specify a "name" in hibernate.cfg.xml, Hibernate will try to bind the SessionFactory to JNDI. You shouldn't need to this in normal circumstances, as your Spring context holds a reference to the SessionFactory anyway.

Juergen

Colin Sampaleanu
Sep 29th, 2004, 01:42 PM
Personally I don't think it's unreasonable that people have to use the 'combined' approach, i.e. the more major properties come from the LocalSessionFactory definition, but more obscure ones need to be added in hibernate.cfg.xml which get's combined. It's not necessarilly desirable or realistic for Spring to support all the properties possible in the latter file.

lenny
Apr 13th, 2005, 05:18 PM
Indeed, Spring does currently not support cache definitions at the SessionFactory level. Note that you can easily combine properties defined on LocalSessionFactoryBean with ones defined in hibernate.cfg.xml, provided that you load the latter via "configLocation" (as you've done above), so that shouldn't be a big issue.

Juergen

I just ran into a problem with this approach. Using spring-framework-1.2-rc1 and Hibernate3. LocalSessionFactoryBean configures the configFile if present before loading the mappings. If there are any cache-class elements in the config file, Configuration winds up looking for the associated mapping file and throwing a NullPointerException.

java.lang.NullPointerException
at org.hibernate.cfg.Configuration.setCacheConcurrenc yStrategy(Configuration.java:1469)
at org.hibernate.cfg.Configuration.parseSessionFactor y(Configuration.java:1290)
at org.hibernate.cfg.Configuration.doConfigure(Config uration.java:1266)
at org.hibernate.cfg.Configuration.doConfigure(Config uration.java:1233)
at org.hibernate.cfg.Configuration.configure(Configur ation.java:1176)
at org.springframework.orm.hibernate3.LocalSessionFac toryBean.afterPropertiesSet(LocalSessionFactoryBea n.java:448)
at org.springframework.beans.factory.support.Abstract AutowireCapableBeanFactory.invokeInitMethods(Abstr actAutowireCapableBeanFactory.java:1075)
at org.springframework.beans.factory.support.Abstract AutowireCapableBeanFactory.createBean(AbstractAuto wireCapableBeanFactory.java:349)
at org.springframework.beans.factory.support.Abstract AutowireCapableBeanFactory.createBean(AbstractAuto wireCapableBeanFactory.java:257)
at org.springframework.beans.factory.support.Abstract BeanFactory.getBean(AbstractBeanFactory.java:222)
at org.springframework.beans.factory.support.Abstract BeanFactory.getBean(AbstractBeanFactory.java:146)
at org.springframework.beans.factory.support.DefaultL istableBeanFactory.preInstantiateSingletons(Defaul tListableBeanFactory.java:285)
at org.springframework.context.support.AbstractApplic ationContext.refresh(AbstractApplicationContext.ja va:317)
at org.springframework.web.context.support.AbstractRe freshableWebApplicationContext.refresh(AbstractRef reshableWebApplicationContext.java:131)
at org.springframework.web.context.ContextLoader.crea teWebApplicationContext(ContextLoader.java:224)
at org.springframework.web.context.ContextLoader.init WebApplicationContext(ContextLoader.java:150)
at org.springframework.web.context.ContextLoaderListe ner.contextInitialized(ContextLoaderListener.java: 48)
at org.apache.catalina.core.StandardContext.listenerS tart(StandardContext.java:3827)
at org.apache.catalina.core.StandardContext.start(Sta ndardContext.java:4343)
at org.apache.catalina.core.StandardContext.reload(St andardContext.java:3043)
at org.apache.catalina.manager.ManagerServlet.reload( ManagerServlet.java:1014)
at org.apache.catalina.manager.ManagerServlet.doGet(M anagerServlet.java:330)
at javax.servlet.http.HttpServlet.service(HttpServlet .java:689)
at javax.servlet.http.HttpServlet.service(HttpServlet .java:802)
at org.apache.catalina.core.ApplicationFilterChain.in ternalDoFilter(ApplicationFilterChain.java:237)
at org.apache.catalina.core.ApplicationFilterChain.do Filter(ApplicationFilterChain.java:157)
at org.apache.catalina.core.StandardWrapperValve.invo ke(StandardWrapperValve.java:214)
at org.apache.catalina.core.StandardValveContext.invo keNext(StandardValveContext.java:104)
at org.apache.catalina.core.StandardPipeline.invoke(S tandardPipeline.java:520)
at org.apache.catalina.core.StandardContextValve.invo keInternal(StandardContextValve.java:198)
at org.apache.catalina.core.StandardContextValve.invo ke(StandardContextValve.java:152)
at org.apache.catalina.core.StandardValveContext.invo keNext(StandardValveContext.java:104)
at org.apache.catalina.authenticator.AuthenticatorBas e.invoke(AuthenticatorBase.java:540)
at org.apache.catalina.core.StandardValveContext.invo keNext(StandardValveContext.java:102)
at org.apache.catalina.core.StandardPipeline.invoke(S tandardPipeline.java:520)
at org.apache.catalina.core.StandardHostValve.invoke( StandardHostValve.java:137)
at org.apache.catalina.core.StandardValveContext.invo keNext(StandardValveContext.java:104)
at org.apache.catalina.valves.ErrorReportValve.invoke (ErrorReportValve.java:117)
at org.apache.catalina.core.StandardValveContext.invo keNext(StandardValveContext.java:102)
at org.apache.catalina.valves.AccessLogValve.invoke(A ccessLogValve.java:535)
at org.apache.catalina.core.StandardValveContext.invo keNext(StandardValveContext.java:102)
at org.apache.catalina.authenticator.SingleSignOn.inv oke(SingleSignOn.java:417)
at org.apache.catalina.core.StandardValveContext.invo keNext(StandardValveContext.java:102)
at org.apache.catalina.core.StandardPipeline.invoke(S tandardPipeline.java:520)
at org.apache.catalina.core.StandardEngineValve.invok e(StandardEngineValve.java:109)
at org.apache.catalina.core.StandardValveContext.invo keNext(StandardValveContext.java:104)
at org.apache.catalina.core.StandardPipeline.invoke(S tandardPipeline.java:520)
at org.apache.catalina.core.ContainerBase.invoke(Cont ainerBase.java:929)
at org.apache.coyote.tomcat5.CoyoteAdapter.service(Co yoteAdapter.java:160)
at org.apache.coyote.http11.Http11Processor.process(H ttp11Processor.java:799)
at org.apache.coyote.http11.Http11Protocol$Http11Conn ectionHandler.processConnection(Http11Protocol.jav a:705)
at org.apache.tomcat.util.net.TcpWorkerThread.runIt(P oolTcpEndpoint.java:577)
at org.apache.tomcat.util.threads.ThreadPool$ControlR unnable.run(ThreadPool.java:683)
at java.lang.Thread.run(Thread.java:552)



Here was my beans file:

<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFac toryBean">
<property name="mappingJarLocations">
<list>
<value>WEB-INF/lib/eop-hibernate.jar</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.Oracle9Dialect</prop>
<prop key="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</prop>
</props>
</property>
<property name="dataSource">
<ref bean="dataSource"/>
</property>
<property name="configLocation">
<value>classpath:hibernate.cfg.xml</value>
</property>
</bean>


Hibernate Config:

<hibernate-configuration>
<session-factory>
<class-cache class="org.aps.eop.model.manuscript.Marker"
usage="read-write"/>
</session-factory>

</hibernate-configuration>

From org.hibernate.cfg.Configuration

void setCacheConcurrencyStrategy(String clazz, String concurrencyStrategy, String region)
throws MappingException {
RootClass rootClass = getRootClassMapping( clazz );
rootClass.setCacheConcurrencyStrategy( concurrencyStrategy );
}

I wanted to be able to easily control the caching strategy on a per application basis which is definitely easier to do if the cache usage is not specified in the mapping files themselves.

carl
Oct 26th, 2006, 08:47 AM
Has this been resolved in Spring 2.0?

thanks
Carl