@Entity
@Table(name = "test_table")
class Test {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
var testIdPk: Long? = null
var number: Int = 0
}
for it to work with JpaRepository, testIdPk must be nullable - otherwise, I won’t be able to save new entities.
On the other hand, anytime such entity is loaded from the database, we know testIdPk is not null.
Right now anytime I want to access testIdPk I need to !! it.
I was wondering if there is a way to mark JpaRepository methods, to tell kotlin compiler that Test objects coming from these marked methods would have non-null testIdPk. I’ve looked at contracts, but it won’t work with interfaces.
As @madmax1028 says, for simple keys, I haven’t found a better wya than supplying a dummy value (e.g. 0, -1, or "").
For other fields, especially for references to other entities, you could instead use lateinit.
Neither approach is elegant, but seem to both work well enough in practice. (For the first, there’s often a natural value to use, but in general it doesn’t matter as your code will never see it when loading existing objects; and you wouldn’t bother setting it when creating new ones.)
Thanks a lot. Somehow I was convinced that it needs to be null.
Some info on why does this work if someone else lands here:
Looking into org.springframework.data.repository.core.support.AbstractEntityInformation
there’s a method used to determine if the entity is new:
public boolean isNew(T entity) {
ID id = getId(entity);
Class<ID> idType = getIdType();
if (!idType.isPrimitive()) {
return id == null;
}
if (id instanceof Number) {
return ((Number) id).longValue() == 0L;
}
throw new IllegalArgumentException(String.format("Unsupported primitive id type %s!", idType));
}
So if I understand this correctly, in Kotlin: val testIdPk: Long = 0 would work, since here Long would be converted to primitive long,
but: val testIdPk: Long? = 0 would fail, since the first check id == null would be in effect (so it would actually save the entity with id set to 0).