1. ホーム
  2. spring-boot

[解決済み] Entity上で@AllArgsConstructorと@NoArgsConstructorを併用する理由とは?

2022-02-26 18:17:11

質問

ネット上でIntelliJでのSpring Bootの応用について複数のコードを見ましたが、多くの場合は @AllArgsConstructor@NoArgsConstructor というように、どちらもコンストラクタですが、その目的は異なります。

  • @AllArgsConstructor アノテーションされたクラスのすべてのフィールドの引数を必要とするコンストラクタを生成します。
  • @NoArgsConstructor はパラメータを持たないコンストラクタを生成します。

では、なぜ同じエンティティに対して両者を併用するのか、またその場合、両者はどのように機能するのでしょうか。

@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
@Entity
public class Product {
    @Id
    private int id;
    private String name;
    private String type;
}

解決方法は?

その JPA仕様 は、すべての永続的なクラス ( @Entity ) は、public か protected かを問わず、引数のないコンストラクタを持ちます。(Hibernateのような実装を扱う場合、これは必ずしも正しいとは限らないことに注意してください。 本解 ).

これは、JPAがReflection APIを使用してビーンクラスを作成するために、デフォルトのコンストラクタメソッドを使用するために必要です。実際、クラスが多くのコンストラクタを含む場合、JPAはどれを呼び出すべきかわからなくなります。

Product.class.newInstance();

と同等である。 new Product() ( Product.class クラスリテラル インスタンス化されると、フィールドセッターを使用してそのクラスを処理します。

そして、Javaでは、他のコンストラクタを定義しない限り(他のコンストラクタを用意しない場合のみ)、クラスに対してデフォルトのコンストラクタ(無引数型コンストラクタ)が自動的に生成されます。

つまり、他にコンストラクタが定義されていない場合、コンパイラは自動的にデフォルトの無引数コンストラクタを作成するので、フレームワーク(ここではJPA)が要求する場合は、コンストラクタを定義するクラスだけが無引数コンストラクタも含めなければならないのです。このため @NoArgsConstructor アノテーションを追加した場合 @AllArgsConstructor アノテーションを使用します。

を使用している点にも注意してください。 @Data の機能を束ねたものです。 @RequiredArgsConstructor のコンストラクタを生成し、すべての final または @NonNull 注釈付きフィールド(Lombok参照 ドキュメンテーション ). そのため、null 値が確定しないフィールドのみを使用している場合、たとえそのフィールドに @NoArgsConstructor アノテーションを使用します。私はこのケースをテストしたわけではありませんが @RequiredArgsConstructor を使用した場合に同じように動作するかどうかはわかりません。 @Data .

@Data もバンドルされます。 @ToString を追加する必要はありません。

私は、個人的に @Data のようなアノテーションが必要でない場合、私は通常、単に.NET Frameworkを使用します。

@Entity
@Getter
@Setter
@EqualsAndHashCode
public class Product {

    @Id
    private int id;

    private String name;

    private String type;

}

を使用しないことが多いので toString() また、パラメータ化されたコンストラクタを使用することもできます。より冗長かもしれませんが、私にとってはより意味のあることです。