which SessionFactory should be use for transactionManager? - java

<bean id="projectService" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager" ref="transactionManager"/>
<property name="target">
<bean class="com.company.project.company.services.ServiceImpl" init-method="init">
<property name="HRappsdao" ref="HRappsdao"/>
<property name="projectdao" ref="projectdao"/>
</bean>
</property>
<property name="transactionAttributes">
<props>
<prop key="store*">PROPAGATION_REQUIRED</prop>
<prop key="update*">PROPAGATION_REQUIRED</prop>
<prop key="remove*">PROPAGATION_REQUIRED</prop>
<prop key="bulkUpdate*">PROPAGATION_REQUIRED</prop>
<prop key="*">PROPAGATION_SUPPORTS,readOnly</prop>
</props>
</property>
</bean>
i have 2 datasource HRappsdao and projectdao, both are using different sessionFactory. in this case, my transactionmanager should be using which sessionfactory? (hrappsdao or projectdao) ?
editted
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" > //my HRappsdao using same
<ref local="sessionFactory"/>
</property>
</bean>

Actually, you're not showing the configuration of your transaction manager so I'm not really sure of what your are currently using but, quoting the documentation:
JTA (usually through JtaTransactionManager) is necessary for accessing multiple transactional resources within the same transaction.
With Spring 2.5, consider using the "new" <tx:jta-transaction-manager/> configuration element for automatic detection of the underlying JTA-based transaction platform (works with most app servers). See the chapter 9.8. Application server-specific integration for more details on this.
If you are using an older version of Spring, you'll need to configure your JtaTransactionManager manually. This will require some knowledge of your application server as the JNDI location of the JTA TransactionManager is specific to each J2EE server.
Please provide more details (like the version of Spring and the application server you are using if you need more guidance).
UPDATE: As I said, when using multiple datasources, you need to use the JtaTransactionManager and not the HibernateTransactionManager (see the javadoc). If you are using Spring 2.5, update your Spring configuration as below:
<?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:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
<tx:jta-transaction-manager />
<!--
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory">
//my HRappsdao using same
<ref local="sessionFactory" />
</property>
</bean>
-->
...
</beans>
Note that you'll need something like JOTM with Tomcat or Jetty. You should maybe consider moving to a J2EE app server like JBoss or Glassfish.

Related

Spring EJB Integration

In my application we have the following architecture:
Web Layer: JSF+Rich Faces
Service Layer: EJB
DAO Layer: EJB Classes [consist of JDBC Queries]
We want to use Hibernate as ORM framework instead of JDBC in DAO layer. I want to use Spring ORM feature for integrating Hibernate in DAO layer. Now, challenges that we are facing:
DAO layer classes are stateless EJB classes. So,to use Spring DI inside EJB classes, I have to go for an interceptor as follows:
#Stateless(mappedName = "myAppDao")
#Interceptors(SpringBeanAutowiringInterceptor.class)
public class MyAppDaoImpl implements MyAppDaoRemote {
#Autowired
private SessionFactory sessionFactory;
#Override
public void getSession() {
if(sessionFactory!=null){
Session session = null;
try{
session = sessionFactory.getCurrentSession();
}catch (Exception e) {
session = sessionFactory.openSession();
System.out.println("Exception:"+e.getMessage());
}
}
With sessionFactory.getCurrentSession() I am getting this exception:
Exception:Could not obtain transaction-synchronized Session for current thread.
The reason behind this I am not able to use Spring transaction at Service layer since I have EJB classes in my service layer.
Moreover I don't want to use sessionFactory.openSession() as in that case I would have to manually close the session.
These are my Spring configuration files:
1) beanRefContext.xml -> Used by Interceptors
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd">
<bean id="businessBeanFctory" class="org.springframework.context.support.ClassPathXmlApplicationContext">
<constructor-arg value="classpath*:daoConfig.xml" />
</bean>
</beans>
2) daoConfig.xml -> Hibernate Configuration
<?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:p="http://www.springframework.org/schema/p"
xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.2.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.2.xsd">
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="packagesToScan" value="com.myapp.model"/>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop>
<prop key="hibernate.show_sql">false</prop>
</props>
</property>
</bean>
<jee:jndi-lookup id="dataSource" jndi-name="jdbc/MyAppDS" expected-type="javax.sql.DataSource"/>
<bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager"/>
<tx:annotation-driven transaction-manager="transactionManager" />
</beans>
I know that there is no point in using EJB along with Spring since they are alternate to each other.But due to some restriction at project level I can't remove EJB for the time being.
So, is there any solution by which we can get the Hibernate current session inside an EJB class through Spring?
If you're using JBossAS/WildFly then you just need:
#Stateless(mappedName = "myAppDao")
public class MyAppDaoImpl implements MyAppDaoRemote {
#PersistenceContext
private Session session;
public void someDaoMethod(YourEntity e) {
// use session directly
// Transactions are automatically managed by the EJB container
// because that's one of EJB's raison d'ĂȘtre
}
}
Ensure that your (traditional) Hibernate configuration specifies JTA transactions.
See the WildFly JPA Reference Guide for more information.
If you're not using one of these JavaEE implementations then you can still use the Spring configuration that you have, but remember to include:
<property name="jtaTransactionManager" value="transactionManager"/>
in your sessionFactory bean.
Additionally, if you're using WebLogic or WebSphere you may need to specify platform dependent JTA transaction managers for these servers, such as WebLogicJtaTransactionManager or org.springframework.transaction.jta.WebSphereUowTransactionManager.
I have modified my daoConfig.xml in following way
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.2.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.2.xsd">
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="packagesToScan" value="com.oms.model"/>
<property name="jtaTransactionManager" ref="transactionManager"/>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
</bean>
<jee:jndi-lookup id="dataSource" jndi-name="jdbc/OMSDS" expected-type="javax.sql.DataSource"/>
<bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager"/>
</beans>
I have added <property name="jtaTransactionManager" ref="transactionManager"/>
under sessionFactory bean definition.After this I am able to use
session = sessionFactory.getCurrentSession();in my dao layer class.

