diff --git a/app/models/project.rb b/app/models/project.rb
index a63c40deeac50745b1e0d53f3add76bf6ee11db2..374b825a6e2708600f78a2f38736faeabc8315e3 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -131,13 +131,15 @@ class Project < ApplicationRecord
   # Storage specific hooks
   after_initialize :use_hashed_storage
   after_initialize :set_project_feature_defaults, if: :new_record?
-  before_validation :mark_remote_mirrors_for_removal, if: -> { RemoteMirror.table_exists? }
 
+  before_validation :mark_remote_mirrors_for_removal, if: -> { RemoteMirror.table_exists? }
   before_validation :ensure_project_namespace_in_sync
   before_validation :set_package_registry_access_level, if: :packages_enabled_changed?
   before_validation :remove_leading_spaces_on_name
   before_validation :set_last_activity_at
+
   after_validation :check_pending_delete
+
   before_save :ensure_runners_token
 
   after_create -> { create_or_load_association(:project_feature) }
diff --git a/app/services/projects/create_service.rb b/app/services/projects/create_service.rb
index 37588800439531ec16dd25a718abb309155abf5d..3dcc116b30530d9686d0e6e2508b0b199de15a6e 100644
--- a/app/services/projects/create_service.rb
+++ b/app/services/projects/create_service.rb
@@ -56,6 +56,9 @@ def execute
       namespace_id = params[:namespace_id] || current_user.namespace_id
       @project.namespace_id = namespace_id.to_i
 
+      organization_id = params[:organization_id] || @project.namespace.organization_id
+      @project.organization_id = organization_id.to_i
+
       @project.check_personal_projects_limit
       return @project if @project.errors.any?
 
diff --git a/app/services/projects/gitlab_projects_import_service.rb b/app/services/projects/gitlab_projects_import_service.rb
index 63a41d172eab3a72064b7f7b0749d1ba8afebb88..1bef3330599941f5445eef2e5c3ac1c54990a6c6 100644
--- a/app/services/projects/gitlab_projects_import_service.rb
+++ b/app/services/projects/gitlab_projects_import_service.rb
@@ -72,6 +72,8 @@ def prepare_import_params
         params[:import_type] = 'gitlab_project'
       end
 
+      params[:organization_id] = current_namespace.organization_id
+
       params[:import_data] = { data: data } if data.present?
     end
   end
diff --git a/ee/app/services/registrations/standard_namespace_create_service.rb b/ee/app/services/registrations/standard_namespace_create_service.rb
index 5d51740f293ed733244fd1b7541484bef6ad8fc4..b207247028638d30a571630d998ec11f807fd8ce 100644
--- a/ee/app/services/registrations/standard_namespace_create_service.rb
+++ b/ee/app/services/registrations/standard_namespace_create_service.rb
@@ -47,7 +47,10 @@ def create_project_params
     end
 
     def project_params(*extra)
-      params.require(:project).permit(project_params_attributes + extra).merge(namespace_id: group.id)
+      params
+        .require(:project)
+        .permit(project_params_attributes + extra)
+        .merge(namespace_id: group.id, organization_id: group.organization_id)
     end
 
     def project_params_attributes
diff --git a/ee/app/services/security/security_orchestration_policies/project_create_service.rb b/ee/app/services/security/security_orchestration_policies/project_create_service.rb
index e29907872c135d3beb3b088b5414b29bed16599d..cc0a5caaf8955b199a3df9db33e4c31714f825a9 100644
--- a/ee/app/services/security/security_orchestration_policies/project_create_service.rb
+++ b/ee/app/services/security/security_orchestration_policies/project_create_service.rb
@@ -63,6 +63,7 @@ def create_project_params
           name: "#{container.name} - Security policy project",
           description: "This project is automatically generated to manage security policies for the project.",
           namespace_id: namespace_id,
+          organization_id: namespace.organization_id,
           initialize_with_readme: true,
           container_registry_enabled: false,
           packages_enabled: false,
