jwalgemoed
06/16/2023, 1:23 PM@Entity class Person(val id: Int?, val name: String?, val withDefault: String = "default)
Assume that the other annotations are also there. Now, given this constructor, we would need to apply the kotlin compiler plugin for JPA so it will generate a no-arg constructor. This works ok, and we can persist this entity in the database and retrieve it again.
Now when we make a small change, marking a field with a default value as transient, like this:
@Entity class Person(val id: Int?, val name: String?, @Transient val withDefault: String = "default)
This causes a strange effect; we can create an instance in Kotlin and persist it. However, when we look at the returned instance the default value is no longer applied! We did some checking and found that the cause for this was that the default constructor generated by the no-arg/jpa plug-in looks like this:
public Person() { super(); }
When marking a field as transient, no data will be read from the database and therefor the value will remain null, even though it looks from the code that the default should be applied.
There is a workaround for this, declaring your class with a default value for every field:
@Entity class Person(val id: Int? = null, val name: String? = null, @Transient val withDefault: String = "default)
When doing this, the Kotlin compiler (not the no-arg/jpa plug-in) will generate this default constructor:
public Person() { this(null, null, "default"); }
And it's this constructor that I would have expected the no-arg plugin to generate. Is this a problem with the no-arg plugin, or am I doing something I really should not be doing? Anyone have insights on this?
I realize this may be a niche issue, since it only really becomes a problem when mixing default fields with non-default and having one of them be transient.
Is my assumption regarding the jpa/no-arg plugin incorrect? Maybe it is intentional that it cannot generate the correct constructor for classes that do not define defaults for all fields. Curious to hear if there are people here that can tell me if this is a bug or something we just should not be doing -- and that the workaround is the way to deal with this particular scenario.Riccardo Lippolis
06/16/2023, 1:57 PMjwalgemoed
06/16/2023, 2:12 PMkqr
06/17/2023, 3:19 PM@Transient
bring?Riccardo Lippolis
06/17/2023, 3:22 PM@Transient
doesn't change the generated constructor, but it does prevent populating the field when reading an entity from the database via JPA, causing it to be null
(and not, as Jarno would have expected, the default value specified in the constructor)