Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support partially filled composite IDs #2282

Merged
merged 2 commits into from
Oct 28, 2024

Conversation

sickfar
Copy link
Contributor

@sickfar sickfar commented Oct 19, 2024

Description

Summary of the change:
This PR supports a new scenario of Composite ID usage.
In case when composite ID can be partially generated (autoGenerated UUID or database-side autoIncrement column), I should be able to specify only static required CompositeID parts.

Detailed description:

  • What: CompositeID is now longer required to be fully constructed if part of it based on generated columns
  • Why: If I have a multi-tenant application, and the multi-tenancy is provided by a specific DB column, I want to be able to specify this tenant ID and leave the the in-tenant ID to be generated by database. In my own case, I have a project with "School" as tenant and school_id column as constant component of composite primary key, and "Client" with client_id generated from a sequence, which I do not really need to specify when creating a new entity.
object ClientTable : CompositeIdTable("clients") {
    val schoolId = long("school_id").entityId()
    val clientId = long("id").autoIncrement().entityId()
    override val primaryKey = PrimaryKey(schoolId, clientId)
}

// before this PR:
Client.new(CompositeID {
    it[ClientTable.schoolId] = schoolId
    it[ClientTable.clientId] = getNextClientId() // fetch from some sequence even though clientId is defined as autoIncrement(). NPE thrown if not provided
}) { /* init */ }

// after this PR clientId defined as autoIncrement() will be generated by database as it designed
Client.new(CompositeID {
    it[ClientTable.schoolId] = schoolId
}) { /* init */ }
  • How: writeValues in EntityClass will be written only if column is presented in CompositeID. To avoid mistakes by forgotten column, missed column is additionally checked to be AutoIncrementColumn or to have defaultValueFun. To be completely reloaded by entityCache, id will be set to null after setting writeValues

Type of Change

Please mark the relevant options with an "X":

  • Bug fix
  • New feature
  • Documentation update

Updates/remove existing public API methods:

  • Is breaking change

Affected databases:

  • MariaDB
  • Mysql5
  • Mysql8
  • Oracle
  • Postgres
  • SqlServer
  • H2
  • SQLite

Checklist

  • Unit tests are in place
  • The build is green (including the Detekt check)
  • All public methods affected by my PR has up to date API docs
  • Documentation for my change is up to date

Related Issues

…D should be defined by user and other part generated by database

Update documentation for supported feature in DAO-CRUD-Operations.topic
@bog-walk bog-walk self-assigned this Oct 21, 2024
@bog-walk bog-walk self-requested a review October 21, 2024 20:22
# Conflicts:
#	exposed-dao/src/main/kotlin/org/jetbrains/exposed/dao/Entity.kt
Copy link
Member

@bog-walk bog-walk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks very much for this well-needed addition and for opening a PR @sickfar
Also thanks for preemptively rebasing and updating the docs and tests 👍

If you come across any other oversights when using composite keys (etc.), please feel free to contribute again, either by opening an issue on YouTrack or with another PR.

@bog-walk bog-walk merged commit 7fde5e4 into JetBrains:main Oct 28, 2024
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants