Class TenantAwareEntity
java.lang.Object
io.leandev.appfuse.jpa.tenant.TenantAwareEntity
- All Implemented Interfaces:
TenantAware
租戶感知實體基類
所有需要多租戶數據隔離的 Entity 都應繼承此類(或其子類)。租戶隔離由 Hibernate 原生
discriminator 多租戶(TenantId)承擔,見
ADR-016:
- Session 建構時由
TenantContextIdentifierResolver決定租戶, Hibernate 自動套用租戶 filter——不需任何人呼叫enableFilter - filter 的
applyToLoadByKey = true,故entityManager.find()亦受過濾(不需手寫租戶比對) - INSERT 時由
TenantIdGeneration注入租戶;已顯式設值者:root 放行、非 root 須相符 (不符拋PropertyValueException) updatable = false:租戶歸屬不可被 UPDATE 改寫
使用方式
方式 1:直接繼承(不需要審計功能)
@Entity
@Table(name = "products")
public class Product extends TenantAwareEntity {
// ...
}
方式 2:建立應用層基類加入審計功能(推薦)
@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
public abstract class AuditableTenantEntity extends TenantAwareEntity {
@CreatedBy
@Column(name = "created_by", updatable = false)
private String createdBy;
@CreatedDate
@Column(name = "created_date", updatable = false)
private Instant createdDate;
@LastModifiedBy
@Column(name = "last_modified_by")
private String lastModifiedBy;
@LastModifiedDate
@Column(name = "last_modified_date")
private Instant lastModifiedDate;
}
設計說明
- tenantId 使用 String 欄位而非
@ManyToOne關聯,避免不必要的 JOIN 查詢(ADR-001 的欄位策略,維持不變) - 建立前必須指明租戶:
TenantContext.runAs(tenantId, ...)(首選)或顯式setTenantId(...); 兩者皆無時由@PrePersist守衛擋下(見rejectRootTenantOnPersist()) - 先設
TenantContext、再開交易——租戶綁在 Session 建構時 - 不包含審計欄位,讓應用層自行決定是否需要審計功能
- 不包含
@Id欄位,讓子類自行定義主鍵策略
- See Also:
-
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescription取得此 Entity 所屬的租戶 IDvoidsetTenantId(String tenantId) 設定此 Entity 所屬的租戶 ID
-
Constructor Details
-
TenantAwareEntity
public TenantAwareEntity()
-
-
Method Details
-
getTenantId
Description copied from interface:TenantAware取得此 Entity 所屬的租戶 ID- Specified by:
getTenantIdin interfaceTenantAware- Returns:
- 租戶 ID
-
setTenantId
Description copied from interface:TenantAware設定此 Entity 所屬的租戶 ID
一般情況由 Hibernate
@TenantId於寫入時自動注入,不需手動呼叫;root session 要替特定租戶建立資料時才顯式設定(見TenantAwareEntity的守衛說明)。- Specified by:
setTenantIdin interfaceTenantAware- Parameters:
tenantId- 租戶 ID
-