我试图将我所有的数据库变成延迟加载,因为它太大了(比如数百万), 为了不加载所有内容,我应用了惰性,并开始进行 Spring Projections, 然后,在投影中,当我添加一个实体时,它会在邮递员中正确显示该实体, 但是当添加另一个实体时,两者是相同的,但其中一个有一些其他的急切加载, 急切的那个会抛出错误,而另一个则不会。
我认为是因为其他急切的表
@JsonIgnoreProperties("decoratedClass")
public interface UbicacionesLugaresProjection {
Integer getId();
int getTipolugar();
Lugar getiDlugar();
boolean getPordefecto();
ArticulosV3 getArticuloOneway();
}
所以,我问,我能做些什么,在投影中加载另一列的另一个投影吗?没有热切的专栏?比如,在投影中做一个投影就可以解决这个问题?
或者有什么我可以做的吗?
加载的那个:
@JoinColumn(name = "ID_lugar", referencedColumnName = "ID")
@ManyToOne(optional = false)
@JsonView(JsonViews.Summary.class)
private Lugar iDlugar;
(卢加尔没有急切的桌子)
没有的:
@JoinColumn(name = "articulo_oneway", referencedColumnName = "ID")
@NotFound(action = NotFoundAction.IGNORE)
@ManyToOne(optional = true)
@JsonView(JsonViews.Summary.class)
private ArticulosV3 articuloOneway;
(很多人都渴望这个)
删除 ArtivulosV3 中的 eager 不是一个选择
如果需要错误
2024-04-25 17:09:19 [http-nio-8080-exec-2] WARN o.s.w.s.m.s.DefaultHandlerExceptionResolver - Failed to write HTTP message: org.springframework.http.converter.HttpMessageNotWritableException: Could not write content: No serializer found for class org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) ) (through reference chain: java.util.ArrayList[0]->$Proxy349["articuloOneway"]->com.clickrent.backoffice.ws.entities.ArticulosV3["articulosUbicacion"]->org.hibernate.collection.internal.PersistentBag[0]->com.clickrent.backoffice.ws.entities.ArticulosUbicacion["idUbicaciones"]->com.clickrent.backoffice.ws.entities.Ubicaciones_$$_jvst1a7_9e["handler"]); nested exception is com.fasterxml.jackson.databind.JsonMappingException: No serializer found for class org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) ) (through reference chain: java.util.ArrayList[0]->$Proxy349["articuloOneway"]->com.clickrent.backoffice.ws.entities.ArticulosV3["articulosUbicacion"]->org.hibernate.collection.internal.PersistentBag[0]->com.clickrent.backoffice.ws.entities.ArticulosUbicacion["idUbicaciones"]->com.clickrent.backoffice.ws.entities.Ubicaciones_$$_jvst1a7_9e["handler"])
谢谢!
该错误对应于序列化错误,因为不可序列化的对象作为 API 的响应主体传递,无法为响应主体写入 HTTP 消息(代理没有兼容的序列化程序),并且 Jackson不是访问 getter,而是访问字段。
所以,我问,我能做些什么,在投影中加载另一列的另一个投影吗?没有热切的专栏?比如,在投影中做一个投影就可以解决这个问题?
这并不重要。问题是控制器返回的列表中引用的至少一个对象是代理。
对于你的问题:
或者有什么我可以做的吗?
我建议您使用 DTO 模式 来分离关注点。当您通过 getter 将投影对象映射到 DTO 时,会从惰性对象中获取数据,问题就消失了,因为 DTO 实际上是可序列化的。
例如:
// In your API controller
@GetMapping
public ResponseEntity<List<UbicacionesLugaresResponse>> getUbicacionesLugares() {
return ResponseEntity.ok(mapToResponse(service.getUbicacionesLugares()));
}
private List<UbicacionesLugaresResponse> mapToResponse(List<UbicacionesLugaresProjection> ubicacionesLugares) {
// map the objects using projection getters
}
class UbicacionesLugaresResponse {
private Integer id;
private int tipolugar;
private LugarResponse idLugar;
private boolean pordefecto;
private ArticulosV3Response articuloOneway;
//getters, setters and non-private empty constructor
}
另一种方法是为您的
UbicacionesLugaresProjection
类型注册 Jackson 序列化器,或者甚至尝试配置 Jackson 来执行 getter 访问而不是该类型的字段访问。
希望对你有帮助!