diff --git a/lib/gitlab/bitbucket_import/project_creator.rb b/lib/gitlab/bitbucket_import/project_creator.rb
index db75b6e519030e9a1a824937558625511096ee23..2a5c6951073468b3022debd616827debe6085a61 100644
--- a/lib/gitlab/bitbucket_import/project_creator.rb
+++ b/lib/gitlab/bitbucket_import/project_creator.rb
@@ -20,6 +20,7 @@ def execute
           path: name,
           description: repo.description,
           namespace_id: namespace.id,
+          organization_id: namespace.organization_id,
           visibility_level: repo.visibility_level,
           import_type: 'bitbucket',
           import_source: repo.full_name,
diff --git a/lib/gitlab/bitbucket_server_import/project_creator.rb b/lib/gitlab/bitbucket_server_import/project_creator.rb
index e856484ca89e35b66ea54a342b67a2d3927aff73..2833b6fa2007f63333e5bb8a299aee80c8ae867d 100644
--- a/lib/gitlab/bitbucket_server_import/project_creator.rb
+++ b/lib/gitlab/bitbucket_server_import/project_creator.rb
@@ -26,6 +26,7 @@ def execute
           path: name,
           description: repo.description,
           namespace_id: namespace.id,
+          organization_id: namespace.organization_id,
           visibility_level: repo.visibility_level,
           import_type: 'bitbucket_server',
           import_source: repo.browse_url,
diff --git a/lib/gitlab/fogbugz_import/project_creator.rb b/lib/gitlab/fogbugz_import/project_creator.rb
index a5e6356eb177cdaa2f21065b33024ed78a1933a1..b7a6467314a9000500f459b0c27679b371575a17 100644
--- a/lib/gitlab/fogbugz_import/project_creator.rb
+++ b/lib/gitlab/fogbugz_import/project_creator.rb
@@ -20,6 +20,7 @@ def execute
           name: name,
           path: name,
           namespace_id: namespace.id,
+          organization_id: namespace.organization_id,
           creator: current_user,
           visibility_level: Gitlab::VisibilityLevel::PRIVATE,
           import_type: 'fogbugz',
diff --git a/lib/gitlab/git_access_project.rb b/lib/gitlab/git_access_project.rb
index b007a957348332d250f35f599a286de2831a2335..a6c956ca0c35fcc7ebcad87891dd67ab94ac8e73 100644
--- a/lib/gitlab/git_access_project.rb
+++ b/lib/gitlab/git_access_project.rb
@@ -58,6 +58,7 @@ def ensure_project_on_push!
       project_params = {
         path: project_path,
         namespace_id: namespace.id,
+        organization_id: namespace.organization_id,
         visibility_level: Gitlab::VisibilityLevel::PRIVATE
       }
 
diff --git a/lib/gitlab/legacy_github_import/project_creator.rb b/lib/gitlab/legacy_github_import/project_creator.rb
index 01e04fa9c81ef4e99584d5963007fedf0c0b3da4..53c4d767ce39a54103f7106996dc3859686e08c5 100644
--- a/lib/gitlab/legacy_github_import/project_creator.rb
+++ b/lib/gitlab/legacy_github_import/project_creator.rb
@@ -20,6 +20,7 @@ def execute(extra_attrs = {})
           path: name,
           description: repo[:description],
           namespace_id: namespace.id,
+          organization_id: namespace.organization_id,
           visibility_level: visibility_level,
           import_type: type,
           import_source: repo[:full_name],
diff --git a/lib/gitlab/manifest_import/project_creator.rb b/lib/gitlab/manifest_import/project_creator.rb
index 6637cbb9cc855a062f20aaf89f46304c0df50c66..70f99c34a0fc08dce33a9aec3dd788d63f3d4cf3 100644
--- a/lib/gitlab/manifest_import/project_creator.rb
+++ b/lib/gitlab/manifest_import/project_creator.rb
@@ -21,6 +21,7 @@ def execute
           import_source: repository[:url],
           import_type: 'manifest',
           namespace_id: group.id,
