Kotlin inline class for @Id-annotated properties
Asked Answered
D

3

7

In my business logic I have to deal with a lot of entity IDs, all of them of type String, which can cause confusion especially when you pass a couple of them as method parameters. So I thought about introducing a little type safety with inline classes. I know, inline classes are still marked as experimental in v1.3. Nevertheless, has anyone ever tried to use an inline class as the @Id property within a DB mapping context, in my case a MongoDB with Spring Data.

@Entity
class User {
   @Id
   var id: UserId
}

with

inline class UserId(val id: String)

I guess there is no unboxing of the underlying property, so _id will end up as an object in the DB? And what about Spring's CrudRepository interfaces? It seems compilable but will it work eventually:

interface UserRepository : CrudRepository<User, UserId>

Probably using AttributeConverter to convert the inline class to a primitive might do the job. Any experiences with this?

Desai answered 3/1, 2020 at 15:50 Comment(2)
No progress so far. When trying to store an inline class to MongoDB, I end up with this: Caused by: java.lang.ArrayIndexOutOfBoundsException: 3 at org.springframework.data.mapping.model.PreferredConstructorDiscoverer$Discoverers.buildPreferredConstructor(PreferredConstructorDiscoverer.java:221) ~[spring-data-commons-2.2.3.RELEASE.jar:2.2.3.RELEASE] Registering CustomConversion from UserId to String and vice versa hasn't helped so far :-/ Changing the type from UserId to String, everything works fine.Desai
The following may be an alternative solution for avoiding primitive types - but I don't know yet if the idea has legs... #77150616Assorted
A
2

As an update to @JuergenZimmermann's answer, this is supported in Spring Data Commons starting from version 3.2 (which is currently release candidate):

https://github.com/spring-projects/spring-data-commons/releases/tag/3.2.0-M1

Then the code as written by the OP should work out as given. For more detailed discussion, see here: https://github.com/spring-projects/spring-data-commons/pull/2866

Assorted answered 24/7, 2023 at 13:47 Comment(0)
O
1

Inline classes result in completely new types, not just a typed Alias. Even if our code base knows what this new type is the MongoDB doesn't right? So you cannot store the inline class directly into the corresponding primitive type Fields

Oryx answered 10/3, 2020 at 9:14 Comment(0)
A
0

There is an unresolved ticket for Spring Data Commons: https://github.com/spring-projects/spring-data-commons/issues/1947

Apricot answered 3/5, 2021 at 2:22 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.