Babak Behzadi
Babak Behzadi

Reputation: 1256

How to prevent Hibernate cache?

I'm working on an web application using Hibernate 4, Spring 3. I'm struggling with an issue for days.

In the application I have an entity class named 'User':

@Entity
public class User {

    @Id
    private int uid;
    @Column(unique = true)
    private String username;
    private String password;
    private boolean confirmed;

    //... getters and setters
}

This entity class is mapped from a table of db called 'user'.

There is another entity class named 'Confirmation':

@Entity
@NamedQueries({
        @NamedQuery(name = "getAllConfirmations", query = "select c from Confirmation c")
})
public class Confirmation {

    @Id
    private String username;
    private boolean confirmed;

    //... getters and setters    
}

This entity class is mapped from a view of db called 'confirmation'.

create view confirmation
as 
select username,confirmed from user

I have a method in my service class to get list of all Confirmation object:

public List<Confirmation> getListOfConfirmations() {
    Query query = entityManager.createNamedQuery("getAllConfirmations");
    return query.getResultList();
}

Also, there's a method to confirm User objects- set confirmed field 'true':

public int confirmUser(int uid) {
    User user = getUser(uid);
    if (user != null) {
        user.setConfirmed(true);
        try {
            entityManager.getTransaction().begin();
            entityManager.merge(user);
            entityManager.getTransaction().commit();
            return 1;
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    return 0;
}

When I call confirmUser() it works fine and User object and it's row in database would be changed, But when I call getListOfConfirmations() after changes no change would be viewed in the result list.

It seems, by default, hibernate caches query result of views.

Is there any way to prevent hibernate to prevent caches this result.

In addition, I've tried @Cacheable(false) for Confirmation class or set @QueryHint(name = "org.hibernate.cacheable", value = "false") for getAllConfirmations named query, these don't work.

Persistence config:

<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="2.0">
     <persistence-unit name="MyPU" transaction-type="RESOURCE_LOCAL">
         <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>

         <class>bob.jpacache.Confirmation</class>
         <class>bob.jpacache.User</class>

         <exclude-unlisted-classes>false</exclude-unlisted-classes>
         <properties>
             <property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver"/>
             <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5InnoDBDialect"/>
             <property name="hibernate.connection.url" value="jdbc:mysql://localhost/cachetest"/>
             <property name="hibernate.connection.username" value="root"/>
             <property name="hibernate.connection.password" value="root"/>
             <property name="hibernate.hbm2ddl.auto" value="update"/>
             <property name="hibernate.show_sql" value="true"/>
             <property name="hibernate.format_sql" value="true"/>
         </properties>
     </persistence-unit>
</persistence>

Thanks, in advance, for your help.

Upvotes: 0

Views: 1189

Answers (1)

Marlon Patrick
Marlon Patrick

Reputation: 2456

@Cacheable refers to the second-level cache and your problem seems to me that it is in the first level cache. I believe that the problem is in the life cycle of your EntityManager (at what time you create a new, at what time you close it), do a simple test: after the change of the User's objects, try call entityManager.clear () and then query your Confirmation object. NOTE: entityManager.clear () must be called on the same EntityManager that will be used to make the query.

Another detail, do not know what his real purpose, but the query has no filter. Thus, whether the User has to confirm or not, will always bring all records of User table.

Upvotes: 1

Related Questions