无法通过hibernate search找到延迟初始化异常的解决方案

Can't find a solution to lazy initialization exception with hibernate search

我 运行 在 Spring 引导环境中使用休眠搜索进行搜索,但是在执行查询时我无法延迟初始化角色集合。

我已经尝试了其他类似问题中暴露的所有变体。我的实体与另外两个实体存在多对多关系。

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

}

我的控制器class:

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

}

我的服务class:

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

}

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

输出:

"message": "Could not write JSON: failed to lazily initialize a 
collection of role: com.xxxx.entity.A.b, 
could not initialize proxy - no Session

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

好的做法是将实体映射到传输对象上,return那些传输对象在外面(不是原始实体)。