What do you think about have persistence models and domain models separated? I've read that you don't have to mix persistence concerns with your business concerns (DDD, Clean Architecture,MartinFowler, Eric Evans and a lot and a lot of much more). Even so, I still see in all projects domain models annotated directly with ORM annotations like that, being the domain model coupled to the persistence mechanism reaching an anemic model and violating other principles.
//PersistenceJPA entity
@Entity
@Table(name="training_cycle")
class TrainingCycle {
@Id
private Long id;
private String name;
@Column(name="discipline_id")
@JoinColumn(name="discipline_id")
private Long disciplineId; //Referencing by Id because Discipline is another Aggregate ROOT
//EmptyConstructor, getters and setters avoided
}
//PersistenceJPA entity
@Entity
@Table(name="training_cycle")
class Discipline {
@Id
private Long disciplineId;
private String name;
//EmptyConstructor, getters and setters avoided
}
So if you want to follow clean principles you need to split Domain and Persistence Model(as shown below)to have Domain model with business behavior(this avoid anemic model and follows the SRP) and because of that you need to map the domain model to the persistence model (with typical methods like mapToEntity(DomainModel DM) and mapToDomain(PersistenceModel PM) maybe in a mapper/tranformer maybe in the repository class) when you want to interact with Datastore and viceversa when you want to retrieve data from database.
class Discipline {
private DisciplineId disciplineId;
private String name;
public Discipline(DisciplineId disciplineId, String name) {
this.disciplineId = disciplineId;
this.name = name
}
}
public class TrainingCycle{
private TrainingCycleId trainingCycleId;
private String name;
private DisciplineId disciplineId;
public TrainingCycle(TrainingCyleId trainingCycleId, String name, DisciplineId disciplineId) {
this.trainingCycleId = trainingCycleId;
this.name = name;
assignDiscipline(disciplineId);
}
public void assignDiscipline(DisciplineId aDisicplineId) {
if(aDisicplineId == null) {
throw new IllegalArgumenException("Discipline cannot be null")
}
this.disciplineId = aDisicplineId;
}
}
@Entity
@Table(name="training_cycle")
class TrainingCycleJpa {
@Id
private Long id;
private String name;
@Column(name="discipline_id")
@JoinColumn(name="discipline_id")
private Long disciplineId; //Referencing by Id because Discipline is another Aggregate ROOT
//EmptyConstructor, getters and setters avoided
}
@Entity
@Table(name="training_cycle")
class DisciplineJpa {
@Id
private Long disciplineId;
private String name;
//EmptyConstructor, getters and setters avoided
}
class TrainingCyleJpaRepository implements TrainigCycleRepository {
public void create(TrainingCycle trainingCycle) {
entityManager.persist(this.mapToEntity(trainingCycle)
}
public TrainingCycle create(TrainingCycleId trainingCycleId) {
return this.mapToDomain(entityManager.find(TrainingCycleId));
}
}
So the discussion/question is Split or not Split Persistence Model from Domain Model? When to split or when not? In the most projects, not to say in all the ones I've seen as an example, I've seen they couple annotations of persistence model in Domain Model when "gurus are allways hawking" DataStore is a detail.
Thanks a lot.
annotations do not execute any code
, but there is code that scans for annotations and executes other code. So effectively annotations execute code. – Renegado