## Release Notes: SeaORM 2.0.0-rc.38 *(since 2.0.0-rc.37)* ### New Features **`find_both_related()` — required inner join loader** (#2997) A new `find_both_related()` method returns `Vec<(E::Model, F::Model)>` (both sides non-optional), as a counterpart to the existing `find_also_related()` which returns `Vec<(E::Model, Option)>`. Use this when you know the relation is always populated and want to avoid the `Option` unwrap: ```rust let results: Vec<(Order, LineItem)> = Order::find() .find_both_related(LineItem) .all(db) .await?; ``` **`set_ne` / `set_ne_and` aliases on `ActiveValue`** (#3040) Shorter aliases for `set_if_not_equals` and `set_if_not_equals_and`. The long-form names are kept as compatibility aliases: ```rust // Before active_model.name.set_if_not_equals("Alice"); // After active_model.name.set_ne("Alice"); ``` **`map_sqlx_*_pool_opts` on `ConnectOptions`** (#2770) Three new methods to customise the underlying `sqlx::pool::PoolOptions` before the connection pool is created — one per driver: ```rust ConnectOptions::new(DATABASE_URL) .map_sqlx_postgres_pool_opts(|opts| opts.max_connections(20).min_connections(5)) .to_owned() ``` **`BTreeMap` / `HashMap` support in `TryGetableFromJson`** (#3009) Map types can now be used directly as model fields when the column holds a JSON object: ```rust pub struct Model { pub id: i32, pub metadata: HashMap, } ``` **Inherited visibility in derive macros** (#3029) `DeriveEntityModel`, `DeriveActiveModel`, `DeriveModel`, and related macros now inherit the `pub(crate)` / `pub(super)` / private visibility of the struct they are applied to, instead of always emitting `pub` items. ### Bug Fixes **Schema sync: drop unique constraint on PostgreSQL** (#2994) `DROP INDEX` fails on PostgreSQL for unique indexes created via column-level `UNIQUE` because they are backed by a named constraint, not a standalone index. Schema sync now uses `ALTER TABLE … DROP CONSTRAINT` on PostgreSQL and falls back to `DROP INDEX` on other backends. **Schema sync: tables in non-default schemas now discovered** (#3016) `sync()` previously ran schema discovery only against `CURRENT_SCHEMA()`. Entities with `#[sea_orm(schema_name = "other")]` were never found, causing every sync to attempt a redundant `CREATE TABLE`. Discovery now collects all schemas referenced by registered entities and queries each one. **Nested `PartialModel` null detection for optional fields** (#3039) A nested `Option` loaded via a left join could incorrectly fail with `Missing value for column 'id'` when the nested model itself contained `Option` fields. The null check now correctly handles arbitrary `Option` nesting depth. **`use_transaction` per-migration config was ignored** (#3002) `exec_with_connection` unconditionally wrapped all PostgreSQL migration operations in a transaction, overriding the per-migration `use_transaction` setting. The macro has been removed and each call site now uses the correct connection type. **Proc macros failed on long type paths with newlines** (#3031) `DeriveActiveModelEx` and other derive macros used `.replace(' ', "")` to strip whitespace, which missed newlines in formatted type paths longer than ~50 characters. Replaced with `.split_whitespace().collect()`. **`TIMESTAMPTZ` conversion in the Postgres proxy driver** (#3004) `from_sqlx_postgres_row_to_proxy_row` now correctly converts `TIMESTAMPTZ` columns, fixing a panic when using the proxy driver with timestamptz fields. ### Dependency Updates - `arrow` updated to 58 (#3007) - `strum` updated to 0.28 (#2993)