Why does testUserAddCommentWithNoID expect exception?

Why does said test expect that there is an exception thrown if _id is not set explicitly?
It gets set automatically on inserting the comment to the database anyway, so why does it expect the _id to be a required field?

@Bjorn_65349,

Great to see that you have noticed this!

The models.Comment class is loaded from the database using POJO support, but the application, on purpose, uses two different value types to address the _id field.
If you look into the implementation of the models.Comment.setId you will see that two different object attributes are set.
Given that we use POJO to parse between BSON documents form the database to Comment class objects, we need to handle these different value types.
If there is an error on the front, where send a request with an incorrect or non-existing _id field, this could cause an error.
To prevent that, we make a check on the daos.CommentsDao.addComment method to prevent any nested incorrect mapping.

In normal conditions, this value should not be set to null or empty, but given that we are using nested POJO mapping, and using different object attributes for the same document field, we need to ensure the consistency of this field and the value.

N.

Hm, I see, thanks.
May I ask two more questions about this?

  1. You verify that the exception is thrown if the _id is null, so I added a check for null.
    I didn’t add a check for emptyness though, as neither of the two were mentioned in any assignment,
    nor was there any test that verifies with empty _id. Shouldn’t there be an additional test that checks for empty _id then and maybe somewhere a mention that we should check for null and empty and maybe why, for example in the TODO comment?

  2. Why do you use two fields for it and then include / exclude them with JSON and BSON properties? What’s the difference, why are both needed? I’m not familiar with such web programming, I guess the BSON part is for communicating with the database, so that there ObjectId instances are read and written and the JSON part is for communicating with the front-end in the browser and there plain strings are wanted, is that correct? Is there any reason you don’t just write the string id to the database? Or does MongoDB require the _id field to be of type ObjectId?

@Norberto piiing :slight_smile:

This is a good point. We will be adding these tests to make it clear that the check should be implemented.

Mostly to make a case for different mapping solutions between Java objects and MongoDB documents.
It is not unusual that we might have to use a different set of fields that are either not exposed to the the front-end code with the same names.
With different types is less common, however if you think about support of legacy code, between front-end or backend, it might not be that hard to find cases where you do need to have different types between your source code and the types you store in the database.

Aside from this, the POJO support has some limitations (currently) like not automatically setting the _id field value (as mentioned in the POJO - Part 2 lesson around min 0:37)
This will lead us to have these two fields.

Does that make sense ?

N.

Thanks for clarification @Norberto, I think it makes a bit more sense to me now.
The questions still unanswered are

I guess the BSON part is for communicating with the database, so that there ObjectId instances are read and written and the JSON part is for communicating with the front-end in the browser and there plain strings are wanted, is that correct?

and

Is there any reason you don’t just write the string id to the database? Or does MongoDB require the _id field to be of type ObjectId?

And if the latter is false, what would be the benefit of having type ObjectId instead of e. g. a numeric or textual _id?

@Norberto piiing :slight_smile:

BSON is the binary format that MongoDB uses. The wire protocol is based in BSON, as well has the binary storage format of documents.
Now, the JSON aspect, to communicate with the front-end is a matter of choice.
In this case, we’ve decided to do so, to provide an independent front-end and backend. But it is not mandatory for all applications.

You could. There is nothing stopping you from doing that. But in this case, and for educational purposes, we decided to use ObjectId.

By default, we recommend that the internal database primary key should be different from the “external” exposed identifier. However, it made sense for us to it this way, in this demo application, to expose some nice mapping capabilities.

N.

PS - sorry for the long delay!

Can you elaborate on why you recommend this @Norberto?
What are the pros and cons if you could be so nice? :slight_smile:

Hi @Vampire0,

The pros are simplicity. You have one identifier of your data throughout all domains.
On the database side, your primary key values are always going to be indexed, so less need for another index.

The cons are mostly related with separation of responsibility architectural design.
Using same id makes it:

  • hard to decouple from database
  • hard to migrate data across domains
  • exposing database identifiers to the end user

Another important aspect is that in many domains, you already have an unique identifier, and you want to use that. But not necessarily use that same id to identify the documents in the database.

N.

1 Like

Thanks for your help