What s wrong with applicationContext.xml file

I'm trying to connect dtatbase to my web application. Database in MSSQL server. Here is my applicationContext.xml file:
<?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:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd">
<bean id="txManagerDH" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="dhSessionFactory"/>
</bean>
<tx:annotation-driven transaction-manager="txManagerDH"/>
<bean id="dhDataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource"
p:driverClassName="com.microsoft.sqlserver.jdbc.SQLServerDriver"
p:url="jdbc:sqlserver://TARAS-PC\SQLEXPRESS:1433:databaseName=DH:"
p:username="GlassfishDH"
p:password="glassfish" />
<bean id="dhSessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"
p:dataSource-ref="dhDataSource">
<property name="annotatedClasses">
<list>
<value>model.User</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">
org.hibernate.dialect.SQLServerDialect
</prop>
<prop key="hibernate.show_sql">false</prop>
</props>
</property>
</bean>
<bean id="UserDao" class="model.UserDao" p:sessionFactory-ref="dhSessionFactory"/>
<bean id="UserService" class="service.UserService"
p:userDao-ref="UserDao"/>
</beans>
When I'm trying run it I have an error:
Error occurred during deployment: Exception while loading the app :
java.lang.IllegalStateException: ContainerBase.addChild: start:
org.apache.catalina.LifecycleException:
org.springframework.beans.factory.BeanCreationException: Error
creating bean with name 'txManagerDH' defined in ServletContext
resource [/WEB-INF/applicationContext.xml]: BeanPostProcessor before
instantiation of bean failed; nested exception is
java.lang.NoClassDefFoundError: org/aopalliance/aop/Advice. Please see
server.log for more details.
I don't what is wrong in my code. Please help me.
You're missing the aop-alliance library from your class path. You can get the binary or the maven dependency here.
Alternatively, get the full spring-aop library.
If your facing the same problem, then you miss aopalliance.jar. Here in this location you can the load the jar http://mvnrepository.com/artifact/aopalliance/aopalliance/1.0. Also it is recommend that you use Maven to handle all these dependencies instead of doing it yourself. I faced the same issue here it is solved. Here my post : Not able to load the applicationContext.xml in Spring. If this problem is solved there would be another in compatability of spring 4.0.0 with hibernate 4.30.
In dipatcher-servlet,instead of
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
Use
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">

Getting save is not valid without active transaction error on using transaction annotation

