# @TenantId on PostgreSQL (PostgreSQL 17.11), Hibernate 7.4.14.Final

== DDL Hibernate generated (read back from the catalog)
column amount numeric nullable=YES
column id bigint nullable=NO
column number character varying nullable=YES
column tenant_id character varying nullable=NO
unique UNIQUE (tenant_id, number)

== insert: nobody sets tenant_id in Java
-- as acme: save(INV-1)
   sql> insert into invoice (amount,number,tenant_id) values (?,?,?)
   entity.tenantId after save = acme
-- as globex: save(INV-1) - same invoice number, allowed by UNIQUE(tenant_id, number)
   sql> insert into invoice (amount,number,tenant_id) values (?,?,?)
   ids: acme INV-1=1, globex INV-1=2 (one IDENTITY column shared by all tenants)

== reads are filtered
-- as acme: findAll()
   sql> select i1_0.id,i1_0.amount,i1_0.number,i1_0.tenant_id from invoice i1_0 where i1_0.tenant_id = ?
   rows = 2, numbers = [INV-1, INV-2]
-- as globex: findById(acme's id 1)
   sql> select i1_0.id,i1_0.amount,i1_0.number,i1_0.tenant_id from invoice i1_0 where i1_0.id=? and i1_0.tenant_id = ?
   result = Optional.empty

== bulk HQL is scoped too
-- as acme: update Invoice set amount = 0
   sql> update invoice i1_0 set amount=0 where i1_0.tenant_id = ?
   rows updated = 2 (globex's row untouched)

== what @TenantId does NOT cover: native SQL
-- as acme: native query  select count(*) from invoice
   result = 3  (acme owns 2 rows; the native query saw every tenant)

== no tenant set
-- strict resolver (throws when TenantContext is empty): repo.findAll() with no tenant
   org.springframework.transaction.CannotCreateTransactionException: Could not open JPA EntityManager for transaction  <- caused by com.ankurm.multitenancy.tenant.MissingTenantException: no tenant in TenantContext: refusing to open a tenant-scoped session
-- lenient resolver (returns null): repo.findAll() with no tenant
   org.springframework.transaction.CannotCreateTransactionException: Could not open JPA EntityManager for transaction  <- caused by org.hibernate.HibernateException: SessionFactory configured for multi-tenancy, but no tenant identifier specified

== writing a row for a different tenant than the session's
-- as acme: new Invoice with tenantId manually set to globex, saveAndFlush
   org.springframework.dao.DataIntegrityViolationException: assigned tenant id differs from current tenant id [globex != acme] for entity com.ankurm.multitenancy.discriminator.Invoice.tenantId  <- caused by org.hibernate.PropertyValueException: assigned tenant id differs from current tenant id [globex != acme] for entity com.ankurm.multitenancy.discriminator.Invoice.tenantId
