使用hibernate搜索找不到延迟初始化异常的解决方案
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用hibernate搜索找不到延迟初始化异常的解决方案相关的知识,希望对你有一定的参考价值。
我在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
答案
Hibernate Session存在于@Transactional
的方法中。
在Service类之外传递实体是一种不好的做法,因为在离开search
方法后会话正在关闭。另一方面,您的实体包含惰性初始化集合,一旦会话关闭就无法拉出。
好的做法是将实体映射到传输对象并将这些传输对象返回到外部(而不是原始实体)。
以上是关于使用hibernate搜索找不到延迟初始化异常的解决方案的主要内容,如果未能解决你的问题,请参考以下文章
org.hibernate.AnnotationException:找不到预期的辅助表
Hibernate、Spring 和 HSQL:找不到表异常
如何解决“找不到方言类:org.hibernate.dialect.MYSQLDialect”异常?
Hibernate org.hibernate.LazyInitializationException:未能延迟初始化角色集合: