Radu D
Radu D

Reputation: 35

Hibernate runs unwanted update statement

I have native query to run :

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

For some reason Hibernate choses to do an update before executing the select and it is really interfering with my data

     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

Any help would be appreciated,Thank you

Upvotes: 2

Views: 2709

Answers (1)

Naros
Naros

Reputation: 21103

What you describe is precisely what Hibernate's FlushMode.AUTO implies.

Any modifications in the Persistence Context (1LC) at the time a query is executed will be automatically flushed prior to executing the query, guaranteeing that the results returned by the database match that which was cached by in-memory modifications.

If the query is going to return entities that you're seeing the update for, then you should likely re-evaluate your operations, making sure that the query fires prior to the update to avoid the flush operation, which can be quite expensive depending on the volume of entities in your Persistence Context.

If you are absolutely sure that the changes you're seeing flushed won't be returned by the query in question, you can always force the query not to cause a flush by setting the flush mode manually:

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

But only do this if you're sure that the query wouldn't then be reading uncommitted changes as this can cause lots of problems and lead to long debug sessions to understand why changes are being inadvertantly lost by your application.

Upvotes: 5

Related Questions