Edited at

Spring Data JPA において継承戦略を SINGLE_TABLE にした際、想定外のクラスにてインスタンスが生成される現象について

More than 1 year has passed since last update.


概要

下記のようなクラス構成にて、継承戦略を実施した際に、本来生成されるべきクラスでインスタンスが生成されず、全てのインスタンスが、Sales になる現象が発生しました。


Company.java

@Entity

@Getter
public class Company<U extends User> {

@Id
private Integer id;

@OneToMany
@JoinColimn(name = "userId")
private Set<U> users;
}



User.java

@Entity

@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@NoArgsConstructor
@Getter
public abstract class User {
@Id
private int id;
@ManyToOne
private Company company;
}


Sales.java

@Entity

@DiscriminatorValue("sales")
@NoArgsConstructor
@Getter
public class Sales extends User {
}


Programmer.java

@Entity

@DiscriminatorValue("programmer")
@NoArgsConstructor
@Getter
public class Programmer extends User {
}


原因

Company クラスにて、User クラスの型パラメーターを指定していますが、@OneToMany の型に型パラメーターを指定しているのが原因でした。

DBに格納されている値 (規定では user.dtype 列) が機能しない動作となりました。

明示的に DiscriminatorColumn を指定しても同じ動作となりましたので、型パラメーターを指定したリレーションは使えないことが想定された動作のようです。

下記のように、users フィールドの型を User クラスに指定することで現象は回避できました。

IntelliJ IDEA にて型安全が保証されていない、という警告が出たのでリファクタしましたが、結果として型が安全ではなくなってしまった次第です。


Company.java

@Entity

@Getter
public class Company<U extends User> {

@Id
private Integer id;

@OneToMany
@JoinColimn(name = "userId")
private Set<User> users;
}