3

I'm working on an inherited codebase of a Hibernate (3.3.2.GA - and since the software should be shipped rather soon there is no time to update) application in which I'm trying to delete some objects from the database. After deleting the Objects via a HQL query the objects can still be retrieved from the hibernate session via the findById method of the (MyEclipse generated) dao. Is there anything I'm missing to get the Objects to disappear? Do I need to invalidate some caches? After waiting a seemingly random while (between about 30 and 300 seconds) the findById starts to return null. The objects use a composite id. Could that be a Problem?

Here is the code to delete the objects:

Query query = objDao.getSession()
            .createQuery("DELETE FROM Obj i WHERE i.id.uuid = ? AND i.userId = ?");
query.setString(0, obj.getUuid());
query.setInteger(1, currentUserId);
objDao.getSession().beginTransaction();

int numRows = query.executeUpdate();
System.out.println("Deleted " + numRows + " Obj for uuid " + obj.getUuid() + " (user: "
            + currentUserId+ ")");
objDao.getSession().flush();
objDao.getSession().getTransaction().commit();

Here is the code that is called afterwards to retrieve the objects from the database. I would expect this to return null but it does not.

objDao.findById(new ObjectId(temp.getId(), temp.getUuid()))

objDao.findById is implemented as such:

public Obj findById(com.application.ObjectId id) {
    Obj instance = (Obj) getSession() // this returns a org.hibernate.Session
    .get("com.application.Obj", id);
    return instance;
}

Any help is appreciated!

Patrick Huy
  • 975
  • 1
  • 8
  • 19
  • What does `objDao.getSession()` do? – axtavt Sep 04 '13 at 14:29
  • It retrieves a ThreadLocal org.hibernate.Session if one exists, if not it uses a org.hibernate.SessionFactory to create a new Session. The HQL and findById code is called within the same thread (both codeblocks use the same session). The config used for creating the SessionFactory sets "org.hibernate.cache.NoCacheProvider" as cache Provider – Patrick Huy Sep 04 '13 at 14:35
  • 1
    The JPA specification states that bulk `UPDATE/DELETE` JPQL queries map directly to a database operation. This causes both the persistence context and second-level cache to become stale (at least according to the spec and my experience with EclipseLink). I'd imagine the same is true in your case, but I don't have enough experience with Hibernate to say that with any confidence :P. See this [this answer](http://stackoverflow.com/a/2400440/1671856) regarding invalidating the cache. – DannyMo Sep 04 '13 at 19:38
  • DannyMo: Thank you for the comment! It helped a lot. I'm now clearing my sessions after the HQL Delete and things are working perfectly. If you could repost your comment as an answer I'd be glad to accept it! – Patrick Huy Sep 05 '13 at 11:54

1 Answers1

0

Not sure how you are getting session, but would recommend following:

getSessionFactory().openSession();

That ways you will always get a new session and anything cached in previous session will not be returned.

Cheers !!

Sachin Thapa
  • 3,559
  • 4
  • 24
  • 42
  • I'm sure that would work but I'm not sure if creating new Sessions all the time is a good Idea (it also does not allow me to do the HQL Delete and hibernate .save()s which might happen later in the same transaction, or am I missing something?) – Patrick Huy Sep 05 '13 at 11:47