mbdavid / LiteDB

LiteDB - A .NET NoSQL Document Store in a single data file
http://www.litedb.org
MIT License
8.5k stars 1.24k forks source link

[BUG] Adding an immutable record to LiteDB gives an NRE #1541

Open isaacabraham opened 4 years ago

isaacabraham commented 4 years ago

Version: LiteDB 5.0.3, Windows, NetCore3.1

Describe the bug Adding an immutable record to LiteDB gives an NRE, although the document is actually inserted.

Code to Reproduce

open LiteDB

type Customer = {
    Id : int
    Name : string
    Phones : string array
    IsActive : bool
}

let db = new LiteDatabase("MyData.db")
let col = db.GetCollection "customers"

let customer =
    { Id = 0
      Name = "John Doe"
      Phones = [| "8000-0000"; "9000-0000" |]
      IsActive = true }

// Insert new customer document (Id will be auto-incremented)
col.Insert customer |> ignore

Expected behavior The record should be inserted without an exception.

System.NullReferenceException: Object reference not set to an instance of an object. at LiteDB.LiteCollection1.Insert(T entity)`

Additional context You can work around this by marking the record type with [<CLIMutable>]. However, this is non-idomatic from an F# perspective.

nightroman commented 4 years ago

FWIW https://github.com/Zaid-Ajaj/LiteDB.FSharp#id-auto-incremented

So this might be by design (cannot tell for sure) but the error should be more specific then.

isaacabraham commented 4 years ago

Yes, maybe that's all that needs to be done. Note that LiteDB.FSharp is not compatible with v5 of LiteDB cc @Zaid-Ajaj

Zaid-Ajaj commented 4 years ago

There is already an opened issue about updating LiteDB.FSharp to latest LiteDB version. I won't be able to work on it any time soon due to other prioritized projects. Feel free to send PRs for the issue in subject, I will be happy to review them

humhei commented 4 years ago

You can work around this by marking the record type with [<CLIMutable>]. However, this is non-idomatic from an F# perspective.

In LiteDB 4.x Another workaround is to change int to ObjectId without adding [<CLIMutable>] attribute


///using `ObjectId.NewObjectId()` but not `new ObjectId()`

type Customer = {
    Id : ObjectId
    Name : string
    Phones : string array
    IsActive : bool
}
humhei commented 4 years ago

A issue is the record type using ObjectId will not support comparision image

lbnascimento commented 4 years ago

@humhei This happens because ObjectId implements IComparable<ObjectId>, but not IComparable (an oversight, I believe). Try using Guid as Id, it should work.