Search code examples
hibernatespring-bootjpaspring-config

What could be causing Spring/Hibernate setup to not find Id of entity?


I have a spring boot application. I am trying to create a jar that will include some entities/controllers that I can pull in via dependency management (Maven) from our artifactory repository.

I'm confident this is a config/annotation thing, so only included those parts of my classes.

When I try to query the database for one of entities included in main application source I get an error about lack of Id field on the entity....

org.springframework.dao.InvalidDataAccessApiUsageException: Could not obtain identifier from MyEntity(id=1 ... <other fields> ...)

When I call one of APIs exposed by the external jar it retrieves from the database without error, any entities defined in the jar.

MyEntity (using Lombok):

@Entity
@ToString
@Slf4j
@EqualsAndHashCode
public class MyEntity
{
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    // removed other simple fields for brevity
 }

My main application class config:

@Slf4j
@EntityScan(basePackages = {"org.domain.matches.entity.location"})
@SpringBootApplication // same as @Configuration @EnableAutoConfiguration 
@ComponentScan
@ImportAutoConfiguration(value = { ConfigInExternalJar.class})
public class Boot extends SpringBootServletInitializer {
    public static void main(String[] args)
    {
        SpringApplication.run(Boot.class, args);
    }

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application)
    {
        return application.sources(Boot.class);
    }

    // some irrelevent debug stuff excluded
}

Additional config in main application:

@Slf4j
@Configuration
public class RestConfig implements RepositoryRestConfigurer, WebMvcConfigurer
{

Repository (others are very similar and fail in same way, missing id exception, but on their respective entity objects):

@RepositoryRestResource(collectionResourceRel = "my-entity", path = "my-entity")
public interface MyEntityRepository extends CrudRepository<MyEntity, Integer>
{
}

ConfigInExternalJar.java :

@ComponentScan(basePackages = { "org.domain.externaljar" })
@EnableJpaRepositories(basePackages = { "org.domain.externaljar" })
@EntityScan(basePackages = { "org.domain.externaljar" })
@Slf4j
@Configuration
public class ReferencesApiConfig {

Example entity in external jar:

@Entity
@Data
public class Reference
{
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    Integer id;

