diff --git a/jOOQ-meta/src/main/java/org/jooq/meta/AbstractDatabase.java b/jOOQ-meta/src/main/java/org/jooq/meta/AbstractDatabase.java
index 6c9b41f5de..e0fd7e2178 100644
--- a/jOOQ-meta/src/main/java/org/jooq/meta/AbstractDatabase.java
+++ b/jOOQ-meta/src/main/java/org/jooq/meta/AbstractDatabase.java
@@ -1310,8 +1310,9 @@ public abstract class AbstractDatabase implements Database {
if (StringUtils.isBlank(type.getBinding()) &&
StringUtils.isBlank(type.getConverter()) &&
- !Boolean.TRUE.equals(type.isEnumConverter())) {
- log.warn("Bad configuration for . Either or or is required: " + type);
+ !Boolean.TRUE.equals(type.isEnumConverter()) &&
+ type.getLambdaConverter() == null) {
+ log.warn("Bad configuration for . Either or or or is required: " + type);
it2.remove();
continue;
@@ -1334,6 +1335,10 @@ public abstract class AbstractDatabase implements Database {
log.warn("Bad configuration for . is not allowed when is provided: " + type);
type.setEnumConverter(null);
}
+ if (type.getLambdaConverter() != null) {
+ log.warn("Bad configuration for . is not allowed when is provided: " + type);
+ type.setLambdaConverter(null);
+ }
}
if (type.getUserType() != null && StringUtils.equals(type.getUserType(), typeName)) {
diff --git a/jOOQ-meta/src/main/java/org/jooq/meta/AbstractTypedElementDefinition.java b/jOOQ-meta/src/main/java/org/jooq/meta/AbstractTypedElementDefinition.java
index d530361dbd..ac9f09dbe1 100644
--- a/jOOQ-meta/src/main/java/org/jooq/meta/AbstractTypedElementDefinition.java
+++ b/jOOQ-meta/src/main/java/org/jooq/meta/AbstractTypedElementDefinition.java
@@ -38,6 +38,7 @@
package org.jooq.meta;
+import static java.lang.Boolean.FALSE;
import static org.jooq.tools.Convert.convert;
import static org.jooq.tools.StringUtils.isEmpty;
@@ -57,6 +58,7 @@ import org.jooq.impl.EnumConverter;
import org.jooq.impl.SQLDataType;
import org.jooq.meta.jaxb.CustomType;
import org.jooq.meta.jaxb.ForcedType;
+import org.jooq.meta.jaxb.LambdaConverter;
import org.jooq.tools.JooqLogger;
import org.jooq.tools.StringUtils;
@@ -225,21 +227,14 @@ public abstract class AbstractTypedElementDefinition
// [#5877] [#6567] EnumConverters profit from simplified configuration
if (Boolean.TRUE.equals(customType.isEnumConverter()) ||
EnumConverter.class.getName().equals(customType.getConverter())) {
-
- String tType = Object.class.getName();
-
- if (resolver != null)
- tType = resolver.resolve(definedType);
- else
- try {
- tType = getDataType(db, definedType.getType(), definedType.getPrecision(), definedType.getScale())
- .getType()
- .getName();
- }
- catch (SQLDialectNotSupportedException ignore) {}
-
+ String tType = tType(db, resolver, definedType);
converter = "new " + EnumConverter.class.getName() + "<" + tType + ", " + uType + ">(" + tType + ".class, " + uType + ".class)";
}
+ else if (customType.getLambdaConverter() != null) {
+ LambdaConverter c = customType.getLambdaConverter();
+ String tType = tType(db, resolver, definedType);
+ converter = "org.jooq.Converter.of" + (!FALSE.equals(c.isNullable()) ? "Nullable" : "") + "(" + tType + ".class, " + uType + ".class, " + c.getFrom() + ", " + c.getTo() + ")";
+ }
else if (!StringUtils.isBlank(customType.getConverter())) {
converter = customType.getConverter();
}
@@ -309,6 +304,20 @@ public abstract class AbstractTypedElementDefinition
return result;
}
+ private static final String tType(Database db, JavaTypeResolver resolver, DataTypeDefinition definedType) {
+ if (resolver != null)
+ return resolver.resolve(definedType);
+
+ try {
+ return getDataType(db, definedType.getType(), definedType.getPrecision(), definedType.getScale())
+ .getType()
+ .getName();
+ }
+ catch (SQLDialectNotSupportedException ignore) {
+ return Object.class.getName();
+ }
+ }
+
@SuppressWarnings("deprecation")
public static final CustomType customType(Database db, ForcedType forcedType) {
String name = forcedType.getName();
@@ -328,6 +337,7 @@ public abstract class AbstractTypedElementDefinition
return new CustomType()
.withBinding(forcedType.getBinding())
.withEnumConverter(forcedType.isEnumConverter())
+ .withLambdaConverter(forcedType.getLambdaConverter())
.withConverter(forcedType.getConverter())
.withName(name)
.withType(forcedType.getUserType());
diff --git a/jOOQ-meta/src/main/java/org/jooq/meta/jaxb/CustomType.java b/jOOQ-meta/src/main/java/org/jooq/meta/jaxb/CustomType.java
index dcb79cbcb1..621d8290e0 100644
--- a/jOOQ-meta/src/main/java/org/jooq/meta/jaxb/CustomType.java
+++ b/jOOQ-meta/src/main/java/org/jooq/meta/jaxb/CustomType.java
@@ -38,6 +38,7 @@ public class CustomType implements Serializable, XMLAppendable
@XmlJavaTypeAdapter(StringAdapter.class)
protected String converter;
protected Boolean enumConverter;
+ protected LambdaConverter lambdaConverter;
@XmlJavaTypeAdapter(StringAdapter.class)
protected String binding;
@@ -121,6 +122,24 @@ public class CustomType implements Serializable, XMLAppendable
this.enumConverter = value;
}
+ /**
+ * @deprecated Use ForcedType only
+ *
+ */
+ @Deprecated
+ public LambdaConverter getLambdaConverter() {
+ return lambdaConverter;
+ }
+
+ /**
+ * @deprecated Use ForcedType only
+ *
+ */
+ @Deprecated
+ public void setLambdaConverter(LambdaConverter value) {
+ this.lambdaConverter = value;
+ }
+
/**
* @deprecated Use ForcedType only
*
@@ -174,6 +193,16 @@ public class CustomType implements Serializable, XMLAppendable
return this;
}
+ /**
+ * @deprecated Use ForcedType only
+ *
+ */
+ @Deprecated
+ public CustomType withLambdaConverter(LambdaConverter value) {
+ setLambdaConverter(value);
+ return this;
+ }
+
/**
* @deprecated Use ForcedType only
*
@@ -190,6 +219,7 @@ public class CustomType implements Serializable, XMLAppendable
builder.append("type", type);
builder.append("converter", converter);
builder.append("enumConverter", enumConverter);
+ builder.append("lambdaConverter", lambdaConverter);
builder.append("binding", binding);
}
@@ -248,6 +278,15 @@ public class CustomType implements Serializable, XMLAppendable
return false;
}
}
+ if (lambdaConverter == null) {
+ if (other.lambdaConverter!= null) {
+ return false;
+ }
+ } else {
+ if (!lambdaConverter.equals(other.lambdaConverter)) {
+ return false;
+ }
+ }
if (binding == null) {
if (other.binding!= null) {
return false;
@@ -268,6 +307,7 @@ public class CustomType implements Serializable, XMLAppendable
result = ((prime*result)+((type == null)? 0 :type.hashCode()));
result = ((prime*result)+((converter == null)? 0 :converter.hashCode()));
result = ((prime*result)+((enumConverter == null)? 0 :enumConverter.hashCode()));
+ result = ((prime*result)+((lambdaConverter == null)? 0 :lambdaConverter.hashCode()));
result = ((prime*result)+((binding == null)? 0 :binding.hashCode()));
return result;
}
diff --git a/jOOQ-meta/src/main/java/org/jooq/meta/jaxb/ForcedType.java b/jOOQ-meta/src/main/java/org/jooq/meta/jaxb/ForcedType.java
index d784ddf04e..a7079524e9 100644
--- a/jOOQ-meta/src/main/java/org/jooq/meta/jaxb/ForcedType.java
+++ b/jOOQ-meta/src/main/java/org/jooq/meta/jaxb/ForcedType.java
@@ -37,6 +37,7 @@ public class ForcedType implements Serializable, XMLAppendable
@XmlJavaTypeAdapter(StringAdapter.class)
protected String converter;
protected Boolean enumConverter;
+ protected LambdaConverter lambdaConverter;
@XmlJavaTypeAdapter(StringAdapter.class)
protected String binding;
@XmlJavaTypeAdapter(StringAdapter.class)
@@ -140,6 +141,22 @@ public class ForcedType implements Serializable, XMLAppendable
this.enumConverter = value;
}
+ /**
+ * A lambda converter implementation for the {@link #getUserType()}.
+ *
+ */
+ public LambdaConverter getLambdaConverter() {
+ return lambdaConverter;
+ }
+
+ /**
+ * A lambda converter implementation for the {@link #getUserType()}.
+ *
+ */
+ public void setLambdaConverter(LambdaConverter value) {
+ this.lambdaConverter = value;
+ }
+
/**
* A {@link org.jooq.Binding} implementation for the custom type.
*
@@ -365,6 +382,15 @@ public class ForcedType implements Serializable, XMLAppendable
return this;
}
+ /**
+ * A lambda converter implementation for the {@link #getUserType()}.
+ *
+ */
+ public ForcedType withLambdaConverter(LambdaConverter value) {
+ setLambdaConverter(value);
+ return this;
+ }
+
/**
* A {@link org.jooq.Binding} implementation for the custom type.
*
@@ -477,6 +503,7 @@ public class ForcedType implements Serializable, XMLAppendable
builder.append("userType", userType);
builder.append("converter", converter);
builder.append("enumConverter", enumConverter);
+ builder.append("lambdaConverter", lambdaConverter);
builder.append("binding", binding);
builder.append("excludeExpression", excludeExpression);
builder.append("includeExpression", includeExpression);
@@ -545,6 +572,15 @@ public class ForcedType implements Serializable, XMLAppendable
return false;
}
}
+ if (lambdaConverter == null) {
+ if (other.lambdaConverter!= null) {
+ return false;
+ }
+ } else {
+ if (!lambdaConverter.equals(other.lambdaConverter)) {
+ return false;
+ }
+ }
if (binding == null) {
if (other.binding!= null) {
return false;
@@ -655,6 +691,7 @@ public class ForcedType implements Serializable, XMLAppendable
result = ((prime*result)+((userType == null)? 0 :userType.hashCode()));
result = ((prime*result)+((converter == null)? 0 :converter.hashCode()));
result = ((prime*result)+((enumConverter == null)? 0 :enumConverter.hashCode()));
+ result = ((prime*result)+((lambdaConverter == null)? 0 :lambdaConverter.hashCode()));
result = ((prime*result)+((binding == null)? 0 :binding.hashCode()));
result = ((prime*result)+((excludeExpression == null)? 0 :excludeExpression.hashCode()));
result = ((prime*result)+((includeExpression == null)? 0 :includeExpression.hashCode()));
diff --git a/jOOQ-meta/src/main/java/org/jooq/meta/jaxb/LambdaConverter.java b/jOOQ-meta/src/main/java/org/jooq/meta/jaxb/LambdaConverter.java
new file mode 100644
index 0000000000..1e6593e5ff
--- /dev/null
+++ b/jOOQ-meta/src/main/java/org/jooq/meta/jaxb/LambdaConverter.java
@@ -0,0 +1,186 @@
+
+package org.jooq.meta.jaxb;
+
+import java.io.Serializable;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlType;
+import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
+import org.jooq.util.jaxb.tools.StringAdapter;
+import org.jooq.util.jaxb.tools.XMLAppendable;
+import org.jooq.util.jaxb.tools.XMLBuilder;
+
+
+/**
+ * A converter taking two lambda definitions.
+ *
+ *
+ *
+ */
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "LambdaConverter", propOrder = {
+
+})
+@SuppressWarnings({
+ "all"
+})
+public class LambdaConverter implements Serializable, XMLAppendable
+{
+
+ private final static long serialVersionUID = 31400L;
+ @XmlElement(required = true)
+ @XmlJavaTypeAdapter(StringAdapter.class)
+ protected String from;
+ @XmlElement(required = true)
+ @XmlJavaTypeAdapter(StringAdapter.class)
+ protected String to;
+ @XmlElement(defaultValue = "true")
+ protected Boolean nullable = true;
+
+ /**
+ * The implementation of {@link org.jooq.Converter#from(Object)}.
+ *
+ */
+ public String getFrom() {
+ return from;
+ }
+
+ /**
+ * The implementation of {@link org.jooq.Converter#from(Object)}.
+ *
+ */
+ public void setFrom(String value) {
+ this.from = value;
+ }
+
+ /**
+ * The implementation of {@link org.jooq.Converter#to(Object)}.
+ *
+ */
+ public String getTo() {
+ return to;
+ }
+
+ /**
+ * The implementation of {@link org.jooq.Converter#to(Object)}.
+ *
+ */
+ public void setTo(String value) {
+ this.to = value;
+ }
+
+ /**
+ * Whether to use {@link org.jooq.Converter#ofNullable(Class, Class, java.util.function.Function, java.util.function.Function)} or {@link org.jooq.Converter#of(Class, Class, java.util.function.Function, java.util.function.Function)}.
+ *
+ * @return
+ * possible object is
+ * {@link Boolean }
+ *
+ */
+ public Boolean isNullable() {
+ return nullable;
+ }
+
+ /**
+ * Sets the value of the nullable property.
+ *
+ * @param value
+ * allowed object is
+ * {@link Boolean }
+ *
+ */
+ public void setNullable(Boolean value) {
+ this.nullable = value;
+ }
+
+ /**
+ * The implementation of {@link org.jooq.Converter#from(Object)}.
+ *
+ */
+ public LambdaConverter withFrom(String value) {
+ setFrom(value);
+ return this;
+ }
+
+ /**
+ * The implementation of {@link org.jooq.Converter#to(Object)}.
+ *
+ */
+ public LambdaConverter withTo(String value) {
+ setTo(value);
+ return this;
+ }
+
+ public LambdaConverter withNullable(Boolean value) {
+ setNullable(value);
+ return this;
+ }
+
+ @Override
+ public final void appendTo(XMLBuilder builder) {
+ builder.append("from", from);
+ builder.append("to", to);
+ builder.append("nullable", nullable);
+ }
+
+ @Override
+ public String toString() {
+ XMLBuilder builder = XMLBuilder.nonFormatting();
+ appendTo(builder);
+ return builder.toString();
+ }
+
+ @Override
+ public boolean equals(Object that) {
+ if (this == that) {
+ return true;
+ }
+ if (that == null) {
+ return false;
+ }
+ if (getClass()!= that.getClass()) {
+ return false;
+ }
+ LambdaConverter other = ((LambdaConverter) that);
+ if (from == null) {
+ if (other.from!= null) {
+ return false;
+ }
+ } else {
+ if (!from.equals(other.from)) {
+ return false;
+ }
+ }
+ if (to == null) {
+ if (other.to!= null) {
+ return false;
+ }
+ } else {
+ if (!to.equals(other.to)) {
+ return false;
+ }
+ }
+ if (nullable == null) {
+ if (other.nullable!= null) {
+ return false;
+ }
+ } else {
+ if (!nullable.equals(other.nullable)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = ((prime*result)+((from == null)? 0 :from.hashCode()));
+ result = ((prime*result)+((to == null)? 0 :to.hashCode()));
+ result = ((prime*result)+((nullable == null)? 0 :nullable.hashCode()));
+ return result;
+ }
+
+}
diff --git a/jOOQ-meta/src/main/java/org/jooq/meta/jaxb/ObjectFactory.java b/jOOQ-meta/src/main/java/org/jooq/meta/jaxb/ObjectFactory.java
index 1e58a7f280..db1fb55d75 100644
--- a/jOOQ-meta/src/main/java/org/jooq/meta/jaxb/ObjectFactory.java
+++ b/jOOQ-meta/src/main/java/org/jooq/meta/jaxb/ObjectFactory.java
@@ -213,6 +213,14 @@ public class ObjectFactory {
return new ForcedType();
}
+ /**
+ * Create an instance of {@link LambdaConverter }
+ *
+ */
+ public LambdaConverter createLambdaConverter() {
+ return new LambdaConverter();
+ }
+
/**
* Create an instance of {@link Generate }
*
diff --git a/jOOQ-meta/src/main/resources/xsd/jooq-codegen-3.14.0.xsd b/jOOQ-meta/src/main/resources/xsd/jooq-codegen-3.14.0.xsd
index 88ba454ce5..6296ee215c 100644
--- a/jOOQ-meta/src/main/resources/xsd/jooq-codegen-3.14.0.xsd
+++ b/jOOQ-meta/src/main/resources/xsd/jooq-codegen-3.14.0.xsd
@@ -1042,6 +1042,18 @@ for Oracle.]]>
+
+
+
+
+
+
+
+ @java.lang.Deprecated
+ @java.lang.Deprecated
+
+
+
@@ -1145,6 +1157,10 @@ or {@link #getBinding()} is required]]>
+
+
+
+
@@ -1199,6 +1215,23 @@ type. If provided, both "includeExpression" and "includeTypes" must match.]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+