java Hibernate 不会删除我的对象。为什么?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5235868/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 10:07:56  来源:igfitidea点击:

Hibernate is not deleting my objects. Why?

javahibernatejunit4

提问by oligofren

I have just set up a test that checks that I am able to insert entries into my database using Hibernate. The thing that drives me crazy is that Hibernate does not actually delete the entries, although it reports that they are gone!

我刚刚设置了一个测试,用于检查我是否能够使用 Hibernate 将条目插入到我的数据库中。让我发疯的是 Hibernate 实际上并没有删除这些条目,尽管它报告说它们已经消失了!

The test below runs successfully, but when I check my DB afterwards the entries that were inserted are still there! I even try to check it using assert(yes I have -ea as vm parameter). Does anyone have a clue why the entries are not deleted?

下面的测试成功运行,但是当我之后检查我的数据库时,插入的条目仍然存在!我什至尝试使用断言来检查它(是的,我有 -ea 作为 vm 参数)。有没有人知道为什么不删除条目?

public class HibernateExportStatisticDaoIntegrationTest {
    HibernateExportStatisticDao dao;
    Transaction transaction;

    @Before
    public void setUp(){
        assert numberOfStatisticRowsInDB() == 0;
        dao = new HibernateExportStatisticDao(HibernateUtil.getSessionFactory());
    }

    @After
    public void deleteAllEntries(){
        assert numberOfStatisticRowsInDB() != 0;
        Session session = HibernateUtil.getSessionFactory().getCurrentSession();
        for(PersistableStatisticItem item:allStatisticItemsInDB()) {
            session.delete(item);
        }
        session.flush();
        assert numberOfStatisticRowsInDB() == 0;
    }

    @Test public void exportAllSavesEntriesToDatabase(){
        int expectedNumberOfStatistics = 20;
        dao.exportAll(StatisticItemFactory.createTestStatistics(expectedNumberOfStatistics));

        assertEquals(expectedNumberOfStatistics, numberOfStatisticRowsInDB());
    }

    private int numberOfStatisticRowsInDB() {
        return allStatisticItemsInDB().size();
    }

    @SuppressWarnings("unchecked")
    private List<PersistableStatisticItem> allStatisticItemsInDB(){
        Session session = HibernateUtil.getSessionFactory().getCurrentSession();
        transaction = session.beginTransaction();
        Query q = session.createQuery("FROM PersistableStatisticItem item");
        return q.list();
    }
}

The console is filled with

控制台充满了

Hibernate: delete from UPTIME_STATISTICS where logDate=? and serviceId=?

but nothing has been deleted when I check it.

但是当我检查时没有删除任何内容。

回答by axtavt

I guess it's related to inconsistent use of transactions (note that beginTransaction()in allStatisticItemsInDB()is called several times without corresponding commits).

我想这与事务的不一致使用有关(请注意,beginTransaction()allStatisticItemsInDB()没有相应提交的情况下多次调用in )。

Try to manage transactions in proper way, for example, like this:

尝试以适当的方式管理事务,例如,像这样:

Session session = HibernateUtil.getSessionFactory().getCurrentSession();
Transaction tx = session.beginTransaction();
for(PersistableStatisticItem item:
    session.createQuery("FROM PersistableStatisticItem item").list()) {
    session.delete(item);
}
session.flush();
assert session.createQuery("FROM PersistableStatisticItem item").list().size() == 0;
tx.commit();

See also:

也可以看看:

回答by Neeraj Bansal

I have the same problem. Although I was not using transaction at all. I was using namedQuery like this :

我也有同样的问题。虽然我根本没有使用事务。我像这样使用namedQuery:

Query query = session.getNamedQuery(EmployeeNQ.DELETE_EMPLOYEES);
int rows = query.executeUpdate();
session.close();

It was returning 2 rows but the database still had all the records. Then I wrap up the above code with this :

它返回 2 行,但数据库仍然有所有记录。然后我用这个结束上面的代码:

Transaction transaction = session.beginTransaction();
Query query = session.getNamedQuery(EmployeeNQ.DELETE_EMPLOYEES);
int rows = query.executeUpdate();
transaction.commit();
session.close();

Then it started working fine. I was using SQL server. But I think if we use h2, above code (without transaction) will also work fine. One more observation : To insert and get records usage of transaction is not mandatory but for deletion of records we will have to use transaction. (only tested in SQL server)

然后它开始正常工作。我正在使用 SQL 服务器。但是我认为如果我们使用 h2,上面的代码(没有事务)也可以正常工作。另一个观察:插入和获取记录使用事务不是强制性的,但对于删除记录,我们将不得不使用事务。(仅在 SQL 服务器中测试过)

回答by Al Dass

Can you post your DB schema and HBM or Fluent maps? One thing that got me a while back was I had a ReadOnly() in my Fluent map. It never threw an error and I too saw the "delete from blah where blahblah=..." in the logs.

你能发布你的数据库架构和 HBM 或 Fluent 地图吗?让我回过头来的一件事是我的 Fluent 地图中有一个 ReadOnly()。它从未抛出错误,我也在日志中看到了“从 blahblah=... 中删除”。