Creating an @Field.Stored property with a default UUID value always returns the same UUID #322

Closed
opened 2025-12-29 15:28:50 +01:00 by adam · 7 comments
Owner

Originally created by @joeljfischer on GitHub (Mar 30, 2020).

I'm having an issue where if I create a new object of a data model and that data model contains a property with a default UUID value (see below), the UUID always turns out to be the same value...which as you might imagine isn't optimal 😓 . Any assistance in debugging that would be awesome. For now I have to have the property be optional and assign it when I create the object, which is also not optimal.

@Field.Stored("timerID")
var timerID: UUID = UUID()
Originally created by @joeljfischer on GitHub (Mar 30, 2020). I'm having an issue where if I create a new object of a data model and that data model contains a property with a default UUID value (see below), the UUID always turns out to be the same value...which as you might imagine isn't optimal 😓 . Any assistance in debugging that would be awesome. For now I have to have the property be optional and assign it when I create the object, which is also not optimal. ``` @Field.Stored("timerID") var timerID: UUID = UUID() ```
adam added the fixedpending docs update labels 2025-12-29 15:28:50 +01:00
adam closed this issue 2025-12-29 15:28:51 +01:00
Author
Owner

@JohnEstropia commented on GitHub (Mar 30, 2020):

It is working as intended. These initial values become the SQLite column default, so you really want this to be a constant rather than an arbitrary value. It works exactly how CoreData's "Default Value" in attributes work, and the same as it always had with Value.Required.

I suggest to avoid using this with Date() and even UUID(). If you need a migration-safe value, use

static let zeroDate = Date.timeIntervalBetween1970AndReferenceDate // or Date.timeIntervalSinceReferenceDate
static let zeroUUID = UUID(uuid: (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0))

// ...

@Field.Stored("uuid")
var uuid: UUID = .zeroUUID

@Field.Stored("timestamp")
var timestamp: Date = .zeroDate

There is no support for function-type values (yet?) like auto-increment, now(), or auto-generated UUIDs. You will need to implement that in your code for now.

@JohnEstropia commented on GitHub (Mar 30, 2020): It is working as intended. These initial values become the SQLite column default, so you really want this to be a constant rather than an arbitrary value. It works exactly how CoreData's "Default Value" in attributes work, and the same as it always had with `Value.Required`. I suggest to avoid using this with `Date()` and even `UUID()`. If you need a migration-safe value, use ```swift static let zeroDate = Date.timeIntervalBetween1970AndReferenceDate // or Date.timeIntervalSinceReferenceDate static let zeroUUID = UUID(uuid: (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)) // ... @Field.Stored("uuid") var uuid: UUID = .zeroUUID @Field.Stored("timestamp") var timestamp: Date = .zeroDate ``` There is no support for function-type values (yet?) like auto-increment, `now()`, or auto-generated UUIDs. You will need to implement that in your code for now.
Author
Owner

@joeljfischer commented on GitHub (Mar 30, 2020):

Thank you for helping me understand how this works with CoreData and SQLite. I haven't had to do a ton of database work in my career (until now!) so your help and this library is much appreciated. I don't have to migrate yet, so I think that having it optional will for now force me to have fewer errors.

I think that "function-type" initial values such as a unique identifier or the current Date would be a useful addition for certain use-cases.

@joeljfischer commented on GitHub (Mar 30, 2020): Thank you for helping me understand how this works with CoreData and SQLite. I haven't had to do a ton of database work in my career (until now!) so your help and this library is much appreciated. I don't have to migrate yet, so I think that having it optional will for now force me to have fewer errors. I think that "function-type" initial values such as a unique identifier or the current `Date` would be a useful addition for certain use-cases.
Author
Owner

@Saklad5 commented on GitHub (May 16, 2020):

I submitted a pull request that allows you to explicitly set the default value of a required Field to nil, which is already allowed by Core Data itself.

Don’t worry, this is still safe: if you fail to set a value for a non-optional attribute before finishing a transaction (or otherwise saving), the save will fail with an error. I consider that much safer than a sentinel value, which won’t raise any flags if left unchanged.

@Saklad5 commented on GitHub (May 16, 2020): I submitted [a pull request](https://github.com/JohnEstropia/CoreStore/pull/387/) that allows you to explicitly set the default value of a required Field to `nil`, which is already allowed by Core Data itself. Don’t worry, this is still safe: if you fail to set a value for a non-optional attribute before finishing a transaction (or otherwise saving), the save will fail with an error. I consider that much safer than a sentinel value, which won’t raise any flags if left unchanged.
Author
Owner

@joeljfischer commented on GitHub (May 18, 2020):

@Saklad5 That would be helpful

@joeljfischer commented on GitHub (May 18, 2020): @Saklad5 That would be helpful
Author
Owner

@JohnEstropia commented on GitHub (May 22, 2020):

I commented on the approach of @Saklad5 's pull request.

While I don't think the proposed approach is ideal, I do understand the need for auto-initializing fields (UUID(), Date()). I'm working on something that would allow the feature, and maybe a way to prevent misuse of the current @Field initial values.

@JohnEstropia commented on GitHub (May 22, 2020): I commented on the approach of @Saklad5 's [pull request](https://github.com/JohnEstropia/CoreStore/pull/387/). While I don't think the proposed approach is ideal, I do understand the need for auto-initializing fields (`UUID()`, `Date()`). I'm working on something that would allow the feature, and maybe a way to prevent misuse of the current `@Field` initial values.
Author
Owner

@JohnEstropia commented on GitHub (May 23, 2020):

@joeljfischer @Saklad5 I implemented a solution for this:
56d0ea46ea (diff-ea4ff9e791326ac2bd37f36fc9238dddR21)

As shown in the updated Demo app, we will now be able to write something like

    @Field.Stored(
        "hue",
        dynamicInitialValue: { Palette.randomHue() }
    )
    var hue: Int

We'll be able to pass UUID.init or Date.init directly to the dynamicInitialValue: argument of UUID and Date fields.

I'm currently writing unit test for it in the dynamicInitializers branch. Feel free to play with it for now.

@JohnEstropia commented on GitHub (May 23, 2020): @joeljfischer @Saklad5 I implemented a solution for this: https://github.com/JohnEstropia/CoreStore/commit/56d0ea46ea84048a62703708e1e2e81b8dd9e92a#diff-ea4ff9e791326ac2bd37f36fc9238dddR21 As shown in the updated Demo app, we will now be able to write something like ```swift @Field.Stored( "hue", dynamicInitialValue: { Palette.randomHue() } ) var hue: Int ``` We'll be able to pass `UUID.init` or `Date.init` directly to the `dynamicInitialValue:` argument of `UUID` and `Date` fields. I'm currently writing unit test for it in the `dynamicInitializers` branch. Feel free to play with it for now.
Author
Owner

@joeljfischer commented on GitHub (May 26, 2020):

Thanks for working on this. I'm sorry I haven't been able to test it, I was working on a separate project for the last few weeks. This will really help my model setup.

@joeljfischer commented on GitHub (May 26, 2020): Thanks for working on this. I'm sorry I haven't been able to test it, I was working on a separate project for the last few weeks. This will really help my model setup.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/CoreStore#322