gpt4 book ai didi

java - 使用延迟获取类型检索外部对象的正确方法

转载 作者:行者123 更新时间:2023-11-29 02:52:54 27 4
gpt4 key购买 nike

我正在使用 Spring、Hibernate 和 MySql,我将 fetchType 设置为 LAZY 以提高我的软件的性能,因为使用 EAGER 时速度非常慢。现在我需要检索链接到我的类的外部对象的信息,例如我有 Car 类:

/**
* Car generated by hbm2java
*/
@Entity
@Table(name = "car", catalog = "ats")
public class Car implements java.io.Serializable {

/**
*
*/
private static final long serialVersionUID = 1L;
private Integer idCar;
private CarType carType;
private Fleet fleet;
private String id;
private int initialKm;
private String carChassis;
private String note;
@JsonIgnore
private Set<Acquisition> acquisitions = new HashSet<Acquisition>(0);

我需要 carType id。所以如果我使用

public List<Car> findByFleetIdFleet(int idFleet);

我检索到一个异常,因为我将结果放在另一个我的类 TableUi 中(用于允许从表进行 ajax 调用):

public class TableUI {

private Object data;

/**
* @return the data
*/
public Object getData() {
return data;
}

/**
* @param data the data to set
*/
public void setData(Object data) {
this.data = data;
}

}

我的 Controller 返回 @ResponseBody TableUI。显然 jackson 无法映射对象,因为它的字段 fleet 和 carType 只是代理。这是异常(exception)情况:

    ERROR com.controller.ErrorController - 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: com.model.tablesField.TableUI["data"]->java.util.ArrayList[0]->com.domain.Car["carType"]->com.domain.CarType_$$_jvst4de_f["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: com.model.tablesField.TableUI["data"]->java.util.ArrayList[0]->com.domain.Car["carType"]->com.domain.CarType_$$_jvst4de_f["handler"])
at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.writeInternal(AbstractJackson2HttpMessageConverter.java:271)
at org.springframework.http.converter.AbstractGenericHttpMessageConverter.write(AbstractGenericHttpMessageConverter.java:100)
at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:167)
at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:100)
at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.handleReturnValue(RequestResponseBodyMethodProcessor.java:166)
at org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite.handleReturnValue(HandlerMethodReturnValueHandlerComposite.java:80)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:127)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:806)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:729)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:959)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:622)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:219)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:142)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:616)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:518)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1091)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:673)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1526)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1482)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:745)
Caused by: 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: com.model.tablesField.TableUI["data"]->java.util.ArrayList[0]->com.domain.Car["carType"]->com.domain.CarType_$$_jvst4de_f["handler"])
at com.fasterxml.jackson.databind.ser.impl.UnknownSerializer.failForEmpty(UnknownSerializer.java:59)
at com.fasterxml.jackson.databind.ser.impl.UnknownSerializer.serialize(UnknownSerializer.java:26)
at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:505)
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:639)
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:152)
at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:505)
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:639)
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:152)
at com.fasterxml.jackson.databind.ser.impl.IndexedListSerializer.serializeContents(IndexedListSerializer.java:100)
at com.fasterxml.jackson.databind.ser.impl.IndexedListSerializer.serializeContents(IndexedListSerializer.java:21)
at com.fasterxml.jackson.databind.ser.std.AsArraySerializerBase.serialize(AsArraySerializerBase.java:183)
at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:505)
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:639)
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:152)
at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:128)
at com.fasterxml.jackson.databind.ObjectWriter.writeValue(ObjectWriter.java:602)
at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.writeInternal(AbstractJackson2HttpMessageConverter.java:264)
... 37 more

.11:24:38.387 [http-nio-8086-exec-4] WARN o.s.w.s.m.m.a.ExceptionHandlerExceptionResolver - Handler execution resulted in exception: 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: com.model.tablesField.TableUI["data"]->java.util.ArrayList[0]->com.domain.Car["carType"]->com.domain.CarType_$$_jvst4de_f["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: com.model.tablesField.TableUI["data"]->java.util.ArrayList[0]->com.domain.Car["carType"]->com.domain.CarType_$$_jvst4de_f["handler"])

相反,如果我在 model.addAttribute 中使用 findByFleetIdFleet 它会起作用因此,我需要另一种方法,它返回带有 Car 对象的 carType,仅当我需要更多信息时才使用该方法(如果我需要所有对象,JOIN FETCH 只处理一个对象?)。我发现的唯一工作方式是:

 @SuppressWarnings("unchecked")
@Override
public List<CarWithCarType> findByFleetIdFleetFetch(int idFleet) {
String jpql = "select f from Fleet f where f.idFleet = :idFleet";
Query query = entityManager.createQuery(jpql);
query.setParameter("idFleet", idFleet);
Fleet fleet=(Fleet) query.getSingleResult();
String jpql2 = "select c from Car c JOIN FETCH c.carType where c.fleet = :fleet";
Query query2 = entityManager.createQuery(jpql2);
query2.setParameter("fleet", fleet);
List<Car> cars= query2.getResultList();
List<CarWithCarType> carsList = new ArrayList<CarWithCarType>();
for (Car car: cars){
CarWithCarType newCar = new CarWithCarType();
newCar.setId(car.getId());
newCar.setCarChassis(car.getCarChassis());
newCar.setCarType(car.getCarType());
newCar.setIdCar(car.getIdCar());
newCar.setInitialKm(car.getInitialKm());
newCar.setNote(car.getNote());
carsList.add(newCar);
}
return carsList;
}

这是最好的方法还是有其他更好的方法?谢谢

更新:这是添加到我的配置类中的 jackson hibernate 映射配置:

   public MappingJackson2HttpMessageConverter jacksonMessageConverter(){
MappingJackson2HttpMessageConverter messageConverter = new MappingJackson2HttpMessageConverter();

ObjectMapper mapper = new ObjectMapper();
//Registering Hibernate4Module to support lazy objects
mapper.registerModule(new Hibernate4Module());

messageConverter.setObjectMapper(mapper);
return messageConverter;

}

@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
//Here we add our custom-configured HttpMessageConverter
converters.add(jacksonMessageConverter());
super.configureMessageConverters(converters);
}

没有抛出异常,但我在 carType 和 fleet 中收到 null:

{
"data": [
{
"idCar": 4,
"carType": null,
"fleet": null,
"id": "06",
"initialKm": 1000,
"carChassis": "VPNEWCAR",
"note": ""
}
]
}

所以我使用了 Hibernate.initialize(car.getCarType()); 并且它有效。正确吗?

最佳答案

我认为解决方案是(使用其中之一):

  1. 配置hibernate module .
  2. 使用数据传输对象 (DTO) 和任何映射实用程序,例如 Dozer 或 ModelMapper。

更新:现在调用 Hibernate4Module hbm.enable(Hibernate4Module.Feature.FORCE_LAZY_LOADING);当然,您可以手动初始化,但这种解决方案要简单得多。

关于java - 使用延迟获取类型检索外部对象的正确方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33754024/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com