Skip to content

Related entity rendered differently depending on JPA fetch type [DATAREST-1494] #1813

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
spring-projects-issues opened this issue Mar 12, 2020 · 8 comments
Assignees
Labels
status: invalid An issue that we don't feel is valid

Comments

@spring-projects-issues
Copy link

jvanheesch opened DATAREST-1494 and commented

Please see reference url for quick reproducer.

On branch mastercurl [http://localhost:8080/books/] results in

{
  "timestamp": "2020-03-12T20:48:22.082+0000",
  "status": 500,
  "error": "Internal Server Error",
  "message": "Type definition error: [simple type, class org.hibernate.proxy.pojo.bytebuddy.ByteBuddyInterceptor]; nested exception is com.fasterxml.jackson.databind.exc.InvalidDefinitionException: No serializer found for class org.hibernate.proxy.pojo.bytebuddy.ByteBuddyInterceptor and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) (through reference chain: org.springframework.hateoas.CollectionModel[\"_embedded\"]->java.util.Collections$UnmodifiableMap[\"books\"]->java.util.ArrayList[0]->org.springframework.data.rest.webmvc.json.PersistentEntityJackson2Module$PersistentEntityResourceSerializer$1[\"content\"]->com.github.jvanheesch.Book[\"author\"]->org.springframework.data.rest.webmvc.json.PersistentEntityJackson2Module$PersistentEntityResourceSerializer$1[\"content\"]->com.github.jvanheesch.Author$HibernateProxy$Co1jR6qK[\"hibernateLazyInitializer\"])",
  "path": "/books/"
}

For us this is currently non-blocking, as we use the following workaround:

@Bean
public ObjectMapper objectMapper(Jackson2ObjectMapperBuilder builder) {
    ObjectMapper objectMapper = builder.build();
    objectMapper.addMixIn(Object.class, IgnoreHibernatePropertiesInJackson.class);
    return objectMapper;
}

// https://stackoverflow.com/a/44152216/1939921
@JsonIgnoreProperties({"hibernateLazyInitializer"})
private static class IgnoreHibernatePropertiesInJackson {
}

This issue seems very similar to https://jira.spring.io/browse/DATAREST-1442, although

With FetchType.EAGER serialization does not fail but resulting JSON does contain unnecessary "_embedded" section.

seems not to apply here


Reference URL: https://github.com/jvanheesch/spring-data-rest-bytebuddyinterceptor

1 votes, 2 watchers

@spring-projects-issues
Copy link
Author

Oliver Drotbohm commented

We cannot control the serialization of object instances produced by Hibernate but AFAIR, the Jackson Hibernate module should make work proxies OOTB. Are you using that?

@spring-projects-issues
Copy link
Author

jvanheesch commented

I was not.
I added the com.fasterxml.jackson.datatype:jackson-datatype-hibernate5 dependency and did nothing else (e.g. I did not register the Hibernate5Module myself), and I no longer have errors!
However, I stumbled upon another issue.
curl [http://localhost:8080/books/1] now returns

{
  "title": "Spring Data REST Reference Guide",
  "author": {
    "content": {
      "name": "Jon Brisbin"
    }
  },
  "_links": {
    "self": {
      "href": "http://localhost:8080/books/1"
    },
    "book": {
      "href": "http://localhost:8080/books/1"
    }
  }
}

If I change the FetchType from LAZY to EAGER, I get:

{
  "title": "Spring Data REST Reference Guide",
  "author": {
    "name": "Jon Brisbin"
  },
  "_links": {
    "self": {
      "href": "http://localhost:8080/books/1"
    },
    "book": {
      "href": "http://localhost:8080/books/1"
    }
  }
}

Notice that in the first case, author has a content property (EntityModel), while in the second case, it doesn't (i.e. the content property is unwrapped).
I assume this behavior should not depend on the FetchType

@spring-projects-issues
Copy link
Author

Oliver Drotbohm commented

Are you able to produce a minimal reproducing project so that I can investigate?

@spring-projects-issues
Copy link
Author

jvanheesch commented

I had made such project, but apparently I forgot to link it.
Reference URL is now updated (https://github.com/jvanheesch/spring-data-rest-bytebuddyinterceptor).
If you GET [http://localhost:8080/books/1], you should see the following:

{
  "title": "Spring Data REST Reference Guide",
  "author": {
    "content": {
      "name": "Jon Brisbin"
    }
  },
  "_links": {
    "self": {
      "href": "http://localhost:8080/books/1"
    },
    "book": {
      "href": "http://localhost:8080/books/1"
    }
  }
}

If in class Book you change the FetchType of author from FetchType.LAZY to EAGER and restart the application, GET [http://localhost:8080/books/1] will return following:

{
  "title": "Spring Data REST Reference Guide",
  "author": {
    "name": "Jon Brisbin"
  },
  "_links": {
    "self": {
      "href": "http://localhost:8080/books/1"
    },
    "book": {
      "href": "http://localhost:8080/books/1"
    }
  }
}

@spring-projects-issues
Copy link
Author

Oliver Drotbohm commented

Unfortunately this seems to be an issue in Jackson's Hibernate 5 module. Whether to unwrap or not involves a lookup in the target serializer which the HibernateProxySerializer doesn't answer accordingly. I'Ve commented on the other ticket to see whether we can get this fixed.

In general I think the fundamental problem shouldn't be that ubiquitous as entities internal to the aggregate (i.e. references to other non-aggregate) should be mapped to eagerly load by default. There's simply no point in delaying the loading as Jackson will need them to render them anyway

@spring-projects-issues
Copy link
Author

jvanheesch commented

Thank you for proposing a fix for that issue!

There's simply no point in delaying the loading as Jackson will need them to render them anyway.
When using projections, Jackson may not need the author property.
In that case, FetchType.LAZY avoids the join of Book with the Author table

@spring-projects-issues
Copy link
Author

jvanheesch commented

The bug in Jackson's Hibernate 5 module has been fixed (com.fasterxml.jackson.datatype:jackson-datatype-hibernate5:jar:2.11.2).
This fix is included when upgrading to spring-boot-starter-parent:2.3.3.RELEASE, so this issue may be closed

@spring-projects-issues
Copy link
Author

Oliver Drotbohm commented

Resolving as suggested as it's fixed in an upstream project

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: invalid An issue that we don't feel is valid
Projects
None yet
Development

No branches or pull requests

2 participants