I'm kinda confused of using null safety in Kotlin by Spring JPA/Hibernate for database entities. How to profit from it when I have such case:
@Entity
@Table(name = "plan")
class Plan(
@Id
@GeneratedValue
var id: UUID? = null,
@Type(JsonType::class)
@Column(name = "name", columnDefinition = "jsonb")
var name: MutableMap<String, String> = HashMap(),
@ManyToOne
@JoinColumn(name = "category_id")
var category: Category,
)
@Entity
@Table(name = "category")
class Category(
@Id
@GeneratedValue
var id: UUID? = null,
@Column(name = "name")
var name: String,
)
I have example usecase that is responsible for creation of new Plan (no need for more complex code cuz simple scenario is enough):
@Component
class CreatePlan(
private val planRepository: PlanRepository,
) {
@Transactional
fun create(plan: Plan) {
planRepository.save(plan);
}
}
Usecase is taking domain class Plan which is provided as example from rest controller where is happening mapping from request class to domain class.
I can not provide to CreatePlan.create Plan object cuz in order to instantiate it I have to provide all the fields/properties - In rest controller we have such request class:
data class PlanRequest(
@field:NotEmpty
@JsonProperty("name")
val name: MutableMap<String, String> = HashMap(),
@field:NotNull
@JsonProperty("category_id")
val categoryId: UUID?,
)
In order to map from PlanRequest to Plan I have to provide in Plan class category field since it is not nullable. In Java it would be simple like this:
new Plan(name, new Category(categoryId))
cuz of null safety we can not do it in Kotlin without making Category class fields nullable.
This example is just simple case but imagine that entities have more relationships and they are nested then it is forcing to make every possible field that is declared in entity classes to be nullable and we lose the advantage of null safety.
I imagine as workaround creating some secondary constructor with id parameter and setting up all other fields with dummy data, but I don't like this approach. I can't also imagine that the other possible solution is to create some DTOs to just pass data from controller to use case in order to fetch from database Category by id to provide it later for Plan to save it.
Did anybody faced with such issue? Is there other better solution to approach it?