I am currently working on a system, that can have 100k customers.
Each customer, usually has 1-10k Endcustomers, but could have up to 1 million endcustomers, in the extreme case.
And EndCustomerEntity has two lazy @OneToMany relations.
public class EndCustomerEntity {
@Id
@JdbcTypeCode(SqlTypes.CHAR)
@Column(length = 36)
@GeneratedValue
public UUID id;
@Column(name = "ext_id")
public String externalId;
@Column(name = "first_name")
public String firstName;
public String email;
@OneToMany(mappedBy = "endCustomerEntity", cascade = CascadeType.ALL, orphanRemoval = true)
/*TODO check orphanRemoval = true*/
public List<EndCustomerFieldEntity> endCustomerFields = new ArrayList<>();
@OneToMany(mappedBy = "endCustomerEntity", cascade = CascadeType.ALL, orphanRemoval = true)
public List<EndCustomerLabelEntity> endCustomerLabels = new ArrayList<>();
@Column(name = "created_at")
@CreationTimestamp
public Instant createdAt;
@Column(name = "updated_at")
@UpdateTimestamp
public Instant updatedAt;
@Version
@Column(columnDefinition = "integer DEFAULT 0", nullable = false)
public long version;
...
}
One EndCustomerEntity can have a maximum of 30 fields and labels (limited for performance reasons)
On a side note - you can search / filter by the fields and labels also.
Adding and updating the endCustomer fields and labels is complex, the Entity alone had 165 lines of code
(without the add/update logic for the fields and labels just 82 lines)
So one goal of me would be to simplify/shorten the Entity.
However, what truly brought me to these thoughts is the fact that for an addon that I am working on,
I want to be informed when a field / label is added, updated or removed.
GPT-4 told me there are event listener or interceptors, further there are some related annotations from JPA, it seems.
But I am unsure if using that is really the best (readable/maintenable/performant/straight forward) approach,
and then I wanted to somehow refactor the entity anyway as written above.
So now I started to create dedicated FieldService and LabelServices -
but that means someone could add an Endcustomer with fields and labels missing.
The fields and labels cannot live on their own without the Endcustomer, so this feels wrong / dangerous / not properly encapsulated.
So what to do (list is without any preference order)
- Keep the Entity as is and use event listener or interceptors or something like that to be informed of changes
- Keep the @OneToMany lists in the Endcustomer Entity, but manage those elements in a dedicated service
- Remove the @OneToMany lists from the Endcustomer Entity, merge the 3 entities in the business domain only
- Move the Management of the @OneToMany lists into static Mappers / Factories that are called from the Entity to simplify the Enity, but use listener/interceptors to be informed of changes
- Move the Management of the @OneToMany lists into static Mappers / Factories, call them from an Endcustomer ORM Service / Repository
… many other possibilities.
What is the best practice here / What would you recommend me to do?
Many thanks in advance for any thoughts on this.