+          organization_id: group.organization_id,
           path: project_path,
           name: project_path,
           visibility_level: destination.visibility_level
diff --git a/lib/gitlab/seeders/ci/catalog/resource_seeder.rb b/lib/gitlab/seeders/ci/catalog/resource_seeder.rb
index c29075cff320626d79842ba7abe7be8e5e607a9f..1a14d027fe9f28b81d35eb28d3cc2e44624c1956 100644
--- a/lib/gitlab/seeders/ci/catalog/resource_seeder.rb
+++ b/lib/gitlab/seeders/ci/catalog/resource_seeder.rb
@@ -33,6 +33,7 @@ def create_project(name, index)
               description: "This is Catalog resource ##{index}",
               name: name,
               namespace_id: @group.id,
+              organization_id: @group.organization_id,
               path: name,
               visibility_level: @group.visibility_level
             ).execute
diff --git a/spec/controllers/dashboard/todos_controller_spec.rb b/spec/controllers/dashboard/todos_controller_spec.rb
index 00b8ca0a4ff319fd427d98227fb69bc03c71005c..b66ad8f1e3c2304d63cda9d57b1e475b09f30c22 100644
--- a/spec/controllers/dashboard/todos_controller_spec.rb
+++ b/spec/controllers/dashboard/todos_controller_spec.rb
@@ -65,7 +65,7 @@
         merge_request_2 = create(:merge_request, source_project: project_2)
         create(:todo, project: project_2, author: author, user: user, target: merge_request_2)
 
-        expect { get :index }.not_to exceed_query_limit(control)
+        expect { get :index }.not_to exceed_query_limit(control).with_threshold(1)
         expect(response).to have_gitlab_http_status(:ok)
       end
     end
diff --git a/spec/factories/projects.rb b/spec/factories/projects.rb
index db2ec3b23d6e0ae9f086b55fb749c308e44e08a5..5e55ad239b7dbb9d8f6bb6ba4ce5c77d0cb25573 100644
--- a/spec/factories/projects.rb
+++ b/spec/factories/projects.rb
@@ -16,6 +16,7 @@
     has_external_wiki { false }
 
     # Associations
+    organization { namespace&.organization }
     namespace
     creator { group ? association(:user) : namespace&.owner }
 
@@ -99,6 +100,7 @@
         name: evaluator.name,
         path: evaluator.path,
         parent: evaluator.namespace,
+        organization: evaluator.organization,
         shared_runners_enabled: evaluator.shared_runners_enabled,
         visibility_level: evaluator.visibility_level
       }
diff --git a/spec/lib/gitlab/database/schema_cache_with_renamed_table_spec.rb b/spec/lib/gitlab/database/schema_cache_with_renamed_table_spec.rb
index 0bea348e6b4ddefe4f7914eeecb12ea387f9b0f3..d9e6d1220bae7a6690235e5f4a1d0e025c58f7b5 100644
--- a/spec/lib/gitlab/database/schema_cache_with_renamed_table_spec.rb
+++ b/spec/lib/gitlab/database/schema_cache_with_renamed_table_spec.rb
@@ -68,7 +68,10 @@
 
     describe 'when the table behind a model is actually a view' do
       let(:group) { create(:group) }
-      let(:attrs) { attributes_for(:project, namespace_id: group.id, project_namespace_id: group.id).except(:creator) }
+      let(:attrs) do
+        attributes_for(:project, namespace_id: group.id, project_namespace_id: group.id).except(:creator, :organization)
+      end
+
       let(:record) { old_model.create!(attrs) }
 
       it 'can persist records' do
