Issue
I'm not entirely sure how to populate the Audit Columns I specify in my project.
I configured a integer-type user id as my "user" column:
ForcedType().apply {
isAuditUpdateUser = true
name = "int"
includeExpression = "last_modifier"
},
ForcedType().apply {
isAuditUpdateTimestamp = true
name = "timestamptz"
includeExpression = "last_modified"
}
To quote the documentation:
All such audit columns compute their actual value from Configuration.auditProvider(), which allows for overriding the org.jooq.impl.DefaultAuditProvider behaviour
So I was expecting to be able to declare a configuration like this in the server
module:
@Configuration
class JooqConfig(
private val principalService: PrincipalService, //has access to spring security context
) {
@Bean
fun configurationCustomizer() = DefaultConfigurationCustomizer { c: DefaultConfiguration ->
c.setAuditProvider(auditProvider())
}
@Bean
fun auditProvider(): AuditProvider = PrincipalAwareAuditProvider(principalService)
private class PrincipalAwareAuditProvider(private val principalService: PrincipalService) : DefaultAuditProvider(){
override fun <T : Any?> provideUser(ctx: GeneratorContext<*, *, T>): Field<T>? {
val userId = principalService.currentUserId()
return ctx.field()?.let { field ->
when(field.dataType.type){
Int::class.java -> TODO("do something with userId")
else -> null
}
}
}
override fun <T : Any?> provideTimestamp(ctx: GeneratorContext<*, *, T>?): Field<T>? {
TODO("figure out what to do about this")
}
}
}
BUT I'm not sure how or why to create a Field
out of the userId
.
Am I trying to do this in the wrong place?
How do I fill the audit columns with values?
Solution
The point of returning a Field<T>
(an expression) rather than just the value T
(a client side value) is, well, to allow for creating expressions.
Imagine you're using e.g. Oracle's SYS_CONTEXT
to populate contextual values like that directly from within the database. How could you possibly access SYS_CONTEXT
expressions if this SPI didn't allow you to provide a Field<T>
?
If your value is purely client side generated, then just wrap it in a bind value, explicitly. But a bind value is just a special case of the more generic case where you produce server side expressions.
Answered By - Lukas Eder
Answer Checked By - Clifford M. (JavaFixing Volunteer)