java - Hibernate 如何使用 InheritanceType.JOINED 区分对象类型
问题描述
我的 Spring 应用程序中有不同的用户类型。我实现了某种继承。所有用户类型都从用户类扩展。我认为这里有两张表就足够了:
- 表“用户” - 包含所有共享实体属性的列
- 表“users_corporate” - 包含 CorporateCustomer 类属性的列:companyName 和 VatNumber
“用户”将有:id、用户名、密码、名字、姓氏、电子邮件、手机、城市、街道、邮政编码
“users_corporate”将有:company_name、vat_number
类 RetailCustomer 和 Provider 没有任何带有 @Column 注释的字段,因此不需要为它们提供表,我只需要声明带有 OneToMany 映射的字段。现在我想知道 hibernate 将如何区分 Provider 和 RetailCustomer其他如果我在他们的班级中没有@Table 注释。当我将使用 Spring Data 存储库并例如调用 providerRepository.findAll() 时,它现在将如何将“用户”表中的哪些行是提供者,哪些是零售客户?它会起作用吗?我错过了什么吗?
基本实体:
@MappedSuperclass
public class BaseEntity{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
}
用户:
@Entity
@Table(name="users")
@Inheritance(strategy = InheritanceType.JOINED)
public class User extends BaseEntity{
@Column(name = "username")
private String userName;
@Column(name = "password")
private String password;
@Column(name = "email")
private String email;
@ManyToMany(fetch = FetchType.EAGER)
@JoinTable(name = "users_roles", joinColumns = @JoinColumn(name = "user_id"), inverseJoinColumns = @JoinColumn(name = "role_id"))
private Collection<Role> roles;
}
企业客户:
@Entity
@Table(name="users_corporate")
public class CorporateCustomer extends User{
@Column(name = "company_name")
private String companyName;
@Column(name = "vat_number")
private String vatNumber;
@OneToMany(mappedBy = "customer")
private List<Appointment> appointments;
}
零售客户:
@Entity
//@Table <---- i think it is not needed here?
public class RetailCustomer extends User {
@OneToMany(mappedBy = "customer")
private List<Appointment> appointments;
}
提供者:
@Entity
//@Table <---- i think it is not needed here?
public class Provider extends User{
@OneToMany(mappedBy = "provider")
private List<Appointment> appointments;
@ManyToMany
@JoinTable(name="works_providers", joinColumns=@JoinColumn(name="id_user"), inverseJoinColumns=@JoinColumn(name="id_work"))
private List<Work> works;
@OneToOne(mappedBy="provider", cascade = {CascadeType.ALL})
private WorkingPlan workingPlan;
}
解决方案
如果我的类中没有 @Table 注释,休眠将如何区分 Provider 和 RetailCustomer?
如果不使用@Table 指定表名,则表名与实体名相同。
当我调用providerRepository.findAll() 时,“users”表中的哪些行是provider,哪些是retailCustomer?
如果从 ProviderRepository 中选择,则休眠生成inner join
. 只会返回提供者实体。Hibernate 生成原生 SQL:
select ... from Provider p
inner join User u on p.id=u.id
对于使用 UserRepository 选择所有用户,休眠将生成left join
. 结果将包含所有可能的用户类型。Hibernate 生成原生 SQL:
select ...,
case
when r.id is not null then 1
when p.id is not null then 2
when u.id is not null then 0
end as clazz_0_
from User u
left outer join Provider p on p.id=u.id
left outer join RetailCustomer r on r.id=u.id
clazz_0_
帮助列区分将创建哪个实体类。
推荐阅读
- scala - IntelliJ Scala 在 32GB 内存的快速 CPU 上速度太慢
- javascript - 如何为给定的实时数据计算angular6中特定列的动态总和
- json - 为 JSON 到 KDB 表创建 GET 请求?
- html - Inconsistent CSS "invalid property value" in Chrome
- flutter - Flutter:尝试删除非 JNI 本地引用,转储线程
- excel - Excel - 使用相同的代码匹配所有行,然后复制和合并单元格的内容
- powershell - 强类型 PS 自定义对象属性
- angular - 如何配置 terserplugin 不破坏类名
- shell - 如何使用valgrind查看很多可执行文件而不用长时间盯着终端?
- dataframe - 如何使用另一个数据框作为字典来翻译 csv 数据文件中某个变量的含义,以便在 R 中读取?