I have this table that has a metadata
jsonb column, that's supposed to be a json array of data about other tables/PKs. I am able to insert rows into the database, but am having a hard time mapping the the record into the data class, due to this json column.
CREATE TABLE IF NOT EXISTS tracked_event
(
id uuid primary key,
user_id uuid references "user" not null,
-- other columns
metadata jsonb not null
);
And I have a data class for it:
data class TrackedEvent(
val id: UUID,
val userId: UUID,
// other fields
val metadata: List<Metadata>
)
data class Metadata(
val tableRef: String,
val value: UUID
)
I can create a row just fine for it like so:
fun createTrackedEvent(trackedEvent: TrackedEvent): TrackedEvent {
val record = dslContext.newRecord(TRACKED_EVENT, trackedEvent)
record.metadata = JSONB.jsonb(objectMapper.writeValueAsString(trackedEvent.metadata))
record.store()
return record.into(TrackedEvent::class.java) // issue here
}
However, that last line of code has a serializing issue:
Resolved [org.springframework.http.converter.HttpMessageNotWritableException: Could not write JSON: object is not an instance of declaring class; nested exception is com.fasterxml.jackson.databind.JsonMappingException: object is not an instance of declaring class (through reference chain: com.my.project.TrackedEvent["metadata"]->java.util.ArrayList[0]->java.util.LinkedHashMap["tableRef"])]
Note that if I change the data class to use an Array
instead of a List
, it works fine. But I think this should be able to work with the Kotlin's List instead?
data class TrackedEvent(
val id: UUID,
val userId: UUID,
// other fields
val metadata: Array<Metadata> // this works but then it asks me the following: Property with 'Array' type in a 'data' class: it is recommended to override 'equals()' and 'hashCode()'
)
The best approach is to attach a Converter
directly to your generated code as documented here:
That way, the conversion from/to JSONB
/ List<MetaData>
will be done transparently, whenever you access this information. Code generation configuration from the above documentation:
<configuration>
<generator>
<database>
<forcedTypes>
<forcedType>
<userType><![CDATA[kotlin.Array<com.example.Metadata>]]></userType>
<jsonConverter>true</jsonConverter>
<includeExpression>(?i:tracked_event\.metadata)</includeExpression>
</forcedType>
</forcedTypes>
</database>
</generator>
</configuration>
See the docs for more details, and additional dependencies required.