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

Kotlin constructors using @ExperimentalUnsignedTypes parameters cause constructor resolution to fail [DATACMNS-1800] #2215

Closed
spring-projects-issues opened this issue Sep 19, 2020 · 3 comments
Assignees
Labels
in: mapping Mapping and conversion infrastructure type: bug A general bug

Comments

@spring-projects-issues
Copy link

magneticflux- opened DATACMNS-1800 and commented

I have a Kotlin entity with a constructor that includes several defaulted parameters in no particular order. I also am using the Kotlin Spring and JPA Gradle plugins to generate default constructors for my entities.

Initializing a repository for my entity causes this crash:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'myRepository' defined in com.x.MyRepository defined in @EnableJpaRepositories declared on JpaRepositoriesRegistrar.EnableJpaRepositoriesConfiguration: Invocation of init method failed; nested exception is java.lang.ArrayIndexOutOfBoundsException: Index 3 out of bounds for length 3
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1794) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:594) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:516) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
	at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:324) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:322) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeansOfType(DefaultListableBeanFactory.java:624) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeansOfType(DefaultListableBeanFactory.java:612) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
	at org.springframework.data.repository.config.DeferredRepositoryInitializationListener.onApplicationEvent(DeferredRepositoryInitializationListener.java:51) ~[spring-data-commons-2.3.4.RELEASE.jar:2.3.4.RELEASE]
	at org.springframework.data.repository.config.DeferredRepositoryInitializationListener.onApplicationEvent(DeferredRepositoryInitializationListener.java:36) ~[spring-data-commons-2.3.4.RELEASE.jar:2.3.4.RELEASE]
	at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:172) ~[spring-context-5.2.9.RELEASE.jar:5.2.9.RELEASE]
	at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:165) ~[spring-context-5.2.9.RELEASE.jar:5.2.9.RELEASE]
	at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:139) ~[spring-context-5.2.9.RELEASE.jar:5.2.9.RELEASE]
	at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:404) ~[spring-context-5.2.9.RELEASE.jar:5.2.9.RELEASE]
	at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:361) ~[spring-context-5.2.9.RELEASE.jar:5.2.9.RELEASE]
	at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:898) ~[spring-context-5.2.9.RELEASE.jar:5.2.9.RELEASE]
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:554) ~[spring-context-5.2.9.RELEASE.jar:5.2.9.RELEASE]
	at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:143) ~[spring-boot-2.3.4.RELEASE.jar:2.3.4.RELEASE]
	at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:758) ~[spring-boot-2.3.4.RELEASE.jar:2.3.4.RELEASE]
	at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:750) ~[spring-boot-2.3.4.RELEASE.jar:2.3.4.RELEASE]
	at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397) ~[spring-boot-2.3.4.RELEASE.jar:2.3.4.RELEASE]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:315) ~[spring-boot-2.3.4.RELEASE.jar:2.3.4.RELEASE]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1237) ~[spring-boot-2.3.4.RELEASE.jar:2.3.4.RELEASE]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1226) ~[spring-boot-2.3.4.RELEASE.jar:2.3.4.RELEASE]
	at com.x.ApplicationKt.main(Application.kt:153) ~[main/:na]
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na]
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
	at java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[na:na]
	at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49) ~[spring-boot-devtools-2.3.4.RELEASE.jar:2.3.4.RELEASE]
