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 cd22f262e9..df6790f134 100644 --- a/jOOQ-codegen/src/main/java/org/jooq/codegen/JavaGenerator.java +++ b/jOOQ-codegen/src/main/java/org/jooq/codegen/JavaGenerator.java @@ -1667,7 +1667,9 @@ public class JavaGenerator extends AbstractGenerator { ? out.ref(getStrategy().getFullJavaIdentifier(tableUdtOrEmbeddable), 2) : null; final List interfaces = out.ref(getStrategy().getJavaClassImplements(tableUdtOrEmbeddable, Mode.RECORD)); - final String abstract_ = tableUdtOrEmbeddable instanceof UDTDefinition && !((UDTDefinition) tableUdtOrEmbeddable).isInstantiable() ? "abstract " : ""; + final String abstract_ = ""; + // [#644] TODO Get this to work + // tableUdtOrEmbeddable instanceof UDTDefinition && !((UDTDefinition) tableUdtOrEmbeddable).isInstantiable() ? "abstract " : ""; printPackage(out, tableUdtOrEmbeddable, Mode.RECORD); @@ -2172,7 +2174,7 @@ public class JavaGenerator extends AbstractGenerator { if (!replacingEmbeddablesAndUnreplacedColumns.equals(embeddablesOrColumns)) generateRecordConstructor(tableUdtOrEmbeddable, out, embeddablesOrColumns, false); - if (generatePojos()) + if (generatePojos() && !(tableUdtOrEmbeddable instanceof UDTDefinition && ((UDTDefinition) tableUdtOrEmbeddable).isInTypeHierarchy())) generateRecordConstructor(tableUdtOrEmbeddable, out, replacingEmbeddablesAndUnreplacedColumns, true); if (tableUdtOrEmbeddable instanceof TableDefinition) @@ -2213,9 +2215,9 @@ public class JavaGenerator extends AbstractGenerator { else out.println("%sinterface %s> extends [[%s]] {", visibility(), className, UDTRecord.class, interfaces); - List> typedElements = getTypedElements(udt); + List typedElements = udt.getAttributes(); for (int i = 0; i < typedElements.size(); i++) { - TypedElementDefinition column = typedElements.get(i); + AttributeDefinition column = typedElements.get(i); if (!generateImmutableInterfaces()) generateUDTRecordTypeSetter(column, i, out); @@ -2230,42 +2232,54 @@ public class JavaGenerator extends AbstractGenerator { /** * Subclasses may override this method to provide their own record type setters. */ - protected void generateUDTRecordTypeSetter(TypedElementDefinition column, int index, JavaWriter out) { + protected void generateUDTRecordTypeSetter(AttributeDefinition column, int index, JavaWriter out) { generateUDTRecordTypeSetter0(column, index, out); } - private final void generateUDTRecordTypeSetter0(TypedElementDefinition column, @SuppressWarnings("unused") int index, JavaWriter out) { + private final void generateUDTRecordTypeSetter0(AttributeDefinition column, @SuppressWarnings("unused") int index, JavaWriter out) { final String className = getStrategy().getJavaClassName(column.getContainer(), Mode.RECORD_TYPE); final String setterReturnType = generateFluentSetters() ? className : tokenVoid; final String setter = getStrategy().getJavaSetterName(column, Mode.RECORD_TYPE); final String typeFull = getJavaType(column.getType(resolver(out, Mode.RECORD_TYPE)), out, Mode.RECORD_TYPE); final String type = out.ref(typeFull); final String name = column.getQualifiedOutputName(); + final boolean override = + column.getContainer().getSupertype() != null + && column.getContainer().getSupertype().getAttributes().stream().anyMatch(c -> c.getName().equals(column.getName())) + || !kotlin && getStrategy().getJavaSetterOverride(column, Mode.RECORD) + || kotlin && getStrategy().getJavaMemberOverride(column, Mode.RECORD); if (!kotlin && !printDeprecationIfUnknownType(out, typeFull)) out.javadoc("Setter for %s.[[before= ][%s]]", name, list(escapeEntities(comment(column)))); if (scala) - out.println("%sdef %s(value: %s): %s", visibilityPublic(), setter, type, setterReturnType); + out.println("%s%sdef %s(value: %s): %s", visibility(override), override ? "override " : "", setter, type, setterReturnType); // The property is already defined in the getter else if (kotlin) {} - else + else { + out.overrideIf(override); out.println("%s%s %s([[before=@][after= ][%s]]%s value);", visibilityPublic(), setterReturnType, setter, list(nullableOrNonnullAnnotation(out, column)), varargsIfArray(type)); + } } /** * Subclasses may override this method to provide their own record type getters. */ - protected void generateUDTRecordTypeGetter(TypedElementDefinition column, int index, JavaWriter out) { + protected void generateUDTRecordTypeGetter(AttributeDefinition column, int index, JavaWriter out) { generateUDTRecordTypeGetter0(column, index, out); } - private final void generateUDTRecordTypeGetter0(TypedElementDefinition column, @SuppressWarnings("unused") int index, JavaWriter out) { + private final void generateUDTRecordTypeGetter0(AttributeDefinition column, @SuppressWarnings("unused") int index, JavaWriter out) { final String member = getStrategy().getJavaMemberName(column, Mode.RECORD_TYPE); final String getter = getStrategy().getJavaGetterName(column, Mode.RECORD_TYPE); final String typeFull = getJavaType(column.getType(resolver(out, Mode.RECORD_TYPE)), out, Mode.RECORD_TYPE); final String type = out.ref(typeFull); final String name = column.getQualifiedOutputName(); + final boolean override = + column.getContainer().getSupertype() != null + && column.getContainer().getSupertype().getAttributes().stream().anyMatch(c -> c.getName().equals(column.getName())) + || !kotlin && getStrategy().getJavaSetterOverride(column, Mode.RECORD) + || kotlin && getStrategy().getJavaMemberOverride(column, Mode.RECORD); if (!kotlin && !printDeprecationIfUnknownType(out, typeFull)) out.javadoc("Getter for %s.[[before= ][%s]]", name, list(escapeEntities(comment(column)))); @@ -2275,12 +2289,16 @@ public class JavaGenerator extends AbstractGenerator { if (kotlin && !generateImmutableInterfaces()) printKotlinSetterAnnotation(out, column, Mode.RECORD_TYPE); - if (scala) - out.println("%sdef %s: %s", visibilityPublic(), scalaWhitespaceSuffix(getter), type); - else if (kotlin) - out.println("%s%s %s: %s%s", visibilityPublic(), (generateImmutableInterfaces() ? "val" : "var"), member, type, kotlinNullability(out, column, Mode.RECORD_TYPE)); - else + if (scala) { + out.println("%s%sdef %s: %s", visibility(override), override ? "override " : "", scalaWhitespaceSuffix(getter), type); + } + else if (kotlin) { + out.println("%s%s%s %s: %s%s", visibilityPublic(), (override || generateInterfaces() ? "override " : ""), (generateImmutableInterfaces() ? "val" : "var"), member, type, kotlinNullability(out, column, Mode.RECORD_TYPE)); + } + else { + out.overrideIf(override); out.println("%s%s %s();", visibilityPublic(), type, getter); + } } @FunctionalInterface @@ -5664,7 +5682,9 @@ public class JavaGenerator extends AbstractGenerator { : ""; final String superName = out.ref(getStrategy().getJavaClassExtends(tableUdtOrEmbeddable, Mode.POJO)); final List interfaces = out.ref(getStrategy().getJavaClassImplements(tableUdtOrEmbeddable, Mode.POJO)); - final String abstract_ = tableUdtOrEmbeddable instanceof UDTDefinition && !((UDTDefinition) tableUdtOrEmbeddable).isInstantiable() ? "abstract " : ""; + final String abstract_ = ""; + // [#644] TODO Get this to work + // tableUdtOrEmbeddable instanceof UDTDefinition && !((UDTDefinition) tableUdtOrEmbeddable).isInstantiable() ? "abstract " : ""; if (generateInterfaces()) interfaces.add(interfaceName); diff --git a/jOOQ-meta/src/main/java/org/jooq/meta/AbstractUDTDefinition.java b/jOOQ-meta/src/main/java/org/jooq/meta/AbstractUDTDefinition.java index 04aeb2c5cd..ea9186fab3 100644 --- a/jOOQ-meta/src/main/java/org/jooq/meta/AbstractUDTDefinition.java +++ b/jOOQ-meta/src/main/java/org/jooq/meta/AbstractUDTDefinition.java @@ -118,6 +118,11 @@ implements return synthetic; } + @Override + public boolean isInTypeHierarchy() { + return getSupertype() != null || !getSubtypes().isEmpty(); + } + @Override public UDTDefinition getSupertype() { return supertypeSchema == null ? null : getDatabase().getUDT(supertypeSchema, supertypeName); diff --git a/jOOQ-meta/src/main/java/org/jooq/meta/UDTDefinition.java b/jOOQ-meta/src/main/java/org/jooq/meta/UDTDefinition.java index 1cdf1c96b6..873b41ce6d 100644 --- a/jOOQ-meta/src/main/java/org/jooq/meta/UDTDefinition.java +++ b/jOOQ-meta/src/main/java/org/jooq/meta/UDTDefinition.java @@ -77,6 +77,11 @@ public interface UDTDefinition extends PackageDefinition { @Override boolean isSynthetic(); + /** + * Whether this UDT has either subtypes or supertypes or both. + */ + boolean isInTypeHierarchy(); + /** * The subtypes of this UDT, if any. */ diff --git a/jOOQ/src/main/java/org/jooq/impl/Tools.java b/jOOQ/src/main/java/org/jooq/impl/Tools.java index 0e678a0a5b..7ee6a31bfc 100644 --- a/jOOQ/src/main/java/org/jooq/impl/Tools.java +++ b/jOOQ/src/main/java/org/jooq/impl/Tools.java @@ -219,10 +219,10 @@ import static org.jooq.impl.Tools.ExtendedDataKey.DATA_OMIT_DATETIME_LITERAL_PRE import static org.jooq.impl.Tools.SimpleDataKey.DATA_BLOCK_NESTING; import static org.jooq.tools.StringUtils.defaultIfNull; -import java.lang.annotation.Annotation; import java.lang.reflect.AccessibleObject; import java.lang.reflect.Constructor; import java.lang.reflect.Method; +import java.lang.reflect.Modifier; import java.math.BigDecimal; import java.math.BigInteger; import java.sql.Connection;