Avoiding IllegalStateExceptions (Unfetched attributes, etc)

I have a lot of somewhat complex code (with a lot more that will be written!) in prePersist() and preUpdate() for quite a few entities. Of course in a complex system, numerous different screens and services use these entities, all with varying views. Some of these views won’t have all the attributes in them and of course if one of those happens to be used in one of those methods…you get an ISE.

Is there a way to check before using an attribute if it is fetched or not? And then…fetch it somehow?

I don’t want to have to add everything to every view; that obviously defeats the purpose of views in the first place. As would something like using dataManager.load() every time, since sometimes (perhaps even most of the time) it won’t be a problem.

Just to be clear, what I’m looking for is something like:

if (!someEntity.someAttribute.isFetched()) {
    fetch(someAttribute);
}

Or more likely…

if (!isFetched(someEntity.someAttribute)) {
    fetch(someEntity.someAttribute);
}

Hi,
You can use com.haulmont.cuba.core.global.PersistenceHelper#isLoaded and nearby methods to check if particular attribute is loaded.
There are no methods that allow to load unfetched attribute(s).

If you have complex logic in the prePersist(), preUpdate() methods, I would recommend to reload all necessary associations with DataManager before accessing their fields. Such approarch would not be perfectly efficient, but the logic will become much simpler.

Also you should take a look to entity changed event listeners as an alternative to implement “before update / before insert” logic:
https://doc.cuba-platform.com/manual-7.2/entityChangedEvent.html
https://doc.cuba-platform.com/manual-7.2/entityPersistingEvent.html

EntityChangedEvent does not provide access to the entity. And this is good, because you have to load all necessary data yourself, and less likely to meet unexpected UnfetchedAttribute errors.

Again, experienced CUBA developers can use isLoaded() magic as one of tools in their pocket, but it should be a last resort, because the code becomes harder to read and maintain.

I’d recommend using EntityStates bean instead of PersistenceHelper static methods. The latter will be deprecated in the future.