diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml
index 5dff7aff..2f7e1ae4 100644
--- a/.github/workflows/maven.yml
+++ b/.github/workflows/maven.yml
@@ -53,6 +53,27 @@ jobs:
- name: Build with Maven
run: mvn -B install -Pmetrics --file pom.xml
+ - name: Check for uncommitted generated source changes
+ if: github.event_name == 'pull_request'
+ run: |
+ echo "Checking for uncommitted generated source changes..."
+
+ # Check if there are any changes in generated-sources directories
+ if git diff --name-only HEAD | grep -E "target/generated-sources/"; then
+ echo "❌ ERROR: Found uncommitted generated source changes!"
+ echo ""
+ echo "The following generated files have changed:"
+ git diff --name-only HEAD | grep -E "target/generated-sources/" | sed 's/^/ /'
+ echo ""
+ echo "Please commit these changes to the repository:"
+ echo " git add target/generated-sources/"
+ echo " git commit -m \"Update generated sources\""
+ echo ""
+ exit 1
+ else
+ echo "✅ No uncommitted generated source changes found"
+ fi
+
- name: SonarCloud Analysis
# Skip for Dependabot PRs (no access to secrets)
if: github.actor != 'dependabot[bot]'
diff --git a/example/.gitignore b/example/.gitignore
new file mode 100644
index 00000000..6dbe5dc8
--- /dev/null
+++ b/example/.gitignore
@@ -0,0 +1,3 @@
+# Include generated sources (they're ignored by main .gitignore)
+!/target/generated-sources/
+!/target/generated-test-sources/
diff --git a/example/target/generated-sources/annotations/org/javahelpers/simple/builders/example/BookDtoBuilder.java b/example/target/generated-sources/annotations/org/javahelpers/simple/builders/example/BookDtoBuilder.java
new file mode 100644
index 00000000..322928bc
--- /dev/null
+++ b/example/target/generated-sources/annotations/org/javahelpers/simple/builders/example/BookDtoBuilder.java
@@ -0,0 +1,516 @@
+package org.javahelpers.simple.builders.example;
+
+import static org.javahelpers.simple.builders.core.util.TrackedValue.changedValue;
+import static org.javahelpers.simple.builders.core.util.TrackedValue.initialValue;
+import static org.javahelpers.simple.builders.core.util.TrackedValue.unsetValue;
+
+import java.math.BigDecimal;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.javahelpers.simple.builders.core.util.BuilderToStringStyle;
+import org.javahelpers.simple.builders.core.util.TrackedValue;
+
+/**
+ * Builder for {@code org.javahelpers.simple.builders.example.BookDto}.
+ *
+ * This builder provides a fluent API for creating instances of org.javahelpers.simple.builders.example.BookDto with
+ * method chaining and validation. Use the static {@code create()} method
+ * to obtain a new builder instance, configure the desired properties using
+ * the setter methods, and then call {@code build()} to create the final DTO.
+ */
+public class BookDtoBuilder {
+ /**
+ * Tracked value for title: the book title to set.
+ */
+ private TrackedValue title = unsetValue();
+
+ /**
+ * Tracked value for author: the book author to set.
+ */
+ private TrackedValue author = unsetValue();
+
+ /**
+ * Tracked value for isbn: the ISBN to set.
+ */
+ private TrackedValue isbn = unsetValue();
+
+ /**
+ * Tracked value for pages: the page count to set.
+ */
+ private TrackedValue pages = unsetValue();
+
+ /**
+ * Tracked value for price: the book price to set.
+ */
+ private TrackedValue price = unsetValue();
+
+ /**
+ * Tracked value for exactPrice: the exact book price to set.
+ */
+ private TrackedValue exactPrice = unsetValue();
+
+ /**
+ * Tracked value for available: true if available, false otherwise.
+ */
+ private TrackedValue available = unsetValue();
+
+ /**
+ * Tracked value for rating: the book rating to set.
+ */
+ private TrackedValue rating = unsetValue();
+
+ /**
+ * Tracked value for edition: the edition number to set.
+ */
+ private TrackedValue edition = unsetValue();
+
+ /**
+ * Tracked value for salesCount: the sales count to set.
+ */
+ private TrackedValue salesCount = unsetValue();
+
+ /**
+ * Tracked value for discount: the discount percentage to set.
+ */
+ private TrackedValue discount = unsetValue();
+
+ /**
+ * Tracked value for category: the category code to set.
+ */
+ private TrackedValue category = unsetValue();
+
+ /**
+ * Tracked value for publishDate: the publication date to set.
+ */
+ private TrackedValue publishDate = unsetValue();
+
+ /**
+ * Tracked value for lastUpdated: the last update timestamp to set.
+ */
+ private TrackedValue lastUpdated = unsetValue();
+
+ /**
+ * Tracked value for subtitle: an Optional containing the subtitle to set.
+ */
+ private TrackedValue> subtitle = unsetValue();
+
+ /**
+ * Tracked value for tags: the list of tags to set.
+ */
+ private TrackedValue> tags = unsetValue();
+
+ /**
+ * Tracked value for genres: the set of genres to set.
+ */
+ private TrackedValue> genres = unsetValue();
+
+ /**
+ * Tracked value for metadata: the metadata map to set.
+ */
+ private TrackedValue