diff --git a/spec/models/preloaders/users_max_access_level_by_project_preloader_spec.rb b/spec/models/preloaders/users_max_access_level_by_project_preloader_spec.rb
index 73095560b97764df92e01f99bfe4e043a7907ac7..4129d14125207433a69c856840266014bff8773c 100644
--- a/spec/models/preloaders/users_max_access_level_by_project_preloader_spec.rb
+++ b/spec/models/preloaders/users_max_access_level_by_project_preloader_spec.rb
@@ -44,7 +44,7 @@
         end
       end
 
-      expect(policy_queries).not_to exceed_query_limit(0)
+      expect(policy_queries).not_to exceed_query_limit(1)
     end
   end
 end
diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb
index c23b94a31e7b84217d7a8e98ebca4304154dd7d3..be486fb567606c428b925d6bc1ed769988411f77 100644
--- a/spec/models/project_spec.rb
+++ b/spec/models/project_spec.rb
@@ -672,10 +672,7 @@
   end
 
   describe 'validation' do
-    let!(:project) { create(:project) }
-
     it { is_expected.to validate_presence_of(:name) }
-    it { is_expected.to validate_uniqueness_of(:name).scoped_to(:namespace_id) }
     it { is_expected.to validate_length_of(:name).is_at_most(255) }
     it { is_expected.to allow_value('space last ').for(:name) }
     it { is_expected.not_to allow_value('colon:in:path').for(:path) } # This is to validate that a specially crafted name cannot bypass a pattern match. See !72555
@@ -692,6 +689,12 @@
     it { is_expected.to validate_numericality_of(:max_artifacts_size).only_integer.is_greater_than(0) }
     it { is_expected.to validate_length_of(:suggestion_commit_message).is_at_most(255) }
 
+    it 'validates name is case-sensitively unique within the scope of namespace_id' do
+      project = create(:project)
+
+      expect(project).to validate_uniqueness_of(:name).scoped_to(:namespace_id)
+    end
+
     it 'validates build timeout constraints' do
       is_expected.to validate_numericality_of(:build_timeout)
         .only_integer
@@ -9278,7 +9281,8 @@ def create_hook
   context 'with loose foreign key on organization_id' do
     it_behaves_like 'cleanup by a loose foreign key' do
       let_it_be(:parent) { create(:organization) }
-      let_it_be(:model) { create(:project, organization: parent) }
+      let_it_be(:group) { create(:group, organization: parent) }
+      let_it_be(:model) { create(:project, group: group, organization: parent) }
     end
   end
 
