How to resolve LazyInitializationException in Spring data rest @RepositoryEventHandler @HandleAfterLinkSave?

cybodelic :

I have a spring data rest application with relation between types Match and Round

@Entity
public class Match {

    @OneToMany
    private List<Round> rounds;
    ...
}

When a link is created between a match and a round, e.g. like this

curl -X PUT -d "http://localhost:8080/rounds/2" -H "Content-Type:text/uri-list" http://localhost:8080/matches/1/rounds;

i capture this with an EventHandler to do some updates on my domain model:

public class MatchEventHandler

    @HandleAfterLinkSave
    public void handleLinkSave(Match match, List<Round> rounds) {
        ...
}

I need to access the second argument in order to do my update but doing so, e.g. with rounds.get(0), returns

org.hibernate.LazyInitializationException: failed to lazily initialize a collection, could not initialize proxy - no Session

Reading other threads about Hibernates LazyInitializationExceptions i see mainly three approaches that are suggested:

  1. Use Hibernate.initialize() - i don't see on which method i could call this and it would add an ugly dependency to Hibernate framework
  2. Put controller method into a transaction - i understand that spring data already puts everything into a transaction. Also as this is a spring data rest application i'm not using any controller or service layer and therfore i would not know what exactly to put into a transaction.
  3. Set FetchType.EAGER on the relation - although not really a valid solution i did try it. In that case the second argument of the @HandleAfterLinkSave method is an empty list, so it also does not deliver the expected result.
Selindek :

The property references are handled in the following Spring class:

org.springframework.data.rest.webmvc.RepositoryPropertyReferenceController

Although it works quite well most of the time, it's buggy here or there. Or let's say this way: It has some interesting behaviours... (I've spent months during the last two years for creating an improved version of Spring Data Rest).

If the request method was POST or PATCH then the 2nd parameter contains the updated collection. But if you use a PUT method, it contains the original collection.

(Also, there is no way to decide which collection was modified, if you have multiple property-collections in your main entity. And there are those questionable results for map-type properties, but that's an other story.)

So the best solution IMHO if you create a repository method in RoundRepository, and use it to reload the collection:

@RestResource(exported = false)
List<Round> findAllByMatch(Match match);

By the way! In regards of your Option 2, please read this topic!

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=83321&siteId=1