Go - How to properly upsert with UpdateOne/ReplaceOne

In the case of a new user with the following struct

type User struct {
  Id primitive.ObjectId `bson:"_id"`
  Name string `bson:"name"`
}

and using

user := &User{
Name: "John",
}
opts := options.FindOneAndReplace().SetUpsert(true).SetReturnDocument(options.After)
results, err := collection.FindOneAndReplace(context.Background(), bson.D{{ "_id", user.Id }}, user, opts)

Upsert works but it creates a document with primitive.Object ID ObjectId(“000000000000”) instead of generating a ID.

If we were to change the struct to use the pointer instead.

type User struct {
  Id *primitive.ObjectId `bson:"_id"`
  Name string `bson:"name"`
}

It also doesn’t generate a new _id, instead it upserts with _id: null even though *primitive.ObjectId is nil. I was expecting it to generate a new object ID when it’s

What’s the solution to this, other than generating the objectid manually at the application side?