简体   繁体   English

休眠查询未返回正确值

[英]Hibernate query not returning correct value

So in my database, I have 3 rows, two rows have defaultFlag as 0 and one is set to 1, now in my processing am updating defaultProperty of one object to 1 from 0 but am not saving this object yet. 因此,在我的数据库中,我有3行,两行的defaultFlag为0,一行设置为1,现在在我的处理中,将一个对象的defaultProperty从0更新为1,但尚未保存该对象。

Before saving I need to query database and find if any row has defaultFlag set or not, there would be only 1 default set. 保存之前,我需要查询数据库并查找是否有设置了defaultFlag的行,只有1个默认集。

So before doing update am running query to find if default is set and i get 2 values out, note here if i go and check in db then there is only 1 row with default set but query gives me two result because this.object default property has changed from 0 to 1 but note that this object is not yet saved in database. 因此,在执行更新之前运行查询以查找是否设置了默认值,并且获取了2个值,请注意,如果我去检查db,则只有1行具有默认值设置,但是查询给出了两个结果,因为this.object默认属性已从0更改为1,但请注意,该对象尚未保存在数据库中。

I am really confused here as to why hibernate query is returning 2 when there is one row with default set in database and other object whose default property has changed but it is not saved. 对于数据库中设置了默认值的一行以及其他对象的默认属性已更改但未保存的默认设置,为什么休眠查询为何返回2的问题我确实感到困惑。

Any thoughts would be helpful. 任何想法都会有所帮助。 I can provide query if need be. 我可以根据需要提供查询。

Update 更新

Following suggestions, I added session.clear() to before running the query. 根据建议,我在运行查询之前将session.clear()添加到了。

session.clear();
String sql = "SELECT * FROM BANKACCOUNTS WHERE PARTYID = :partyId AND CURRENCYID = :currencySymbol AND ISDEFAULTBANKACCOUNT= :defaultbankAccount";
                SQLQuery q = session.createSQLQuery(sql);
                q.addEntity(BankAccount.class);
                q.setParameter("partyId", partyId);
                q.setParameter("currencySymbol", currencySymbol);
                q.setParameter("defaultbankAccount", 1);
                return q.uniqueResult();

and it returns 1 row in result as expected but now am getting 它按预期返回1行结果,但现在越来越

nested exception is org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session exception 嵌套的异常是org.hibernate.NonUniqueObjectException:具有相同标识符值的另一个对象已与会话异常关联

Either query which row has the "default flag" set before you start changing it, or query for a list of rows with default flag set & clear all except the one you're trying to set. 您可以开始更改之前查询设置了“默认标志”的行,或者查询已设置默认标志的行列表 ,并清除除您要设置的行之外的所有行。

Very easy, stop mucking about with your "brittle" current approach which will break in the face of concurrency or if data is ever in an inconsistent state. 非常简单,不要再为当前的“脆弱”方法而烦恼了,因为这种方法在并发或数据处于不一致状态时会中断。 Use a reliable approach instead, which will always set the data to a valid state. 而是使用可靠的方法,该方法将始终将数据设置为有效状态。

protected void makeAccountDefault (BankAccount acc) {

    // find & clear any existing 'Default Accounts', other than specified.
    //
    String sql = "SELECT * FROM BANKACCOUNTS WHERE PARTYID = :partyId AND CURRENCYID = :currencySymbol AND ISDEFAULTBANKACCOUNT= :defaultbankAccount";
    SQLQuery q = session.createSQLQuery(sql);
    q.addEntity(BankAccount.class);
    q.setParameter("partyId", partyId);
    q.setParameter("currencySymbol", currencySymbol);
    q.setParameter("defaultbankAccount", 1);
    //
    List<BackAccount> existingDefaults = q.list();
    for (BankAccount existing : existingDefaults) {
        if (! existing.equals( acc))
            existing.setDefaultBankAccount( false);
    }

    // set the specified Account as Default.
    acc.setDefaultBankAccount( true);

    // done.
}

This is how you write proper code, do it simple & reliable. 这是您编写适当的代码,简单可靠的方式。 Never make or depend on weak assumptions about the reliability of data or internal state, always read & process "beforehand state" before you do the operation, just implement your code clean & right and it will serve you well. 切勿对数据或内部状态的可靠性做出任何虚假假设或依赖于这些假设,在执行操作之前 ,请务必先读取并处理“事前状态”,只需正确执行代码即可,将为您提供良好的服务。

I think that your second query won't be executed at all because the entity is already in the first level cache. 我认为根本不会执行第二个查询,因为该实体已经在第一级缓存中。

As your transaction is not yet commited, you don't see the changes in the underlying database. 由于尚未提交事务,因此您看不到基础数据库中的更改。

(this is only a guess) (这只是一个猜测)

That's only a guess because you're not giving many details, but I suppose that you perform your myObject.setMyDefaultProperty(1) while your session is open. 这只是一个猜测,因为您没有提供很多详细信息,但是我想您是在打开会话时执行myObject.setMyDefaultProperty(1)

In this case, be careful that you don't need to actually perform a session.update(myObject) to save the change. 在这种情况下,请注意,您不需要实际执行session.update(myObject)即可保存更改。 It is the nominal case when database update is transparently done by hibernate. 在正常情况下,休眠由数据库透明地完成数据库更新。

So, in fact, I think that your change is saved... (but not commited, of course, thus not seen when you check in db) 因此,事实上,我认为您的更改已保存...(但是,由于未提交,因此当您签入数据库时​​看不到)

To verify this, you should enable the hibernate.show_sql option. 要验证这一点,您应该启用hibernate.show_sql选项。 You will see if an Update statement is triggered (I advise to always enable this option in development phase anyway) 您将看到是否触发了Update语句(无论如何,我建议始终在开发阶段启用此选项)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM