Java 如何在不设置Hybris中硬编码目录版本的情况下获取导航节点?

Java 如何在不设置Hybris中硬编码目录版本的情况下获取导航节点?,java,hybris,Java,Hybris,我从AfterSaveListener中的自定义类别服务调用了一个方法,在此方法中,我需要根导航节点,该节点由cmsNavigationService返回,但每当调用此方法时,它都会抛出一个错误: de.hybris.platform.cms2.exceptions.CMSItemNotFoundException:没有id为的导航节点 当我通过设置硬编码内容目录时 getCatalogVersionService().setSessionCatalogVersion(".....") 我处理

我从
AfterSaveListener
中的自定义类别服务调用了一个方法,在此方法中,我需要根导航节点,该节点由
cmsNavigationService
返回,但每当调用此方法时,它都会抛出一个错误:

de.hybris.platform.cms2.exceptions.CMSItemNotFoundException:没有id为的导航节点

当我通过设置硬编码内容目录时

getCatalogVersionService().setSessionCatalogVersion(".....")
我处理这个问题,但对我来说似乎不是真的。我可以通过使用

userService.setCurrentUser(userService.getAdminUser());
为了消除灵活搜索的所有限制,但此解决方案不适用于导航节点


如何解决此问题?

通常,如果没有目录版本,您无法获取导航节点,因为它们是目录感知的,这意味着您有一个NavigationNode的多个实例。在这种情况下,Hybris无法确切知道您需要哪个。但是,您的变通方法可以以更好的方式处理。当代码中的某些内容需要特定用户时,可以这样使用它。当然,您可以在execute()中添加try-finally块,在try中设置参数,并在finally中删除它们

private Object myMethod()
{
    return getSessionService().executeInLocalView(new SessionExecutionBody()
    {
        @Override
        public Object execute()
        {
            // Your code for an isolated session. Set session params here, remove restrictions and so on.
            //searchRestrictionService.disableSearchRestrictions(); for example
            return new Object();

        }
    }, userService.getAdminUser()); // You can also specify as which user you want to execute the code
}
另一件有趣的事是这个

final Map<String, Object> params = ImmutableMap.of(InterceptorExecutionPolicy.DISABLED_INTERCEPTOR_TYPES,
                ImmutableSet.of(InterceptorExecutionPolicy.InterceptorType.VALIDATE));
        sessionService.executeInLocalViewWithParams(params, new SessionExecutionBody()
final Map params=ImmutableMap.of(InterceptoreExecutionPolicy.DISABLED_INTERCEPTOR_类型,
ImmutableSet.of(interceptoreexecutionpolicy.InterceptorType.VALIDATE));
sessionService.executeInLocalViewWithParams(params,new SessionExecutionBody()

您可以在其中指定不同的参数。例如,此参数禁用某些拦截器。

CMSNavigationService提供了两种获取根导航节点的方法:

一个不接受任何内容作为参数,另一个接受目录版本作为参数。当您传递目录版本时,服务将在此特定目录版本中搜索导航节点

如果未指定导航节点,它将在会话目录版本中进行搜索。hybris不会在会话中为cronjobs设置目录版本。因此,您不应该找到导航节点。当您在会话中手动设置目录版本(使用问题中的代码段)时,它将再次工作


我希望我正确地理解了这个问题。

我已经使用executeInLocalView for admin用户来获取类别和产品,它已经起到了作用,但我只是想知道,在不知道获取导航节点的具体内容目录的情况下,是否可以找到一个解决方案。我想知道的原因是,在我们设置的cronjob impex中例如,“XXXNavNode”到CMSNavigationNode模型,它可以工作(CMSNavigationNode是cronjob的一个属性)而且它不询问它属于哪个内容目录。嗯,很奇怪。一个可能的原因可能是impex的某个地方设置了默认目录。或者cronjob使用该字段作为字符串,然后通过id和一些默认目录获取正确的navnode。我检查了它,发现我看不到impex.impex头的任何默认目录“插入更新类别VisibilityHandlerCronJob;代码[unique=true];作业(代码);类别(代码);CMSNavigationNode(uid);singleExecutable;sessionLanguage(isocode)”只要您不同步目录,此标题就可以工作。为什么?当您引用一个项目(例如CMSNavigationNode)时您需要使用一个属性和值来唯一标识该项。在您的情况下,您通过其uid引用节点。只要数据库中只有一个项具有此uid,这将起作用。当您同步目录时,将有两个项具有相同的uid,并且您的impex将不再起作用。我有一个目录,刚刚暂存,并且可以工作但是为什么它在AfterSaveListener中不起作用呢?正如你所说,我有一个项目CmsNavigationNode和一个唯一的属性。是否可以根据类别确定目录版本?你使用的是哪种cmsNavigationService方法?是否有一种方法可以传递目录版本?例如,cmsNavigationService#getRootNavigationNodes(CatalogVersionModel)我使用了“getCmsNavigationService().getNavigationNodeForId(..)”,我尝试了cmsNavigationService.getRootNavigationNodes(),但没有使用CatalogVersionModel。两者都不起作用。当我设置硬编码的目录会话时(我的自定义方法setCatalogSession(“customContentCatalog”)),它可以工作。正如我在下面的评论中提到的,在没有设置自定义内容目录的情况下,cronjob会找到导航节点。我只是想知道为什么或如何找到?我想,你理解错了,或者我不能正确地说出来。很抱歉,我没有在cron job impex中设置目录版本(“INSERT_UPDATE CategoryVisibilityHandlerCronJob;code[unique=true];作业(代码);类别(代码);CMSNavigationNode(uid);单个可执行文件;会话语言(等代码)”)它在cronjob可执行java类中从CMSNavigationService中找到导航节点,但当我没有在自定义AfterSaveListener中设置目录版本时,它会失败。我不想直接在AfterSaveListener中键入内容目录名称的名称,因为将来可能会有多个目录。这是不灵活的。我在不知道内容目录的情况下,无法理解cronjob如何查找导航节点。或者我如何在AfterSaveListener或类似的地方参数化内容目录的名称?因此,您有一个cronjob,它执行了上面的impex。这很有效。但是,当您尝试使用CmsNavigationService以java代码获取导航节点时,它确实有效不起作用?是的,没错。在自定义AfterSaveListener java代码中,它不起作用。好的,它在impex中起作用,因为只有一个uid项。java代码的行为不同。如果会话中没有目录版本,它将找不到任何内容。应该是这样的。