简体   繁体   中英

Hibirnate: failed to lazily initialize a collection of role with @Transactional

I have such a problem: when I load the collection lazily, it throws an exception. I used the Transactional annotation, Hibernate.initialize , but it still gives an error when loading the collection. Only EAGER helps, but it will be too expensive to use.

Entity:

public class Release extends AbstractEntity {

    ...

    @ManyToMany(fetch = FetchType.LAZY)
    @JoinTable(
            name = "releases_artists",
            joinColumns = @JoinColumn(name = "release_id"),
            inverseJoinColumns = @JoinColumn(name = "artist_id")
    )
    private Set<Artist> artists = new HashSet<>();

    ...
}

The class where the exception is thrown:

@Transactional
public class ReleaseXmlReader extends XmlReaderArrays<Release> {

    ...

    @Override
    protected void handle(Release release) {
        Release releaseFromDb = releaseRepository
                .findFirstByFonalId(release.getFonalId()).orElse(null);
        if (releaseFromDb != null) {
            for (Artist artist : release.getArtists()) {
                if (releaseFromDb.getArtists() <-- HERE
                        .stream()
                        .noneMatch(artist1 -> artist1.getDiscogsArtistId() != null)
                ) {
        ....

             

        releaseRepository.save(releaseFromDb);
    }
}

Parent abstract class:

@Transactional
public abstract class XmlReaderArrays<T extends AbstractEntity> {

    ....

    public void parse() {
        try {
            XMLStreamReader reader = XMLInputFactory
                    .newInstance()
                    .createXMLStreamReader(inputStream);

            XmlMapper mapper = new XmlMapper();
            while (next(reader)) {
                limit--;
                try {
                    T obj = mapper.readValue(reader, type);
                    handle(obj); <--- HERE
                } catch (Exception e) {
                    log.error("Error parse xml", e);
                }
            }

        } catch (Exception e) {
            log.error("Error parse xml", e);
        }
    }
  
    ...

}

I tried to match annotation only with the parent class or only with the inheritor. I also tried to put the annotation on the methods, but it did not help.

In order for @Transactional to work, spring AOP needs to create a proxy over your bean. There are 2 issues here:

  1. Here you're not using bean, just using handle as the method of the same class. You would have to inject a bean to use it as proxy.

  2. The method is protected , but it has to be public for the @Transactional to work.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM