EdeeShop · Implementace
Upraveno

Rozšíření produktu o kompozitní atributy

Tento dokument popisuje obecný postup, jak do produktového modelu přidat nový „kompozitní“ atribut. Jako ilustrativní příklad je použit atribut materiálového složení produktu (MaterialComposition).

Pojem „kompozitní atribut produktu“ vyjadřuje, že jde o hodnotu se vnitřní strukturou (objekt, seznam, mapa), která se typicky ukládá serializovaně (např. JSON) do jedné databázové kolony.

Co budete dělat v krátkosti

  • Rozšíříte datový model a databázi o novou persistovanou vlastnost (sloupec) pro kompozitní atribut.
  • Definujete modelovou třídu pro nová data a připojíte ji k produktu pomocí traitu.
  • Zaregistrujete převodníky (convertory) mezi String (persistovaná forma) a doménovým objektem (model).

1) Rozšíření datového modelu a DB schématu

  1. Přidejte DB migraci, která zavede novou kolonu do tabulky s produkty (nebo jiné cílové entity). Typicky VARCHAR/TEXT/JSON podle databáze a velikosti:
sql
-- příklad: /META-INF/.../sql/mysql/patch_yyyy.MM.dd.HH.mm.sqlALTER TABLE T_EDEESHOP_PRODUCT     ADD COLUMN material_composition TEXT NULL COMMENT 'JSON s materiálovým složením produktu';
  1. Ujistěte se, že váš „feature“/konfigurační modul zvyšuje verzi modelu, aby se migrace a změny modelu správně propsaly. V tomto projektu je to anotace @ModelVersion na třídě feature. Příklad:
java
// com.example.project.ProjectFeaturemodelVersion = @ModelVersion(		name = "lib_project_eshop",		version = "yyyy.MM.dd.HH.mm",		scriptDir = "classpath:/META-INF/lib_project_eshop/sql/")public class ProjectFeature implements Feature {    // ...}

2) Definice modelu a připojení k produktu pomocí traitu

  1. Vytvořte doménový model pro kompozitní atribut. V příkladu com.fg.project.model.MaterialComposition:
java
package com.fg.project.model;
import java.io.Serial;import java.io.Serializable;import java.util.Map;
/** * Příklad kompozitního atributu – materiálové složení * (např. { "cotton": 80, "polyester": 20 }). */public class MaterialComposition implements Serializable {    @Serial private static final long serialVersionUID = 1L;
    /**     * Mapování materiál -> procenta (0–100).     */    private Map<String, Integer> materials;
    public Map<String, Integer> getMaterials() { return materials; }    public void setMaterials(Map<String, Integer> materials) { this.materials = materials; }}
  1. Připojte kompozitní atribut k produktu pomocí traitu. V projektu je produktový trait com.fg.project.model.ProjectProduct, který rozšiřuje produkt o nové vlastnosti. Ukázka minimálního napojení:
java
package com.example.project.model;
import com.fg.cps.eshop.catalogEntity.model.trait.Trait;
/** * Trait pro rozšíření produktu o materiálové složení. */@Traitpublic interface ProjectProduct extends Product {    MaterialComposition getMaterialComposition() { return materialComposition; }    void setMaterialComposition(MaterialComposition materialComposition) { this.materialComposition = materialComposition; }}

Poznámka – traity se registrují v deskriptorech modelu, např. ve feature vrstvě přes ModelClassDescriptor#addTrait.

java

// uvnitř konfigurace modelů ve feature@Overridepublic void beforeSpringInitialization() {	super.beforeSpringInitialization();	// ...	ModelClassDescriptor<?> productModelDescriptor = entityModelClassConfiguration.getProductModelDescriptor();	productModelDescriptor.addTrait(ProjectProduct.class);	// ...}

3) Registrace konvertorů (String <-> doménový objekt)

Kompozitní atribut je v perzistenci často reprezentován jako String (typicky JSON). Pro pohodlnou práci v aplikaci zaregistrujte konvertory v obou směrech:

  • com.fg.hugoboss.eshop.dao.MaterialCompositionToStringConvertor
  • com.fg.hugoboss.eshop.dao.StringToMaterialCompositionConvertor

Ukázky tříd:

java
// com.fg.hugoboss.eshop.dao.StringToMaterialCompositionConvertorpublic class StringToMaterialCompositionConvertor implements Converter<String, MaterialComposition> {    @Override    public MaterialComposition convert(String source, Class<? extends MaterialComposition> expectedType) {        return EdeeShopJsonParserBuilder.fromJson(source, MaterialComposition.class);    }}
java
// com.fg.hugoboss.eshop.dao.MaterialCompositionToStringConvertorpublic class MaterialCompositionToStringConvertor implements Converter<MaterialComposition, String> {    @Override    public String convert(MaterialComposition source, Class<? extends String> expectedType) {        return EdeeShopJsonParserBuilder.toJson(source);    }}

Registrace konvertorů:

  • V tomto projektu se používá interní conversionService. Konvertory registrujte v inicializaci feature:
java
@Overridepublic void afterSpringInitialization(AbstractRefreshableApplicationContext moduleContext) {	super.afterSpringInitialization(moduleContext);
	final MetadataManager metadataManager = moduleContext.getBean(COMMON_EDEE_SHOP_METADATA_MANAGER, MetadataManager.class);	final MetadataConversionService conversionService = metadataManager.getMetadataConfiguration().getConversionService();
	conversionService.addConverter(new StringToMaterialCompositionConvertor());	conversionService.addConverter(new MaterialCompositionToStringConvertor());}

Shrnutí

  1. Přidejte DB migraci a zvyšte verzi modelu (@ModelVersion).
  2. Definujte doménový model kompozitního atributu a připojte jej k entitě pomocí traitu (+ zaregistrujte trait v konfiguraci modelu).
  3. Zaregistrujte konvertory String <-> DoménovýTyp a použijte je v aplikační logice.