Each time I upgrade platform version, old code lose the ability to save changes to existing records

Hi all,

The symptom is that, each time I upgrade platform version, after the upgarde, the combined entity screen (list on left edit on right) lost the ability to save changes to existing records - I can create successfully, I can delete successfully, just can’t save edits. There is no error on the output whatsoever (I’m using the IntelliJ based studio at the moment, starting the server from there). The value shows changed on the list to the left, but the change is reverted on the edit side, and when I refresh the list, the list value reverts back, too.

I’ve debugged into platform code. It looks like it’s not being saved because the modified property on the Datasource object is not changed to true. But I do not know how to make it realize the object has been modified so the value is true. It seems during creation, it’s explicitly changed to true (setModified method called) but I failed to find the same code for edit mode/action.

This happened when I upgraded from an earlier version (don’t remember which) to 6.7.x. I managed to fix it back then but I don’t remember how. It could have something to do with the controller class hierarchy change in the platfrom. Looking at Git history, the controller class used to extend AbstractLookup but was changed to extend EntityCombinedScreen. Now that I have migrated from 6.7.x to 6.10.x, this problem has come back!

I guess I’m going to try generating a new generic combined edit screen and see what the new version creates but it’s frustrating how this is a repetitive issue and how I can’t get it fixed easily with a small change. Please help!

Nope. I’ve just tried generating a new generic web UI. Still not saving.

I do admit that it was a bottom up model (tables already exist), not a top down model (where tables are created and updated with generated scripts) but the data was already there, and it was already working before the version upgrade so it would be nice if I can make it work as before.

Hi Max

This is really strange.
When editing an instance, the datasource becomes modified when its modified(entity) method is called from the listener which is notified when entity attribute value changes.

Try to debug these points, maybe it will shed some light on the problem.

Thanks for the suggestion. I’ll try it when I have a chance. It won’t be for a few days though 'cause I’m stuck in a production issue… (not CUBA related).

By the way, for easier editing, I did add that project to IntelliJ as a generic/Java project. Is there a way I can convert it to a CUBA project and have access to the visual editors and other facilities? The reason I upgraded it to version 6.10 was because I wanted to use the new IntelliJ based Studio but when I opened the project in Studio, besides build errors (resolved after fiddling with Gradle) there are missing facets for some reason. Should I delete the .idea directory and re-import it into Studio? What’s the best way to do it here?

You should import it as a Gradle project. Check out this guide.
And make sure you are using the latest Studio IntelliJ Plugin.

My apologies. I did import it as a Gradle project. Still, no sign of visual editors after the upgrade to platform 6.10.

Hi Konstantin, I had another try with the debugger, the modified(entity) method was never called… The entity does appear to be of the correct type though, because the isModified() method was called. What does that suggest? There is something wrong with the generated GUI web page?

Looks like the entity class is not properly enhanced at build time. Try to clean and rebuild the project:

gradlew clean assemble

Hi,

Regarding the project import issue.
First please make sure your project is .idea directory based.

Also please check dependencies in your build.gradle.
For the projects migrated from old CUBA versions manual dependencies update may be needed.
cuba and other application components should be defined as
appComponent("com.haulmont.cuba:cuba-global:$cubaVersion")
in the dependencies section in the root of your build script.
Not as a classpath dependency of buildscript section.
You can always create new project and use it’s build.gradle file as a reference.

Hi Alexander, is this 7.0.x you are talking about? I created a new 6.10.x project using the IntelliJ based Studio and did not find addComponent() in the root build.gradle.

Is it a good idea, since I’m already upgrading the version, to go from 6.7.x to 7.0.2, or should it be easier to go from 6.7.x to 6.10.x and fix the IDEA project and hopefully the saving issue I’m having?

I’ve manipulated the cuba-platform.xml in .idea directory and now getting the visual editor for entity classes. Places I changed include repositories and gradle version. The newly generated project had 4.3 while the migrated one had 4.10 (I think I changed it to that).

Hi Konstantin, unfortunately this did not make a difference. I’ve gone back and looked at the generated SQL scripts because I have been ignoring them from day 1 - because I created the tables first.

Now I’ve diabled generate scripts on some of the entities which are pure mapping of inherited tables which already contained data and is not for CUBA to modify, that’s better, fewer scripts were generated - only those for new tables since the beginning of this CUBA project. That was great. However, the generated scripts failed to execute, now that I can afford to let the deploy task execute them because the untouchable tables are out of the way for script generation.

