spring-projects / spring-projects/spring-data-jpa

Cannot create a repository for an entity with a shared key [DATAJPA-649]

Open
#1,028 9 comments 0 reactions 1 assignee View on GitHub

@mp911de is already working on this.

Since Dec 30, 2020.

has: votes-jira in: core status: blocked type: bug
Dominant language
Java
Stars
3.3k
Forks
1.6k
PR merge metrics
No merged PRs in 30d

Description

Mauro Molinari opened DATAJPA-649 and commented

I have an entity:

@Entity
public class EntityA {
  @Id 
  private Long id;
  // getters/setters omitted
}

and another one with a shared primary key:

@Entity
public class EntityB {
  @Id
  @OneToOne
  private EntityA entityA;
  // getter/setters omitted
}

I'm trying to define a repository for EntityB:

public interface EntityBRepository extends JpaRepository<EntityB, EntityA> {
}

Apart from the fact that in order for this to be correct, EntityA must be serializable, even if it is I get the following error at runtime when the application starts (note I'm using EclipseLink 2.5.2):

Caused by: java.lang.IllegalArgumentException: Expected id attribute type [class java.lang.Long] on the existing id attribute [SingularAttributeImpl[EntityTypeImpl@1077297176:EntityA [ javaType: class com.example.EntityA descriptor: RelationalDescriptor(com.example.EntityA --> [DatabaseTable(EntityA)]), mappings: 9],org.eclipse.persistence.mappings.OneToOneMapping[entityA]]] on the identifiable type [EntityTypeImpl@512803841:EntityB [ javaType: class com.example.EntityB descriptor: RelationalDescriptor(com.example.EntityB --> [DatabaseTable(entityB)]), mappings: 7]] but found attribute type [class com.example.EntityA].
	at org.eclipse.persistence.internal.jpa.metamodel.IdentifiableTypeImpl.getId(IdentifiableTypeImpl.java:200) ~[org.eclipse.persistence.jpa-2.5.2.jar:?]
	at org.springframework.data.jpa.repository.support.JpaMetamodelEntityInformation$IdMetadata.<init>(JpaMetamodelEntityInformation.java:222) ~[spring-data-jpa-1.7.1.RELEASE.jar:?]
	at org.springframework.data.jpa.repository.support.JpaMetamodelEntityInformation.<init>(JpaMetamodelEntityInformation.java:79) ~[spring-data-jpa-1.7.1.RELEASE.jar:?]
	at org.springframework.data.jpa.repository.support.JpaEntityInformationSupport.getMetadata(JpaEntityInformationSupport.java:65) ~[spring-data-jpa-1.7.1.RELEASE.jar:?]
	at org.springframework.data.jpa.repository.support.JpaRepositoryFactory.getEntityInformation(JpaRepositoryFactory.java:145) ~[spring-data-jpa-1.7.1.RELEASE.jar:?]
	at org.springframework.data.jpa.repository.support.JpaRepositoryFactory.getTargetRepository(JpaRepositoryFactory.java:89) ~[spring-data-jpa-1.7.1.RELEASE.jar:?]
	at org.springframework.data.jpa.repository.support.JpaRepositoryFactory.getTargetRepository(JpaRepositoryFactory.java:69) ~[spring-data-jpa-1.7.1.RELEASE.jar:?]
	at org.springframework.data.repository.core.support.RepositoryFactorySupport.getRepository(RepositoryFactorySupport.java:177) ~[spring-data-commons-1.9.1.RELEASE.jar:?]
	at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.initAndReturn(RepositoryFactoryBeanSupport.java:239) ~[spring-data-commons-1.9.1.RELEASE.jar:?]
	at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.afterPropertiesSet(RepositoryFactoryBeanSupport.java:225) ~[spring-data-commons-1.9.1.RELEASE.jar:?]
	at org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean.afterPropertiesSet(JpaRepositoryFactoryBean.java:92) ~[spring-data-jpa-1.7.1.RELEASE.jar:?]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1627) ~[spring-beans-4.1.2.RELEASE.jar:4.1.2.RELEASE]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1564) ~[spring-beans-4.1.2.RELEASE.jar:4.1.2.RELEASE]
	... 21 more

I tried to change the repository definition as such:

public interface EntityBRepository extends JpaRepository<EntityB, Long> {
}

and change the code that invokes findOne(ID) on that repository as such:

// instead of: entityBRepository.findOne(entityAInstance);
entityBRepository.findOne(entityAInstance.getId());

but the same error is produced when the repository gets initialized.

I then tried to change EntityB definition as such:

@Entity
public class EntityB {
  @Id
  private Long id;

  @MapsId
  @OneToOne
  private EntityA entityA;
  // getter/setters omitted
}

while keeping Long as the ID type in EntityBRepository definition, but still the same error is produced. So, I can't produce a repository for EntityB in any way :-(


Affects: 1.7.1 (Evans SR1)

13 votes, 15 watchers

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.