I was asked recently to troubleshoot a DXA 1.5 module that was not behaving properly. The apparent issue was that nested embedded fields in all models were not filled in with values once the Semantic Mapper would execute and create the models.
This prompted me to do a little bit of digging into the Semantic Mapper and its registries of model entities, property and field maps. It turned out the models in the custom module were not being scanned and as such not registered as entities by the Semantic Mapper.
The Semantic Mapper is DXA's de facto model factory that converts a Generic Page or Component into a specific page or component model, by mapping fields in the generic object to properties in the specific object.
The solution was to simply call method registerEntities on the SemanticMapperRegistry singleton and pass it the base package name. The logic will then scan for entity models (i.e. classes that extend DXA's AbstractEntityModel class) in sub-packages and register them for later use by using reflection to extract Entity maps, Property maps and Field maps.
I placed the code-above in the model initializer class, which I present below. The semanticMappingRegistry is an autowired singleton that Spring framework injects into the initializer class upon instantiation.
A more in-depth explanation and tutorial on how to create a DXA 1.5 Java module is available in my next post Creating a DXA Java Module.
This prompted me to do a little bit of digging into the Semantic Mapper and its registries of model entities, property and field maps. It turned out the models in the custom module were not being scanned and as such not registered as entities by the Semantic Mapper.
The Semantic Mapper is DXA's de facto model factory that converts a Generic Page or Component into a specific page or component model, by mapping fields in the generic object to properties in the specific object.
The solution was to simply call method registerEntities on the SemanticMapperRegistry singleton and pass it the base package name. The logic will then scan for entity models (i.e. classes that extend DXA's AbstractEntityModel class) in sub-packages and register them for later use by using reflection to extract Entity maps, Property maps and Field maps.
@PostConstruct private void registerModels() { semanticMappingRegistry.registerEntities(getClass().getPackage().getName()); }
I placed the code-above in the model initializer class, which I present below. The semanticMappingRegistry is an autowired singleton that Spring framework injects into the initializer class upon instantiation.
package com.mihaiconsulting.dxa.emerald; import com.mihaiconsulting.dxa.emerald.model.entity.MainNavigation; import com.sdl.webapp.common.api.mapping.semantic.SemanticMappingRegistry; import com.sdl.webapp.common.api.mapping.views.AbstractInitializer; import com.sdl.webapp.common.api.mapping.views.ModuleInfo; import com.sdl.webapp.common.api.mapping.views.RegisteredViewModel; import com.sdl.webapp.common.api.mapping.views.RegisteredViewModels; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import javax.annotation.PostConstruct; @org.springframework.context.annotation.Configuration public class EmeraldInitializer { @RegisteredViewModels({ @RegisteredViewModel(viewName = "MainNavigation", modelClass = MainNavigation.class) }) @Component @ModuleInfo(name = "Emerald module", areaName = "Emerald") public static class EmeraldViewInitializer extends AbstractInitializer { @Autowired private SemanticMappingRegistry semanticMappingRegistry; @Override protected String getAreaName() { return "Emerald"; } @PostConstruct private void registerModels() { semanticMappingRegistry.registerEntities(getClass().getPackage().getName()); } } }
A more in-depth explanation and tutorial on how to create a DXA 1.5 Java module is available in my next post Creating a DXA Java Module.
Comments