Announcement Announcement Module
Collapse
No announcement yet.
Spring 3.1 + Hibernate 4 + compile time AspectJ weaving: @Transactional doesn't work Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Spring 3.1 + Hibernate 4 + compile time AspectJ weaving: @Transactional doesn't work

    Hello all,

    I'm having a annnoyingly resilient problem that I'm having trouble to understand and get rid of... essentially, I'm setting up Hibernate 4 with Spring 3.1 using all the vanilla stuff, and using @Transactional on my method to ensure the session. The method is in a regular class, and while there are no interfaces nor CGLib, the @Transactional support is weaved in at compile time using the AspectJ plugin for Maven. It's done this way because the project already has this set up for a Neo4J database.

    The @Transactional doesn't seem to work. I get the following error:

    Code:
    org.hibernate.HibernateException: No Session found for current thread
    However, the @Transactional used for methods that manipulate the Neo4J database work just fine (without @Transactional, they do nothing). Hence my confusion.

    The error is a common one, it would seem. Many google results, but nothing has helped so far. I have only one context, so there are no duplicate beans or beans scanned into the wrong context. I have put in all the configuration I could find. And no interfaces/no CGLIB shouldn't matter, as I'm weaving in the aspects at compile time (showWeaveInfo displays the advices being applied). I did notice the local database file is being created.

    Any insight anyone could give me would be much appreciated

    These are my files:

    Application context:
    Code:
    <?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:util="http://www.springframework.org/schema/util"
    	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.0.xsd
    		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
    		http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-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/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
    
    <context:component-scan base-package="audited" />
    
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    	<property name="driverClassName" value="org.h2.Driver" />
    	<property name="url" value="audited" />
    	<property name="username" value="audited" />
    	<property name="password" value="audited" />
    </bean>
    
    <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
    	<property name="dataSource" ref="dataSource" />
    	<property name="packagesToScan" value="audited" />
    	<property name="hibernateProperties">
    		<props>
    			<prop key="hibernate.dialect">org.hibernate.dialect.H2Dialect</prop>
    			<prop key="hibernate.show_sql">true</prop>
    		</props>
    	</property>
    </bean>
    
    <tx:annotation-driven transaction-manager="transactionManager" />
    
    <bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
    	<property name="sessionFactory" ref="sessionFactory" />
    </bean>
    
    </beans>
    POM:
    Code:
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    	<modelVersion>4.0.0</modelVersion>
    
    	<groupId>audited</groupId>
    	<artifactId>audited</artifactId>
    	<version>1.0.0-SNAPSHOT</version>
    	<packaging>jar</packaging>
    
    	<name>audited</name>
    	<url>http://maven.apache.org</url>
    
    	<properties>
    		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    		<aspectj.version>1.7.2</aspectj.version>
    	</properties>
    
    	<dependencies>
    		<dependency>
    			<groupId>audited</groupId>
    			<artifactId>audited</artifactId>
    			<version>1.0.0-SNAPSHOT</version>
    		</dependency>
    		<dependency>
    			<groupId>commons-io</groupId>
    			<artifactId>commons-io</artifactId>
    			<version>2.1</version>
    		</dependency>
    		<dependency>
    			<groupId>log4j</groupId>
    			<artifactId>log4j</artifactId>
    			<version>1.2.16</version>
    		</dependency>
    		<dependency>
    			<groupId>junit</groupId>
    			<artifactId>junit</artifactId>
    			<version>3.8.1</version>
    			<scope>test</scope>
    		</dependency>
    		
    		<dependency>
    			<groupId>org.springframework</groupId>
    			<artifactId>spring-orm</artifactId>
    			<version>3.1.4.RELEASE</version>
    		</dependency>
    		<dependency>
    			<groupId>org.hibernate</groupId>
    			<artifactId>hibernate-entitymanager</artifactId>
    			<version>4.1.10.Final</version>
    		</dependency>
    		<dependency>
    			<groupId>org.hibernate</groupId>
    			<artifactId>hibernate-validator</artifactId>
    			<version>4.3.1.Final</version>
    		</dependency>
    	</dependencies>
    
    	<build>
    		<plugins>
    			<plugin>
    				<groupId>org.apache.maven.plugins</groupId>
    				<artifactId>maven-jar-plugin</artifactId>
    				<version>2.3.1</version>
    				<configuration>
    					<archive>
    						<manifest>
    							<mainClass>audited.App</mainClass>
    							<packageName>audited</packageName>
    						</manifest>
    					</archive>
    				</configuration>
    			</plugin>
    			<plugin>
    				<groupId>org.apache.maven.plugins</groupId>
    				<artifactId>maven-assembly-plugin</artifactId>
    				<version>2.2.1</version>
    				<configuration>
    					<finalName>audited</finalName>
    					<descriptors>
    						<descriptor>assemble.xml</descriptor>
    					</descriptors>
    					<archive>
    						<manifest>
    							<mainClass>audited.App</mainClass>
    							<packageName>audited</packageName>
    						</manifest>
    					</archive>
    				</configuration>
    			</plugin>
    			<plugin>
    			 <groupId>org.apache.maven.plugins</groupId>
    			 <artifactId>maven-compiler-plugin</artifactId>
    			 <version>2.3.2</version>
    			 <configuration>
    			  <source>1.7</source>
    			  <target>1.7</target>
    			 </configuration>
    			</plugin>
    			<plugin>
    			<groupId>org.codehaus.mojo</groupId>
    			<artifactId>aspectj-maven-plugin</artifactId>
    			<version>1.4</version>
    			<configuration>
    			  <outxml>true</outxml>
    			  <showWeaveInfo>true</showWeaveInfo>
    			  <aspectLibraries>
    				<aspectLibrary>
    				  <groupId>org.springframework</groupId>
    				  <artifactId>spring-aspects</artifactId>
    				</aspectLibrary>
    			  </aspectLibraries>
    			  <source>1.7</source>
    			  <target>1.7</target>
    			</configuration>
    			<executions>
    			  <execution>
    				<goals>
    				  <goal>compile</goal>
    				  <goal>test-compile</goal>
    				</goals>
    			  </execution>
    			</executions>
    			<dependencies>
    			  <dependency>
    				<groupId>org.aspectj</groupId>
    				<artifactId>aspectjrt</artifactId>
    				<version>${aspectj.version}</version>
    			  </dependency>
    			  <dependency>
    				<groupId>org.aspectj</groupId>
    				<artifactId>aspectjtools</artifactId>
    				<version>${aspectj.version}</version>
    			  </dependency>
    			</dependencies>
    		  </plugin>
    		</plugins>
    	</build>
    </project>
    Test POJO:
    Code:
    package audited;
    
    import javax.persistence.*;
    
    @Entity
    public class Audited {
    	int id;
    	String audited;
    	
    	
    	public Audited() {
    		id = -1;
    		audited = "";
    	}
    	
    	
    	@Id
    	public int getId() {
    		return id;
    	}
    
    	public void setId(int id) {
    		this.id = id;
    	}
    	
    	
    	public String getAudited() {
    		return audited;
    	}
    
    	public void setAudited(String audited) {
    		this.audited= audited;
    	}
    }
    Test method:
    Code:
    @Transactional
    public void audited() {
    	ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("context.xml");
    
    	Audited audited = new Audited();
    
    	SessionFactory sessionFactory = context.getBean(SessionFactory.class);
    	sessionFactory.getCurrentSession().saveOrUpdate(audited);
    
    	context.close();
    }
    It's the saveOrUpdate(Object) method that throws the exception.

  • #2
    Which is as expected....

    You have an @Transactional and after that construct the applicationcontext containing the transactional configuration. This isn't going to work. You need to put the @Transactional on a bean in the context (a Service) to make it work.

    Comment


    • #3
      Thanks, I suspected it was either something really annoying or something really simple... Guess this test case was a little too low-tech. It's definitely showing that I don't normally work with this stuff, haha.

      I created an additional bean with @Transactional on its methods, and defined it in the context XML, injecting the session factory into it with a property. I can retrieve this bean from the context and use its methods no problem.

      Still wonder why it works for Neo4J though... well, it works so I'm not going to complain :P

      Comment

      Working...
      X