What's wrong in my context.xml?
A number of things. First you are trying to use Hibernate.getCurrentSession() when no tx is started.
void init() {
Session session = sessionFactory.getCurrentSession();
session.beginTransaction();
System.out.println(session.createQuery("from Event").list());
session.getTransaction().commit();
}
Even though your are using Spring transaction demarcation you are trying also to use Hibernate transcations by hand - why is that? Your code doesn't handle the case of an exception and you'll never have rollback - basically if an exception is thrown in list() your transaction will never be closed.
Moreover, assuming that what you do is correct, you are first trying to get a hold of the currentSession and then starting a transaction - you should do the other way around.
As for the application context you are wrapping the bean inside a proxy but you are not using the proxy but actually the original bean. Do not execute code inside the init method - the init method is used for creating the bean - only after that one should execute methods on the bean.
Here is a reworked application context:
Code:
<beans>
<bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="org.hsqldb.jdbcDriver"/>
<property name="url" value="jdbc:hsqldb:db/test"/>
<property name="username" value="sa"/>
<property name="password" value=""/>
</bean>
<bean id="myTxManager" class="org.springframework.orm.hibernate3.Hibernat eTransactionManager">
<property name="sessionFactory" ref="mySessionFactory"/>
</bean>
<bean id="transactionProxy" class="org.springframework.transaction.interceptor .TransactionProxyFactoryBean">
<property name="transactionManager"><ref bean="myTxManager"/></property>
<property name="transactionAttributes">
<props>
<prop key="*">PROPAGATION_REQUIRED</prop>
</props>
</property>
<property name="target">
<bean class="TestBean">
<property name="sessionFactory" ref="mySessionFactory"/>
</bean>
</property>
</bean>
<bean id="mySessionFactory" class="org.springframework.orm.hibernate3.LocalSes sionFactoryBean">
<property name="dataSource" ref="myDataSource"/>
<property name="mappingResources">
<list>
<value>events/model.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.HSQL Dialect</prop>
<prop key="hibernate.cache.provider_class">org.hibernate .cache.NoCacheProvider</prop>
</props>
</property>
</bean>
</beans>
Note that I've moved the bean definition inside the TransactionalProxy as an inner bean (a good way of preventing access to the unproxied bean).
As for your code you could do something like this:
Code:
public class Server {
public static void main(String[] args) throws Exception {
AbstractApplicationContext ctx =
new ClassPathXmlApplicationContext(new String []{"context.xml"});
TestBean bean = (TestBean) ctx.getBean("transactionProxy");
bean.doSmth();
ctx.close();
}
}
where TestBean is:
Code:
import org.hibernate.Session;
public class TestBean extends HibernateDaoSupport {
public void doSmth() {
Session session = sessionFactory.getCurrentSession();
System.out.println(session.createQuery("from Event").list());
}
}
You can see that the code is quite smaller and cleaner - this is where Spring power lies. I strongly suggest (again) to take a look at the samples provided with the Spring distribution and to take the time to read the reference documentation. It's a great way to learn how Spring works (makes your life easier). You have also plenty of book and a quick google will give you plenty of tutorials with code included (try springhub.com for example).