Announcement Announcement Module
Collapse
No announcement yet.
No Session Auto Flushing with Nested @Transactional in OpenSessionInViewFilter Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • No Session Auto Flushing with Nested @Transactional in OpenSessionInViewFilter

    I am nesting an @Transactional service call within an HTTP request that is filtered using OpenSessionInViewFilter (OSIVF). It is my (perhaps incorrect) understanding that while the OSIVF has FlushMode.NEVER the nested @Transactional method will perform a FlushMode.AUTO for the length of the method? That doesn't appear to be happening...

    The problem is that only changes before the point where the service calls the DAO save method (see below) are persisted. Changes to member fields after the save, but before the end of the transactional method are not saved. The simple solution is to move the save to the end of the method, but I'm concerned that I've missunderstood what should happen. I thought that because the object is persisted by the save then any susbsequent member field changes within the @Transactional method will automatically be persisted by the current session?

    P.S. I know the arguments for and against the OSIVF [anti]pattern, I'm not seeking a discussion on this contentious topic!

    In the (parent) Folder class:


    Code:
    @javax.persistence.Entity
    public class Folder extends AbstractContent {
    
    	@OneToMany(fetch=FetchType.LAZY,mappedBy="folder",cascade=CascadeType.ALL)
    	private Set<AbstractContent> contents = new HashSet<AbstractContent>();
    In the (child) AbstractContent class:
    Code:
    @javax.persistence.Entity
    public abstract class AbstractContent extends Entity {
    
    	/** Folder this content is stored in. */
    	@ManyToOne(cascade=CascadeType.ALL)
    	private Folder folder;

    In the service:

    Code:
    	@Transactional(readOnly=false)
    	@Override
    	public Long createAndSaveFolder(String name,Long parentFolderId)
    	{
    		Folder folder = new Folder();
    		//entityDao.save(folder); // * Changes after this are NOT persisted
    		folder.setName(name);
    		Folder parentFolder = entityDao.load(Folder.class,parentFolderId);
    		folder.setFolder(parentFolder);
    		entityDao.save(folder); // * Changes before this ARE persisted
    		return folder.getId();		
    	}
    In the DAO:

    Code:
    	@Override
    	public <T extends Entity> void save(T entity) {
    		sessionFactory.getCurrentSession().save(entity);
    	}
    In the root context config:

    Code:
    	<tx:annotation-driven transaction-manager="transactionManager" />
    
    	<bean
    		id="transactionManager"
    		class="org.springframework.orm.hibernate3.HibernateTransactionManager"
    	>
    		<property
    			name="sessionFactory"
    			ref="sessionFactory" />
    	</bean>
    In web.xml:

    Code:
    	<filter>
    		<filter-name>OpenSessionInViewFilter</filter-name>
    		<filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
    		<init-param>
    			<param-name>sessionFactoryBeanName</param-name>
    			<param-value>sessionFactory</param-value>
    		</init-param>
    	</filter>
    
    	<filter-mapping>
    		<filter-name>OpenSessionInViewFilter</filter-name>
    		<url-pattern>*</url-pattern>
    	</filter-mapping>

  • #2
    Okay, it looks like no one is able to help with the specific problem. I guess the next question is how do I debug and troubleshoot the code that is produced by the @Transactional AOP annotation (instead of my code)?

    Comment

    Working...
    X