相同的查询方法差异结果;如果对象(未完全)加载到内存中,springboot或hibernate是否可以阻止查询?

我希望我能弄清楚自己并弄清问题的核心。因此,我有一个使用Spring-boot和Hibernate的应用程序。我为DAO使用JPA仓库接口。 我有一个名为NameSection的对象,该对象由7个不同的对象持有。 NameSection具有3个不同名称对象的列表(拉丁名称,通用名称,瑞典名称)。 当我打电话给service.getNameSection(30);例如,根据得到的位置,我会得到不同的结果。如果我从我的控制器中调用它,而我的名称节的副本不完整,那么即使我调用了服务和getNameSection(nameSectionId),它似乎也不想对数据库进行查询。 (依次将其称为我的JPA存储库)。

Spring Boot或Hibernate是否有可能停止对我的数据库的查询,因为它认为它的内存中有完整的NameSection?

当我在表单中提交一个对象(让我说一个Plant-object)并想转到相关的NameSection表单时,就会调用我正在努力使用的方法。

提交植物表格时,将植物作为模型属性注入到我的方法中。 在这种方法中,我获得了NameSection-id并进行了调用service.getNameSection(nameSectionId);它没有给我完整的姓名部分。在工厂形式中,我确实引用了名称部分,因此在我的CommonName列表(在NameSection中)中,我加载了一个CommonName。但是还有更多需要收集的原因,这就是为什么我打电话给我的服务。

我将其归结为: 如果我提交包含NameSection.id = 30的Plant-form并致电service.getNameSection(30);我将只用一个CommonName来获得nameSection。

如果我提交了另一个包含另一个NameSection的Plant-form,但是我对service.getNameSection(30)进行了硬编码;并将其记录下来,就像测试一样,我确实获得了完整的NameSection(30)和完整加载的列表。

更令人沮丧的是NameSection可以像我想要的那样为对象类型Fish起作用,该对象类型还包含NameSection。两种方法遵循完全相同的流程。在下面的方法中,只需将每个“植物”替换为“鱼”即可。

我怀疑是春天还是冬眠,或者某些事情走捷径。我尝试在调用service.getNameSection(id);之前使Plant和NameSection无效。同样,但是即使我已经有一个不完整的副本,即使它为空,它也不会加载完整的nameSection。至少我是这样。我已经被困了好几天了。

调用service.getPlant(plantId);也将加载完整的NameSection,但这在此特定方法中均无效。例如,在我的editPlant方法中,可以在同一Controller类中正常工作。

所以,这是方法:

// Process Plant form
@RequestMapping("/processplantForm")
public String savePlantForm(Model model,@RequestParam("saveButt") String saveButt,// plant holds an incomplete namesection at this point
@Valid @ModelAttribute("plant") Plant plant,BindingResult theBindingResult){

...snipped validation...


plantService.savePlant(plant);

if (saveButt.equals("Edit NameSection")) {

   // Here is the problem section!!

NameSection nameSec = 
    plantService.getNameSection(plant.getNameSection().getId());
System.out.println("common names size: " + nameSec.getcommonNames().size());

   // Hardcoded test phrase         
   NameSection secNameSec = plantService.getNameSection(30);       
   System.out.println("common names size: " + secNameSec.getcommonNames().size());

model.addAttribute("plant",plant);
model.addAttribute("nameSectionForm",new NameSectionForm(nameSec));
model.addAttribute("inflateNameSection",true);
    return "form/create-plant";
}

else {      
    return "redirect:/listPlant";
}
}

因此,使用持有ID为30的NameSection的工厂进入此方法,它将在两个“ getNameSection( id )”中调用,以仅加载NameSection(id = 30)一个CommonName(与modelAttribute中不完整的NameSection相匹配)。

将此方法与任何其他不具有NameSection(id = 30)的工厂一起使用,它将在我的“ Hardcoded测试短语”中加载带有所有相关CommonNames的完整NameSection(id = 30)。

在这两种情况下,我都将获得与NameSection相关的所有瑞典语名称和所有拉丁语名称,可能是因为它们都是来自ModelAttribute的不完整NameSection中的空列表。

因此,我期望plantService.getNameSection(nameSectionId);对于相同的nameSectionId ofc,总是给出相同的结果。但是似乎有些“智能快捷方式”使得如果内存中有可用的碎片,它跳过了几步,并且在这种情况下,它做出了错误的假设,或者仅仅是我吗?

我也许可以创建一个特殊的查询来询问缺少的CommonNames,但是必须有一种更整洁的方法。令我丧命的是,它确实可以在拥有名称节的7个不同对象中工作1个。当然它们之间应该有一些区别,但我只是找不到。我发现的唯一区别是,在方法注入中,我最初在“ BindingResult theBindingResult”之后具有“模型模型”。我将其移动以使其与鱼类的工作方法相匹配,但是并没有任何区别。

我还尝试在我的service.getNameSection(id)方法中添加对getcommonNames()。size()的调用,以“收集惰性列表”,但是没有区别。

有什么主意的专业人士吗?

yezhao07 回答:相同的查询方法差异结果;如果对象(未完全)加载到内存中,springboot或hibernate是否可以阻止查询?

我不想创建比我更多的文字墙,但我认为有人会希望看到提到的有效的鱼方法。

    @RequestMapping("/processFishForm")
    public String processFishForm(Model model,@RequestParam("saveButt") String saveButt,@Valid @ModelAttribute("fish") Fish fish,BindingResult theBindingResult) {

    // this is the snipped validation from plant-method example above
    if (theBindingResult.hasErrors()) {
        System.out.println(theBindingResult.getAllErrors());
        return "form/create-fish";
    }

    fishService.saveFish(fish);

    if (saveButt.equals("Edit NameSection")) {
        NameSection nameSec = fishService.getNameSection(fish.getNameSection().getId());

        model.addAttribute("inflateNameSection",true);
        model.addAttribute("fish",fish);
        model.addAttribute("nameSectionForm",new NameSectionForm(nameSec););
        return "form/create-fish";
    } 
    else {
        return "redirect:/listFish";
    }
}

FishService和PlantService都具有完全相同的getNameSection(id)方法,根据我的测试,它们是100%可互换的。

更新 因此,我为CommonNames创建了一个新的DAO(JpaRepository接口)(因为我没有),并创建了自定义方法:

List<CommonName> findByNameSection(NameSection nameSection);

然后在服务中,当我调用NameSection时,该服务还将调用该方法,以确保获得所有CommonNames。现在它可以按我的意愿工作了。除了我可能对数据库进行不必要的查询以解决其他问题。

本文链接:https://www.f2er.com/3157258.html

大家都在问