jklingsporn / vertx-jooq

A jOOQ-CodeGenerator to create vertx-ified DAOs and POJOs.
MIT License
382 stars 53 forks source link

RowMapper error with Postgres INET type converter #218

Open termermc opened 1 year ago

termermc commented 1 year ago

Hello. I've just started evaluating this library, and I have noticed that there is an issue with the code generated for RowMappers.java when dealing with table that have column(s) of type inet.

I have the necessary PostgreSQL jOOQ extensions installed, and have set up the ForcedType for it:

ForcedType().apply {
    userType = "org.jooq.postgres.extensions.types.Inet"
    binding = "org.jooq.postgres.extensions.bindings.InetBinding"
    converter = "org.jooq.postgres.extensions.converters.InetConverter"
    includeTypes = "inet"
    priority = -2147483648
}

Here is the problematic part of RowMappers.java:

public static Function<Row,com.myproj.generated.tables.pojos.Login> getLoginMapper() {
    return row -> {
        com.myproj.generated.tables.pojos.Login pojo = new com.myproj.generated.tables.pojos.Login();
        pojo.setSeqid(row.getInteger("seqid"));
        pojo.setUuid(row.getUUID("uuid"));
        pojo.setUserSeqid(row.getInteger("user_seqid"));
        pojo.setIp(com.myproj.generated.tables.converters.Converters.ORG_JOOQ_POSTGRES_EXTENSIONS_CONVERTERS_INETCONVERTER_INSTANCE.rowConverter().fromRow(key->row.get(com.myproj.generated.tables.converters.Converters.ORG_JOOQ_POSTGRES_EXTENSIONS_CONVERTERS_INETCONVERTER_INSTANCE.rowConverter().fromType(),key),"ip"));
        pojo.setCreatedTs(row.getOffsetDateTime("created_ts"));
        return pojo;
    };
}

rowConverter() is not a method on ORG_JOOQ_POSTGRES_EXTENSIONS_CONVERTERS_INETCONVERTER_INSTANCE.

There are also other related errors on the Login table object with ip.

Is there something obvious that I am missing? If there is some work to be done to support this, I would be happy to contribute.

Thank you.

jklingsporn commented 1 year ago

When using postgres, vertx-jooq assumes that all converters implement the io.github.jklingsporn.vertx.jooq.shared.postgres.PgConverter. I'm afraid this is not documented. The main issue when using the reactive driver together with jooq is, that we have potentially three different types we have to convert between:

  1. the POJO-type (a.k.a userType)
  2. the database-type (as provided by jOOQ)
  3. the reactive-driver-type

For example, imagine you have a POJO and it has a property called user which is represented by a JSONB-column in the database. You want to map that JSON to another POJO, called my.example.User, then

  1. is my.example.User
  2. is org.jooq.JSONB
  3. is io.vertx.core.json.JsonObject

Here is an example: https://github.com/jklingsporn/vertx-jooq/blob/master/vertx-jooq-generate/src/test/java/io/github/jklingsporn/vertx/jooq/generate/converter/SomeJsonPojoConverter.java

termermc commented 1 year ago

Would this mean a custom converter would need to be used? I imagine that ther ecould be some reflection done by the generator to check whether the converter implements PgConverter, or whether it's a default jOOQ one. In that case a wrapper class could possibly be generated for it.

If that's not possible, would that mean a custom converter would need to be written? That seems less than ideal considering the converter for the inet type is built into jOOQ and I belive just needs to be converted into a String.

Let me know if I'm not underestanding anything correctly.

jklingsporn commented 1 year ago

Feel free to contribute 🚀 The problem I see with reflection is that at the time of generation the generated code is not on the classpath of the (vertx-) jOOQ-Codegenerator and thus cannot be instantiated. For example when using the generator as a maven-plugin, your module has a dependency to it. But the generator itself is not aware of any custom converters you wrote. Instead, it generates (think of writing a text-file) class-files and puts them into a location of your choice.