Hi all,
Sorry for this yet-another-post on the classic "LazyInitializationProblem".
I extensively searched through the forum, both Spring's and Hibernate,
and googled the internet, but sorry to say, I could not find a single
definitive reference or step-by-step guide like solution.
They were many different views, and some were very confusing. I read about this
"OpenSessionInView" pattern and the "Filter" thing. And at the end, I am still
confused. Though some links like Karl Baum's Post were helpful in understanding
the concept, but still, what exactly to-do, was missing.
I would really appreciate, if someone could guide me through this maze.
Just for the background, following are Spring-Config, .hbm.xml, the DAOImpl, and the
PoJo files.
I am using Hibernate v3.0.5 and Spring v1.2.3 and MySQL v4.1.
Their is no Web or JUnit component, because I first like to get my this small-house in order.
Please help !!!
Thanks in advance,
Vaibhav
Spring Configuration File
Code:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<!-- Data Source Configuration -->
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName"><value>com.mysql.jdbc.Driver</value></property>
<property name="url">
<value>jdbc:mysql://localhost:3306/cdcDB</value>
</property>
<property name="username" value="root"/>
<property name="password" value="quanta"/>
</bean>
<!-- Hibernate Properties -->
<bean id="hibernateProperties"
class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="properties">
<props>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
</bean>
<!-- Hibernate SessionFactory -->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource">
<ref local="dataSource"/>
</property>
<property name="hibernateProperties">
<ref local="hibernateProperties"/>
</property>
<property name="mappingResources">
<list>
<value>Country.hbm.xml</value>
<value>State.hbm.xml</value>
</list>
</property>
</bean>
<!-- Transaction manager for a single Hibernate SessionFactory (alternative to JTA) -->
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory">
<ref local="sessionFactory"/>
</property>
</bean>
<!-- This bean implements the functionality -->
<bean id="territorialDataServiceProvider"
class="com.csam.ccp.cdc.service.realization.TerritorialDataServiceProvider">
<property name="sessionFactory">
<ref local="sessionFactory"/>
</property>
</bean>
<!-- This bean is the interface -->
<bean id="territorialDataService"
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager">
<ref local="transactionManager"/>
</property>
<property name="target">
<ref local="territorialDataServiceProvider"/>
</property>
<property name="transactionAttributes">
<props>
<prop key="add*">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>
</beans>
DAOImpl Implementation
Code:
package com.csam.ccp.cdc.service.realization;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import com.csam.ccp.cdc.exceptions.NonExistentParentException;
import com.csam.ccp.cdc.persistence.Country;
import com.csam.ccp.cdc.persistence.State;
import com.csam.ccp.cdc.service.TerritorialDataService;
public class TerritorialDataServiceProvider extends HibernateDaoSupport
implements TerritorialDataService
{
public String addCountry()
{
Country bharat = new Country();
bharat.setLabel("India");
getHibernateTemplate().save( bharat );
return bharat.getCountryID().toString();
}
public String addState(String countryID, String label)
throws NonExistentParentException
{
final Country bharat =
(Country) getHibernateTemplate()
.load( Country.class, Long.valueOf(countryID) );
if( bharat == null )
{
throw new NonExistentParentException("The Country identified " +
"by the supplied countryID (" + countryID + ") " +
"does not exist");
}
State stateToBeAdded = new State();
stateToBeAdded.setLabel( label );
bharat.addState( stateToBeAdded );
session.save( stateToBeAdded );
session.update( bharat );
return stateToBeAdded.getStateID().toString();
}
public Country getCountry(String countryID)
{
final Country bharat = (Country) getHibernateTemplate()
.load( Country.class, Long.valueOf(countryID) );
return bharat;
}
public State getState(String stateID)
{
final State state =
(State) getHibernateTemplate()
.load( State.class, Long.valueOf(stateID) );
return state;
}
}
Hibernate Mappings
Country.hbm.xml
Code:
<?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>
<class
name="com.csam.ccp.cdc.persistence.Country" table="COUNTRY"
dynamic-update="false" dynamic-insert="false">
<id name="countryID" column="COUNTRY_ID" type="java.lang.Long">
<generator class="native"/>
</id>
<property
name="label"
type="string"
length="40"
not-null="true"/>
<set
name="states"
inverse="true"
cascade="all-delete-orphan">
<key column="COUNTRY_ID"/>
<one-to-many class="com.csam.ccp.cdc.persistence.State"/>
</set>
</class>
<query name="findCountryByID">
<![CDATA[ from Country country where country.countryID = :countryID ]]>
</query>
</hibernate-mapping>
State.hbm.xml
Code:
<?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>
<class
name="com.csam.ccp.cdc.persistence.State" table="STATE"
dynamic-update="false" dynamic-insert="false">
<id name="stateID" column="STATE_ID" type="java.lang.Long">
<generator class="native"/>
</id>
<property
name="label"
type="string"
length="40"
not-null="true"/>
<many-to-one
name="country"
column="COUNTRY_ID"
class="com.csam.ccp.cdc.persistence.Country"
not-null="true"
cascade="none"/>
<set
name="districts"
inverse="true"
cascade="all-delete-orphan">
<key column="STATE_ID"/>
<one-to-many class="com.csam.ccp.cdc.persistence.District"/>
</set>
</class>
<query name="findStateByID">
<![CDATA[ from State state where state.stateID = :stateID ]]>
</query>
</hibernate-mapping>
PoJo
Country.java
Code:
package com.csam.ccp.cdc.persistence;
import java.util.HashSet;
import java.util.Set;
public class Country extends BaseObject
{
private static final long serialVersionUID = 1L;
private Long countryID;
private String label;
private Set states = new HashSet( 7 );
protected void setCountryID( Long countryID )
{
this.countryID = countryID;
}
public Long getCountryID()
{
return countryID;
}
public void setLabel( String label )
{
this.label = label;
}
public String getLabel()
{
return label;
}
public void setStates( Set states )
{
this.states = states;
}
public Set getStates()
{
return states;
}
public void addState( State state )
{
if( state == null )
{
throw new IllegalArgumentException("State reference is null.");
}
final Country country = state.getCountry();
if( country != null )
{
country.getStates().remove( state );
}
state.setCountry( this );
states.add( state );
}
}
State.java
Code:
package com.csam.ccp.cdc.persistence;
import java.util.HashSet;
import java.util.Set;
public class State extends BaseObject
{
private static final long serialVersionUID = 1L;
private Long stateID;
private String label;
private Country country;
private Set districts = new HashSet( 10 );
protected void setStateID( Long stateID )
{
this.stateID = stateID;
}
public Long getStateID()
{
return stateID;
}
public void setLabel( String label )
{
this.label = label;
}
public String getLabel()
{
return label;
}
public void setCountry( Country country )
{
this.country = country;
}
public Country getCountry()
{
return country;
}
public void setDistricts( Set districts )
{
this.districts = districts;
}
public Set getDistricts()
{
return districts;
}
public void addDistrict( District district )
{
if( district == null )
{
throw new IllegalArgumentException("District reference is null.");
}
final State state = district.getState();
if( state != null )
{
state.getDistricts().remove( district );
}
district.setState( this );
districts.add( district );
}
}