sequelize: findOne returns null, while findAll returns single desired record

What you are doing?

I have models Thread, ChannelIntegration, and PhoneNumber. These are related as such:

Thread.belongsTo(ChannelIntegration)
ChannelIntegration.hasMany(Thread)

PhoneNumber.belongsTo(ChannelIntegration)
ChannelIntegration.hasOne(PhoneNumber)

I am trying to perform a findOne query on PhoneNumber, including the Thread and ChannelIntegration models.

What do you expect to happen?

This query should return the single PhoneNumber record I am looking for:

PhoneNumber.findOne({
  attributes: ['number_value', 'number_type', 'channel_integration_id'],
  include: [{
    model: ChannelIntegration,
    include: [{
      model: Thread,
      where: {
        id: message.thread_id,
      },
    }],
  }],
});

What is actually happening?

The findOne query returns null. If I change this to findAll it returns an array with a single record. If I add limit: 1 to the findAll query, it returns null (as it generates the same query as findOne).

SQL for findOne:

SELECT "phone_number".*, "channel_integration.threads"."id" AS "channel_integration.threads.id", "channel_integration.threads"."organization_id" AS "channel_integration.threads.organization_id", "channel_integration.threads"."type" AS "channel_integration.threads.type", "channel_integration.threads"."fake" AS "channel_integration.threads.fake", "channel_integration.threads"."status" AS "channel_integration.threads.status", "channel_integration.threads"."name" AS "channel_integration.threads.name", "channel_integration.threads"."priority" AS "channel_integration.threads.priority", "channel_integration.threads"."lifecycle" AS "channel_integration.threads.lifecycle", "channel_integration.threads"."integration_data" AS "channel_integration.threads.integration_data", "channel_integration.threads"."last_updater_id" AS "channel_integration.threads.last_updater_id", "channel_integration.threads"."parent_id" AS "channel_integration.threads.parent_id", "channel_integration.threads"."channel_integration_id" AS "channel_integration.threads.channel_integration_id", "channel_integration.threads"."channel_instance_id" AS "channel_integration.threads.channel_instance_id", "channel_integration.threads"."created_at" AS "channel_integration.threads.created_at", "channel_integration.threads"."updated_at" AS "channel_integration.threads.updated_at" FROM (SELECT "phone_number"."id", "phone_number"."number_value", "phone_number"."number_type", "phone_number"."channel_integration_id", "channel_integration"."id" AS "channel_integration.id", "channel_integration"."type_id" AS "channel_integration.type_id", "channel_integration"."organization_id" AS "channel_integration.organization_id", "channel_integration"."creator_id" AS "channel_integration.creator_id", "channel_integration"."fake" AS "channel_integration.fake", "channel_integration"."status" AS "channel_integration.status", "channel_integration"."settings" AS "channel_integration.settings", "channel_integration"."shared" AS "channel_integration.shared", "channel_integration"."integration_value" AS "channel_integration.integration_value", "channel_integration"."created_at" AS "channel_integration.created_at", "channel_integration"."updated_at" AS "channel_integration.updated_at", "channel_integration"."channel_instance_id" AS "channel_integration.channel_instance_id" FROM "phone_numbers" AS "phone_number" LEFT OUTER JOIN "channel_integrations" AS "channel_integration" ON "phone_number"."channel_integration_id" = "channel_integration"."id" LIMIT 1) AS "phone_number" INNER JOIN "threads" AS "channel_integration.threads" ON "channel_integration.id" = "channel_integration.threads"."channel_integration_id" AND "channel_integration.threads"."id" = 759;

SQL for findAll:

SELECT "phone_number"."id", "phone_number"."number_value", "phone_number"."number_type", "phone_number"."channel_integration_id", "channel_integration"."id" AS "channel_integration.id", "channel_integration"."type_id" AS "channel_integration.type_id", "channel_integration"."organization_id" AS "channel_integration.organization_id", "channel_integration"."creator_id" AS "channel_integration.creator_id", "channel_integration"."fake" AS "channel_integration.fake", "channel_integration"."status" AS "channel_integration.status", "channel_integration"."settings" AS "channel_integration.settings", "channel_integration"."shared" AS "channel_integration.shared", "channel_integration"."integration_value" AS "channel_integration.integration_value", "channel_integration"."created_at" AS "channel_integration.created_at", "channel_integration"."updated_at" AS "channel_integration.updated_at", "channel_integration"."channel_instance_id" AS "channel_integration.channel_instance_id", "channel_integration.threads"."id" AS "channel_integration.threads.id", "channel_integration.threads"."organization_id" AS "channel_integration.threads.organization_id", "channel_integration.threads"."type" AS "channel_integration.threads.type", "channel_integration.threads"."fake" AS "channel_integration.threads.fake", "channel_integration.threads"."status" AS "channel_integration.threads.status", "channel_integration.threads"."name" AS "channel_integration.threads.name", "channel_integration.threads"."priority" AS "channel_integration.threads.priority", "channel_integration.threads"."lifecycle" AS "channel_integration.threads.lifecycle", "channel_integration.threads"."integration_data" AS "channel_integration.threads.integration_data", "channel_integration.threads"."last_updater_id" AS "channel_integration.threads.last_updater_id", "channel_integration.threads"."parent_id" AS "channel_integration.threads.parent_id", "channel_integration.threads"."channel_integration_id" AS "channel_integration.threads.channel_integration_id", "channel_integration.threads"."channel_instance_id" AS "channel_integration.threads.channel_instance_id", "channel_integration.threads"."created_at" AS "channel_integration.threads.created_at", "channel_integration.threads"."updated_at" AS "channel_integration.threads.updated_at" FROM "phone_numbers" AS "phone_number" LEFT OUTER JOIN "channel_integrations" AS "channel_integration" ON "phone_number"."channel_integration_id" = "channel_integration"."id" INNER JOIN "threads" AS "channel_integration.threads" ON "channel_integration"."id" = "channel_integration.threads"."channel_integration_id" AND "channel_integration.threads"."id" = 759;

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Comments: 17 (3 by maintainers)

Most upvoted comments

Is this issue fixed? As I have same issue on my side.

I actually still am finding this to be a bug. findOne with an include fails, removing the include passes. findAll without a limit passes (returns one record), with a limit of 1 fails (returns empty)

Running

"sequelize": "5.21.5",

Another thing I noticed - if the primary key is not in the where, it fails. Adding it passes.

As of today, this is still an issue as far as I can tell.

I am working around it via .findAll({limit:1})

Similar issue, using spring and hibernate…any solutions?

Same here with this code:

const dbUser = await db.User.findOne({
        include: [{
          model: db.Email,
          where: {email: email}
        }]
      })

Note the User to Email relationship is many-to-many.