Hibernate运行不需要的更新语句

时间:2017-03-01 22:33:20

标签: java spring hibernate jpa

我有本机查询运行:

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选择在执行select之前进行更新,它确实干扰了我的数据

     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

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

1 个答案:

答案 0 :(得分:2)

你所描述的正是Hibernate的FlushMode.AUTO所暗示的。

执行查询时持久化上下文(1LC)中的任何修改都将在执行查询之前自动刷新,从而保证数据库返回的结果与内存修改缓存的结果相匹配。

如果查询要返回您正在查看更新的实体,那么您应该重新评估您的操作,确保在更新之前触发查询以避免刷新操作,这可能是相当的昂贵取决于持久化上下文中的实体数量。

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

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

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