Thursday, 19 December 2024

Kotlin and Java and Interfaces and Automatic Getters and Setters

Kotlin is great, Java is great, but there are sometimes little things that can be a little bit tricky. Especially when combining the two.

I am going to talk about one tricky thing now.

So we have an interface in Java:

And I wish to implement it using an enum in Kotlin.

Like so:

Obviously this will break, because a public val description automatically gets a getter in Kotlin, which conflicts with the implementation of the getDescription method.

You'll get error messages during compile time like this:

Platform declaration clash: The following declarations have the same JVM signature (getDescription()Ljava/lang/String;):
Platform declaration clash: The following declarations have the same JVM signature (getDescription()Ljava/lang/String;):

Well, you think, that's fine. If Kotlin already makes a getDescription automatically, I can simply remove my method getDescription() from the enum.

But that doesn't work. It immediately starts complaining that you have not implemented all members of the interface.

The way to solve it is to make the description field private ("private val description: String") so Kotlin no longer automatically creates a getter.

Trivial but a bit surprising.

From what I can tell, Kotlin is being careful not to create what they call "accidental overrides".

References

YouTrack - KT-6653 - Kotlin properties do not override Java-style getters and setters (created 10 years ago)
https://youtrack.jetbrains.com/issue/KT-6653
YouTrack - KT-19444 - Add JVM-specific annotation to permit "accidental" overrides of interface members
https://youtrack.jetbrains.com/issue/KT-19444

Thursday, 12 December 2024

Postgres and Migrating Databases

So, it's doable to transfer all data from an Oracle database structure into a similar (hopefully exactly the same) database structure in Postgres.

One of the problems you encounter, is the Foreign Keys. These will get triggered when inserting data .

Now, in a perfect scenario, you know that the Oracle database structure, which also has the same Foreign Keys, is fine, so we won't need to check the Foreign Keys in Postgres when inserting data.

You cannot turn off Foreign Keys in Postgres, however, Postgres automatically creates system triggers for Foreign Keys that check if referential integrity is maintained.

So it simply comes down to temporarily disabling those triggers.

ALTER TABLE some_table DISABLE TRIGGER ALL;

And afterwards, enable them again.

ALTER TABLE some_table ENABLE TRIGGER ALL;

Problem

But what is not all data was successfully transferred? (due to network problems for instance). Now you have a Postgres database that no longer has referential integrity in all cases and you might not find out about this until God knows when.

So, you need to check afterwards if all the Foreign Keys are accounted for, i.e. does every value for a foreign key have an equivalent row in the related table?

I found a script for this at [1].

References

[1] Github.com - enrico-lt/ForeignKeyCheck
https://github.com/enrico-lt/ForeignKeyCheck