Java hibernate和MySql中通过外键链接的外部对象

Java hibernate和MySql中通过外键链接的外部对象,java,mysql,database,spring,hibernate,Java,Mysql,Database,Spring,Hibernate,我在Hibernate和MySql中使用Spring数据,我对此表示怀疑。 我的实体是 @Entity @Table(name = "car", catalog = "DEMO") public class Car implements java.io.Serializable { /** * */ private static final long serialVersionUID = 1L; private Integer idCar;

我在Hibernate和MySql中使用Spring数据,我对此表示怀疑。 我的实体是

@Entity
@Table(name = "car", catalog = "DEMO")
public class Car implements java.io.Serializable {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    private Integer idCar;
    @JsonBackReference
    private CarType carType;
    @JsonBackReference
    private Fleet fleet;
    private String id;
    private int initialKm;
    private String carChassis;
    private String note;
    @JsonManagedReference
    private Set<Acquisition> acquisitions = new HashSet<Acquisition>(0);
从我的html页面我可以检索carType.idCarType,但是如果我使用这个

@Override
    @RequestMapping(value = { "/cars/{idFleet}"}, method = RequestMethod.GET)
    public @ResponseBody TableUI getCars(@PathVariable int idFleet) {   
        TableUI ajaxCall=new TableUI();
        try {   
            ajaxCall.setData(fleetAndCarService.findCarsByIdFleet(idFleet));
            return ajaxCall;
        } catch (QueryException e) {
            ErrorResponse errorResponse= ErrorResponseBuilder.buildErrorResponse(e);
            LOG.error("Threw exception in FleetAndCarControllerImpl::addCar :" + errorResponse.getStacktrace());
            return ajaxCall;
        }
    }
TableUi只有一个字段数据,我将结果放入datatables中,没有carType和fleet。为什么?我必须使用Hibernate.initialize吗?它是一个怎样的列表

此外,此更新不起作用:

@Override
@Transactional
public List<Car> findByFleetIdFleet(int idFleet) {
    List<Car> carList= carRepository.findByFleetIdFleet(idFleet);
    for (Car car:carList)
        Hibernate.initialize(car.getCarType());
    return carList; 
}
@覆盖
@交易的
公共列表FindByFleetId车队(int idFleet){
列表carList=carRepository.findbyfleetidfilet(idFleet);
用于(汽车:carList)
初始化(car.getCarType());
返回卡利斯特;
}

您可以对每个元素调用Hibernate.initialize

Collection<Car> cars = fleetAndCarService.findCarsByIdFleet(idFleet);
for(Car car : cars) {
    Hibernate.initialize(car.getCarType());
    Hibernate.initialize(car.getFleet());
}
ajaxCall.setData();
return ajaxCall;
Collection cars=fleetAndCarService.findCarsByIdFleet(idFleet);
用于(汽车:汽车){
初始化(car.getCarType());
初始化(car.getFleet());
}
ajaxCall.setData();
返回ajaxCall;
这将是一个很好的起点,可以让你向前迈进。但是,在高比例下,这可能会成为性能瓶颈,因为它将在每次调用初始化时执行查询,因此您将有2*n个对数据库的查询

为了获得最佳性能,您将有几个其他选项:

  • 遍历汽车并建立一个ID列表,然后使用ID列表在单个查询中按ID查询汽车类型。对舰队也要这样做。然后调用Hibernate.initialize。前两个查询将填充持久性上下文,初始化调用不需要转到数据库

  • 为此调用创建一个特殊查询,该查询将fetch加入您需要的属性

  • 设置批量取车,将批量取卡和车队,而不是每次查询一辆车/车队

  • 使用第二级缓存,这样初始化会导致Hibernate从缓存而不是数据库中提取


  • 详细描述这些选项超出了单个问题的范围,但一个好的起点是

    可以对每个元素调用Hibernate.initialize

    Collection<Car> cars = fleetAndCarService.findCarsByIdFleet(idFleet);
    for(Car car : cars) {
        Hibernate.initialize(car.getCarType());
        Hibernate.initialize(car.getFleet());
    }
    ajaxCall.setData();
    return ajaxCall;
    
    Collection cars=fleetAndCarService.findCarsByIdFleet(idFleet);
    用于(汽车:汽车){
    初始化(car.getCarType());
    初始化(car.getFleet());
    }
    ajaxCall.setData();
    返回ajaxCall;
    
    这将是一个很好的起点,可以让你向前迈进。但是,在高比例下,这可能会成为性能瓶颈,因为它将在每次调用初始化时执行查询,因此您将有2*n个对数据库的查询

    为了获得最佳性能,您将有几个其他选项:

  • 遍历汽车并建立一个ID列表,然后使用ID列表在单个查询中按ID查询汽车类型。对舰队也要这样做。然后调用Hibernate.initialize。前两个查询将填充持久性上下文,初始化调用不需要转到数据库

  • 为此调用创建一个特殊查询,该查询将fetch加入您需要的属性

  • 设置批量取车,将批量取卡和车队,而不是每次查询一辆车/车队

  • 使用第二级缓存,这样初始化会导致Hibernate从缓存而不是数据库中提取


  • 详细描述这些选项超出了单个问题的范围,但一个好的起点是

    我被你的问题弄糊涂了。你是说在第二个代码段还是第一个代码段中,carType和fleet都是空的?在第二个代码段中,没有fleet和carTypeI我被你的问题弄糊涂了。您是说在第二个代码段还是第一个代码段中,carType和fleet为null?在第二个代码段中,没有fleet和cartypes第一种方法是昨天使用的,但是在carserviceinpl中,它不起作用。在这种情况下,carType是一个只有一个字段的对象,即我的webui的一个查找表,所以它必须是相同的,还是不同的?例如,采集曾经被返回,但我不需要它。2和4在我看来是最好的,我必须搜索如何实现它们。事实上,现在我仔细看看,您已经用JsonBackReference标记了这两个字段。对于序列化,这些字段不会被忽略。我认为这不一定是一个初始化问题。我已经标记了JsonManagedReference I retrieve,JsonBackReference将被忽略。我必须使用这些注释来解决无限递归上的异常。我不知道问题出在哪里。任何标有@JsonBackReference的字段在序列化过程中将被忽略。这就是它阻止无限递归的原因,也是您无法在这些字段中获取值的原因。您需要在设计中以某种方式解决这个问题。这是hibernate的问题,而不是我的ER模型的问题。我使用hibernate工具生成实体,但它添加了模型中未包含的字段。例如,汽车有id_车队和id_车型,其中aI生成实体并添加收购。如果我在mysql工作台中进行查询,一切正常。我是新加入hibernate的。第一种方法是昨天使用的,但是在carServiceImpl中没有使用。在这种情况下,carType是一个只有一个字段的对象,即我的webui的一个查找表,所以它必须是相同的,还是不同的?例如,采集曾经被返回,但我不需要它。2和4在我看来是最好的,我必须搜索如何实现它们。事实上,现在我仔细看看,您已经用JsonBackReference标记了这两个字段。对于序列化,这些字段不会被忽略。我认为这不一定是一个初始化问题。我已经标记了JsonManagedReference I retrieve,JsonBackReference将被忽略。我必须使用这些注释来解决无限递归上的异常。我不知道problemAny字段在哪里用@JsonBackReference标记