I kept getting this error while calling an API (under development) in my spring boot app:
java.base/java.lang.Thread.run(Thread.java:1623)
Caused by: 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: com.example.service.model.Listing[\"project\"]-
>com.example.service.model.Project[\"user\"]->com.example.service.model.User$HibernateProxy$Nf8nVUyV[\"company\"]-
>com.example.service.model.Company$HibernateProxy$ulaPUlxC[\"hibernateLazyInitializer\"])
From my research, it looks like it's caused by Jackson not being able to serialize the object into json.
Here's my code exerpts:
Model:
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Table(name = "listing")
public class Listing {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "project_id", referencedColumnName = "id")
private Project project;
@NotNull
@Column(name = "limit")
private Integer limit;
...
}
Controller:
@RestController
@AllArgsConstructor
@RequestMapping("/listing")
public class ListingController {
private final ListingService listingService;
@PostMapping
public ResponseEntity<?> create(@Valid @RequestBody CreateListingRequest request) {
Listing listing = listingService.create(request);
return new ResponseEntity<>(listing, HttpStatus.CREATED);
}
I set the breakpoint on the return line in the controller while debugging and observed a valid object constructed before it was serialized, so everything up to the serialization step is working.
What I've tried:
- Turning off
spring.jackson.serialization.FAIL_ON_EMPTY_BEANS
through bothapplication.properties
file and via a custom bean:
@Bean
@Primary
public ObjectMapper objectMapper() {
return new ObjectMapper().disable(SerializationFeature.FAIL_ON_EMPTY_BEANS)
.setVisibility(PropertyAccessor.FIELD, Visibility.ANY);
}
- Setting visibility to "visible to all" (via the bean code above). But this shouldn't be necessary since Lombok does this already through annotations in the model;
- Setting
FetchType
fromLAZY
toEAGER
; - Adding
@JoinColumn
annotation forproject
field; - Adding the
@OneToMany
counterpart in theProject
class (with propertylistings
); - Adding
@JsonIgnore
forproject
property. This actually solves the problem, but this causes problem with deserialization - theproject
field becomes null during deserilization;
I'm looking for a way to make this work for both serialization and deserialization.