开发者

Weird query issue on hibernate

I met a weird problem with updating & displaying data in hibernate. Can anyone help me please!?

I am using hibernate, spring with开发者_JS百科 mysql.

The problem here i am facing is, any changes can be applied to database. But if I load updated item on web page, it always returns the old data or new data randomly.

I am sure that it is not a problem of browser cache. I tried to print out return data in getPost method in dao class. It just print out wrong message sometimes.

Say, if I change post content for multiple times, all changes can be stored in database. But If I continuously refresh page to display changed data, it displays all previous changes randomly.

I have tried different ways to load data in getPost method, but still face same problem:

  1. tried session.clear, and session.flush

  2. close second level cache as :

    <prop key="hibernate.cache.use_second_level_cache">false</prop>
    <prop key="hibernate.cache.use_query_cache">false</prop>
    <prop key="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</prop>
    <prop key="hibernate.cache.use_structured_entries">false</prop>
    
  3. different way to load data: session.load, session.get, hibernate query, Criteria, all have same issue.

  4. In getPost method of postDAO: I tried to load data by native SQL first, and wanted to compare with result of hibernate query. both queries return old data.

Code:

public class Post implements Cloneable, Serializable {

    private String postID;
    private String content;
}

PostSelectController (controller):

public class PostSelectController extends AbstractController
{
....
protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception
    {
        String id = request.getParameter("id");

        Course course = null;
        Vendor vendor = null;
        Post post = null;

        ModelAndView modelAndView = new ModelAndView();

        modelAndView.setViewName(getSuccessView());

        post = postService.getPost(id);

        modelAndView.addObject("post", post);

        return modelAndView;
    }
}

postService:

@Transactional(propagation=Propagation.SUPPORTS, isolation=Isolation.READ_COMMITTED, readOnly=true)
public class PostService
{
@Transactional(propagation=Propagation.REQUIRED, readOnly=false)
    public boolean updatePost(Post post) {

        System.out.println("service side::::::::::::::::::::::"+(post.getBestAnswer()!=null));
        if(post.getBestAnswer()!=null) System.out.println(">>>>>>>>"+post.getBestAnswer().getPostID());
        System.out.println("service side::::::::::::::::::::::"+(post.getBestAnswer()!=null));;

        return this.postDAO.updatePost(post);
    }

    public Post getPost(String postID) {
        return this.postDAO.getPost(postID);
    }
}

postDAO:

public class  PostDAO {
private SessionFactory sessionFactory;
...

public boolean updatePost(Post post) {
        boolean proceed = true;

        try {

            Session session = sessionFactory.getCurrentSession();
            session.merge(post); //tried session.update, same problem

            session.flush(); //it does not help

        } catch (Exception ex) {
            logger.error(post.getPostID() + " refused :: " + ex.getMessage());
            proceed = false;
        }
        return proceed;
    }


public Post getPost(String postID) {

        Session session = sessionFactory.getCurrentSession();       
        try{
         PreparedStatement st = session.connection()
            .prepareStatement("select content from post where postid='"+postID+"'") ;

             ResultSet rs =st.executeQuery();
             while (rs.next()) {

                System.out.println("database::::::::::::::::::"+rs.getInt("content")); 
                // tried to use native sql to load data from database and compare it with result of hibernate query.
                break;
             }
        }catch(Exception ex){

        }

        Criteria crit = session.createCriteria(Post.class);
        NaturalIdentifier natId = Restrictions.naturalId();
        natId.set("postID", postID);
        crit.add(natId);
        crit.setCacheable(false);

        List<Post> posts = crit.list();

        Post post = null;
        if(posts!=null)  post = posts.get(0);
        System.out.println("hibernate::::::::::::::::::"+post.getContent());


        return post;

    }


I had the same trouble. The answer i found quikly. As Riccardo said the problem was in not cleanly closing session, so session was randomly recycled. i`ve done this in consructor of the class.

Ex(i used here HybernateUtil):

 public yourHelper() {

        this.session = HibernateUtil.getSessionFactory().getCurrentSession();
         if (session.isOpen()){
            session.close();
            session=HibernateUtil.getSessionFactory().openSession();
        }   
    }

code of HibernateUtil:

    public class HibernateUtil {

    private static final SessionFactory sessionFactory;

    static {
        try {
            // Create the SessionFactory from standard (hibernate.cfg.xml) 
            // config file.
            sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory();
            System.out.println("SRPU_INFO: Initial SessionFactory creation success.");
        } catch (Throwable ex) {
            // Log the exception.

            System.out.println("SRPU_INFO: Initial SessionFactory creation failed." + ex);
            throw new ExceptionInInitializerError(ex);
        }
    }

    public static SessionFactory getSessionFactory() {
        return sessionFactory;
    }
}

thanx for reading


Looks like you retrieve a list and display only the first entry of the list. I am guessing that the list is populated with more than one item, in random order each time, since there's no order-by criteria.Thus the first element of the list might differ for different executions.

Are you expecting a unique result ? If so, it would be better to use Criteria.uniqueResult();


It may depend on the way you obtain the session: if you are using the typycal HibernateUtil with ThreadLocal session it may be the case you are not correctly closing the session after you finish working with it. In this case the session in almost randomly recycled by completely unrelated units of work which will get the cached value

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