Search code examples
kotlinjooqjooq-codegen-maven

kotlin field foo and isFoo clash: The following declarations have the same JVM signature


data class Bar(
  var foo: String = "",
  var isFoo: String = ""
)

compiler reports error:

Platform declaration clash: The following declarations have the same JVM signature (setFoo(Ljava/lang/String;)V): public final fun (<set-?>: String?): Unit defined in com.example.Bar public final fun (<set-?>: String?): Unit defined in com.example.Bar

how to tip the compiler use original field name for setters? (setFoo and setIsFoo) NOTICE: the code is generated by jooq(from database schema), so manually change the code is not a good way


Solution

  • This is a bug in jOOQ's code generator, which should generate the @set:JvmName annotation for such cases, as suggested by Михаил Нафталь. The bug number is #11912, fixed for 3.15.0 and 3.14.12.

    You can work around this problem by overriding the KotlinGenerator.generatePojo() method (requires copying the entire code and patching the relevant bits), or by using a hack: You can override the KotlinGenerator.printColumnJPAAnnotation() method and implement your logic there:

    // Example implemented in Java:
    @Override
    protected void printColumnJPAAnnotation(JavaWriter out, ColumnDefinition column) {
        super.printColumnJPAAnnotation(out, column);
    
        String member = getStrategy().getJavaMemberName(column, Mode.POJO);
        if (member.startsWith("is") && ((ColumnDefinition) column)
                .getContainer()
                .getColumns()
                .stream()
                .anyMatch(c -> member.equals("is" + 
                    StringUtils.toUC(getStrategy().getJavaMemberName(c, Mode.POJO))
                ))) {
            out.println("@set:JvmName(\"%s\")", 
                getStrategy().getJavaSetterName(column, Mode.POJO));
        }
    }