Skip to content

Commit

Permalink
fix(model): throw error if calling create() with multiple docs in a…
Browse files Browse the repository at this point in the history
… transaction unless `ordered: true`

Fix #15091
  • Loading branch information
vkarpov15 committed Dec 15, 2024
1 parent 7ed441e commit 8cd67ef
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 0 deletions.
4 changes: 4 additions & 0 deletions lib/model.js
Original file line number Diff line number Diff line change
Expand Up @@ -2619,6 +2619,10 @@ Model.create = async function create(doc, options) {

delete options.aggregateErrors; // dont pass on the option to "$save"

if (options.session && !options.ordered && args.length > 1) {
throw new MongooseError('Cannot call `create()` with a session and multiple documents unless `ordered: true` is set');
}

if (options.ordered) {
for (let i = 0; i < args.length; i++) {
try {
Expand Down
40 changes: 40 additions & 0 deletions test/docs/transactions.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -660,4 +660,44 @@ describe('transactions', function() {
const { name } = await Test.findById(_id);
assert.strictEqual(name, 'bar');
});

it('throws error if using `create()` with multiple docs in a transaction (gh-15091)', async function() {
const BookingSchema = new Schema({
user: mongoose.Types.ObjectId,
slot: mongoose.Types.ObjectId,
bookingFor: String,
moreInfo: String
});

// Create models
const Booking = db.model('Test', BookingSchema);

// Define a sample payload
const user = { userId: new mongoose.Types.ObjectId() };
const payload = {
slotId: new mongoose.Types.ObjectId(),
data: [
{ bookingFor: 'Person A', moreInfo: 'Some info' },
{ bookingFor: 'Person B', moreInfo: 'Other info' }
]
};

const session = await mongoose.startSession();
session.startTransaction();

const bookingData = payload.data.map((obj) => ({
user: user.userId,
slot: payload.slotId,
bookingFor: obj.bookingFor,
moreInfo: obj.moreInfo
}));

await assert.rejects(
Booking.create(bookingData, { session }),
/Cannot call `create\(\)` with a session and multiple documents unless `ordered: true` is set/
);

const bookings = await Booking.create(bookingData, { session, ordered: true });
assert.equal(bookings.length, 2);
});
});

0 comments on commit 8cd67ef

Please sign in to comment.