    // removed other irrelevent fields

Stacktrace:

org.springframework.dao.InvalidDataAccessApiUsageException: Could not obtain identifier from MyEntity(id=1, version=2019_1_0, createdDate=2019-01-01, softwareVersion=null, softwareBuildDate=null)!; nested exception is java.lang.IllegalStateException: Could not obtain identifier from MyEntity(id=1, version=2019_1_0, createdDate=2019-01-01, softwareVersion=null, softwareBuildDate=null)!
at org.springframework.orm.jpa.EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(EntityManagerFactoryUtils.java:370) ~[spring-orm-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:255) ~[spring-orm-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:527) ~[spring-orm-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:61) ~[spring-tx-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:242) ~[spring-tx-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:153) ~[spring-tx-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:93) ~[spring-aop-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.data.repository.core.support.SurroundingTransactionDetectorMethodInterceptor.invoke(SurroundingTransactionDetectorMethodInterceptor.java:61) ~[spring-data-commons-2.1.5.RELEASE.jar:2.1.5.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212) ~[spring-aop-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at com.sun.proxy.$Proxy124.findAll(Unknown Source) ~[na:na]
at **org.domain.application.ApplicationListenerBean.onApplicationEvent(ApplicationListenerBean.java:47) ~[classes/:na]
at org.domain.application.ApplicationListenerBean.onApplicationEvent(ApplicationListenerBean.java:29) ~[classes/:na]**
at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:172) ~[spring-context-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:165) ~[spring-context-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:139) ~[spring-context-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:402) ~[spring-context-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:359) ~[spring-context-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:896) ~[spring-context-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.finishRefresh(ServletWebServerApplicationContext.java:163) ~[spring-boot-2.1.3.RELEASE.jar:2.1.3.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:552) ~[spring-context-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:142) ~[spring-boot-2.1.3.RELEASE.jar:2.1.3.RELEASE]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:775) ~[spring-boot-2.1.3.RELEASE.jar:2.1.3.RELEASE]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397) ~[spring-boot-2.1.3.RELEASE.jar:2.1.3.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:316) ~[spring-boot-2.1.3.RELEASE.jar:2.1.3.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1260) ~[spring-boot-2.1.3.RELEASE.jar:2.1.3.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1248) ~[spring-boot-2.1.3.RELEASE.jar:2.1.3.RELEASE]
at org.lhasalimited.mirabilis.Boot.main(Boot.java:45) ~[classes/:na]

Caused by: java.lang.IllegalStateException: Could not obtain identifier from KnowledgeBase(id=1, version=2019_1_0, createdDate=2019-01-01, softwareVersion=null, softwareBuildDate=null)!
at org.springframework.data.mapping.TargetAwareIdentifierAccessor.getRequiredIdentifier(TargetAwareIdentifierAccessor.java:47) ~[spring-data-commons-2.1.5.RELEASE.jar:2.1.5.RELEASE]
at org.springframework.data.jdbc.core.JdbcAggregateTemplate.publishAfterLoad(JdbcAggregateTemplate.java:251) ~[spring-data-jdbc-1.0.5.RELEASE.jar:1.0.5.RELEASE]
at org.springframework.data.jdbc.core.JdbcAggregateTemplate.findAll(JdbcAggregateTemplate.java:159) ~[spring-data-jdbc-1.0.5.RELEASE.jar:1.0.5.RELEASE]
at org.springframework.data.jdbc.repository.support.SimpleJdbcRepository.findAll(SimpleJdbcRepository.java:84) ~[spring-data-jdbc-1.0.5.RELEASE.jar:1.0.5.RELEASE]
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.data.repository.core.support.RepositoryComposition$RepositoryFragments.invoke(RepositoryComposition.java:359) ~[spring-data-commons-2.1.5.RELEASE.jar:2.1.5.RELEASE]
at org.springframework.data.repository.core.support.RepositoryComposition.invoke(RepositoryComposition.java:200) ~[spring-data-commons-2.1.5.RELEASE.jar:2.1.5.RELEASE]
at org.springframework.data.repository.core.support.RepositoryFactorySupport$ImplementationMethodExecutionInterceptor.invoke(RepositoryFactorySupport.java:644) ~[spring-data-commons-2.1.5.RELEASE.jar:2.1.5.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:608) ~[spring-data-commons-2.1.5.RELEASE.jar:2.1.5.RELEASE]
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.lambda$invoke$3(RepositoryFactorySupport.java:595) ~[spring-data-commons-2.1.5.RELEASE.jar:2.1.5.RELEASE]
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:595) ~[spring-data-commons-2.1.5.RELEASE.jar:2.1.5.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:59) ~[spring-data-commons-2.1.5.RELEASE.jar:2.1.5.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:294) ~[spring-tx-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98) ~[spring-tx-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:139) ~[spring-tx-5.1.5.RELEASE.jar:5.1.5.RELEASE]
... 24 common frames omitted

Solution

  • So the problem was using the spring data jdbc at the same time as the spring data. It is clear the dependency in the stacktrace:

    Caused by: java.lang.IllegalStateException: Could not obtain identifier from KnowledgeBase(id=1, version=2019_1_0, createdDate=2019-01-01, softwareVersion=null, softwareBuildDate=null)!
    at org.springframework.data.mapping.TargetAwareIdentifierAccessor.getRequiredIdentifier(TargetAwareIdentifierAccessor.java:47) ~[spring-data-commons-2.1.5.RELEASE.jar:2.1.5.RELEASE]
    at org.springframework.data.jdbc.core.JdbcAggregateTemplate.publishAfterLoad(JdbcAggregateTemplate.java:251) ~[spring-data-jdbc-1.0.5.RELEASE.jar:1.0.5.RELEASE]
    at org.springframework.data.jdbc.core.JdbcAggregateTemplate.findAll(JdbcAggregateTemplate.java:159) ~[spring-data-jdbc-1.0.5.RELEASE.jar:1.0.5.RELEASE]
    at org.springframework.data.jdbc.repository.support.SimpleJdbcRepository.findAll(SimpleJdbcRepository.java:84) ~[spring-data-jdbc-1.0.5.RELEASE.jar:1.0.5.RELEASE]
    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.data.repository.core.support.RepositoryComposition$RepositoryFragments.invoke(RepositoryComposition.java:359) ~[spring-data-commons-2.1.5.RELEASE.jar:2.1.5.RELEASE]
    

    Here:

    spring-data-jdbc-1.0.5.RELEASE.jar:1.0.5.RELEASE
    

    After removed the dependency, all seems to work again.