How to "reload" an entity without actually reloading it (because it's in state New), to get other fields of it?

Basically I need to “reload” an entity, to get at other fields, basically change which view I’m using, without actually calling reload because sometimes it will be in state New.

We have a fairly standard Invoice-and-its-lines composition, but in the lines there are a few transient fields. In the invoice header, there are also some transient fields, that are calculated based on the transient fields of the lines. So in the getters for the header’s transients, I sum up the lines’ transients - after using dataManager.reload() to ensure the view is changed to one that contains said transients. However, when is line is in state New, an exception is thrown.

So - how can I get at those transients, without calling dm.reload() since it throws an exception where they’re in New state?

Hi @jon.craig,
Take a look at EntityStates.

You can check if the entity is new, or if the required attribute is loaded to determine if you need to call dm.reload().

Regards,
Peterson.

1 Like

I know about that - problem is, if the entity is new and the attribute isn’t loaded… how do I load/reload it without calling dm.reload() which if I do… exception city!

I’m puzzled… If the entity is new, aren’t all attributes in memory? If so, a reload() does not make sense.

Maybe you are using related information in your transient fields that are not yet in database. If that is the case you should change your logic to calculate transient field values when the entity is new.

Regards,
Peterson.

Hmmm, why would you need to reload new entity?

No, because all of these transients are not in all views used by all screens.

Here’s a simplified explanation…in probably bad pseudo-code-ish since I’m at home:

In InvoiceLine:

(a transient attribute)

BigDecimal getExtendedPrice {
    // return price*qty
}

In Invoice:

(another transient entity)

BigDecimal getTotalAmount {
   BigDecimal total = BigDecimal.ZERO;
   for (InvoiceLine line : lines) {
       line = dm.reload(line, "name-of-view-that-has-the-transients");
       total = total.add(line.getExtendedPrice());
   }
   return total;
}

If I don’t do the reload() I get detached/not loaded attribute exceptions, but when that code gets called with a new InvoiceLine, and it will because the total amount is displayed on the invoice editor screen, of course… I get an exception as described in the OP.

So, I’m reloading to switch the view to one with the transients.

If I just skip the reload() for new lines, the total displayed on the screen doesn’t update (because the totals of the new lines aren’t getting added in because they’re skipped), obviously, so that’s no good. So I need a way to do what the reload() does…without using reload() because of the new line problem.

See post I just made!

1 Like

Hi @jon.craig,
If possible, attach a test project and describe the steps to reproduce the problem.

I don’t know if I’m understanding the situation correctly, but I’ll share more ideas that may help you:

  • Review your transient fields (‘related attributes’)
  • Use a view that includes all attributes required for your screen’s logic (I’d try to avoid the need to reload on the web module)

Regards,
Peterson.

1 Like

Not applicable in this case since here Invoice's transient depends on a transient in InvoiceLine.

That I can do, but I can’t do it in every single screen that uses Invoice - and I’ve seen from experience that those gets are going to get called all the time… and there will be exceptions. :confused:

I can make a test project easily enough tomorrow AM when I’m in the office. That’s a quickie.

1 Like