Spring Data Repository for Entity where foreign key is also primary key
Asked Answered
L

2

5

I have some problems with JPA2 (EclipseLink) and Spring Data 1.4.2. In my case two tables has one-to-one relation:

TableA:

  • aId (PK)
  • ...

TableB:

  • bId (PK, FK - maps to aId in TableA)
  • ...

so I tried to do this entities:

EntityA:

@Entity
@Table(name = "TableA")
public class EntityA implements Serializable {
    @Id
    @GeneratedValue
    @Column(name = "aId")
    private Long id;
    // another fields and getter/setter/business methods
    ... 
}

EntityB:

@Entity
@Table(name = "TableB")
public class EntityB {
    @Id
    @OneToOne
    @JoinColumn(name = "bId", referencedColumnName = "aId")
    private EntityA id;
    // another fields and getter/setter/business methods
    ... 
}

Spring Data Repository for EntityA works well:

@Repository(value = "aRepository")
public interface RepositoryA extends CrudRepository<EntityA, Long> {
}

but for EntityB:

@Repository(value = "bRepository")
public interface RepositoryB extends PagingAndSortingRepository<EntityB, EntityA> {
}

throws Exception:

Expected id attribute type [class java.lang.Long] on the existing id attribute [SingularAttributeImpl[EntityTypeImpl@5270829:EntityA [....] but found attribute type [class EntityB]. 
Luddite answered 22/11, 2013 at 16:6 Comment(4)
Which class is raising the exception? I think the problem is the OneToOne annotation in EntityB, then id in EntityA is expected to be EntityB type.Octosyllabic
Exception is thrown when container tries to instantiate bRepository bean. I need just unidirectional mapping, so I thought that reverse link is not needed.Luddite
Try adding @MapsId to the @OneToOne annotation in EntityB: @OneToOne @MapsId.Octosyllabic
Caused by: java.lang.NullPointerException at org.eclipse.persistence.internal.jpa.metadata.accessors.mappings.ObjectAccessor.processMapsId(ObjectAccessor.java:542) I don't know why and how it happened :)Luddite
G
4

The annotation to use is @PrimaryKeyJoinColumn, not @JoinColumn:

Specifies a primary key column that is used as a foreign key to join to another table.

It is used to join the primary table of an entity subclass in the JOINED mapping strategy to the primary table of its superclass; it is used within a SecondaryTable annotation to join a secondary table to a primary table; and it may be used in a OneToOne mapping in which the primary key of the referencing entity is used as a foreign key to the referenced entity.

(emphasis mine)

Grati answered 22/11, 2013 at 16:40 Comment(3)
Thank you. I tried to use this annotation earlier and saw description of its usage. But with this annotation instantiating Spring Data repository throws exception too :( Maybe the problem is in my lack of understanding of Spring Data?Luddite
I haven't used this annotation for a while. IIRC, you need another field, of type Long, annotated with @Id. And the ManyToOne shouldn't be annotated with @Id.Grati
@Luddite why you marked it as an answer, since you report that spring data continue throwing exception?Janniejanos
D
4

The main problem (the exception) is not about the use of @JoinColumn rather than @PrimaryKeyJoinColumn, but what must be a limit of current Spring Data (as of 1.7.1). I also hit this problem and opened DATAJPA-649 for it. I couldn't find a workaround, rather than change the data model so that EntityB has a primary key independent from EntityA. The use of @MapsId does not help either.

Dateless answered 29/12, 2014 at 9:3 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.