diff --git a/spec/requests/api/invitations_spec.rb b/spec/requests/api/invitations_spec.rb
index dff3205f55d9dbe85fca9e9b84affe291d8f50f6..aa0ea390b14e0e7faa4d4fb9e10b5cca488826d4 100644
--- a/spec/requests/api/invitations_spec.rb
+++ b/spec/requests/api/invitations_spec.rb
@@ -435,7 +435,7 @@ def invite_member_by_email(source, source_type, email, created_by, access_level:
       emails = 'email3@example.com,email4@example.com,email5@example.com,email6@example.com,email7@example.com,' \
         'EMAIL8@EXamPle.com'
 
-      unresolved_n_plus_ones = 73 # currently there are 10 queries added per email
+      unresolved_n_plus_ones = 77 # currently there are 10 queries added per email
 
       expect do
         post invitations_url(project, maintainer), params: { email: emails, access_level: Member::DEVELOPER }
diff --git a/spec/requests/api/members_spec.rb b/spec/requests/api/members_spec.rb
index cb8dc38a8bfcf648c5143b09978fc41a1fdf6052..e53a1bebcf62ee7d923edba337b05efe25a2835f 100644
--- a/spec/requests/api/members_spec.rb
+++ b/spec/requests/api/members_spec.rb
@@ -1117,6 +1117,10 @@ def request
 
   it_behaves_like 'POST /:source_type/:id/members', 'project' do
     let(:source) { project }
+
+    before do
+      allow(Gitlab::QueryLimiting::Transaction).to receive(:threshold).and_return(102)
+    end
   end
 
   it_behaves_like 'POST /:source_type/:id/members', 'group' do
diff --git a/spec/requests/api/project_import_spec.rb b/spec/requests/api/project_import_spec.rb
index 9bc4be936955f41639289b59a91d291852f57705..a86e77319d4163721a9dcd9233aae737551edf3b 100644
--- a/spec/requests/api/project_import_spec.rb
+++ b/spec/requests/api/project_import_spec.rb
@@ -64,7 +64,7 @@
     it 'executes a limited number of queries', :use_clean_rails_redis_caching do
       control = ActiveRecord::QueryRecorder.new { perform_archive_upload }
 
-      expect(control.count).to be <= 111
+      expect(control.count).to be <= 113
     end
 
     it 'schedules an import using a namespace' do
diff --git a/spec/requests/git_http_spec.rb b/spec/requests/git_http_spec.rb
index 591ba49812194298127546a3c795a98a0542b979..68d18200df705e7e892d65ecc3956636c84f9273 100644
--- a/spec/requests/git_http_spec.rb
+++ b/spec/requests/git_http_spec.rb
@@ -229,6 +229,10 @@
         let(:path) { "#{user.namespace.path}/new-project.git" }
 
         context 'when authenticated' do
+          before do
+            allow(Gitlab::QueryLimiting::Transaction).to receive(:threshold).and_return(102)
+          end
+
           it 'creates a new project under the existing namespace' do
             # current scenario does not matter with the user activity case,
             # so stub/double it to escape more sql running times limit
diff --git a/spec/services/projects/create_service_spec.rb b/spec/services/projects/create_service_spec.rb
index a328cc905c5b8a6959f771ca294a326da841fd85..548a56d9260b9c0f9d4d271dd885a438f58aecc5 100644
--- a/spec/services/projects/create_service_spec.rb
+++ b/spec/services/projects/create_service_spec.rb
@@ -5,7 +5,7 @@
 RSpec.describe Projects::CreateService, '#execute', feature_category: :groups_and_projects do
   include ExternalAuthorizationServiceHelpers
 
-  let(:user) { create :user }
+  let_it_be(:user) { create(:user) }
   let(:project_name) { 'GitLab' }
   let(:opts) do
     {
@@ -86,6 +86,28 @@
     end
   end
 
+  describe 'setting organization' do
+    subject(:project) { create_project(user, opts) }
+
+    context 'with group namespace' do
+      let_it_be(:namespace) { create(:group) }
+
+      before do
+        opts[:namespace_id] = namespace.id
+      end
+
+      it 'sets correct organization' do
+        expect(project.organization).to eq(namespace.organization)
+      end
+    end
+
+    context 'with user namespace' do
+      it 'sets correct organization' do
+        expect(project.organization).to eq(user.namespace.organization)
+      end
+    end
+  end
+
   describe 'topics' do
     subject(:project) { create_project(user, opts) }
 
diff --git a/spec/support/shared_contexts/policies/project_policy_shared_context.rb b/spec/support/shared_contexts/policies/project_policy_shared_context.rb
index 218c7f89e34c7b3e3b170e6219d29d7853ac02c7..fc9aa9275f9fa79baa6d682bf413115f0cc123d2 100644
--- a/spec/support/shared_contexts/policies/project_policy_shared_context.rb
+++ b/spec/support/shared_contexts/policies/project_policy_shared_context.rb
@@ -10,8 +10,8 @@
   let_it_be(:inherited_reporter) { create(:user) }
   let_it_be(:inherited_developer) { create(:user) }
   let_it_be(:inherited_maintainer) { create(:user) }
-  let_it_be(:owner) { create(:user) }
   let_it_be(:organization) { create(:organization, :default) }
+  let_it_be(:owner) { create(:user, namespace: create(:user_namespace, organization: organization)) }
   let_it_be(:organization_owner) { create(:user, :organization_owner) }
   let_it_be(:admin) { create(:admin) }
   let_it_be(:non_member) { create(:user) }