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

Check MapsId with custom id generation #1912

Open
DavideD opened this issue May 21, 2024 · 0 comments
Open

Check MapsId with custom id generation #1912

DavideD opened this issue May 21, 2024 · 0 comments
Labels
testing Improvements to test suite

Comments

@DavideD
Copy link
Member

DavideD commented May 21, 2024

Related to this question on Stack Overflow.

Entity Example:

@Id
@GeneratedValue(generator = "SharedPrimaryKeyGenerator")
@GenericGenerator(
    name = "SharedPrimaryKeyGenerator",
    strategy = "foreign",
    parameters = [Parameter(name = "property", value = "bookLineItem")]
)
@Column(
    name = ENTITY_B_ID,
    unique = true,
    nullable = false
)
var entityBId: Int? = null

@OneToOne
@PrimaryKeyJoinColumn
@JsonBackReference
var entityA: EntityA? = null

Custom generator:

 class ReactiveSharedPrimaryKeyGenerator: ReactiveIdentifierGenerator<Int> {
    override fun generate(p0: ReactiveConnectionSupplier?, entity: Any?): CompletionStage<Int> {
        return CompletableFuture.supplyAsync {
            val primaryKey = getPrimaryKey(entity!!)
            primaryKey as Int ?: throw IllegalStateException("Primary Key value is null")
        }.toCompletableFuture()
    }

    /**
     * Returns the ID or the One2One parent by checking for the @PrimaryKeyJoinColumn field to retrieve the parent
     * and then searches for the field annotated with @Id to retrieve the ID of the parent
     */
    fun getPrimaryKey(entity: Any?): Int? {
        entity?.let {
            var currentClass: Class<*> = it::class.java
            while (currentClass != null && currentClass != Any::class.java) {
                currentClass.declaredFields.forEach { field ->
                    val annotation = field.getAnnotation(PrimaryKeyJoinColumn::class.java)
                    annotation?.let { an ->
                        field.trySetAccessible()
                        val primaryKeyOwner = field.get(it)
                        primaryKeyOwner?.let { pk ->
                            val primaryKeyField = pk::class.java.getDeclaredFields().find { pkF ->
                                pkF.getAnnotation(javax.persistence.Id::class.java) != null
                            }
                            if (primaryKeyField != null) {
                                primaryKeyField.trySetAccessible()
                                val pkId = primaryKeyField.get(pk)
                                return pkId as Int?
                            }
                        }

                    }
                }
                currentClass = currentClass.superclass
            }
        }
        return null
    }
}

If somebody wants to provide a test, we a similar use case in OneToOneMapsIdTest, except that it doesn't use a custom generator.

@DavideD DavideD added the testing Improvements to test suite label May 21, 2024
@DavideD DavideD added problem A limitation or source of discomfort and removed problem A limitation or source of discomfort labels Dec 6, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
testing Improvements to test suite
Projects
None yet
Development

No branches or pull requests

1 participant