Home > Blockchain >  Storing Kotlin Generics in a single database table
Storing Kotlin Generics in a single database table

Time:10-24

I'm trying to implement a way of using a single database table to hold a number of application settings of varying object types.

I figured I would use generics in order to do this, however, I don't think I'm doing it correctly. This is what my entity looks like so far:

@Entity
@Table(name = "table_application_settings")
data class ApplicationSetting<T>(
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "application_setting_id")
    val id: Long? = null,

    @Column(name = "application_setting_name")
    var name: String = "",

    @Column(name = "application_setting_value")
    var value: T? = null,
)

My Repository:

@Repository
interface ApplicationSettingsRepository : JpaRepository<ApplicationSetting<*>, Long> {
    fun findApplicationSettingByName(name: String): ApplicationSetting<*>
}

My Service:

@Service
@Transactional
class ApplicationSettingsServiceImpl(
    private val applicationSettingsRepository: ApplicationSettingsRepository,
) : ApplicationSettingsService {
    override fun saveBooleanApplicationSetting(applicationSetting: ApplicationSetting<Boolean>): ApplicationSetting<Boolean> {
        return applicationSettingsRepository.save(applicationSetting)
    }

    override fun saveIntegerApplicationSetting(applicationSetting: ApplicationSetting<Int>): ApplicationSetting<Int> {
        return applicationSettingsRepository.save(applicationSetting)
    }

    override fun getAllApplicationSettings(): MutableList<ApplicationSetting<*>> {
        return applicationSettingsRepository.findAll()
    }
}

However, I get the following error when I then try to run the application:

Caused by: org.hibernate.AnnotationException: Property com.jre.hireout.database.entities.application.ApplicationSetting.value has an unbound type and no explicit target entity. Resolve this Generic usage issue or set an explicit target attribute (eg @OneToMany(target=) or use an explicit @Type

I get that I'm having an annotation issue, however I'm unsure how to fix it along with getting this to work as intended.

CodePudding user response:

There is no support for entities with generics in JPA.

The closest you can get is probably to have an entity that keeps the value as String which I guess is what you use in the database as well.

And then have a couple of methods to returning the value using different types, e.g. valueAsInt.

You will need to do the conversion yourself.

An alternative would be to have an inheritance hierarchy. But by default that would map the value to different columns. I'm not sure if you could map it to the same column without anything blowing up.

  • Related