Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Converter attempts to instantiate an entity if the database value is null #670

Closed
Inego opened this issue Oct 19, 2021 · 1 comment
Closed
Assignees
Labels
type: bug A general bug

Comments

@Inego
Copy link

Inego commented Oct 19, 2021

Two related problems:

  1. In case when a custom converter is provided for a type and a null value is converted, there is no way to disambiguate whether I want it to be be left null or converted to a specific instance of the target type.
    For example, if my target type is Jackson's JsonNode and the souce value is null, it's not possible to customize conversion to return just null or com.fasterxml.jackson.databind.node.NullNode.

  2. MappingR2dbcConverter fails to convert null values to JsonNode even in the presence of the corresponding converter, see an example here.

	Suppressed: org.springframework.data.mapping.MappingException: Could not read property private final com.fasterxml.jackson.databind.JsonNode com.example.r2dbcconverternull.MyRow.field1 from column field1!
		at app//org.springframework.data.r2dbc.convert.MappingR2dbcConverter.readFrom(MappingR2dbcConverter.java:185)
		at app//org.springframework.data.r2dbc.convert.MappingR2dbcConverter.access$000(MappingR2dbcConverter.java:64)
		at app//org.springframework.data.r2dbc.convert.MappingR2dbcConverter$RowParameterValueProvider.getParameterValue(MappingR2dbcConverter.java:706)
		at app//org.springframework.data.mapping.model.SpELExpressionParameterValueProvider.getParameterValue(SpELExpressionParameterValueProvider.java:53)
		at app//org.springframework.data.relational.core.conversion.BasicRelationalConverter$ConvertingParameterValueProvider.getParameterValue(BasicRelationalConverter.java:268)
		at app//org.springframework.data.mapping.model.ClassGeneratingEntityInstantiator.extractInvocationArguments(ClassGeneratingEntityInstantiator.java:276)
		at app//org.springframework.data.mapping.model.ClassGeneratingEntityInstantiator$EntityInstantiatorAdapter.createInstance(ClassGeneratingEntityInstantiator.java:248)
		at app//org.springframework.data.mapping.model.ClassGeneratingEntityInstantiator.createInstance(ClassGeneratingEntityInstantiator.java:89)
		at app//org.springframework.data.relational.core.conversion.BasicRelationalConverter.createInstance(BasicRelationalConverter.java:145)
		at app//org.springframework.data.r2dbc.convert.MappingR2dbcConverter.createInstance(MappingR2dbcConverter.java:326)
		at app//org.springframework.data.r2dbc.convert.MappingR2dbcConverter.read(MappingR2dbcConverter.java:124)
		at app//org.springframework.data.r2dbc.convert.MappingR2dbcConverter.read(MappingR2dbcConverter.java:119)
		at app//com.example.r2dbcconverternull.R2dbcConverterNullApplicationTests.convertNullValue$lambda-0(R2dbcConverterNullApplicationTests.kt:33)
		at app//io.r2dbc.h2.H2Result.lambda$map$0(H2Result.java:67)
		at app//reactor.core.publisher.FluxMap$MapSubscriber.onNext(FluxMap.java:106)
		... 181 more
	Caused by: org.springframework.data.mapping.model.MappingInstantiationException: Failed to instantiate com.fasterxml.jackson.databind.JsonNode using constructor protected com.fasterxml.jackson.databind.JsonNode() with arguments 
		at app//org.springframework.data.mapping.model.ClassGeneratingEntityInstantiator$MappingInstantiationExceptionEntityInstantiator.createInstance(ClassGeneratingEntityInstantiator.java:321)
		at app//org.springframework.data.mapping.model.ClassGeneratingEntityInstantiator.createInstance(ClassGeneratingEntityInstantiator.java:89)
		at app//org.springframework.data.relational.core.conversion.BasicRelationalConverter.createInstance(BasicRelationalConverter.java:145)
		at app//org.springframework.data.r2dbc.convert.MappingR2dbcConverter.createInstance(MappingR2dbcConverter.java:326)
		at app//org.springframework.data.r2dbc.convert.MappingR2dbcConverter.readEntityFrom(MappingR2dbcConverter.java:293)
		at app//org.springframework.data.r2dbc.convert.MappingR2dbcConverter.readFrom(MappingR2dbcConverter.java:175)
		... 195 more
	Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.fasterxml.jackson.databind.JsonNode]: Class is abstract
		... 201 more
@mp911de
Copy link
Member

mp911de commented Oct 19, 2021

That's by design and by intent. We generally do not convert null values. Part of the rationale is that in some cases we do not have sufficient type information (e.g. convert null to Object). What seems to be a bug is that we attempt to create an instance while the database is null. We should fix that.

@mp911de mp911de added type: bug A general bug and removed status: waiting-for-triage An issue we've not yet triaged labels Oct 19, 2021
@mp911de mp911de changed the title Null values and custom converters Converter attempts to instantiate an entity if the database value is null Oct 19, 2021
@mp911de mp911de self-assigned this Oct 19, 2021
mp911de added a commit that referenced this issue Oct 25, 2021
We now no longer attempt to create instances of nested entities if the column value is null. Previously the null check happened after checking registered custom conversions which has lead to potential object creation for columns containing null values.

Closes #670
mp911de added a commit that referenced this issue Oct 25, 2021
We now no longer attempt to create instances of nested entities if the column value is null. Previously the null check happened after checking registered custom conversions which has lead to potential object creation for columns containing null values.

Closes #670
@mp911de mp911de added this to the 1.2.15 (2020.0.15) milestone Oct 25, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: bug A general bug
Projects
None yet
Development

No branches or pull requests

3 participants