Crash when serializing result with multiple-nested models without attributes
See original GitHub issueWhen sequelize tries to serialize the result of a query returning an instance within an instance (with no attributes), within an instance (with no attributes), it fails with the following error:
TypeError: Cannot set property 'C' of undefined
Probably a hidden assumption that there must be at least one attribute included in each included instance somewhere in the code. Notably, with only one nested instance, sequelize manages it, but fails with two or more.
Below is a minimal example showing the problem, one would expect to get the following output in the console, but instead gets the error above.
[{
B: {
C: {
x: "hello"
}
}
}]
Code:
/* ----- SETUP ----- */
const Sequelize = require("sequelize")
const db = new Sequelize("mysql://localhost:3306/test")
const A = db.define("A")
const B = db.define("B")
const C = db.define("C", {
x: Sequelize.STRING
})
A.belongsTo(B)
B.hasOne(C)
db.query("SET FOREIGN_KEY_CHECKS = 0")
.then(() => db.sync({ force: true }))
.then(() => A.create())
.then(a => a.createB())
.then(() => B.findById(1))
.then(b => b.createC({ x: "hello" }))
/* ----- PROBLEM STARTS HERE ----- */
.then(() => A.findAll({ attributes: [], include: [{ attributes: [], model: B, include: [{ model: C, attributes: ["x"] }] }] }))
.then(x => console.log(x.toJSON()))
Dialect: mysql Database version: 5.7.13 Sequelize version: 3.24.3
Issue Analytics
- State:
- Created 7 years ago
- Comments:5 (2 by maintainers)
Top Results From Across the Web
c# - Crash after serializing JObject with DataContractSerializer ...
A JObject is the JSON document object model of Json.NET, there is no reason to imagine it could be serialized to XML by...
Read more >Serialization Error Handling - Json.NET
The Error event is an event handler found on JsonSerializer. The error event is raised whenever an exception is thrown while serializing or...
Read more >Hibernate Search 6.1.7.Final: Reference Documentation
There are multiple mismatches between the entity model and the document model: properties vs. fields, associations vs. nested ...
Read more >YAML: The Missing Battery in Python
You'll also serialize Python objects and create a YAML syntax highlighter. ... As a result, YAML is more applicable to configuration files ...
Read more >PHP 5 ChangeLog
Fixed bug #73337 (try/catch not working with two exceptions inside a same ... Fixed bug #72339 (Integer Overflow in _gd2GetHeader() resulting in heap ......
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
After some investigating I’ve found that the problem is that
groupJoinData
in query.js assumes that the rows returned will contain attributes at every level of depth up to the deepest level. This assumption only holds when the depth is 2 or less, because this code in model.js ensures the root attributes array is never empty, instead it tacks on theprimaryKeyAttribute
, which is filtered out after the result has been passed togroupJoinData
.The problem is that the
primaryKeyAttribute
is not force added in this way for nested instances, fatally breaking the assumption ingroupJoinData
. For example in my post the row contains columns['id','B.C.id','B.C.x']
, missing any direct attribute ofB
. If we add theid
attribute for modelB
in the code above the problem goes away (the returned row contains['id','B.id','B.C.id','B.C.x']
), since the assumption is fulfilled.Now, there are a few places where one can force the
primaryKeyAttribute
of nested models with further nested models, such as right after here in query-generator.js, wrapped in anif (include.include && include.attributes.length === 0)
. This attribute will then simply be filtered when the result returns just as with the root attributes.Same problem here, I was using version 3.0.0. and query with empty attributes used to work
After updating to 3.25.0, in order to work I had to add the primary to attributes list, so the objects won’t be undefined: