-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 7 posts ] 
Author Message
 Post subject: OpenSessionInView & DML operations
PostPosted: Tue Aug 26, 2008 12:06 pm 
Newbie

Joined: Thu Jul 24, 2008 10:13 am
Posts: 17
Hi! I'm trying to use Hibernate in my data access layer in combination with Spring MVC for the web layer. When I launch my test cases to test DAOs they work perfectly, but trying to invoke the same use cases from the web layer, they fail.

First I'll show some relevant information about my configuration:


Hibernate version:
Hibernate 3.2.5.ga
Hibernate Annotations 3.3.0.ga


application-Context.xml snippets[b]
Code:
<bean id="dataSource"
      class="org.apache.commons.dbcp.BasicDataSource"
      destroy-method="close">
     ...
</bean>

   <bean id="sessionFactory"
      class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
      <property name="dataSource">
         <ref bean="dataSource" />
      </property>
      <property name="hibernateProperties">
         <props>
            <prop key="hibernate.dialect">
               org.hibernate.dialect.PostgreSQLDialect
            </prop>
            <prop key="hibernate.c3p0.min_size">5</prop>
            <prop key="hibernate.c3p0.max_size">20</prop>
            <prop key="hibernate.c3p0.timeout">2000</prop>
            <prop key="hibernate.c3p0.max_statements">50</prop>
            <prop key="hibernate.show_sql">true</prop>
            <prop key="hibernate.format_sql">true</prop>
         </props>
      </property>
      ...
</bean>


   <bean id="transactionManager"
      class="org.springframework.orm.hibernate3.HibernateTransactionManager">
      <property name="sessionFactory" ref="sessionFactory" />
   </bean>
   
   
   <bean name="openSessionInViewInterceptor"
        class="org.springframework.orm.hibernate3.support.OpenSessionInViewInterceptor">
        <property name="sessionFactory" >
            <ref bean="sessionFactory" />
        </property>
    </bean>

<tx:annotation-driven transaction-manager="transactionManager"/>


Not relevant information is omitted, but for this example the annotated entity to use will be Link (its attributes aren't important).


In the web layer, invoking NewLink.do we can write the corresponding attributes of this entity in a form, and when the form is submitted, the controller do this:

Code:
linkService.createLink(link);


with linkService the facade which invokes link DAO. Trying to do this, the stacktrace given is :

Code:
HTTP ERROR: 500

Write operations are not allowed in read-only mode (FlushMode.NEVER/MANUAL): Turn your Session into FlushMode.COMMIT/AUTO or remove 'readOnly' marker from transaction definition.

org.springframework.dao.InvalidDataAccessApiUsageException: Write operations are not allowed in read-only mode (FlushMode.NEVER/MANUAL): Turn your Session into FlushMode.COMMIT/AUTO or remove 'readOnly' marker from transaction definition.
   at org.springframework.orm.hibernate3.HibernateTemplate.checkWriteOperationAllowed(HibernateTemplate.java:1182)
   at org.springframework.orm.hibernate3.HibernateTemplate$21.doInHibernate(HibernateTemplate.java:802)
   at org.springframework.orm.hibernate3.HibernateTemplate.doExecute(HibernateTemplate.java:419)
   at org.springframework.orm.hibernate3.HibernateTemplate.executeWithNativeSession(HibernateTemplate.java:374)
   at org.springframework.orm.hibernate3.HibernateTemplate.persist(HibernateTemplate.java:800)
   at es.udc.pojo.modelutil.dao.GenericDaoHibernate.create(GenericDaoHibernate.java:57)
   at es.udc.lbd.portal.model.services.link.service.LinkServiceImpl.createLink(LinkServiceImpl.java:28)
   at es.udc.lbd.portal.http.controller.other.NewLinkController.processSubmit(NewLinkController.java:43)
   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
   at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
   at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
   at java.lang.reflect.Method.invoke(Unknown Source)
   at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.doInvokeMethod(HandlerMethodInvoker.java:413)
   at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:134)
   at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:310)
   at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:297)
   at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:875)
   at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:809)
   at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:523)
   at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:463)
   at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
   at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
   at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:487)
   at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:362)
   at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
   at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:181)
   at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:726)
   at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:405)
   at org.mortbay.jetty.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:206)
   at org.mortbay.jetty.handler.HandlerCollection.handle(HandlerCollection.java:114)
   at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:139)
   at org.mortbay.jetty.Server.handle(Server.java:324)
   at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:505)
   at org.mortbay.jetty.HttpConnection$RequestHandler.content(HttpConnection.java:842)
   at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:648)
   at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:211)
   at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:380)
   at org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:395)
   at org.mortbay.thread.BoundedThreadPool$PoolThread.run(BoundedThreadPool.java:450)



Now, I'll show the DAO implementation. To perfom the usage of Hibernate, and as shown in the documentation, I use an abstract class GenericDao implementing an interface GenericDaoHibernate:

[b] Interface GenericDao - Snippet

Code:
public interface GenericDao <E, PK extends Serializable>{

   void create(E entity);

...
}


Abstract class GenericDaoHibernate - Snippet
Code:
public class GenericDaoHibernate<E, PK extends Serializable>
      extends HibernateDaoSupport
      implements GenericDao<E, PK>


   private Class<E> entityClass;

   
   
   @SuppressWarnings("unchecked")
   public GenericDaoHibernate()
   {
      this.entityClass = (Class<E>) ((ParameterizedType) getClass().
         getGenericSuperclass()).getActualTypeArguments()[0];   
   }

   public void create(E entity)
   {
      getHibernateTemplate().persist(entity);   
   }

...
}



Link DAO
Code:
public class LinkDAOHibernate
   extends GenericDaoHibernate<Link, String> implements LinkDAO
{

   @Autowired
   public LinkDAOHibernate(SessionFactory sessionFactory)
   {
      super.setSessionFactory(sessionFactory);
   }
}



Using getHibernateTemplate() and the OpenSessionInView the session management will be transparent, but not really... With data retrying methods (not dml), all work perfect, but in data manipulation methods this error occurs. Trying to solve this problem, I set the flushmode to the session in the create method, but this way was wrong.

¿Any way to solve this problem?


Also, I want to comment that one friend have the similar problem and the way he found to solve it was removing the extension of HibernateDaoSupport and doing something like this:

Code:
sessionFactory.getCurrentSession().persist(entity);


Using Hibernate Session Core, with the OpenSessionInViewFilter (he uses the filter, not the interceptor), the queries works perfectly, but the DML operations (insert, delete or update) fail. Removing the filter, nothing works ( No Hibernate Session bound to thread... ).

Thanks.


Top
 Profile  
 
 Post subject: Re: OpenSessionInView & DML operations
PostPosted: Wed Apr 21, 2010 1:49 pm 
Newbie

Joined: Wed Apr 21, 2010 1:48 pm
Posts: 2
Hi!

Any news about this issue?

I'm having exactly the same problem...

R.


Top
 Profile  
 
 Post subject: Re: OpenSessionInView & DML operations
PostPosted: Wed Apr 21, 2010 2:18 pm 
Newbie

Joined: Wed Apr 21, 2010 1:48 pm
Posts: 2
I found the solution. The problem is that both OpenSessionInView objects(Interceptor and Filter) have the FlushMode set to FLUSH_NEVER by default.

You can override this problem by extending either class (OpenSessionInViewInterceptor or OpenSessionInViewFilter) like this:
Code:
import org.springframework.orm.hibernate3.support.OpenSessionInViewInterceptor;

public class CustomHibernateSessionInterceptor extends OpenSessionInViewInterceptor {

    public HibernateSessionInterceptor() {
      setFlushMode(FLUSH_AUTO);
   }
}

Code:

import org.springframework.orm.hibernate3.support.OpenSessionInViewFilter;
import org.hibernate.*;
import org.springframework.dao.*;

public class CustomHibernateSessionFilter extends OpenSessionInViewFilter {
   
    protected Session getSession(SessionFactory sessionFactory)
                        throws DataAccessResourceFailureException {
        Session session = super.getSession(sessionFactory);
        session.setFlushMode(FlushMode.COMMIT);   
        return session;
    }
   
    protected void closeSession(Session session, SessionFactory factory) {
        session.flush(); 
        super.closeSession(session, factory); 
    }
}


With this your Spring MVC Controllers can make read and write operations without any problem.

Hope this helps someone!

R.


Top
 Profile  
 
 Post subject: Re: OpenSessionInView & DML operations
PostPosted: Sat May 22, 2010 6:13 am 
Newbie

Joined: Sat May 22, 2010 6:06 am
Posts: 1
Hi Rodrigo,

Thanks for the solution you've described!

It really works and has assisted me in resolving a similar problem I had in environment Spring/Spring WebFlow/Hibernate.
Just wonder whether an original OpenSessionInView filter can be tuned dynamically or pre-configured statically.

Regards,
Alexei


Top
 Profile  
 
 Post subject: Re: OpenSessionInView & DML operations
PostPosted: Fri Oct 15, 2010 4:30 pm 
Newbie

Joined: Thu Dec 07, 2006 6:47 pm
Posts: 3
I have a one-to-many relationship modeled similar to the following...
Code:
@Entity
@Table(name="parent")
public class Parent implements Serializable {

  @Id
  @GeneratedValue
  @Column(name="parent_id")
  private Long parentID;

  @Column(name="name")
  private String parentName;

  @OneToMany(mappedBy="parent", fetch=FetchType.LAZY, cascade = {CascadeType.ALL})
  private List<Child> children;
}

@Entity
@Table(name="child")
public class Child implements Serializable {

  @Id
  @GeneratedValue
  @Column(name="child_id")
  private Long childID;

  @Column(name="name")
  private String childName;

  @ManyToOne(fetch=FetchType.LAZY, cascade={CascadeType.ALL})
  @JoinColumn(name="parent_id", nullable=false, insertable=false, updatable=false)
  private Parent parent;
}


Extending OpenSessionInViewFilter to set the Hibernate session's flush mode to commit seems to help, though not entirely. I think it may be because I am doing something wrong with the above mapping annotations. My service component issues the DAO's save method as follows:
Code:
  hibernateTemplate.saveOrUpdate(parent);
  return parent;


I run into an exception that complains that parent_id does not have a value when inserting the child records into the database. Not only that; I end up in an inconsistent state because the parent record gets inserted but no associated child records are inserted.

What am I doing wrong?

Ashwin


Top
 Profile  
 
 Post subject: Re: OpenSessionInView & DML operations
PostPosted: Sat Jul 02, 2016 12:22 am 
Dear rodrigobartels, i did the the filter in the same way, but i am not using the c3po pool and i am executing the Dave instead of saveorupdate method.

I am still with same error!
For same reason, the session filter and the hibernatetemplate session are not the same !


Top
  
 
 Post subject: Re: OpenSessionInView & DML operations
PostPosted: Sat Jul 02, 2016 12:28 am 
I forget other things, my filter is from hibernate4 package ,
Do you think that is this a problem ?


Top
  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 7 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.