Alex
Alex

Reputation: 281

go.mongodb.org/mongo-driver - InsertOne with NilValueObjectId

I have the following struct

type Account struct {
    ID       primitive.ObjectID `json:"id" bson:"_id"`
    Email    string             `json:"email"`
    Password string             `json:"password"`
}

and the following function

func (a *Account) Create() map[string]interface{} {

    if resp, ok := a.Validate(); !ok {
        return resp
    }

    hashedPassword, _ := bcrypt.GenerateFromPassword([]byte(a.Password), bcrypt.DefaultCost)
    a.Password = string(hashedPassword)

    users := db.Collection("users")

    insertResult, err := users.InsertOne(context.TODO(), a)

    if err != nil {
        return utils.Message(false, "Error inserting user document "+err.Error())
    }

      ... more code down hre
}

The problem I am having is that I can insert the first account, but any account after that can't be inserted due to a dup key error on the _id field. I know that mongoDB will auto generate an _id field and will use the one provided if there is an id. In my case in this create function, the a.ID (_id) is always be NilValue "_id" : ObjectId("000000000000000000000000")

Is there any way mongoDB can generate an _id for me even if I provide and ID field with the nil value?

I need the Account.ID `bson: "_id"` property on there so I can decode it when I am reading from mongoDB such as

func GetUser(email string) *Account {
        account := &Account{}
    users := db.Collection("users")

    filter := bson.D{{"email", email}}

    if err := users.FindOne(context.TODO(), filter).Decode(&account); err != nil {
        return utils.Message(false, "Error Retrieving account for "+email)
    }

        // account.ID will be available due to the bson tag
}

I'd appreciate some feedback if I am doing this wrong and how I could do this better.

Thanks!

Upvotes: 0

Views: 951

Answers (1)

Alex
Alex

Reputation: 281

I found the problem. I did not add ```omitempty` to the bson tag.

It should be

type Account struct {
    ID       primitive.ObjectID `json:"id" bson:"_id,omitempty"`
    Email    string             `json:"email"`
    Password string             `json:"password"`
}

Upvotes: 3

Related Questions