我遇到的一个问题是在不牺牲SOLID原则的情况下映射与JPA / Hibernate一对多关系的好方法。这是我正在处理的当前项目中此问题的示例:
给出以下定义单向一对多关系的代码:
@Entity
@Table(name = "users")
public class User extends AggregateEntity<User> implements HasRoles, HasContactInfo, HasContacts, HasDeals {
@OneToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE}, fetch = FetchType.LAZY)
@JoinColumn(name = "fk_hasContacts")
private Set<Contact> contacts;}
我的理解是,这将在“联系人”表中创建“ fk_hasContacts”列,而无需“ Contact”类知道或关心它是从哪个对象引用的。另外,请注意“用户”如何实现“ hasContacts”接口,该接口在两个实体之间产生去耦效果。如果明天我想再上一堂课;说“ BusinessEntity”(也有联系人),则在当前代码中无需更改任何内容。但是,在阅读完该主题之后,从数据库性能的角度来看,这种方法似乎效率不高。
映射@OneToMany关联关系的最佳方法是依靠@ManyToOne端传播所有实体状态更改-As expounded upon here。
似乎是盛行的智慧。如果以这种方式进行工程设计,“ User”类现在将如下所示:
@Entity
@Table(name = "users")
public class User extends AggregateEntity<User> implements HasRoles, HasContactInfo, HasContacts, HasDeals {
@OneToMany(mappedBy = "user", fetch = FetchType.LAZY)
private Set<Contact> contacts;
(以前已分离的)“ Contact”类现在必须看起来像这样:
@Entity
@Table(name = "contacts")
public class Contact extends StandardEntity<Contact> {
@ManyToOne(fetch = FetchType.LAZY, cascade = {CascadeType.PERSIST, CascadeType.MERGE})
@JoinColumn(name = "fk_user")
private User user;
关键问题是,从here看来,JPA似乎不支持将接口定义为实体属性。所以这段代码:
@Entity
@Table(name = "contacts")
public class Contact extends StandardEntity<Contact> {
@ManyToOne(fetch = FetchType.LAZY, cascade = {CascadeType.PERSIST, CascadeType.MERGE})
@JoinColumn(name = "fk_user")
private HasContacts hasContacts;//some class which implements the "HasUser" interface
不是一个选择。似乎必须在SOLID OOP和有效的ORM实体之间进行选择。经过大量阅读之后,我仍然不知道对数据库性能的影响是否足够严重,不足以证明编写紧耦合,僵化甚至最终是糟糕代码的合理性。
对于设计原则中这种似乎矛盾的方法,是否有任何解决方法/解决方案?