Entity Mutator patterns - JoseCanova/brainz GitHub Wiki
Welcome to the brainz wiki!
This page captures the recommended patterns for implementing mutator methods in Java JPA entities, especially as used in this repository. These patterns help keep the codebase consistent and robust, and ensure correct mapping between Java objects and database schema constraints.
- General Principle
- Pattern 1: Mutable Field, Nullable Column
- Pattern 2: Mutable Field, Not Null Column
- Decision Table
- Example Implementations
- References
The implementation of mutator methods for entity fields should match the JPA @Column(nullable = ...)
annotation. This ensures that the code's behavior matches the database schema's expectations regarding null values.
When:
- The JPA annotation is
@Column(nullable = true)
(the default). - The database column allows
NULL
values.
Implementation:
@Column(name="description", nullable=true)
private String description;
@Override
public Optional<String> description(@Nullable String description) {
return Optional.ofNullable(description).map(p -> this.description = p);
}
- The parameter is annotated with
@Nullable
(if available in your codebase). - The implementation uses
Optional.ofNullable(...)
to safely allow for nulls.
When:
- The JPA annotation is
@Column(nullable = false)
. - The database column does not allow
NULL
values.
Implementation:
@Column(name="description", nullable=false)
private String description;
@Override
public Optional<String> description(String description) {
return Optional.of(description).map(p -> this.description = p);
}
- The parameter is not annotated as
@Nullable
. - The implementation uses
Optional.of(...)
, which throws aNullPointerException
if null is passed, enforcing the non-null contract.
Column Nullability | Mutator Parameter | Optional Usage | Allows null? |
---|---|---|---|
nullable = true |
@Nullable String |
Optional.ofNullable() |
YES |
nullable = false |
String |
Optional.of() |
NO |
@Column(name = "comment", nullable = true)
private String comment;
public Optional<String> comment(@Nullable String comment) {
return Optional.ofNullable(comment).map(c -> this.comment = c);
}
@Column(name = "artistName", nullable = false)
private String artistName;
public Optional<String> artistName(String artistName) {
return Optional.of(artistName).map(a -> this.artistName = a);
}
When your JPA entity field is annotated as @Column(nullable = false)
, it must never be set to null
. To enforce this semantic correctness at the code level, use the @NonNull
annotation from org.springframework.lang
. This is especially helpful for static analysis tools and makes your intent clear to other developers and IDEs.
Example:
import org.springframework.lang.NonNull;
@Column(name = "description", nullable = false)
private String description;
/**
* Sets the description.
* @param description the new description, must not be null
* @return an Optional containing the new description
*/
public Optional<String> description(@NonNull String description) {
return Optional.of(description).map(p -> this.description = p);
}
Key Points:
- The
@NonNull
annotation on the parameter documents and enforces thatnull
is not an acceptable value. - If
null
is passed,Optional.of(description)
will throw aNullPointerException
, matching the database constraint. - IDEs and static analysis tools will highlight any incorrect usage.
Tip:
Always use@NonNull
for parameters of mutator methods when the corresponding JPA column isnullable = false
. This ensures your code and your database schema are aligned for null safety.
- JPA
@Column
documentation: Oracle JPA @Column - Java Optional: Java SE Documentation
- Project entity examples:
Note:
Always align your Java mutator methods with database schema constraints. Consistency in this pattern helps avoid runtime errors and makes code more maintainable and self-documenting.