0

I have my main object:

@Data
@Entity
@EqualsAndHashCode(callSuper = false)
@Table(name = MAIN_OBJ)
public class MainObj {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "MAIN_OBJ_ID", unique = true, nullable = false)
    private Integer manObjId;

    @ManyToOne
    @JoinColumn(name = "SUB_OBJ_ID", referencedColumnName = "SUB_OBJ_ID", nullable = false)
    @NotNull
    private SubObj subObj;

}

and it's sub object:

@Data
@Entity
@EqualsAndHashCode(callSuper = false)
@Table(name = SUB_OBJ)
public class SubObj {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "SUB_OBJ_ID", unique = true, nullable = false)
    private Integer subObjId;

    @Column(name = "NAME", nullable = false)
    @NotNull
    private String name;

}

When I do a creation:

@Override
@Transactional
public MainObj create(MainObj mainObj) {
    MainObj createdMainObj = mainObjRepository.save(mainObj);
    return createdMainObj;
}

It saves properly but when I return it to the user (back through the controller) I get a 500 back. After debugging I can see that all the fields in the subObj are null.

But it does actually create the mainObj and put it into the db, it just fails to serialize it and return.

If I trace it enough I see:

No serializer found for class org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer

Not really sure what I need to add so I can return the fully created object with it's foreign key reference to the subObj back to the user.

I tried Hibernate.initialize() like a lot of posts said but no luck.

If it wasn't clear it gives me one of these back:

enter image description here

Full stack trace (some details removed):

org.springframework.http.converter.HttpMessageNotWritableException: Could not write JSON: No serializer found for class org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS); nested exception is com.fasterxml.jackson.databind.JsonMappingException: No serializer found for class org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) (through reference chain: com.path.to.MainObj["subObj"]-com.path.to.SubObj_$$_jvsta14_f["handler"])

canpan14
  • 1,181
  • 1
  • 14
  • 36
  • Possible duplicate of [No serializer found for class org.hibernate.proxy.pojo.javassist.Javassist?](https://stackoverflow.com/questions/24994440/no-serializer-found-for-class-org-hibernate-proxy-pojo-javassist-javassist) – Lesiak Apr 25 '19 at 13:20
  • Can you change your @ManyToOne to something like @ManyToOne(fetch = FetchType.EAGER), please read about it to understand the performance implications as well. – Adil Khalil Apr 25 '19 at 13:21
  • 1
    @AdilKhalil `fetch = EAGER` *is* the default for `@ManyToOne` – crizzis Apr 25 '19 at 13:28
  • That's the main thing I don't get, why is LazyInitializer involved at all when it's an EAGER load? – canpan14 Apr 25 '19 at 13:38

2 Answers2

1

The best practice is NOT return entity directly in controller (because it may cause stack over flow exception). The entity should convert to DTO (data transfer object) and return DTO.

If you still want to use entity, you should use eager instead of lazy for all references (includes reference object inside reference object);

Sann Tran
  • 159
  • 5
  • ManyToOne is eager by default. And we are converting it into a DTO. But it doesn't help as the sub objects stays in that weird state where if you open it in the debugger it says everything is null and has a 'handler' on it. If you open the handler you can find the full definition for the object under that. – canpan14 Apr 26 '19 at 15:18
0

Can you please try this ? Add this annotation to SubObj Class

@JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class, property="SUB_OBJ_ID")
SRK
  • 135
  • 8