【问题标题】:Hibirnate: failed to lazily initialize a collection of role with @TransactionalHibirnate:无法使用@Transactional 懒惰地初始化角色集合
【发布时间】:2021-01-30 16:54:09
【问题描述】:

我有这样一个问题:当我懒加载集合时,它会抛出一个异常。我使用了Transactional注解Hibernate.initialize,但是在加载集合时仍然报错。只有 EAGER 有帮助,但使用起来太贵了。

实体:

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<>();

    ...
}

抛出异常的类:

@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);
    }
}

父抽象类:

@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);
        }
    }
  
    ...

}

我尝试仅将注释与父类或仅与继承者匹配。我也尝试将注释放在方法上,但没有帮助。

【问题讨论】:

    标签: java spring spring-boot hibernate hibernate-mapping


    【解决方案1】:

    为了让@Transactional 工作,spring AOP 需要在你的 bean 上创建一个代理。这里有两个问题:

    1. 这里你没有使用bean,只是使用handle作为同一个类的方法。您必须注入一个 bean 才能将其用作代理。

    2. 方法是protected,但必须是public@Transactional 才能工作。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-03-30
      • 2011-07-21
      • 2021-08-20
      • 1970-01-01
      • 2016-06-16
      相关资源
      最近更新 更多