增强型 For 循环仅使用第一次循环的值而不是循环完成后的更新值

Enhanced For-Loop only uses value from first loop instead of the updated value after a loop has been completed

编辑:更新了我的post,第一部分有图片是更新编辑

我使用 Android 房间数据库。我想删除事务对象。通过这样做,与该交易相关联的会员的余额将被交易金额扣除。第一个循环运行良好。但是第一个循环之后的每个循环都有这个问题:它总是使用第一个循环的 getBalance 值而不是更新后的值。我使用调试器找到了问题,我注意到了这一点:

在这个例子中,我删除了两个交易,它们都链接到同一个成员。

交易 ID 正在更改,但这是正确的,因为我删除了两个不同的交易。

两个成员列表的编号也不同。我觉得是对的,因为每笔交易里面都有不同的成员,所以会得到不同的列表。

但是会员号变了(应该只有一个会员,不应该用同一个号吗?)。我认为,这可能也是它在每个循环中使用旧的 getBalance 的原因。我使用@Update 方法,那么为什么它在第一个循环之后不使用更新后的值?

这段代码是这样工作的: 我有很多交易。此代码针对每个交易循环。假设我有两个交易,第一个有 deletebalance = 10,第二个有 deletebalance = 5。我有两个成员,第一个有 helper = 30 和 helper = 10。

通常,在循环结束后,我应该为第一个成员设置余额 = 15,为第二个成员设置余额 = -5。

第一个事务启动循环。它正常工作,我有第一个成员的余额 = 20,第二个成员的余额 = 0.

第二个事务开始循环。这就是问题所在:它没有使用 20 和 0 作为助手,而是使用旧值 30 和 10 作为助手。它不使用我在循环中的 setbalance 方法中设置的值。

我可以拥有任意数量的事务,它总是使用第一个循环中的助手。我怎样才能让循环在下一个事务开始循环时使用更新后的值?

我得到适配器传递的事务 ID。

for (String transactionid : transactionArray){
    Transaction transaction = mTransactionViewModel.getTransaction(Long.parseLong(transactionid));
    final BigDecimal deletebalance = transaction.getBalance();

    List<Member> members = mTransactionViewModel.getMembersFromTransactionList(Long.parseLong(transactionid));

    for (Member member : members) {
        if (member != null) {
        BigDecimal helper = member.getBalance();
        BigDecimal helpbalance = helper.subtract(deletebalance);
        member.setBalance(helpbalance);
        mMemberViewModel.update(member);
        }
    }
}

成员实体:

@PrimaryKey(autoGenerate = true)
@ColumnInfo(name = "MemberID")
private long id;

@ColumnInfo(name = "FirstName")
private String firstname;

@ColumnInfo(name = "Surname")
private String surname;

@ColumnInfo(name = "MemberBalance")
private BigDecimal balance;

public String getFirstname() {
    return firstname;
}

public void setFirstname(String firstname) {
    this.firstname = firstname;
}

public String getSurname() {
    return surname;
}

public void setSurname(String surname) {
    this.surname = surname;
}

public BigDecimal getBalance() {
    return balance;
}

public void setBalance(BigDecimal balance) {
    this.balance = balance;
}


public long getId() {
    return id;
}

public void setId(long id) {
    this.id = id;
}

public Member(String firstname, String surname) {
    this.firstname = firstname;
    this.surname = surname;
    this.balance = new BigDecimal(0).setScale(2, RoundingMode.HALF_EVEN);
}

这就是我试图实现的目标:我删除了多个交易并且我想减去每个成员的所有交易值。每个交易都经过这个循环,第一个交易从所有成员中删除并减去它的值,然后第二个交易从所有成员中删除并减去它的值,等等

例如:我们只看一位会员。

BigDecimal helper = member.getBalance();

这里helper是30

BigDecimal helpbalance = helper.subtract(deletebalance);

助手 (30) - deletebalance (10) = 20

member.setBalance(helpbalance);

member.setBalance(20);

mMemberViewModel.update(member);

内循环结束。外循环以下一个事务开始下一个循环。

但是下一个循环会发生什么? this:它与第一个循环中的成员相同,但与下一个事务相同。这里的成员应该有更新后的值。 getBalance 应该给出值 20。然后从 20 中扣除第二个交易值。这是实际发生的情况:

BigDecimal helper = member.getBalance();

在这里,helper 是 30,但它应该是 20,因为第一个循环使用 setBalance 将值设置为 20。

BigDecimal helpbalance = helper.subtract(deletebalance);

助手 (30) - deletebalance (10) = 20 应该是这样的:helper(20) - deletebalance(5) = 15

member.setBalance(helpbalance);

member.setBalance(15);

mMemberViewModel.update(member);

在你的内部循环中,为了测试,通过它的 id 重新加载成员实体。

Member currentMember = entityManager.get(member.id)

如果它具有正确的值,则您的实体正在存储,问题是 mMemberViewModel.update(member)/getMembersFromTransactionList 正在使用状态实体。如果是那种情况,我们也必须查看该代码。

如果该值是错误的,则说明您没有在外循环之间提交事务。


您确定您在致电时会得到相同的成员吗:

List<Member> members = mTransactionViewModel.getMembersFromTransactionList(Long.parseLong(transactionid));

记录您的成员对象并确保它们第二次具有相同的 ID。

如果它们是相同的 ID,您是否提交了交易?

您是否使用旧的 TRANSACTION_ID 获取会员?

要检查您的数据库是否持久存在,请尝试这样的操作。

List<Member> members = mTransactionViewModel.getMembersFromTransactionList(Long.parseLong(transactionid));

for (Member member : members) {
    member.setBalance(new BigDecimal(12));
}

for (Member member : members) {
    if (member.getBalance().intValue() != 12){
      // bad
    }
}

for (Member member : members) {
    mMemberViewModel.update(member);
}

for (Member member : members) {
    if (member.getBalance().intValue() != 12){
      // bad
    }
}

transactionId = NEW_TRANSACTION_ID
mTransactionViewModel.getMembersFromTransactionList(Long.parseLong(transactionid));

for (Member member : members) {
    if (member.getBalance().intValue() != 12){
      // bad
    }
}

此外,请确保您使用的是附加实体,方法是在您的提供商中使用 merge(...) 的结果值。

我能看到的唯一解释是您执行的更改没有保存在数据库中。尝试控制您是否处于事务上下文中以及事务何时结束。由于您正在为每个事务重复查询,因此您希望先前事务的更改已经保存在数据库中,请检查此。

我一次只删除一个就解决了。这对我来说很管用。