Fabian Lurz
Fabian Lurz

Reputation: 2039

Strange behaviour of spring data jpa

I'm new to JPA and I have a case where in my opinion JoinColumn behaves different and I want to know why.

UserEntites should join authorites.

Organziations should join OrganizationSettings.

I have two different approaches and both work.

Case 1

UserEntity :

    @Entity
@Table(name = "users")
@Inheritance(strategy = InheritanceType.JOINED)
public class UserEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
    @JoinColumn(name = "userId")
    private List<UserAuthority> authorities;
}

UserAuthoritiesEntity

@Entity(name = "authorities")
@Table(name = "authorities")
public class UserAuthority {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private Long userId;

    private String authority;
}

Here in my opinion the JoinColumn name references to UserAuthority.userId - and it works as expected.

Case 2

See my two other classes:

OrganizationEntity:

@Entity
@Table(name="organization")
public class OrganizationEntity {

    @Id
    @GeneratedValue(strategy= GenerationType.IDENTITY)
    private Long id;

    @NotNull
    private String url;

    @NotNull
    private String name;

    @OneToOne (cascade = CascadeType.ALL,fetch = FetchType.EAGER)
    @JoinColumn(name="id",updatable = false)
    private OrganizationSettingsEntity settings;
}

OrganizationSettings:

    @Entity
@Table(name = "organization_settings")
public class OrganizationSettingsEntity {

    @Id
    private Long organizationId;
}

As you can see here -> Organization is Joining OrganizationSettings with the name id - which works. But in OrganizationSettings there is no id - just organizationId. This works - but makes me wonder.

Why does the second one also work? Shouldn't it be @JoinColumn(name="organizationId") ?

Upvotes: 0

Views: 113

Answers (1)

Neil Stockton
Neil Stockton

Reputation: 11531

Spring is nothing to do with it. JPA is a standard API.

1-N case : you will create a FK column in the authorities table with name userId (linking back to the users table). You seem to also want to REUSE that same column for this userId field in the element ... this will cause you problems sooner or later since reusing columns without marking the userId field as insertable=false, updatable=false will mean that both may try to update it. Either get rid of the userId field in the element, or convert the field to be of type UserEntity (and have it as a bidirectional relation, using mappedBy on the 1-N owner field), or mark the userId field with those attributes mentioned earlier.

1-1 case : you will create a FK column in the organization table with name id (linking across to the organization_settings table). Sadly this is the same column as the PK of that table is going to use, so again you are reusing the column for 2 distinct purposes, and hell will result. Change the column of the relation FK to something distinct - the FK is in the organization table, not the other side.

Upvotes: 2

Related Questions