Spring Boot: как сохранить объекты DDD чистыми от JPA / Hibernate Аннотации? - PullRequest
0 голосов
/ 19 сентября 2019

Я пишу приложение, в котором я хочу следовать шаблонам DDD, типичный класс сущностей выглядит следующим образом:

@Entity
@Table(name = "mydomain_persons")
class Person { 
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private int id;

    @Column(name="fullname") 
    private String fullName;

    @OneToMany(cascade=ALL, mappedBy="item")
    private Set<Item> items;
}

Как видите, поскольку JPA / Hibernate в значительной степени опирается на аннотации к классам сущностейклассы сущностей моего домена теперь загрязнены постоянными аннотациями.Это нарушает принципы DDD, а также разделение слоев.Также это вызывает у меня проблемы со свойствами, не связанными с ORM, такими как события.Если я использую @Transient, он не будет инициализировать список событий, и мне придется делать это вручную или получать странные ошибки.

Мне бы хотелось, чтобы сущность домена была POJO (или POKO, поскольку я использую Kotlin), поэтому я не хочу, чтобы такие аннотации были в классе сущности.Однако я определенно не хочу использовать XML-конфигурации, это ужас и причина, по которой разработчики Spring в первую очередь перешли к аннотациям.

Какие варианты у меня есть?Должен ли я определить класс DTO, содержащий такие аннотации, и класс Mapper, который преобразует каждый DTO в соответствующий объект домена?Это хорошая практика?

Редактировать: Я знаю, что в C # Entity Framework позволяет создавать классы отображения вне классов Entity с классами Configuration, что является лучшей альтернативой, чем ад XML.Я не уверен, что такая техника доступна в мире JVM или нет, кто-нибудь знает, что приведенный ниже код можно сделать с помощью Spring или нет?

public class PersonDbContext: DbContext 
{
    public DbSet<Person> People { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
    //Write Fluent API configurations here

    //Property Configurations
    modelBuilder.Entity<Person>().Property(p => p.id).HasColumnName("id").IsRequired();
    modelBuilder.Entity<Person>().Property(p => p.name).hasColumnName("fullname").IsRequired();
    modelBuilder.Entity<Person>().HasMany<Item>(p => p.items).WithOne(i => i.owner).HasForeignKey(i => i.ownerid)
}
...