Skip to content

chore(): update folder structure and domain entities into hexa arc…#27

Draft
brandPittCode wants to merge 7 commits intomainfrom
chore/update-folder-structure-into-hexa-archi
Draft

chore(): update folder structure and domain entities into hexa arc…#27
brandPittCode wants to merge 7 commits intomainfrom
chore/update-folder-structure-into-hexa-archi

Conversation

@brandPittCode
Copy link
Copy Markdown
Collaborator

@brandPittCode brandPittCode commented Apr 15, 2026

PR Description

What this PR Provides

This pull request refactors the domain model layer to enforce a clear separation between domain and persistence concerns, following Domain-Driven Design (DDD) best practices. It removes all persistence (JPA/Hibernate) and serialization (Jackson) annotations from domain model classes, ensuring they are pure business objects. Additionally, it introduces MapStruct and its Lombok integration for object mapping, and makes minor documentation and reference updates.

Domain Model Refactoring:

  • Removed all JPA and Jackson annotations from domain model classes (Entity, Property, Relation, EntityTemplate, PropertyDefinition), making them pure business objects and moving persistence concerns to the infrastructure layer. This includes removing table/column mappings, cascade types, and serialization strategies.

Migration from Lombok Classes to Java Records:

Why Records over Lombok @value

  • Language-level immutability: Records enforce immutability at the JVM level — fields are private final with no setters, no escape hatches. Lombok's @value achieves this via annotation processing, which can be bypassed through reflection or misconfiguration.

  • Less dependencies in the domain layer: In a hexagonal architecture, the domain layer should have less framework dependencies. Records are a pure JDK feature (Java 17+), eliminating the need for Lombok in the core domain. Lombok remains in the infrastructure layer (JPA entities, adapters) where framework coupling is expected.

  • Explicit data carrier semantics: A record declaration communicates intent — "this type is an immutable data carrier, nothing more". This is clearer than a class annotated with @value, @AllArgsConstructor, @tostring, etc.

  • Records naturally support a functional programming approach in the service layer:

    Referential transparency — merge operations produce new values without mutating inputs
    Thread safety — immutable records can be shared across threads without synchronization
    Testability — pure functions on immutable data are trivial to unit test

Added @EntityGraph annotations on all JpaEntityTemplateRepository query methods:

Eliminates N+1 queries: Without @EntityGraph, loading an EntityTemplate triggers:

Without @EntityGraph With @EntityGraph
1 + 1 + N + 1 queries per template 1 single query per template
Multiple DB round-trips Single DB round-trip
Risk of lazy loading exceptions All associations pre-loaded
  • Prevents LazyInitializationException: Our adapter maps JPA entities to domain records inside findByIdentifier(). Without @EntityGraph, accessing lazy collections outside the original transaction would fail. The entity graph guarantees all associations are initialized before the mapper touches them.

  • Scoped to the repository layer: The @EntityGraph is defined on specific query methods, not on the entity annotations. This means different query methods can choose different fetch strategies — we only eagerly load the full object graph when we know we need it.

Build and Dependency Updates:

  • Added MapStruct and its processor to the project dependencies in pom.xml, along with the Lombok-MapStruct binding for annotation processing compatibility.
    Documentation and Reference Updates:

  • Deleted the JacksonConfiguration class, as serialization configuration is no longer handled in the domain layer.

Fixes

Review

The reviewer must double-check these points:

  • The reviewer has tested the feature
  • The reviewer has reviewed the implementation of the feature
  • The documentation has been updated
  • The feature implementation respects the Technical Doc / ADR previously produced
  • The Pull Request title has a ! after the type/scope to identify the breaking
    change in the release note and ensure we will release a major version.

How to test

Please refer (copy/paste) the test section from the User Story. This should include

  • The initial state: what should be the status of the system before testing
    (for example, ensure the data xxx exists in idp-back to be able to test the feature)
  • What and how to test: steps to perform to test the feature
    (for example, go to page xxx, fill the xxx field and click the 'send' button)
  • Expected results: what should be observed for success or failure
    (for example, there is a link in the database between component X and component Y.
    You can retrieve the information with a GET request to the API)

Breaking changes (if any)

  • N/A

Context of the Breaking Change

  • N/A

Result of the Breaking Change

  • N/A

@brandPittCode brandPittCode changed the title refactor(): update folder structure and domain entities into hexa arc… chore(): update folder structure and domain entities into hexa arc… Apr 15, 2026
import lombok.NoArgsConstructor;

@Entity
@Data
joinColumns = @JoinColumn(name = "entity_template_id"),
inverseJoinColumns = @JoinColumn(name = "relations_definitions_id"))
@OrderBy("name ASC")
private Set<RelationDefinitionJpaEntity> relationsDefinitions = new LinkedHashSet<>();
joinColumns = @JoinColumn(name = "entity_template_id"),
inverseJoinColumns = @JoinColumn(name = "properties_definitions_id"))
@OrderBy("name ASC")
private Set<PropertyDefinitionJpaEntity> propertiesDefinitions = new LinkedHashSet<>();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant