diff --git a/tree/ntuple/v7/inc/ROOT/RNTupleReader.hxx b/tree/ntuple/v7/inc/ROOT/RNTupleReader.hxx index c9ee0a5d0e5dd..5da1919e2440d 100644 --- a/tree/ntuple/v7/inc/ROOT/RNTupleReader.hxx +++ b/tree/ntuple/v7/inc/ROOT/RNTupleReader.hxx @@ -234,7 +234,13 @@ public: LoadEntry(index, fModel->GetDefaultEntry()); } /// Fills a user provided entry after checking that the entry has been instantiated from the ntuple model - void LoadEntry(NTupleSize_t index, REntry &entry) { entry.Read(index); } + void LoadEntry(NTupleSize_t index, REntry &entry) + { + if (R__unlikely(entry.GetModelId() != fModel->GetModelId())) + throw RException(R__FAIL("mismatch between entry and model")); + + entry.Read(index); + } /// Returns an iterator over the entry indices of the RNTuple. /// diff --git a/tree/ntuple/v7/test/ntuple_basics.cxx b/tree/ntuple/v7/test/ntuple_basics.cxx index 784718800cccd..dd34c78134d22 100644 --- a/tree/ntuple/v7/test/ntuple_basics.cxx +++ b/tree/ntuple/v7/test/ntuple_basics.cxx @@ -547,27 +547,43 @@ TEST(RNTuple, ModelId) TEST(RNTuple, Entry) { - auto m1 = RNTupleModel::Create(); + auto m = RNTupleModel::Create(); try { - m1->CreateEntry(); + m->CreateEntry(); FAIL() << "creating entry of unfrozen model should throw"; } catch (const ROOT::RException &err) { EXPECT_THAT(err.what(), testing::HasSubstr("invalid attempt to create entry")); } - m1->Freeze(); - auto e1 = m1->CreateEntry(); + m->Freeze(); + auto e = m->CreateEntry(); - auto m2 = RNTupleModel::Create(); - m2->Freeze(); - auto e2 = m2->CreateEntry(); + auto mWrite = m->Clone(); + mWrite->Freeze(); + auto eWrite = mWrite->CreateEntry(); FileRaii fileGuard("test_ntuple_entry.root"); - auto ntuple = RNTupleWriter::Recreate(std::move(m1), "ntpl", fileGuard.GetPath()); - ntuple->Fill(); - ntuple->Fill(*e1); + { + auto ntuple = RNTupleWriter::Recreate(std::move(mWrite), "ntpl", fileGuard.GetPath()); + ntuple->Fill(); + ntuple->Fill(*eWrite); + try { + ntuple->Fill(*e); + FAIL() << "filling with wrong entry should throw"; + } catch (const ROOT::RException &err) { + EXPECT_THAT(err.what(), testing::HasSubstr("mismatch between entry and model")); + } + } + + auto mRead = m->Clone(); + mRead->Freeze(); + auto eRead = mRead->CreateEntry(); + + auto ntuple = RNTupleReader::Open(std::move(mRead), "ntpl", fileGuard.GetPath()); + ntuple->LoadEntry(0); + ntuple->LoadEntry(0, *eRead); try { - ntuple->Fill(*e2); - FAIL() << "filling with wrong entry should throw"; + ntuple->LoadEntry(0, *e); + FAIL() << "loading the wrong entry should throw"; } catch (const ROOT::RException &err) { EXPECT_THAT(err.what(), testing::HasSubstr("mismatch between entry and model")); }