Retrieve an id from Create operation during a transaction

I am trying to create an audit trail using Apollo Server and Mongoose. When a user initially registers and I create a document for them in my users collection, I can successfully add a document to my history collection for each piece of data they provided (username, password, email, etc) . And for each one, I am able to include the id for the document that was created for the user (the document in the user collection).

However, when I add a transaction in (see below), the userId for the user document comes back as undefined. I am assuming that the id for a document does not get created until the entire transaction has been completed?

Any ideas?

Mutation: {
  register: async (_, { data }) => {

    // Start a mongo session & transaction
    const session = await mongoose.startSession()
    session.startTransaction()

    try {

      // Hash password and create user
      const hashedPassword = await bcrypt.hash(data.password, 12)
      const user = await User.create(
        [{ ...data, password: hashedPassword }],
        { session }
      )
      
      // Create array of items to add to history entries
      const historyEntries = [
        {
          type: 'userAction',
          user: user.id,
          object: 'profile',
          instance: user.id,
          action: 'set',
          property: 'username',
          details: user.username
        },
        {
          type: 'userAction',
          user: user.id,
          object: 'profile',
          instance: user.id,
          action: 'set',
          property: 'password'
        }
      ]

      // If the user included an email, add it to historyEntries array
      if (user.email) {
        historyEntries.push({
          type: 'userAction',
          user: user.id,
          object: 'profile',
          instance: user.id,
          action: 'set',
          property: 'email',
          details: user.email
        })
      }

      // If the user included a mobile, add it to historyEntries array
      if (user.mobile) {
        historyEntries.push({
          type: 'userAction',
          user: user.id,
          object: 'profile',
          instance: '1',
          action: 'set',
          property: 'mobile',
          details: user.mobile
        })
      }

      // Create a history entry for each item in historyEntries
      await HistoryEntry.create(historyEntries, { session })

      // commit the changes if everything was successful
      await session.commitTransaction()
      return {
        ok: true,
        user
      }
    } catch (err) {
      // if anything fails above, rollback the changes in the transaction
      await session.abortTransaction()
      return formatErrors(err)
    } finally {
      // end the session
      session.endSession()
    }
  }
}

It has been 5 days, and I still haven’t received a reply in mongoDB’s system. So I went to Stack Overflow, and I got my question answered within a few hours.

Hi @Gregg_Squire ,

Thanks for sharing the answer to your question.

Similar to the Stack Exchange network, answers in the MongoDB Developer Community Forums are provided by community members without any specific SLA or guarantee of response. You may have to be extra patient for responses during weekend and holiday periods, or for questions requiring more specific expertise.

Stack Overflow reaches a much larger community of developers who may be able to help with general programming questions, while the MongoDB community has more specific experience and expertise for questions relating to MongoDB (including MongoDB engineering and product team members). If you do end up posting on multiple sites, it is always helpful to include a link for context.

Regards,
Stennie

This topic was automatically closed 5 days after the last reply. New replies are no longer allowed.