2

休止状態でのデータの更新と表示で奇妙な問題に遭遇しました。誰でも私を助けてくれませんか!?

私はmysqlで休止状態の春を使用しています。

ここで私が直面している問題は、変更をデータベースに適用できることです。しかし、更新されたアイテムを Web ページにロードすると、常に古いデータまたは新しいデータがランダムに返されます。

ブラウザのキャッシュの問題ではないことは確かです。daoクラスのgetPostメソッドでリターンデータを出力してみました。時々間違ったメッセージを出力するだけです。

たとえば、投稿の内容を複数回変更すると、すべての変更がデータベースに保存されます。しかし、変更されたデータを表示するためにページを継続的に更新すると、以前のすべての変更がランダムに表示されます。

getPost メソッドでデータをロードするさまざまな方法を試しましたが、それでも同じ問題に直面しています:

  1. session.clear と session.flush を試してみました

  2. 次のように第 2 レベルのキャッシュを閉じます。

    <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. データをロードするさまざまな方法: session.load、session.get、hibernate クエリ、基準、すべて同じ問題があります。

  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;

    }
4

3 に答える 3

1

私も同じ悩みを抱えていました。すぐに見つけた答え。リカルドが言ったように、問題はセッションをきれいに閉じていないことにあるため、セッションはランダムにリサイクルされました。私はクラスのコンストラクターでこれを行いました。

例(ここでは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;
    }
}

読んでくれてありがとう

于 2011-12-23T09:02:27.837 に答える
0

リストを取得して、リストの最初のエントリのみを表示しているように見えます。順序付けの基準がないため、リストには毎回ランダムな順序で複数のアイテムが入力されていると思います。したがって、リストの最初の要素は実行ごとに異なる可能性があります。

ユニークな結果を期待していますか?その場合は、Criteria.uniqueResult();を使用することをお勧めします。

于 2011-05-11T10:48:21.723 に答える
0

セッションを取得する方法に依存する場合があります。ThreadLocal セッションで典型的な HibernateUtil を使用している場合、作業が終了した後にセッションを正しく閉じていない可能性があります。この場合、セッションは、キャッシュされた値を取得する、まったく関係のない作業単位によってほぼランダムにリサイクルされます

于 2011-05-11T10:55:23.907 に答える