使用hibernate搜索找不到延迟初始化异常的解决方案

问题描述 投票:0回答:1

我在Spring Boot环境中使用hibernate搜索运行搜索,但在执行查询时,我无法懒惰地初始化角色集合。

我尝试过在其他类似问题中公开的所有变体。我的实体与另外两个实体有很多关系。

@Entity
@Indexed
public class A extends AbstractAuditableEntity<D, Long> implements 
Serializable {

  @Column
  @Field(index = Index.YES, analyze = Analyze.YES, store = 
       Store.NO)
  private String name;

  @ManyToMany(mappedBy = "a")
  @IndexedEmbedded
  private List<B> b;

  @OneToMany(mappedBy = "a")
  @IndexedEmbedded
  private List<C> c;

}

我的控制器类:

@RestController
public class SearchController {

@Autowired
private SearchService searchService;

@GetMapping("/search")
public ResponseEntity<?> search(@RequestParam String terms){

    List<A> aList = searchService.search(terms);

    return aList.isEmpty() ? new ResponseEntity<> 
            (HttpStatus.NO_CONTENT) : new ResponseEntity<>(aList, 
            HttpStatus.OK);
}

}

我的服务类:

@Service
public class SearchService {

@Autowired
private aRepository aRepository;

@Transactional
public List<A> search(String terms) {
    return aRepository.search(terms);
}

}

我的存储库层:

public interface ARepository extends JpaRepository<A, Long>, 
      IndexSearchARepository {  
}

扩展接口:

@Transactional
public interface IndexSearchARepository {
   public List<A> search(String terms);
}

好的部分,实施:

public class IndexSearchARepositoryImpl implements 
      IndexSearchARepository {

private final EntityManager entityManager;

@Autowired
public IndexSearchARepositoryImpl(EntityManager entityManager) 
    {
    this.entityManager = entityManager;
}

@Override
@Transactional
public List<A> search(String terms) {

   FullTextEntityManager fullTextEntityManager = 
          Search.getFullTextEntityManager(entityManager);

   QueryBuilder queryBuilder = 
       fullTextEntityManager.getSearchFactory().buildQueryBuilder()
            .forEntity(A.class).get();

   Query luceneQuery = queryBuilder
              .keyword()
              .fuzzy()
              .withEditDistanceUpTo(1)
              .withPrefixLength(1)
      .onFields("name")
      .matching(terms)
              .createQuery();

    javax.persistence.Query jpaQuery = fullTextEntityManager
             .createFullTextQuery(luceneQuery, A.class);

    List<A> aList = null;

    try {
      aList = jpaQuery.getResultList();
    } catch (NoResultException nre) {
      log.debug(nre.getMessage());
    }

     return aList;
}

}

突出显示如果我放置一个断点并逐步执行它不会抛出异常。我不知道什么时候尝试访问显然会话关闭之前的关系,@ Transaction不应该处理这个?

输出:

"message": "Could not write JSON: failed to lazily initialize a 
collection of role: com.xxxx.entity.A.b, 
could not initialize proxy - no Session
spring-boot lucene hibernate-search lazy-initialization
1个回答
1
投票

Hibernate Session存在于@Transactional的方法中。 在Service类之外传递实体是一种不好的做法,因为在离开search方法后会话正在关闭。另一方面,您的实体包含惰性初始化集合,一旦会话关闭就无法拉出。

好的做法是将实体映射到传输对象并将这些传输对象返回到外部(而不是原始实体)。

© www.soinside.com 2019 - 2024. All rights reserved.