问题摘要
说是在使用 getOne() 方法出现的问题,其实是在返回数据给前端时出现了json序列化的问题,这个也是由于懒加载出现的,实体对象会多出一个 handler属性,导致无法序列化成 json格式的数据给前端。
解决问题
通过网上查询的方法,只要在实体类上加上注解:
@JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
就可以解决序列化的问题,在序列化的时候去掉 handler属性
后续
虽然网上的方法可以解决我的问题,但是在已有的代码上每个持久化实体去加上一个注解,暴躁小哥我实在不能接受,继续研究一下问题。
通过 debug 之后发现是由于 getOne() 获取唯一实体的方法引起的懒加载导致的,还有其他人是由于 findOne() 方法导致的,但我使用的已经是基于 hibernate比较高版本的了,并没有 findOne()这个方法。
JPA源码中用到的 getReference() 就是懒加载的源头,有兴趣的可以去了解一下
em.getReference(getDomainClass(), id);
既然是由于这个方法引起的,那我就索性不要了这个方法,自己重新写了一个获取唯一实体的方法
public T getEntityById(Class<T> cls, Long id){
T result = null;
result = entityManager.find(cls, id);
return result;
}
我这里用到的是 find() 方法,就不会有懒加载这个问题。更详细的内容只有查一下 find() 和 getReference() 的异同就可以了。
注:
find()返回指定OID的实体,如果这个实体存在于当前的persistence context中,那么返回值是被缓存的对象;否则会创建一个新的实体,并从数据库中加载相关的持久状态。如果数据库不存在指定的OID的记录,那么find()方法返回null。
getReference()方法和find()相似。不同的是:如果缓存中没有指定的实体,EntityManager会创建一个新的实体,但是不会立即访问数据库来加载持久状态,而是在第一次访问某个属性的时候才加载。此外,getReference()方法不返回null,如果数据库找不到相应的实体,这个方法会抛出javax.persistence.EntityNotFoundException