Spring FetchType.Lazy 和投影抛出错误

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

我试图将我所有的数据库变成延迟加载,因为它太大了(比如数百万), 为了不加载所有内容,我应用了惰性,并开始进行 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"])

谢谢!

spring hibernate lazy-loading eager-loading spring-projections
1个回答
0
投票

该错误对应于序列化错误,因为不可序列化的对象作为 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 访问而不是该类型的字段访问。

希望对你有帮助!

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