W tym artykule omówimy, jak dostosować mapowanie typów kolumn w bibliotekach jOOQ i Hibernate. Często zdarza się, że domyślne mapowania typów danych nie spełniają specyficznych wymagań naszego projektu. Dlatego ważne jest, aby wiedzieć, jak wprowadzać customowe mapowania, które pozwolą na bardziej precyzyjne odwzorowanie struktur danych w bazie danych
Dlaczego warto używać forcedTypes w jOOQ?
Korzystanie z opcji forcedTypes pozwala na precyzyjne określenie, jak dane kolumny w bazie danych powinny być mapowane do typów w Java. Domyślnie, jOOQ mapuje pola Instant / OffsetDateTime z wykorzystaniem pluginu jOOQ-Hibernate na LocalDateTime, co może powodować problemy, gdy pracujesz z danymi Timestamp zawierającymi strefę czasową np UTC. Dzięki forcedTypes unikniesz problemów z niezgodnością typów i zapewnisz lepszą kontrolę nad generowanym kodem, szczególnie w przypadku Timestamp z UTC.
Przykład konfiguracji forcedTypes
Oto przykładowa konfiguracja, która wymusza mapowanie pól Timestamp do typu Instant wraz ze strefą czasową UTC w maven:
<forcedTypes>
<forcedType>
<name>Instant</name>
<userType>java.time.Instant</userType>
<converter>com.example.LocalDateTimeToInstantConverter</converter>
<expression>TABLE.SOME_TIMESTAMP_COLUMN</expression>
</forcedType>
<forcedType>
<name>Instant</name>
<userType>java.time.Instant</userType>
<converter>com.example.LocalDateTimeToInstantConverter</converter>
<expression>TABLE.SOME_TIMESTAMP_COLUMN</expression>
</forcedType>
<forcedType>
<name>Instant</name>
<userType>java.time.Instant</userType>
<converter>com.example.LocalDateTimeToInstantConverter</converter>
<expression>TABLE.SOME_TIMESTAMP_COLUMN</expression>
</forcedType>
<!-- Dodaj kolejne forcedType w razie potrzeby -->
</forcedTypes>
lub gradle:
forcedTypes {
forcedType {
name = 'Instant'
userType = 'java.time.Instant'
expression = 'TABLE.SOME_TIMESTAMP_COLUMN'
}
forcedType {
name = 'Instant'
userType = 'java.time.Instant'
expression = 'TABLE.SOME_TIMESTAMP_COLUMN'
}
forcedType {
name = 'Instant'
userType = 'java.time.Instant'
expression = 'TABLE.SOME_TIMESTAMP_COLUMN'
}
}
cała przykładowa konfiguracja:
jooq {
version = '3.18.13'
edition = nu.studer.gradle.jooq.JooqEdition.OSS
configurations {
main {
generateSchemaSourceOnCompilation = true
generationTool {
generator {
name = 'org.jooq.codegen.DefaultGenerator'
database {
name = 'org.jooq.meta.extensions.jpa.JPADatabase'
properties {
property {
key = 'packages'
value = 'pl.devset.example'
}
property {
key = 'useAttributeConverters'
value = true
}
property {
key = 'unqualifiedSchema'
value = 'none'
}
}
forcedTypes {
forcedType {
name = 'Instant'
userType = 'java.time.Instant'
expression = 'TABLE.SOME_TIMESTAMP_COLUMN'
}
forcedType {
name = 'Instant'
userType = 'java.time.Instant'
expression = 'TABLE.SOME_TIMESTAMP_COLUMN'
}
forcedType {
name = 'Instant'
userType = 'java.time.Instant'
expression = 'TABLE.SOME_TIMESTAMP_COLUMN'
}
}
}
generate {
deprecated = false
records = true
immutablePojos = true
fluentSetters = true
}
target {
packageName = 'pl.devset.example'
directory = 'build/generated-src/jooq/main'
}
strategy.name = 'org.jooq.codegen.DefaultGeneratorStrategy'
}
}
}
}
}
- Zdefiniuj typy:
Określ typ danych, które chcesz wymusić, np. Instant, z odpowiednim uwzględnieniem strefy czasowej UTC.
- Ustal wyrażenie:
Wprowadź wyrażenie, które wskazuje kolumnę w bazie danych, np. TABLE.SOME_TIMESTAMP_COLUMNTABLE
- Dodaj kolejne forcedTypes:
Jeśli masz więcej kolumn do zmapowania, dodaj kolejne wpisy forcedType.
Podsumowanie
Korzystając z konfiguracji forcedTypes, możesz precyzyjnie kontrolować mapowanie pól Timestamp z UTC w jOOQ generowanych z Hibernate. Dzięki temu zyskujesz większą elastyczność i pewność, że Twoje dane są przekształcane prawidłowo.