The first one (and only one so far, because build stops on first error) which failed contained this:
alter table UW_LEVEL_LIMIT add UW_LIMIT_TYPE_ID bigint not null ;
Well that’s never gonna work, because the colume is a foreign key column. I had a look at the table, it’s currently in a undetermined state because of a previous (failed) attempt of executing update scripts. The two foreign key columns are temporarily renamed and constraints dropped. I think this is something missing in your database table script generation - a rollback function in case any script execution fails.

But this still does not explain why the modified(item) method was not invoked. I’ll try to fix the database and see if it recovers.

Hi Max,

The database structure cannot affect the issue with saving changes.

In order to check if the entity is properly enhanced, unpack *-global.jar and open the *.class file in IntelliJ. The decompiled class should have PersistenceWeaved, PersistenceObject, PersistenceWeavedFetchGroups, PersistenceWeavedLazy, PersistenceWeavedChangeTracking, CubaEnhanced interfaces.

Hi,

Both 7.0.x and 6.10.x are the same.

Here is the legacy build script fragment. Note the classpath dependencies.
This format is not supported in Studio IntelliJ edition.

buildscript {
    ext.cubaVersion = '6.9.8'
    repositories {
        ...
    }
    dependencies {
        classpath "com.haulmont.gradle:cuba-plugin:$cubaVersion"
        classpath "com.haulmont.cuba:cuba-global:$cubaVersion"
        classpath "com.haulmont.reports:reports-global:$cubaVersion"
    }
}

Here is the supported format.
Only cuba gradle plugin dependency left as a classpath. While cuba-global and reports-global dependencies defined as appComponent()

buildscript {
    ext.cubaVersion = '6.10.8'
    repositories {
        ...
    }
    dependencies {
        classpath "com.haulmont.gradle:cuba-plugin:$cubaVersion"
    }
}

...

dependencies {
    appComponent("com.haulmont.cuba:cuba-global:$cubaVersion")
    appComponent("com.haulmont.reports:reports-global:$cubaVersion")
}

Studio IntelliJ edition doesn’t support CUBA versions prior to 6.10.
So migration from version 6.7.x to 7.0.x need to be performed in two steps. First open it in Studio 6.10 and update version to 6.10.x. Then you can import the project as a Gradle project in the Studio Intellij (see guide for details).
As it was mentioned before, your project should be .idea directory based, .ipr project format is not supported.
When you have CUBA menu and CUBA project tree available you can migrate platform version from 6.10.x to 7.0.x if needed.

I’ve checked database structure and found that some key fields were in interim state, a result from previous failed database update scripts. I corrected the schema manually and disabled script generation on all entities. But still, the server wouldn’t start because some fields in some tables were not mapped in entities. I then map those fields, the server starts now, but we are back to the same point where modify fails to save.

I checked the decompiled .class for the entity which is failing to save, it has none of those interfaces. I did clean assemble several times. Any ideas how to fix this? Should I try what Alex suggested and upgrade the build script to see if it makes a difference?

On a side note, please don’t make the application fail to start because some extra fields in a database table is not mapped. It’s relevant if those fields are mandatory, but can be left out with a warning if they are nullable. The platform is extremely capable, but it would be nice if it can make peace with established tables. The best capability I’m trying to leverage here is the generic GUI. Sometimes that’s all your users/customers need - a generic GUI so they don’t fiddle with database records directly, which is difficult and error-prone.

I unpacked and decompiled a newly generated 6.10.x entity class file and it was correctly enhanced with all the interfaces. I checked the entity class source code and persistence.xml, compared it with the one which is failing to enhance, didn’t find any noticeable difference. Both are annotated javax.persistence.Entity, both are listed in persistence.xml. The only difference is for the newly created test one, I’ve chosen to generate DDL and have let CUBA create the database structure. But it doesn’t work with my old database because there is data in there, it’s hard to migrate the data to a new database because of foreign key based relationships.

Check that the entity is located in the global module and build.gradle contains the entitiesEnhancing section:

configure(globalModule) {
    // ...

    entitiesEnhancing {
        main {
            enabled = true
        }
    }
}

Thanks for your reply. I actually started looking at the build.gradle file yesterday and aligned it with the new 6.10.x script generated in a new test project and this resolved the enhancement issue.

Thank you for your help. It would be nice going forward if upgrades to newer versions can be made easier. Last time it was class heirarchy. This time it was changed gradle scripts. Fix was easy but it takes a lot of time to invetigate.

Normally, Studio changes build.gradle automatically when you upgrade to a newer version. Did you use Studio or just changed the platform version in build.gradle manually?