10

I have an enterprise project configured by spring mvc4 + hibernate5 that all of its relation are eager and its performance is very bad...So I am transforming all eager relations to lazy step by step...But I see many errors in each step...and it works sometimes properly and sometimes not....

in this example HeaderFromStore is an instnace of RequestHeaders and a child of RequestLine. DeliveryPoint is child of requestHeader and I don't want to fetch deliveryPoint of requestHeader...But if don't use it in select query it couldn't fetch HeaderFromStore !!

I used this query and I get error!

select m from MAMRequestLines m join fetch  m.mamRequestHeaders r 
left join fetch m.requestHeaderFromStore rr where m.id =:id

If I use this query I don't get error

select m from MAMRequestLines m join fetch  m.mamRequestHeaders r
left join fetch m.requestHeaderFromStore rr
join fetch rr.mamDeliveryPoints
left join fetch r.mamDeliveryPoints
join fetch where m.id =:id

RequestLine.java

@Entity(name = "RequestLines")
@Table(name = "_REQUEST_LINES")
//@JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class, property = "@id")
public class RequestLines extends Entity implements Serializable {

    @JsonInclude(JsonInclude.Include.NON_EMPTY)
    private RequestHeaders requestHeaders;

    @JsonInclude(JsonInclude.Include.NON_EMPTY)
    private RequestHeaders requestHeaderFromStore;

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "_REQUEST_Line_SEQ")
    @SequenceGenerator(name = "_REQUEST_Line_SEQ", sequenceName = "_REQUEST_Line_SEQ")
    @Column(name = "REQUEST_LINE_ID")
    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "REQUEST_HEADER_ID", nullable = false)
    public RequestHeaders getRequestHeaders() {
        return RequestHeaders;
    }

    public void setRequestHeaders(RequestHeaders requestHeaders) {
        this.RequestHeaders = requestHeaders;
    }

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "REQUEST_HEADER_FROM_STORE")
    public RequestHeaders getRequestHeaderFromStore() {
        return requestHeaderFromStore;
    }

    public void setRequestHeaderFromStore(RequestHeaders requestHeaderFromStore) {
        this.requestHeaderFromStore = requestHeaderFromStore;
    }

}

RequestHeader.java

 @Entity(name = "RequestHeaders")
    @Table(name = "REQUEST_HEADERS")
    //@JsonInclude(JsonInclude.Include.NON_EMPTY)
    public class RequestHeaders extends Entity implements Serializable {

        private long id;



    // @JsonInclude(JsonInclude.Include.NON_EMPTY)
      // @JsonIgnore
        private DeliveryPoints DeliveryPoints;


        @JsonIgnore
        private Set<RequestLines> RequestLinesSet;


        @Id
        @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "_REQUEST_HEADERS_SEQ")
        @SequenceGenerator(name = "_REQUEST_HEADERS_SEQ", sequenceName = "_REQUEST_HEADERS_SEQ")
        @Column(name = "REQUEST_HEADER_ID")
        public long getId() {
            return id;
        }

        public void setId(long id) {
            this.id = id;
        }



        @ManyToOne(fetch = FetchType.LAZY)
        @JoinColumn(name = "DELIVERY_POINT_ID", nullable = false)
        public DeliveryPoints getDeliveryPoints() {
            return DeliveryPoints;
        }

        public void setDeliveryPoints(DeliveryPoints DeliveryPoints) {
            this.DeliveryPoints = DeliveryPoints;
        }


        @OneToMany(mappedBy = "RequestHeaders", fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true)
        @OnDelete(action = OnDeleteAction.CASCADE)
        public Set<RequestLines> getRequestLinesSet() {
            return RequestLinesSet;
        }

        public void setRequestLinesSet(Set<RequestLines> RequestLinesSet) {
            this.RequestLinesSet = RequestLinesSet;
        }


    }

exception:

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: domain.RequestLine["HeaderFromStore"]->.domain.RequestHeaders["DeliveryPoint"]->domain.DeliveryPoint_$$_jvst393_f["handler"])

notice that I used JsonIgnore and JsonInclude(on fields and class) but none of them doesn't work...

Edit: I finally found this solution to avoid exception and ignoring unwanted properties. I added this part of code to WebMvcConfig extends WebMvcConfigurerAdapter class:

{
public MappingJackson2HttpMessageConverter jacksonMessageConverter(){
    MappingJackson2HttpMessageConverter messageConverter = new  MappingJackson2HttpMessageConverter();

    ObjectMapper mapper = new ObjectMapper();
    //Registering Hibernate4Module to support lazy objects
    mapper.registerModule(new Hibernate4Module());

    messageConverter.setObjectMapper(mapper);
    return messageConverter;

}

@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
    //Here we add our custom-configured HttpMessageConverter
    converters.add(jacksonMessageConverter());
    super.configureMessageConverters(converters);
}

But I have another problem now...all post requests will receive with null properties in request body ....for example in this code all properties of "requestHeaders" in input is null or empty!

 @RequestMapping(value = "/requestHeader/", method = RequestMethod.POST, consumes = {"application/json"})
    public ResponseEntity<Void> createRequestHeaders(@RequestBody RequestHeaders requestHeaders, UriComponentsBuilder ucBuilder) {

        requestHeaders.setDeliveryPoints(deliveryPointsService.find(requestHeaders.getDeliveryPointsId()));

        requestHeadersService.add(requestHeaders);
        HttpHeaders headers = new HttpHeaders();

        return new ResponseEntity<Void>(headers, HttpStatus.CREATED);

    }
7
  • 1
    can you show your hibernate 5 bean in mvc config class? Commented Oct 20, 2017 at 18:50
  • @Generic I solved previous problem and now I have another problem...I edited my post...and I added parts of mvc config class...If any other code need to answer let me know...thank's :) Commented Oct 21, 2017 at 5:38
  • 1
    I think its better to remove unnecessary part of your question that you solved. if your lazy loading work remove that part. Commented Oct 21, 2017 at 7:28
  • 1
    This may not be the answer, but I suggest not to use entity objects as data transfer objects. It would make your application easier to maintain and extend. Problems like yours often resulted from mixing the two. Commented Oct 24, 2017 at 10:04
  • @faraa - Means you are saying RequestBody annotation not working. It not set the property value in the RequestHeaders requestHeaders Commented Oct 27, 2017 at 14:31

1 Answer 1

1

you should add each entities which have relation this annotation at the top of class definition.

@JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})

details are explained here and here

I hope these solves your problem.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.