diff --git a/jOOQ-codegen/src/main/java/org/jooq/codegen/JavaGenerator.java b/jOOQ-codegen/src/main/java/org/jooq/codegen/JavaGenerator.java
index 48fde919b2..77f0419763 100644
--- a/jOOQ-codegen/src/main/java/org/jooq/codegen/JavaGenerator.java
+++ b/jOOQ-codegen/src/main/java/org/jooq/codegen/JavaGenerator.java
@@ -779,13 +779,14 @@ public class JavaGenerator extends AbstractGenerator {
if (generateUDTs()) {
generateUDTRecords(schema);
- generateUDTRecordTypes(schema);
if (generatePojos())
generateUDTPojos(schema);
if (generateInterfaces())
generateUDTInterfaces(schema);
+ else
+ generateUDTRecordTypes(schema);
if (generateRoutines())
generateUDTRoutines(schema);
@@ -1713,10 +1714,10 @@ public class JavaGenerator extends AbstractGenerator {
interfaces.add(rowTypeRecord);
}
- if (generateInterfaces())
+ if (generateInterfaces()) {
interfaces.add(out.ref(getStrategy().getFullJavaClassName(tableUdtOrEmbeddable, Mode.INTERFACE)));
-
- if (tableUdtOrEmbeddable instanceof UDTDefinition u) {
+ }
+ else if (tableUdtOrEmbeddable instanceof UDTDefinition u) {
if (u.getSupertype() != null || !u.getSubtypes().isEmpty())
interfaces.add(out.ref(getStrategy().getFullJavaClassName(u, Mode.RECORD_TYPE)));
}
@@ -2243,7 +2244,8 @@ public class JavaGenerator extends AbstractGenerator {
final String type = out.ref(typeFull);
final String name = column.getQualifiedOutputName();
final boolean override =
- udtAttributeOverride(column)
+ generateInterfaces()
+ || udtAttributeOverride(column)
|| !kotlin && getStrategy().getJavaSetterOverride(column, Mode.RECORD)
|| kotlin && getStrategy().getJavaMemberOverride(column, Mode.RECORD);
@@ -2274,7 +2276,8 @@ public class JavaGenerator extends AbstractGenerator {
final String type = out.ref(typeFull);
final String name = column.getQualifiedOutputName();
final boolean override =
- udtAttributeOverride(column)
+ generateInterfaces()
+ || udtAttributeOverride(column)
|| !kotlin && getStrategy().getJavaSetterOverride(column, Mode.RECORD)
|| kotlin && getStrategy().getJavaMemberOverride(column, Mode.RECORD);
@@ -2550,7 +2553,7 @@ public class JavaGenerator extends AbstractGenerator {
final boolean isUDTArray = t.getType(r).isUDTArray();
final ArrayDefinition array = database.getArray(t.getType(r).getSchema(), t.getType(r).getQualifiedUserType());
final String indexTypeFull = array == null || array.getIndexType() == null ? null : getJavaType(array.getIndexType(resolver(out)), out);
- final boolean isArrayOfUDTs = isArrayOfUDTs(t, r);
+ final boolean isArrayOfUDTs = isArrayOfUDTs(t, r, Mode.RECORD);
final String udtType = (isUDT || isArray)
? out.ref(getJavaType(t.getType(r), out, Mode.RECORD))
@@ -2705,7 +2708,7 @@ public class JavaGenerator extends AbstractGenerator {
}
}
- private boolean isArrayOfUDTs(final TypedElementDefinition> t, final JavaTypeResolver r) {
+ private boolean isArrayOfUDTs(final TypedElementDefinition> t, final JavaTypeResolver r, Mode mode) {
// [#11183] TODO: Move this to DataTypeDefinition?
String javaType = t.getType(r).getJavaType(r);
@@ -2714,11 +2717,11 @@ public class JavaGenerator extends AbstractGenerator {
String baseType = getArrayBaseType(javaType);
for (UDTDefinition udt : t.getDatabase().getUDTs())
- if (baseType.equals(getStrategy().getFullJavaClassName(udt, Mode.RECORD)))
+ if (baseType.equals(getStrategy().getFullJavaClassName(udt, mode)))
return true;
for (TableDefinition table : t.getDatabase().getTables())
- if (baseType.equals(getStrategy().getFullJavaClassName(table, Mode.RECORD)))
+ if (baseType.equals(getStrategy().getFullJavaClassName(table, mode)))
return true;
return false;
@@ -2772,17 +2775,19 @@ public class JavaGenerator extends AbstractGenerator {
final String member = getStrategy().getJavaMemberName(column, Mode.RECORD);
final String typeFull = getJavaType(column.getType(resolver(out)), out);
final String type = out.ref(typeFull);
+ final String recordTypeFull = getJavaType(column.getType(resolver(out, Mode.RECORD)), out, Mode.RECORD);
final String name = column.getQualifiedOutputName();
final boolean isUDT = column.getType(resolver(out)).isUDT();
final boolean isArray = column.getType(resolver(out)).isArray();
final boolean isUDTArray = column.getType(resolver(out)).isUDTArray();
+ final boolean isArrayOfUDTs = isArrayOfUDTs(column, resolver(out, RECORD), RECORD);
final boolean override = generateInterfaces() && !generateImmutableInterfaces() && !isUDT
|| column instanceof AttributeDefinition && ((AttributeDefinition) column).getContainer().isInTypeHierarchy()
|| !kotlin && getStrategy().getJavaSetterOverride(column, Mode.RECORD)
|| kotlin && getStrategy().getJavaMemberOverride(column, Mode.RECORD);
// We cannot have covariant setters for arrays because of type erasure
- if (!(generateInterfaces() && isArray)) {
+ if (!(generateInterfaces() && (isArray || isUDT))) {
if (!kotlin && !printDeprecationIfUnknownType(out, typeFull))
out.javadoc("Setter for %s.[[before= ][%s]]", name, list(escapeEntities(comment(column))));
@@ -2839,7 +2844,7 @@ public class JavaGenerator extends AbstractGenerator {
out.println("if (value == null)");
out.println("set(%s, null)", index);
out.println("else");
- out.println("set(%s, value.into(new %s()))", index, type);
+ out.println("set(%s, value.into(new %s()))", index, out.ref(recordTypeFull));
if (generateFluentSetters())
out.println("this");
@@ -2858,7 +2863,15 @@ public class JavaGenerator extends AbstractGenerator {
if (isUDT) {
out.println("else");
- out.println("set(%s, value.into(new %s()));", index, type);
+
+ if (isArrayOfUDTs) {
+ final UDTDefinition columnBaseType = column.getDatabase().getUDT(column.getSchema(), column.getType().getQualifiedUserType());
+ final String columnBaseTypeName = out.ref(getStrategy().getFullJavaClassName(columnBaseType, Mode.RECORD));
+
+ out.println("set(%s, %s.of(value).map(u -> u.into(new %s())).toArray(%s[]::new));", index, Stream.class, columnBaseTypeName, columnBaseTypeName);
+ }
+ else
+ out.println("set(%s, value.into(new %s()));", index, out.ref(recordTypeFull));
}
else if (isArray) {
final ArrayDefinition array = database.getArray(column.getType(resolver(out)).getSchema(), column.getType(resolver(out)).getQualifiedUserType());
@@ -2921,7 +2934,7 @@ public class JavaGenerator extends AbstractGenerator {
out.println("%s%s %s([[before=@][after= ][%s]]%s value) {", visibility(override), setterReturnType, setter, list(nonnullAnnotation(out)), type);
}
- final Wrap wrap = wrap(embeddable, out, Mode.RECORD);
+ final Wrap wrap = wrapInterface(embeddable, out, Mode.RECORD);
if (index > -1) {
if (kotlin) {
@@ -3232,6 +3245,11 @@ public class JavaGenerator extends AbstractGenerator {
final String className = getStrategy().getJavaClassName(tableUdtOrEmbeddable, Mode.INTERFACE);
final List interfaces = out.ref(getStrategy().getJavaClassImplements(tableUdtOrEmbeddable, Mode.INTERFACE));
+ if (tableUdtOrEmbeddable instanceof UDTDefinition u) {
+ if (u.getSupertype() != null)
+ interfaces.add(out.ref(getStrategy().getFullJavaClassName(u.getSupertype(), Mode.INTERFACE)));
+ }
+
printPackage(out, tableUdtOrEmbeddable, Mode.INTERFACE);
if (tableUdtOrEmbeddable instanceof TableDefinition)
generateInterfaceClassJavadoc((TableDefinition) tableUdtOrEmbeddable, out);
@@ -5962,7 +5980,7 @@ public class JavaGenerator extends AbstractGenerator {
for (Definition column : replacingEmbeddablesAndUnreplacedColumns) {
final String columnMember = getStrategy().getJavaMemberName(column, Mode.POJO);
- final Wrap wrap = wrap(column, out, Mode.POJO);
+ final Wrap wrap = wrapInterface(column, out, Mode.POJO);
out.println("this.%s = %s%s%s;", columnMember, wrap.prefix(), columnMember, wrap.suffix());
}
@@ -5973,15 +5991,21 @@ public class JavaGenerator extends AbstractGenerator {
static final record Wrap(String prefix, String suffix) {}
- private Wrap wrap(Definition column, JavaWriter out, Mode mode) {
- return wrap(column, out, mode, generateInterfaces());
+ private Wrap wrapInterface(Definition column, JavaWriter out, Mode mode) {
+ return wrapInterface(column, out, mode, generateInterfaces());
}
- private Wrap wrap(Definition column, JavaWriter out, Mode mode, boolean check) {
-
-
-
-
+ private Wrap wrapInterface(Definition column, JavaWriter out, Mode mode, boolean check) {
+ if (check) {
+ boolean wrap = false;
+ boolean array = false;
+ Definition definition = null;
+
+ if (column instanceof TypedElementDefinition> e) {
+ wrap = e.getType().isUDT();
+ array = isArrayOfUDTs(e, resolver(out, mode), mode);
+ definition = e.getDatabase().getUDT(e.getSchema(), e.getType().getQualifiedUserType());
+ }
@@ -5989,8 +6013,24 @@ public class JavaGenerator extends AbstractGenerator {
+ if (wrap) {
+ String className = out.ref(getStrategy().getFullJavaClassName(definition, mode));
+ switch (language) {
+ case KOTLIN: {
+ // [#15892] [#17176] TODO: Arrays
+ return new Wrap("" + className + "(", ")");
+ }
+ default: {
+ if (array)
+ return new Wrap(out.ref(Optional.class) + ".ofNullable(", ").map(e -> " + out.ref(Stream.class) + ".of(e).map(" + className + "::new).toArray(" + className + "[]::new)).orElse(null)");
+ else
+ return new Wrap("new " + className + "(", ")");
+ }
+ }
+ }
+ }
return new Wrap("", "");
}
@@ -6012,7 +6052,7 @@ public class JavaGenerator extends AbstractGenerator {
out.println("%sdef this(value: %s) = this(", visibility(), generateInterfaces() ? interfaceName : className);
forEach(replacingEmbeddablesAndUnreplacedColumns, (column, separator) -> {
- Wrap wrap = wrap(column, out, Mode.POJO);
+ Wrap wrap = wrapInterface(column, out, Mode.POJO);
out.println("%svalue.%s%s%s",
wrap.prefix(),
@@ -6050,7 +6090,7 @@ public class JavaGenerator extends AbstractGenerator {
}
else {
for (Definition column : replacingEmbeddablesAndUnreplacedColumns) {
- Wrap wrap = wrap(column, out, Mode.POJO);
+ Wrap wrap = wrapInterface(column, out, Mode.POJO);
out.println("this.%s = %svalue.%s%s%s;",
getStrategy().getJavaMemberName(column, Mode.POJO),
@@ -6326,6 +6366,7 @@ public class JavaGenerator extends AbstractGenerator {
final String columnMember = getStrategy().getJavaMemberName(column, Mode.POJO);
final boolean isUDT = column.getType(resolver(out)).isUDT();
final boolean isUDTArray = column.getType(resolver(out)).isUDTArray();
+ final boolean isArrayOfUDTs = isArrayOfUDTs(column, resolver(out, POJO), POJO);
final String name = column.getQualifiedOutputName();
// We cannot have covariant setters for arrays because of type erasure
@@ -6384,7 +6425,15 @@ public class JavaGenerator extends AbstractGenerator {
if (isUDT) {
out.println("else");
- out.println("this.%s = %s.into(new %s());", columnMember, columnMember, columnType);
+
+ if (isArrayOfUDTs) {
+ final UDTDefinition columnBaseType = column.getDatabase().getUDT(column.getSchema(), column.getType().getQualifiedUserType());
+ final String columnBaseTypeName = out.ref(getStrategy().getFullJavaClassName(columnBaseType, Mode.POJO));
+
+ out.println("this.%s = %s.of(%s).map(u -> u.into(new %s())).toArray(%s[]::new);", columnMember, Stream.class, columnMember, columnBaseTypeName, columnBaseTypeName);
+ }
+ else
+ out.println("this.%s = %s.into(new %s());", columnMember, columnMember, columnType);
}
else if (isUDTArray) {
final ArrayDefinition array = database.getArray(column.getType(resolver(out)).getSchema(), column.getType(resolver(out)).getQualifiedUserType());
@@ -9236,9 +9285,12 @@ public class JavaGenerator extends AbstractGenerator {
}
private void printFromAndInto(JavaWriter out, Definition tableUdtOrEmbeddable, Mode mode) {
- String qualified = out.ref(getStrategy().getFullJavaClassName(tableUdtOrEmbeddable, Mode.INTERFACE));
-
out.header("FROM and INTO");
+ printFromAndInto0(out, tableUdtOrEmbeddable, mode);
+ }
+
+ private void printFromAndInto0(JavaWriter out, Definition tableUdtOrEmbeddable, Mode mode) {
+ String qualified = out.ref(getStrategy().getFullJavaClassName(tableUdtOrEmbeddable, Mode.INTERFACE));
boolean override = generateInterfaces() && !generateImmutableInterfaces();
if (scala) {
@@ -9259,7 +9311,7 @@ public class JavaGenerator extends AbstractGenerator {
final String setter = getStrategy().getJavaSetterName(column, Mode.INTERFACE);
final String getter = getStrategy().getJavaGetterName(column, Mode.INTERFACE);
final String member = getStrategy().getJavaMemberName(column, Mode.INTERFACE);
- final Wrap wrap = wrap(column, out, Mode.POJO, generateImmutableInterfaces() && !generatePojosAsJavaRecordClasses());
+ final Wrap wrap = wrapInterface(column, out, Mode.POJO, generateImmutableInterfaces() && !generatePojosAsJavaRecordClasses());
if (scala)
out.println("%s(%sfrom.%s%s)", setter, wrap.prefix(), getter, wrap.suffix());
@@ -9307,6 +9359,11 @@ public class JavaGenerator extends AbstractGenerator {
out.println("}");
}
}
+
+ if (tableUdtOrEmbeddable instanceof UDTDefinition u) {
+ if (u.getSupertype() != null)
+ printFromAndInto0(out, u.getSupertype(), mode);
+ }
}
protected void printReferences(JavaWriter out, List extends Definition> definitions, Class> type) {
@@ -11177,6 +11234,8 @@ public class JavaGenerator extends AbstractGenerator {
else if ((udt = db.getUDT(schema, u)) != null) {
if (udt.getSubtypes().isEmpty() || udtMode == Mode.RECORD || udtMode == Mode.POJO || udtMode == Mode.INTERFACE)
type = getStrategy().getFullJavaClassName(udt, udtDefaultMode);
+ else if (generateInterfaces())
+ type = getStrategy().getFullJavaClassName(udt, Mode.INTERFACE);
else
type = getStrategy().getFullJavaClassName(udt, Mode.RECORD_TYPE);
}