Skip to content

Entités JPA et Value Objects (VO)

Copy of sumaris-pod/.agents/rules/jpa-entities-and-vos.md (rule written for AI coding agents, when creating or modifying JPA entities, Value Objects (VO), repositories, or entity-VO mappings). Do not edit here: run npm run site:sync-rules to update it.

  • Entités JPA

    • Annotations Lombok: @FieldNameConstants, @Getter, @Setter, @EqualsAndHashCode(onlyExplicitlyIncluded = true).
    • Implémente IEntity<ID>; la clé primaire est annotée @EqualsAndHashCode.Include.
    • @Table avec nom en snake_case.
    • Identifiant via séquence @SequenceGenerator (suffixe _seq).
    • Colonnes NON NULL par défaut (nullable = false).
    • Clés étrangères suffixées par _fk.
  • Value Objects (VO)

    • Lombok: @Data, @FieldNameConstants.
    • Implémente IValueObject<ID> et contient au minimum id et updateDate.
    • Pour chaque relation: ajoute à la fois l'objet VO lié ET un champ <attr>Id (identifiant seul).
    • Collections de types simples: tableaux (String[], Integer[], ...). Collections de VO: List<>.
    • Chaque entité doit avoir son VO correspondant.
    • Un VO doit contenir l'ID et la date de mise à jour (updateDate).
    • Pour une relation vers OtherEntity, le VO doit avoir :
      • private OtherEntityVO otherEntity;
      • private Integer otherEntityId;
    • Les mappings entre Entité et VO se font dans *RepositoryImpl.toVO() et toEntity().
  • Spécifications JPA

    • Interface: extends IEntitySpecifications<ID, E>.
    • Utilise Daos.composePath() / Daos.composeJoin() / Daos.composeJoinList() au lieu de créer les joins manuellement.
    • Référence toujours les champs via Entity.Fields.FIELD_NAME (jamais de chaînes litérales).
  • Repository

    • Interface: extends SumarisJpaRepository<E extends IEntity<ID>, V extends IValueObject<ID>> et implémente l'interface Specifications correspondante.
  • RepositoryImpl

    • Étend SumarisJpaRepositoryImpl<E, ID, V>.
    • Constructeur type:
      protected RepositoryImpl(EntityManager entityManager) {
        super(E.class, E.class, entityManager);
      }
      
    • Conversion toVO(E, V, boolean) et toEntity(V, E, boolean):
      • Pour chaque sous-entité: utilise les repositories correspondants, ex. otherEntityRepository.toVO(...) et otherEntityRepository.getById(source.getOtherEntityId()).