Ok, I'm doing a sample project on which I'm documenting studies of different kinds. I'm trying to refactor the project to follow a hexagonal-ish (hopefully hexagonal someday) architecture.
I currently have this domain class:
package com.kaue.ticketservice.domain.model;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.annotation.PersistenceCreator;
import java.time.Instant;
import java.time.OffsetDateTime;
@ToString
public class Ticket {
@Schema(description = "User email")
@Getter
final private String requesterEmail;
@Schema(description = "Assignee / Agent email")
@Getter @Setter
private String assigneeEmail;
@Schema(description = "Title of the ticket")
@Getter
final private String title;
@Schema(description = "Ticket description")
@Getter @Setter
private String description;
@Schema(description = "Create date")
@Getter
final private Instant createDate;
@Getter @Setter @LastModifiedDate
private Instant updatedDate;
@Schema(description = "Resolution date")
@Getter @Setter
private OffsetDateTime resolutionDate;
public Ticket(String requesterEmail, String title, String description) {
this.requesterEmail = requesterEmail;
this.title = title;
this.description = description;
this.createDate = Instant.now();
}
@PersistenceCreator /* infrastucture code, we need to fix this.*/
private Ticket(String requesterEmail, String assigneeEmail, String title, String description, Instant createDate, Instant updatedDate, OffsetDateTime resolutionDate) {
this.requesterEmail = requesterEmail;
this.assigneeEmail = assigneeEmail;
this.title = title;
this.description = description;
this.createDate = createDate;
this.updatedDate = updatedDate;
this.resolutionDate = resolutionDate;
}
}
The catch is: I need the @PersistenceCreator constructor with all fields so my repository can return a list of tickets.It makes sense that the domain class also needs a constructor with all fields, which should the repository use. However, to indicate to JPA / Mongo that it needs to use the constructor, I need to put @PersistenceCreator
.
I want to know which ways I have to refactor the code and make it infrastructure-redundant
I tried the code without annotations, expecting Spring Data MongoDb would use it automatically
By reading the spring data documentation I found this
Use factory methods instead of overloaded constructors to avoid @PersistenceCreator — With an all-argument constructor needed for optimal performance, we usually want to expose more application use case specific constructors that omit things like auto-generated identifiers etc. It’s an established pattern to rather use static factory methods to expose these variants of the all-args constructor.
The alternative is:
package com.kaue.ticketservice.domain.model.factories;
import com.kaue.ticketservice.domain.model.Ticket;
import java.time.Instant;
public class TicketFactory {
public static Ticket createTicket(String requesterEmail, String title, String description){
return new Ticket(requesterEmail,null,title,description,Instant.now(),null,null);
}
}
(it can also be done as a method in ticket class)