Skip to content

Custom converters (such as DateLongConverter via @DateLong) don't work with projections. #2365

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

Closed
LGDOI opened this issue Aug 27, 2021 · 3 comments
Assignees
Labels
type: enhancement A general enhancement

Comments

@LGDOI
Copy link

LGDOI commented Aug 27, 2021

SDN v6.1.4 via Spring Data v2.5.4

We are migrating from OGM to SDN. In OGM @DateLong works well with COALESCE. However, in SDN the same causes an error.

Give following artifacts.

DashboardLite.java

import java.util.Date;
import lombok.Value;
import org.springframework.data.neo4j.core.support.DateLong;

@Value
public class DashboardLite {

  String id;

  @DateLong
  Date created;

  @DateLong
  Date updated;

  @DateLong
  Date modified;
}

DashboardRepository.java

Note that entity mapping type is Dashboard and return type is DashboardLite POJO

@Repository
public interface DashboardRepository extends Neo4jRepository<Dashboard, String> {
  @Query(value = "MATCH (dashboard:Dashboard {id: $dashboardId}) "
      + "RETURN dashboard, COALESCE(dashboard.updated, dashboard.created) AS modified;")
  Optional<DashboardLite> findLiteById(String dashboardId);
}

Test

  @Test
  fun findLiteById() {
    clean()
    val id = "dash-1"
    val dashboard = DashboardStub.getOne(id = id)
    dashboard.created = Date()
    dashboard.updated = Date()
    dashboardRepository.save(dashboard)

    assertingWith(dashboardRepository.findLiteById(id).get()) {
      assertThat(it.id).isEqualTo(id)
      assertThat(it.modified).isNotNull
    }
  }

Error

Caused by: org.springframework.core.convert.ConversionFailedException: Failed to convert from type [org.neo4j.driver.internal.value.IntegerValue] to type [java.util.Date] for value '1630075360851'; nested exception is org.neo4j.driver.exceptions.value.Uncoercible: Cannot coerce INTEGER to Java String
	at app//org.springframework.core.convert.support.ConversionUtils.invokeConverter(ConversionUtils.java:47)
	at app//org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:192)
	at app//org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:175)
	at app//org.springframework.data.neo4j.core.mapping.DefaultNeo4jConversionService.lambda$readValue$0(DefaultNeo4jConversionService.java:74)
	at app//org.springframework.data.neo4j.core.mapping.DefaultNeo4jConversionService.readValueImpl(DefaultNeo4jConversionService.java:96)
	... 128 more
Caused by: org.neo4j.driver.exceptions.value.Uncoercible: Cannot coerce INTEGER to Java String
	at app//org.neo4j.driver.internal.value.ValueAdapter.asString(ValueAdapter.java:91)
	at app//org.springframework.data.neo4j.core.convert.AdditionalTypes.asDate(AdditionalTypes.java:228)
	at app//org.springframework.data.convert.DefaultConverterBuilder$ConfigurableGenericConverter.convert(DefaultConverterBuilder.java:151)
	at app//org.springframework.core.convert.support.ConversionUtils.invokeConverter(ConversionUtils.java:41)
	... 132 more

Workaround

The same test pass by changing modified's data type from Date to long and remove @DateLong annotation.

//  @DateLong
  long modified;

Question

Should @DateLong convert COALESCE returned long to Date?

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Aug 27, 2021
@michael-simons
Copy link
Collaborator

It does, but there are a couple of oddities here:

  • The coalesed column wont be used for the attribute (entity mapper wont recognize it as part of the object)
  • Some domain object seems to have java.util.Date attribute without @DateLong, otherwise the code branch would not reach the above point.

Please share the whole setup.

@michael-simons michael-simons self-assigned this Aug 30, 2021
@michael-simons michael-simons added type: enhancement A general enhancement and removed status: waiting-for-triage An issue we've not yet triaged labels Aug 30, 2021
@michael-simons
Copy link
Collaborator

It is always great to have colleagues helping out to see what has been missed.

So what you are trying to do is to apply @DateLong (or in general, converters), to DTO based projections. This is currently not supported, that's the reason for the failure you seeing. I am gonna fix that.

Also, properties in the projection (your DashboardLite) that already exist in the domain and are annotated there, don't need to be annotated again. So the correct projection will be (with the enhancement in place)

import java.util.Date;
import lombok.Value;
import org.springframework.data.neo4j.core.support.DateLong;

@Value
public class DashboardLite {

  String id;

  Date created;

  Date updated;

  @DateLong
  Date modified;
}

@michael-simons michael-simons changed the title @DateLong and COALESCE do not work well together Custom converters (such as DateLongConverter via @DateLong) don't work with projections. Aug 30, 2021
@michael-simons michael-simons added this to the 6.0.13 (2020.0.13) milestone Aug 30, 2021
@LGDOI
Copy link
Author

LGDOI commented Aug 30, 2021

Thank you Michael for suggesting not needing @DateLong on the properties that are defined in the entity class (Dashboard.java).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: enhancement A general enhancement
Projects
None yet
Development

No branches or pull requests

3 participants