Repository: mikro-orm/mikro-orm (TypeScript)

Issue:
Lazy property with nullable ScalarRef does not initialize when value is `null`
### Describe the bug
When attempting to use a lazy scalar reference that can possibly be nullable, calling `load()` or attempting to populate the field does not initialize the field and results in `undefined` if the resolved value is `null`.
### Reproduction
https://github.com/kpervin/mikro-orm-reproduction/tree/lazy-scalar-reference-issue
### What driver are you using?
None
### MikroORM version
next
### Node.js version
22.18.0
### Operating system
WSL version: 2.6.1.0 Kernel version: 6.6.87.2-1 WSLg version: 1.0.66 MSRDC version: 1.2.6353 Direct3D version: 1.611.1-81528511 DXCore version: 10.0.26100.1-240331-1435.ge-release Windows version: 10.0.26100.6584
### Validations
- [x] Read the [Contributing Guidelines](https://github.com/mikro-orm/mikro-orm/blob/master/CONTRIBUTING.md).
- [x] Read the [docs](https://mikro-orm.io/docs).
- [x] Check that there isn't [already an issue](https://github.com/mikro-orm/mikro-orm/issues) that reports the same bug to avoid creating a duplicate.
- [x] Check that this is a concrete bug. For Q&A open a [GitHub Discussion](https://github.com/mikro-orm/mikro-orm/discussions) or join our [Discord](https://discord.gg/w8bjxFHS7X).
- [x] The provided reproduction is a [minimal reproducible example](https://stackoverflow.com/help/minimal-reproducible-example) of the bug.


Discussion: In investigation, I'm wondering if the issue is here? https://github.com/mikro-orm/mikro-orm/blob/467e31ff8c0eb7c95342d1b0e60ccb7305908681/packages/core/src/hydration/ObjectHydrator.ts#L144-L149

If the value is `null`, then this check fails and re-assigns the value to being an uninitialized ScalarReference. However, I'm unsure as to what the purpose of these lines are and what they're safeguarding.

Changing it to this seems to fix it:

```ts
if (prop.ref) {
        ret.push(`  if (!entity${entityKey}) {`);
        ret.push(`    const value = entity${entityKey};`);
        ret.push(`    entity${entityKey} = new ScalarReference();`);
        ret.push(`    entity${entityKey}.bind(entity, '${prop.name}');`);
        ret.push(`    entity${entityKey}.set(value);`);
        ret.push(`  }`);
      }
```
The point of those is that if a value is not present in the data nor in the entity itself, we initialize an empty ref wrapper. This can happen with partial loading, e.g. when the property is also marked as `lazy: true`. At least I think so 🙃 It's likely covered by some tests, so adding a console.log and running the test suite could point you to the exact example.

I guess we could just move this whole block outside of the if section instead of duplicating what it does:

https://github.com/mikro-orm/mikro-orm/blob/467e31ff8c0eb7c95342d1b0e60ccb7305908681/packages/core/src/hydration/ObjectHydrator.ts#L135-L140
@B4nan I added a PR that solves the issue and keeps it contained within the null value check. Simply added a means to initialize the value as a ScalarRef if `prop.ref` is true, otherwise keep the original implementation.



Fix (patch):
diff --git a/packages/core/src/hydration/ObjectHydrator.ts b/packages/core/src/hydration/ObjectHydrator.ts
index 587c8993f2f9..5f62e27964ee 100644
--- a/packages/core/src/hydration/ObjectHydrator.ts
+++ b/packages/core/src/hydration/ObjectHydrator.ts
@@ -89,7 +89,13 @@ export class ObjectHydrator extends Hydrator {
       }
 
       ret.push(`  if (data${dataKey} === null) {`);
-      ret.push(`    entity${entityKey} = ${nullVal};`);
+      if (prop.ref) {
+        ret.push(`    entity${entityKey} = new ScalarReference();`);
+        ret.push(`    entity${entityKey}.bind(entity, '${prop.name}');`);
+        ret.push(`    entity${entityKey}.set(${nullVal});`);
+      } else {
+        ret.push(`    entity${entityKey} = ${nullVal};`);
+      }
       ret.push(`  } else if (typeof data${dataKey} !== 'undefined') {`);
 
       if (prop.customType) {