Using wrapper for bson.ObjectId

40 views
Skip to first unread message

Sindre Moe

unread,
Nov 30, 2016, 6:54:29 AM11/30/16
to mgo-users
Hi,

I am using the mgo package (gopkg.in/mgo.v2) to write some data to a mongo db. I have created a custom struct type EntityID to represent the ID instead of having references to bson.ObjectId everywhere. I am using the bson.Getter/bson.Setter interfaces to convert to and from bson.ObjectId, which is actually what is stored in the db. This works kind of.. The SetBSON method is called on EntityID when retrieving from the DB and I am able to unmarshal from the ObjectId to my custom stuct. However, it does not work the other way around.  I thought GetBSON is supposed to be called when mgo needs to marshal the value to its BSON representation so I am returning a bson.ObjectId. This method however is never called so instead mgo generates a new ObjectId each time I am inserting a new object and discards the EntityID I have set.

EntityID is nothing more than a wrapper around bson.ObjectId. Here is my implementation:

type EntityID struct {
objectID bson.ObjectId
}

func (id EntityID) String() string {
if !id.objectID.Valid() {
return ""
}
return id.objectID.Hex()
}

func (id EntityID) GetBSON() (interface{}, error) {
if !id.objectID.Valid() {
return nil, errors.New("invalid ID")
}
return id.objectID, nil
}

func (id *EntityID) SetBSON(raw bson.Raw) error {
var oid bson.ObjectId
if err := raw.Unmarshal(&oid); err != nil {
return err
}
*id = EntityID{oid}
return nil
}

I use it like this:

type User struct {
ID        EntityID  `json:"-" bson:"_id,omitempty"`
Email     string    `json:"email"`
Name      string    `json:"name"`
}

When I insert this to mongo I expect the value in EntityID, which actually is an ObjectId, to be stored as "_id". Instead a new ObjectId is generated.

Any ideas?


Sindre Moe

unread,
Nov 30, 2016, 7:24:05 AM11/30/16
to mgo-users
Nevermind, I figured it out. The problem is that I had  `omitempty` flag in the tag for the ID like this:
 
User struct {
        ID        EntityID  `json:"-" bson:"_id,omitempty"`
}


For some reason mgo decided to generate a new ObjectId even though ID was not empty. Don't know why it thinks it is a zero value. After removing `omitempty` it works.
Reply all
Reply to author
Forward
0 new messages