What does the JCRNodeWrapper hasTranslations() method do?
Question
What does the JCRNodeWrapper hasTranslations() method do?
Answer
hasTranslations() tells you whether a node has any translation sub-node at
all. The implementation is one line:
public boolean hasTranslations() throws RepositoryException {
return objectNode.getNodes(TRANSLATION_NODES_PATTERN).hasNext();
}
where the pattern is j:translation_*.
In Jahia, the internationalized properties of a node are not stored on the node
itself but on child nodes named j:translation_en, j:translation_fr and so on,
one per locale. hasTranslations() simply asks whether at least one of those
children exists.
It is not a per-language check
This is the common misunderstanding. The method answers "has this node been
translated at all?", not "is this node translated into French?". It returns
true as soon as any single locale exists.
For a specific locale, use one of these instead - all on JCRNodeWrapper:
| Method | Answers |
|---|---|
hasI18N(Locale locale) | Is there a translation node for this locale? |
hasI18N(Locale locale, boolean fallback) | Same, optionally falling back |
getI18N(Locale locale) | The translation node itself |
getI18Ns() | An iterator over all translation nodes |
checkI18nAndMandatoryPropertiesForLocale(Locale locale) | Is the locale present and are its mandatory i18n properties filled? |
That last one is usually what you want before treating a locale as complete.
It reads the raw node on purpose
objectNode is the underlying provider node, not the wrapper. That matters,
because translation nodes are deliberately hidden from the normal API: they do
not come back from getNodes() on the wrapper, and a JCR SQL2 query such as
select * from [jnt:translation] returns the owning nodes rather than the
translation nodes themselves. Reading the raw node is how the method sees
children the wrapper filters out.
So hasTranslations() is the supported way to ask the question - do not try to
reach the j:translation_* children yourself through the wrapper or through a
query, because neither will show them to you.
Where Jahia uses it
Core calls it in WorkflowService before resolving a locale-specific workflow:
if the node has no translations at all, there is no point fetching the
translation node for the display locale.
This article was drafted with AI assistance, then reviewed and curated by Jahia Customer Support engineers before publication.