Caused by: java.lang.ArrayIndexOutOfBoundsException: Index 3 out of bounds for length 3
	at org.springframework.data.mapping.model.PreferredConstructorDiscoverer$Discoverers.buildPreferredConstructor(PreferredConstructorDiscoverer.java:215) ~[spring-data-commons-2.3.4.RELEASE.jar:2.3.4.RELEASE]
	at org.springframework.data.mapping.model.PreferredConstructorDiscoverer$Discoverers.access$200(PreferredConstructorDiscoverer.java:91) ~[spring-data-commons-2.3.4.RELEASE.jar:2.3.4.RELEASE]
	at org.springframework.data.mapping.model.PreferredConstructorDiscoverer$Discoverers$2.lambda$discover$3(PreferredConstructorDiscoverer.java:171) ~[spring-data-commons-2.3.4.RELEASE.jar:2.3.4.RELEASE]
	at java.base/java.util.Optional.orElseGet(Optional.java:369) ~[na:na]
	at org.springframework.data.mapping.model.PreferredConstructorDiscoverer$Discoverers$2.discover(PreferredConstructorDiscoverer.java:160) ~[spring-data-commons-2.3.4.RELEASE.jar:2.3.4.RELEASE]
	at org.springframework.data.mapping.model.PreferredConstructorDiscoverer.discover(PreferredConstructorDiscoverer.java:79) ~[spring-data-commons-2.3.4.RELEASE.jar:2.3.4.RELEASE]
	at org.springframework.data.mapping.model.BasicPersistentEntity.<init>(BasicPersistentEntity.java:105) ~[spring-data-commons-2.3.4.RELEASE.jar:2.3.4.RELEASE]
	at org.springframework.data.jpa.mapping.JpaPersistentEntityImpl.<init>(JpaPersistentEntityImpl.java:59) ~[spring-data-jpa-2.3.4.RELEASE.jar:2.3.4.RELEASE]
	at org.springframework.data.jpa.mapping.JpaMetamodelMappingContext.createPersistentEntity(JpaMetamodelMappingContext.java:70) ~[spring-data-jpa-2.3.4.RELEASE.jar:2.3.4.RELEASE]
	at org.springframework.data.jpa.mapping.JpaMetamodelMappingContext.createPersistentEntity(JpaMetamodelMappingContext.java:44) ~[spring-data-jpa-2.3.4.RELEASE.jar:2.3.4.RELEASE]
	at org.springframework.data.mapping.context.AbstractMappingContext.addPersistentEntity(AbstractMappingContext.java:372) ~[spring-data-commons-2.3.4.RELEASE.jar:2.3.4.RELEASE]
	at org.springframework.data.mapping.context.AbstractMappingContext.getPersistentEntity(AbstractMappingContext.java:263) ~[spring-data-commons-2.3.4.RELEASE.jar:2.3.4.RELEASE]
	at org.springframework.data.mapping.context.AbstractMappingContext.getPersistentEntity(AbstractMappingContext.java:206) ~[spring-data-commons-2.3.4.RELEASE.jar:2.3.4.RELEASE]
	at org.springframework.data.mapping.context.AbstractMappingContext.getPersistentEntity(AbstractMappingContext.java:90) ~[spring-data-commons-2.3.4.RELEASE.jar:2.3.4.RELEASE]
	at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.lambda$afterPropertiesSet$4(RepositoryFactoryBeanSupport.java:295) ~[spring-data-commons-2.3.4.RELEASE.jar:2.3.4.RELEASE]
	at java.base/java.util.Optional.ifPresent(Optional.java:183) ~[na:na]
	at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.afterPropertiesSet(RepositoryFactoryBeanSupport.java:295) ~[spring-data-commons-2.3.4.RELEASE.jar:2.3.4.RELEASE]
	at org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean.afterPropertiesSet(JpaRepositoryFactoryBean.java:144) ~[spring-data-jpa-2.3.4.RELEASE.jar:2.3.4.RELEASE]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1853) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1790) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
	... 30 common frames omitted

Affects: 2.3.4 (Neumann SR4)

@spring-projects-issues
Copy link
Author

Mark Paluch commented

Can you provide a reproducer or attach the offending entity class?

@spring-projects-issues
Copy link
Author

magneticflux- commented

It stems from using Kotlin unsigned integer types and DATACMNS-1517. Unsigned types are implemented using inline classes, triggering the existing issue. Here's a reproduction of the issue:

package com.skaggsm.reproduction

import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication
import org.springframework.data.jpa.repository.JpaRepository
import javax.persistence.Entity
import javax.persistence.Id

@SpringBootApplication
class ReproductionApplication

fun main(args: Array<String>) {
    runApplication<ReproductionApplication>(*args)
}

@ExperimentalUnsignedTypes
@Entity
data class ExampleEntity(
        @Id
        val id: String,
        val a: UInt = 5u,
        val b: Int = 5,
        val c: Double = 1.5
)

@ExperimentalUnsignedTypes
interface ExampleEntityRepository : JpaRepository<ExampleEntity, String>

@spring-projects-issues spring-projects-issues added status: waiting-for-feedback We need additional information before we can continue type: bug A general bug in: mapping Mapping and conversion infrastructure labels Dec 30, 2020
@mp911de mp911de added status: feedback-provided Feedback has been provided and removed status: waiting-for-feedback We need additional information before we can continue labels Dec 30, 2020
mp911de added a commit that referenced this issue Jan 18, 2021
We now leniently skip parameter name resolution for types using unsigned types. The issue is caused by Kotlin's DefaultConstructorMarker that doesn't report a parameter name.

Closes #2215
mp911de added a commit that referenced this issue Jan 18, 2021
We now leniently skip parameter name resolution for types using unsigned types. The issue is caused by Kotlin's DefaultConstructorMarker that doesn't report a parameter name.

Closes #2215
@mp911de
Copy link
Member

mp911de commented Jan 18, 2021

We can address the issue by guarding the parameter name lookup so the parameter name for DefaultConstructorMarker stays null. However, entity creation will still not work because the reflection method isn't aware that DefaultConstructorMarker should be skipped. Generated code isn't able to access DefaultConstructorMarker because the class is package-private although used in a public constructor.

@mp911de mp911de removed the status: feedback-provided Feedback has been provided label Jan 18, 2021
@mp911de mp911de added this to the 2.3.7 (Neumann SR7) milestone Jan 18, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: mapping Mapping and conversion infrastructure type: bug A general bug
Projects
None yet
Development

No branches or pull requests

2 participants