diff --git a/src/main/java/org/springframework/data/convert/KotlinClassGeneratingEntityInstantiator.java b/src/main/java/org/springframework/data/convert/KotlinClassGeneratingEntityInstantiator.java index 05b7d5cd3..9b35c17e1 100644 --- a/src/main/java/org/springframework/data/convert/KotlinClassGeneratingEntityInstantiator.java +++ b/src/main/java/org/springframework/data/convert/KotlinClassGeneratingEntityInstantiator.java @@ -229,15 +229,19 @@ public class KotlinClassGeneratingEntityInstantiator extends ClassGeneratingEnti int slot = i / 32; int offset = slot * 32; - Object param = provider.getParameterValue(parameters.get(i)); + Parameter parameter = parameters.get(i); + Class type = parameter.getType().getType(); + Object param = provider.getParameterValue(parameter); KParameter kParameter = kParameters.get(i); // what about null and parameter is mandatory? What if parameter is non-null? - if (kParameter.isOptional()) { + if (kParameter.isOptional() && param == null) { - if (param == null) { - defaulting[slot] = defaulting[slot] | (1 << (i - offset)); + defaulting[slot] = defaulting[slot] | (1 << (i - offset)); + + if (type.isPrimitive()) { + param = getPrimitiveDefault(type); } } @@ -251,5 +255,42 @@ public class KotlinClassGeneratingEntityInstantiator extends ClassGeneratingEnti return params; } + + private static Object getPrimitiveDefault(Class type) { + + if (type == Byte.TYPE || type == Byte.class) { + return (byte) 0; + } + + if (type == Short.TYPE || type == Short.class) { + return (short) 0; + } + + if (type == Integer.TYPE || type == Integer.class) { + return 0; + } + + if (type == Long.TYPE || type == Long.class) { + return 0L; + } + + if (type == Float.TYPE || type == Float.class) { + return 0F; + } + + if (type == Double.TYPE || type == Double.class) { + return 0D; + } + + if (type == Character.TYPE || type == Character.class) { + return '\u0000'; + } + + if (type == Boolean.TYPE) { + return Boolean.FALSE; + } + + throw new IllegalArgumentException(String.format("Primitive type %s not supported!", type)); + } } } diff --git a/src/test/kotlin/org/springframework/data/convert/KotlinClassGeneratingEntityInstantiatorUnitTests.kt b/src/test/kotlin/org/springframework/data/convert/KotlinClassGeneratingEntityInstantiatorUnitTests.kt index a2d05cb66..14e0da6b4 100644 --- a/src/test/kotlin/org/springframework/data/convert/KotlinClassGeneratingEntityInstantiatorUnitTests.kt +++ b/src/test/kotlin/org/springframework/data/convert/KotlinClassGeneratingEntityInstantiatorUnitTests.kt @@ -96,6 +96,27 @@ class KotlinClassGeneratingEntityInstantiatorUnitTests { .hasCauseInstanceOf(IllegalArgumentException::class.java) } + @Test // DATACMNS-1200 + fun `should apply primitive defaulting for absent parameters`() { + + val entity = this.entity as PersistentEntity + val constructor = PreferredConstructorDiscoverer.discover(WithPrimitiveDefaulting::class.java) + + doReturn(constructor).whenever(entity).persistenceConstructor + doReturn(constructor.constructor.declaringClass).whenever(entity).type + + val instance: WithPrimitiveDefaulting = KotlinClassGeneratingEntityInstantiator().createInstance(entity, provider) + + Assertions.assertThat(instance.aByte).isEqualTo(0) + Assertions.assertThat(instance.aShort).isEqualTo(0) + Assertions.assertThat(instance.anInt).isEqualTo(0) + Assertions.assertThat(instance.aLong).isEqualTo(0L) + Assertions.assertThat(instance.aFloat).isEqualTo(0.0f) + Assertions.assertThat(instance.aDouble).isEqualTo(0.0) + Assertions.assertThat(instance.aChar).isEqualTo('a') + Assertions.assertThat(instance.aBool).isTrue() + } + data class Contact(val firstname: String, val lastname: String) data class ContactWithDefaulting(val prop0: String, val prop1: String = "White", val prop2: String, @@ -113,5 +134,8 @@ class KotlinClassGeneratingEntityInstantiatorUnitTests { ) data class WithBoolean(val state: Boolean) + + data class WithPrimitiveDefaulting(val aByte: Byte = 0, val aShort: Short = 0, val anInt: Int = 0, val aLong: Long = 0L, + val aFloat: Float = 0.0f, val aDouble: Double = 0.0, val aChar: Char = 'a', val aBool: Boolean = true) }