I'm using spring + hibernate + jersey in my application. I want to use transactions so I used spring's #Transactional annotation in my service layer. This is my hibernate.cfg.xml:
<hibernate-configuration>
<session-factory>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/db</property>
<property name="hibernate.connection.username">user</property>
</session-factory>
</hibernate-configuration>
I haven't used session_context here so spring can manage it. In my applicationCOntext.xml, I have defined transactionManager:
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="driverClass" value="com.mysql.jdbc.Driver"/>
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/db"/>
<property name="user" value="username"/>
</bean>
<context:annotation-config/>
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="configLocation">
<value>classpath:hibernate.cfg.xml</value>
</property>
<property name="packagesToScan">
<list>
<value>com.hibernate.pojos</value>
</list>
</property>
</bean>
<bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<tx:annotation-driven transaction-manager="transactionManager"/>
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
All urls matching /api/v1/* map to a servlet named jersey and servlet class used is com.sun.jersey.spi.spring.container.servlet.SpringServlet to which I have passed com.services as package to scan. In this package I have a class:
#Path("/app")
#Component
public class testApi() {
#Autowired
private DAOImpl daoimpl;
#POST
#Path("/create")
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON)
#Transactional(rollbackFor = {Exception.class})
public Map<String,Object> testHello(user u) {
Map response = daoimpl.save(u);
return response;
}
}
The class daoimpl has the sessionFactory autowired and uses sessionFactory.getCurrentSession() method to get session. The method daoimpl.save(obj) just saves it in db. Since I have marked testHello as transactional, I expect a transaction to begin which is managed by spring and then control should go to daoimpl where the actual save happens. But I get save is not valid without active transaction. I have seen lot of posts where session_context is mentioned in hibernate config and because of that, spring is unable to handle transactions. But in my case, I have ensured that I dont provide any session_context. What am I missing? I even tried adding #transactional to DAO since in my sample app, Im just issuing one DB call for a service. But this didnt work either.
Well could be that you are specifying a session factory via hibernate.cfg.xml and then again in Spring which gets passed to the transaction manager.
Not sure to be honest however I have never used a hibenate.cfg.xml and then following works for me (with the transactional config added as you have specified). This also gives you the advantage of specifying your connection params as properties and allowing you to easily swap db configs via Spring Profiles or some other mechanism.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd">
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan">
<list>
<value>uk.co.xyz.domain</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.show_sql">${hibernate.showsql}</prop>
<prop key="hibernate.format_sql">true</prop>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.hbm2ddl.auto">${hibernate.ddlauto}</prop>
<prop key="hibernate.cache.use_second_level_cache">${hibernate.enablecache}</prop>
<prop key="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</prop>
</props>
</property>
</bean>
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory">
<ref local="sessionFactory" />
</property>
</bean>
</beans>
See also here which actually suggests is shouldn't matter:
applicationContext.xml with datasource or hibernate.cfg.xml. Difference?

Spring integration testing - transaction declaration in config seems to break test

I am playing around with a Spring MVC + Hibernate + MySQL "Hello World" app, and am currently trying run the following integration test on a Spring MVC controller using jUnit.
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration({"file:src/main/webapp/WEB-INF/springapp-servlet.xml"})
public class InventoryControllerIT
{
#Autowired
private InventoryController controller;
#Test
public void handleRequest_anyRequest_returnsSuccessfully() throws Exception
{
ModelAndView modelAndView = this.controller.handleRequest(null, null);
}
}
However, every time I do so I get the following exception:
org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [springapp.web.InventoryController] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency.
Previously I hadn't implemented any real data access and the test passed fine, but now that I have added a Hibernate implementation of my DAO along with spring transaction management I get this error. Here are the relevant parts of my applet context configuration xml:
<?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:p="http://www.springframework.org/schema/p"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<bean name="/hello.htm" class="springapp.web.InventoryController">
<property name="productManager" ref="productManager" />
<property name="productDao" ref="productDao" />
<property name="sessionFactory" ref="sessionFactory" />
</bean>
...
<!-- Hibernate -->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource">
<ref bean="dataSource" />
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
<property name="mappingJarLocations">
<list>
<value>WEB-INF/lib/springapp-dataaccess*.jar</value>
</list>
</property>
</bean>
<bean id="productDao" class="springapp.dataaccess.dao.ProductHibernateDao">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<tx:annotation-driven />
<bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager"
p:sessionFactory-ref="sessionFactory" />
</beans>
If I remove the <tx:annotation-driven /> from the config then the above exception does not occur, but then the test fails because the data access call that occurs in the handler no longer has an open transaction. The app runs just fine outside of the test. Anyone have any ideas as to what the issue is?
When InventoryController implements any interfaces Spring by default applies transactional aspect to it using interface-based proxy. Such a proxy implements interfaces of InventoryController, but it's not a subclass of InventoryController, therefore it cannot be injected into a field of type InventoryController.
You either need to use interface as a type of the field to be autowired, or configure Spring to apply target-class-based proxy instead.
See also:
7.6 Proxying mechanisms
I had a similar issues while running the unit tests of a small library I was building.
replace your :
<tx:annotation-driven />
with
<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>
Note that on my project I also had to add the following dependency (maven project) for the unit tests:
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>2.2.2</version>
<scope>test</scope>
</dependency>
Best regards.

Spring & Hibernate: non transactional service methods

I want my read methods not to use a transaction since this is just not needed at all, I only mark my create/update methods with #Transactional. But how do I do this? I have a pretty basic configuration of Spring with etc...
SessionFactory is injected in my DAO, and in each method I call sessionFactory.getCurrentSession().doQueryStuff();
This, however results in this error:
org.hibernate.HibernateException: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here
If you need my Spring configuration:
<?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:mvc="http://www.springframework.org/schema/mvc"
xmlns:oxm="http://www.springframework.org/schema/oxm"
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-3.0.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/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/oxm
http://www.springframework.org/schema/oxm/spring-oxm-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">
<context:annotation-config />
<context:component-scan base-package="be.howest.kidscalcula" />
<mvc:annotation-driven />
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix">
<value>/WEB-INF/views/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
<bean id="myDataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost/kidscalcula" />
<property name="username" value="root" />
<property name="password" value="" />
</bean>
<bean class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"
id="sessionFactory">
<property name="dataSource" ref="myDataSource" />
<property name="mappingResources">
<list>
<value>be/howest/kidscalcula/model/Foto.hbm.xml</value>
<value>be/howest/kidscalcula/model/Kindleerplanonderdeel.hbm.xml
</value>
<value>be/howest/kidscalcula/model/Klas.hbm.xml</value>
<value>be/howest/kidscalcula/model/Leerkracht.hbm.xml</value>
<value>be/howest/kidscalcula/model/Leerling.hbm.xml</value>
<value>be/howest/kidscalcula/model/Leerplan.hbm.xml</value>
<value>be/howest/kidscalcula/model/LeerplanOefenreeks.hbm.xml
</value>
<value>be/howest/kidscalcula/model/Leerplanonderdeel.hbm.xml</value>
<value>be/howest/kidscalcula/model/Niveau.hbm.xml</value>
<value>be/howest/kidscalcula/model/Oefenreeks.hbm.xml</value>
<value>be/howest/kidscalcula/model/Overgangsregel.hbm.xml</value>
<value>be/howest/kidscalcula/model/Rapport.hbm.xml</value>
<value>be/howest/kidscalcula/model/RapportLeerplanonderdeel.hbm.xml
</value>
<value>be/howest/kidscalcula/model/Schooljaar.hbm.xml</value>
<value>be/howest/kidscalcula/model/Subonderdeel.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.connection.pool_size">3</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">true</prop>
<prop key="hibernate.use_sql_comments">true</prop>
<prop key="hibernate.cache.use_second_level_cache">false</prop>
</props>
</property>
</bean>
<!-- Configure the multipart resolver -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- one of the properties available; the maximum file size in bytes -->
<property name="maxUploadSize" value="500000" />
</bean>
<!--
Transaction manager for a single Hibernate SessionFactory (alternative
to JTA)
-->
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory">
<ref bean="sessionFactory" />
</property>
</bean>
<tx:annotation-driven />
Does this error have anything to do with the fact that Propagation is standard Required?
Mark the method as transactional and read only to ensure the transaction does not modify any data:
#Transactional(readOnly=true)
This is an useful optimization when working with Hibernate. To read more on the implications of this annotation, here is a great post: Read-Only transactions with Spring and Hibernate
As the message clearly says, no session is bound to the thread and the configuration you have specified does NOT allow a "non-transaction" session to be created. I will try to explain each these of scenarios.
When Spring's transaction is enabled in your configuration(as you have done), Spring will wrap the SessionFactory object with a proxy that prevents creation of new sessions, if not already present, when SessionFactory.getCurrentSession is called. The proxy will only get the current session that is bound to the thread local and no ad-hoc session(non-transactional) creation is allowed by your code. This is how your configuration is preventing non-trasactional session creation.
When you annotate a method/class with #Transactional, Spring's TransactionInterceptor will create a session and bind it to the current thread when the method is called so that it is available later. Spring's OpenSessionInViewFilter, if enabled, will also bind a session to the current thread. Since you aren't doing any of these, no thread bound session is found.
What you should do is annotate your class with #Transactional(readOnly = True) and then annotate your create/update/delete methods with #Transactional(readOnly = False). It is important that you have a read-only transaction when you are reading data. This assures you that nobody can commit data during that call.
It is possible to start a session outside of a transaction even when using Spring transaction management. Call sessionFactory.openSession() to get hold of a new session. This session is local in that it is not bound to a thread and so won't be returned when you call sessionFactory.getCurrentSession(). You'll have to manage it and make sure it's properly closed at the the end of your session or if an error occurs.
You can not access the data without an (hibernate) session.
One way to provide such a session is a (when using spring):
org.springframework.orm.hibernate3.support.OpenSessionInViewFilter
or
org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter
(this depends on the way you use your persistence provider)
The positive side effect of this fiters is, that the session is still open when the JSP Views are rendered - so you will have no lazy loading problems when accessing such a not yet loaded property while rendering.
#see http://community.jboss.org/wiki/OpenSessioninView

Categories