Spring – Hibernate mapping resource cannot be opened because it does not exist in a Spring + Hibernate Maven project

hibernatemavenspring

I am doing a Spring/Hibernate application using annotations to autowire the Service and Repository layers and have less configuration. All that seems to be done successfully since when I run the app everything seems initialized appropriately.

Problem

However, when I add the mapping resources in my applicationContext-datasource.xml I get an Error stating that the SessionFactory could not be properly initialized because it can seem to find my pojo.hbm.xml file. See:

Caused by: java.io.FileNotFoundException: class path resource [com/dariopardo/jfreechartdemo/pojo/Grid.hbm.xml] cannot be opened because it does not exist

Setup

applicationContext-datasource.xml

This file is located under src/main/resources/META_INF/spring

  <?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:lang="http://www.springframework.org/schema/lang"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:task="http://www.springframework.org/schema/task"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
    http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd
    http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd
    http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang-3.0.xsd
    http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
    http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd
    http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
    http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd"
    default-autowire="byName">

  <context:annotation-config/>

  <tx:annotation-driven/>

  <context:component-scan base-package="com.dariopardo.jfreechartdemo.service">
    <context:include-filter type="annotation"
        expression="org.springframework.stereotype.Service"/>
 </context:component-scan>

 <context:component-scan base-package="com.dariopardo.jfreechartdemo.dao">
    <context:include-filter type="annotation"
        expression="org.springframework.stereotype.Repository"/>
 </context:component-scan>

 <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
    <property name="driverClassName" value="oracle.jdbc.OracleDriver" />
    <property name="url" value="jdbc:oracle:thin:@myserverhere:1521:mydb" />
    <property name="username" value="myusername" />
    <property name="password" value="mypwd" />
 </bean>

 <!-- Hibernate SessionFactory for k12-->
<!--<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> -->
    <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
    <property name="dataSource"><ref local="dataSource"/></property>
    <property name="mappingResources">
        <list>                                            
            <value>com/dariopardo/jfreechartdemo/pojo/Grid.hbm.xml</value>               
        </list>
    </property>
    <property name="hibernateProperties">
         <props>
        <prop key="hibernate.bytecode.use_reflection_optimizer">false</prop>
        <prop key="hibernate.cache.provider_class">org.hibernate.cache.HashtableCacheProvider</prop>
        <prop key="hibernate.cache.use_second_level_cache">true</prop>
        <prop key="hibernate.cache.region_prefix">hibernate.k12</prop>
        <prop key="hibernate.cglib.use_reflection_optimizer">false</prop>
        <prop key="hibernate.connection.driver_class">oracle.jdbc.driver.OracleDriver</prop>
        <prop key="hibernate.connection.pool_size">1</prop>
        <!-- <prop key="hibernate.current_session_context_class">thread</prop>  -->
        <prop key="hibernate.default_schema">K12INTEL_DW</prop>
        <prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop>
        <prop key="hibernate.format_sql">true</prop>
        <prop key="hibernate.generate_statistics">true</prop>
        <prop key="hibernate.jdbc.batch_versioned_data">true</prop>
        <prop key="hibernate.jdbc.use_streams_for_binary">true</prop>
        <prop key="hibernate.max_fetch_depth">1</prop>
        <prop key="hibernate.proxool.pool_alias">pool_K12</prop>
        <prop key="hibernate.query.substitutions">yes 'Y', no 'N'</prop>
        <prop key="hibernate.show_sql">false</prop>
        <prop key="hibernate.transaction.auto_close_session"></prop>
        <prop key="hibernate.transaction.flush_before_completion"></prop>
        <prop key="hibernate.use_sql_comments">true</prop>
    </props>
    </property>
    <property name="eventListeners">
        <map>
            <entry key="merge">
                <bean class="org.springframework.orm.hibernate3.support.IdTransferringMergeEventListener"/>
            </entry>
        </map>
    </property>
</bean>


<!-- Transaction manager for a single Hibernate SessionFactory (alternative to JTA) -->
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager" p:sessionFactory-ref="sessionFactory"/>

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

<!-- The definition of the Root Spring Container shared by all Servlets and Filters -->
<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/spring/root-context.xml
                 classpath*:META-INF/spring/applicationContext*.xml                  
    </param-value>
</context-param>

<!-- Creates the Spring Container shared by all Servlets and Filters -->
<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<!-- Processes application requests -->
<servlet>
    <servlet-name>appServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>appServlet</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

My POJO

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.dariopardo.jfreechartdemo.pojo">

<class name="Grid">
    <cache usage="read-only" />
    <id name="c1"/>
    <property name="c2"></property>
    <property name="c3"></property>
</class>

<sql-query name="studentAttendanceOver95Pct">
    <return alias="p" class="com.dariopardo.jfreechartdemo.pojo.Grid">
     <return-property name="c1" column="school"/>
     <return-property name="c2" column="at_risk"/>
     <return-property name="c2" column="not_at_risk"/>
     </return>
     My custom sql query goes here
</sql-query>   

My DAO layer

@Repository
public class K12DaoImpl extends HibernateDaoSupport implements K12DaoManager{

@Autowired
public K12DaoImpl(SessionFactory sessionFactory) {
    super.setSessionFactory(sessionFactory);
}

@Override
public List<Grid> getAttendanceBySchoolOver95Pct() {

    List<Grid> list =    getHibernateTemplate().findByNamedQuery("studentAttendanceOver95Pct");
    return list;
}
}

My Service Layer

@Service
public class K12ManagerImpl implements K12Manager {

@Resource
private K12DaoManager k12DaoManager;

@Override
public List<Grid> studentPctAttendance() {

    return k12DaoManager.getAttendanceBySchoolOver95Pct();
}
}

If I comment the the hbm.xml in the mappingResources section everything seems to wire up correctly, but as soon as I bring any hbm.xml file in the mapping resources section the application fails to initialize.

Any thoughts?

Thanks,
– Dario

Best Answer

You specified a location for a mapping file:

<property name="mappingResources">
    <list>                                            
        <value>com/dariopardo/jfreechartdemo/pojo/Grid.hbm.xml</value>               
    </list>
</property>

Hence it is looking for a mapping file under that directory: com/dariopardo/jfreechartdemo/pojo. Create this directory, if it is not there, place the file there, and it is going to work.


To clean up and decouple your Spring configuration from Hibernate, you can create a separate Hibernate config, where you would specify your mapped classes, mapping locations, and more:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>  

        <mapping package="org.gitpod.startup.bank.*" />
        <mapping class="org.gitpod.startup.bank.MoneyRoll"/>

        <mapping resource="META-INF/conf/hibernate/mapping/startup-bank-named-queries.xml"/>

    </session-factory>
</hibernate-configuration> 

Then in your Spring config, point a sessionFactory bean to the above config location:

<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
    <property name="dataSource" ref="dataSource" />
    <property name="configLocation" value="classpath:./META-INF/conf/hibernate/startup-hibernate-config.xml" />
    <property name="hibernateProperties"> ... </property>
</bean>

This way it'll be easier to manage locations and session factory configuration. You can look at the working example here

Related Topic