【问题标题】:Managed objects not deleted by HQL queryHQL 查询未删除的托管对象
【发布时间】:2013-09-08 02:33:24
【问题描述】:

我正在开发 Hibernate(3.3.2.GA - 并且由于该软件应该很快发布,因此没有时间更新)应用程序的继承代码库,我正在尝试从其中删除一些对象数据库。 通过 HQL 查询删除对象后,仍然可以通过(MyEclipse 生成的)dao 的 findById 方法从休眠会话中检索对象。为了让对象消失,我有什么遗漏吗?我需要使一些缓存无效吗?在等待看似随机的一段时间(大约 30 到 300 秒之间)后,findById 开始返回 null。 对象使用复合 ID。这会是个问题吗?

这里是删除对象的代码:

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

这是之后调用以从数据库中检索对象的代码。我希望这会返回 null,但事实并非如此。

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

objDao.findById 是这样实现的:

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

感谢任何帮助!

【问题讨论】:

  • objDao.getSession() 是做什么的?
  • 如果存在,它会检索 ThreadLocal org.hibernate.Session,如果不存在,它会使用 org.hibernate.SessionFactory 创建一个新的 Session。 HQL 和 findById 代码在同一个线程中调用(两个代码块使用同一个会话)。用于创建 SessionFactory 的配置将“org.hibernate.cache.NoCacheProvider”设置为缓存提供者
  • JPA 规范规定批量UPDATE/DELETE JPQL 查询直接映射到数据库操作。这会导致持久性上下文和二级缓存都变得陈旧(至少根据规范和我对 EclipseLink 的经验)。我想你的情况也是如此,但我没有足够的 Hibernate 经验来自信地说:P。请参阅此this answer 关于使缓存无效的内容。
  • DannyMo:感谢您的评论!它有很大帮助。我现在正在清除 HQL 删除后的会话,并且一切正常。如果您可以重新发布您的评论作为答案,我很乐意接受!

标签: java hibernate hql jpql


【解决方案1】:

不确定您是如何获得会话的,但建议您进行以下操作:

getSessionFactory().openSession();

这样您将始终获得一个新会话,并且不会返回之前会话中缓存的任何内容。

干杯!!

【讨论】:

  • 我确信这会起作用,但我不确定是否一直创建新会话是一个好主意(它也不允许我执行 HQL 删除和休眠 .save() s 这可能会在同一事务中稍后发生,还是我遗漏了什么?)
猜你喜欢
  • 2023-03-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-01
  • 1970-01-01
  • 2011-08-21
相关资源
最近更新 更多