hibernate中奇怪的查询问题

发布于 2024-11-05 05:00:37 字数 3967 浏览 0 评论 0原文

我在更新时遇到了一个奇怪的问题在休眠状态下显示数据。谁能帮帮我吗?

我正在使用 hibernate、spring 和 mysql。

我面临的问题是,任何更改都可以应用于数据库。但是,如果我在网页上加载更新的项目,它总是随机返回旧数据或新数据。

我确信这不是浏览器缓存的问题。我尝试在 dao 类的 getPost 方法中打印出返回数据。有时它只是打印出错误的消息。

比如说,如果我多次更改帖子内容,所有更改都可以存储在数据库中。但是如果我不断刷新页面以显示更改的数据,它会随机显示以前的所有更改。

我尝试了不同的方法在 getPost 方法中加载数据,但仍然面临同样的问题:

  1. 尝试了 session.clear 和 session.flush

  2. 关闭二级缓存如:

    false;
    false;
    org.hibernate.cache.EhCacheProvider;
    false;
    
  3. 加载数据的不同方式:session.load、session.get、hibernate 查询、Criteria,都有相同的问题。

  4. 在postDAO的getPost方法中:我尝试首先通过本机SQL加载数据,并想与hibernate查询的结果进行比较。两个查询都返回旧数据。

代码:

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 met a weird problem with updating & displaying data in hibernate. Can anyone help me please!?

I am using hibernate, spring with 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;

    }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

Hello爱情风 2024-11-12 05:00:38

这可能取决于您获取会话的方式:如果您将典型的 HibernateUtil 与 ThreadLocal 会话一起使用,则可能会出现在您完成使用会话后无法正确关闭会话的情况。在这种情况下,会话几乎被完全不相关的工作单元随机回收,这将获得缓存的值

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

你不是我要的菜∠ 2024-11-12 05:00:37

我也有同样的麻烦。我很快找到了答案。正如 Riccardo 所说,问题在于没有完全关闭会话,因此会话被随机回收。我已经在类的构造函数中完成了此操作。

Ex(我在这里使用HybernateUtil):

 public yourHelper() {

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

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用于阅读

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

‖放下 2024-11-12 05:00:37

看起来您检索了一个列表并仅显示该列表的第一个条目。我猜测列表中填充了多个项目,每次都以随机顺序填充,因为没有排序条件。因此,列表的第一个元素可能因不同的执行而有所不同。

您期待独特的结果吗?如果是这样,最好使用 Criteria.uniqueResult();

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();

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文