一尘不染

Hibernate运行不需要的更新语句

hibernate

我有本机查询要运行:

String sqlSelect =
"select r.id_roster as id, " +
                    "count(roster_cat.id_category), " +
            "       sum(case when roster_cat.id_category IN ( :categoryIds)                       then 1 else 0 end) as counter " +
            "from roster r " +
            "inner join roster_sa_categories roster_cat " +
                "on r.id_roster = roster_cat.id_roster " +
            "where r.day = :dayToLookFor " +
                "and r.id_shop = :idShop " +
            "group by r.id_roster " +
            "having count(roster_cat.id_category) = :nrCategories " +
                "and count(roster_cat.id_category) = counter" ;

    Query selectRostersQuery = entityManager.createNativeQuery(sqlSelect);

    selectRostersQuery.setParameter("categoryIds", Arrays.asList(categoryIds));
    selectRostersQuery.setParameter("dayToLookFor", day.toString());
    selectRostersQuery.setParameter("idShop", shopId);
    selectRostersQuery.setParameter("nrCategories", categoryIds.length);

    List<Integer> rosterIds =  new ArrayList<>();

    List<Object> result = (List<Object>) selectRostersQuery.getResultList();

出于某种原因,Hibernate选择在执行选择之前进行更新,这确实干扰了我的数据

     Hibernate: /* update domain.Roster */ update roster set day=?,     employee_count=?, interval_end=?, interval_start=?, id_shop=? where id_roster=?
     Hibernate: /* update Roster */ update roster set day=?, employee_count=?,  interval_end=?, interval_start=?, id_shop=? where id_roster=?
     Hibernate: /* dynamic native SQL query */ select r.id_roster as id,   count(roster_cat.id_category),sum(case when roster_cat.id_category IN ( ?) then 1 else 0 end) as counter from roster r inner join roster_sa_categories 
roster_cat on r.id_roster = roster_cat.id_roster where r.day = ? and r.id_shop = ? group by r.id_roster having count(roster_cat.id_category) = ? and count(roster_cat.id_category) = counter

任何帮助将不胜感激,谢谢


阅读 174

收藏
2020-06-20

共1个答案

一尘不染

您所描述的正是Hibernate的FlushMode.AUTO含义。

执行查询时对持久性上下文(1LC)的任何修改都将在执行查询之前自动清除,以确保数据库返回的结果与内存中修改所缓存的结果匹配。

如果查询将返回您要查看其更新的实体,则您可能应该重新评估您的操作,确保查询在更新之前触发以避免刷新操作,这可能会非常昂贵,具体取决于持久性上下文中实体的数量。

如果您 完全确定 相关查询不会返回您看到的刷新更改,则可以始终通过手动设置刷新模式来强制查询不引起刷新:

Query query = session.createQuery( ... );
query.setFlushMode( FlushMode.COMMIT );
List results = query.list();

但是只有在您确定查询不会再读取未提交的更改时才执行此操作,因为这可能会导致很多问题,并导致长时间的调试会话,以了解为什么应用程序无意间丢失了更改。

2020-06-20