LoginSignup
0
0

More than 5 years have passed since last update.

Spring Data JPA にてメタモデルを使用すると NullPointerException が発生する

Last updated at Posted at 2017-10-07

概要

JPA にてメタモデルを使用して、実装した結果、NullPointerException が発生しました。

詳細

JPA では、メタモデルの機能を提供しています。
メタモデルはエンティティの構造を明確にするものです。
メタモデルを使用せず、Criteria API を書くと下記のような実装になります。

NumberSpecification.java
public class NumberSpecification {
    public static Specification<Group> members(Map<Integer, Integer> lowerUpper) {
        return (root, query, cb) -> {
            final Collection<Predicate> predicates = new ArrayList<>();
            lowerUpper.forEach((lower, upper) -> {
                predicates.add(
                        cb.and(cb.between(root.get("number"), lower, upper))
                );

            });
            return cb.or(predicates.toArray(new Predicate[predicates.size()]));
        };
    }
}

上記の場合、文字列で Group クラスの number フィールドを指定して、下記のような条件を作成しています。

condition.sql
where number between 1 and 2 or number between 3 and 6 ...

上記の文字列指定ではフィールド名が "number" から違う名前に変わったとき正常に動作しません。
メタモデルを使用すると、この問題を解消できます。

Group.java
@Entity
@Table(name ="group_member")
public class Group extends Artist {

    @Getter
    private int number;

}

上記エンティティのメタモデルを作成する場合、@StaticMetamodel() アノテーションをつけて、該当のエンティティのクラス名の最後に "_" をつけたクラスを作成します。

Group_.java
@StaticMetamodel(Group.class)
public class Group_ {
    public static volatile SingularAttribute<Group, Integer> number;
}

これにより下記のように Specification を記述できます。

NumberSpecificationWithMetamodel.java
public class NumberSpecificationWithMetamodel {
    public static Specification<Group> members(Map<Integer, Integer> lowerUpper) {
        return (root, query, cb) -> {
            final Collection<Predicate> predicates = new ArrayList<>();
            lowerUpper.forEach((lower, upper) -> {
                predicates.add(
                        cb.and(cb.between(root.get(Group_.number), lower, upper))
                );

            });
            return cb.or(predicates.toArray(new Predicate[predicates.size()]));
        };
    }
}

しかしながら、上記実装において、Group_.number が Null になる現象が発生しました。

解決策

非常に単純です。
こちらのページ での示唆のように、メタモデルとエンティティを同じパッケージに配置したら問題は解消します。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0