web-dev-qa-db-ja.com

Lombokを使用した明示的なコンストラクター?

データベースを管理する厄介なコードを書き直していて、元のプログラマーが次のようにデータベースにマップされたクラスを作成したことを確認しました。

(この質問で目的のない不要なコードを削除しました)

@Entity
@Data
@EqualsAndHashCode(callSuper = false, of = { "accessionCode", "header", "date" })
@SuppressWarnings("PMD.UnusedPrivateField")
public class PDBEntry implements Serializable {
    @Id
    @NaturalId
    @NotEmpty
    @Length(max = 4)
    private String accessionCode;

    @NaturalId
    @NotEmpty
    private Date date;

    @NaturalId
    // We allow for the header to be 'null'
    private String header;

    private Boolean isValidDssp;

    @Temporal(TemporalType.TIMESTAMP)
    private Date lastUpdated = new Date(System.currentTimeMillis());

    protected PDBEntry(){}

    public PDBEntry(String accessionCode, String header, Date date){
        this.accessionCode = accessionCode;
        this.header = header;
        this.date = date;
    }
}

私はまだHibernateの初心者で、Lombokを使用していますが、これは同じことをしませんか?Lombokは必要なコンストラクターを自動的に作成しませんか?

@Entity
@Data
@SuppressWarnings("PMD.UnusedPrivateField")
public class PDBEntry implements Serializable {
    @Id
    @NaturalId
    @NotEmpty
    @NonNull
    @Length(max = 4)
    private String accessionCode;

    @NaturalId
    @NotEmpty
    @NonNull
    private Date date;

    @NaturalId
    // We allow for the header to be 'null'
    private String header;

    private Boolean isValidDssp;

    @Temporal(TemporalType.TIMESTAMP)
    private Date lastUpdated = new Date(System.currentTimeMillis());
}

また、このコードの元のプログラマーは、ヘッダーを「null」にすることを許可していると述べていますが、ヘッダーの値を必要とするコンストラクターを明示的に作成しました。私は何かが足りないのですか、それともこれは少し矛盾していますか?

16
FinalArt2005

@NoArgsConstructor, @RequiredArgsConstructor, @AllArgsConstructor をご覧ください。

@Dataのコンストラクターの動作は@RequiredArgsConstructorのようなものです。

@RequiredArgsConstructorは、特別な処理が必要なフィールドごとに1つのパラメーターを持つコンストラクターを生成します。すべての最終フィールドは、パラメーターと、@ NonNullとしてマークされ、宣言された場所で初期化されていないフィールドを取得します。

どのフィールドもfinalまたは@NonNullのいずれでもない場合、これは引数のないコンストラクターになります。ただし、これはこの動作を実現するための最も表現力豊かな方法ではありません。

この場合におそらく必要になるのは、ドキュメントにも示されているように、意図した動作を明確に伝えるための@NoArgsConstructor(オプションで@AllArgsConstructorと組み合わせる)です。

HibernateやServiceProviderInterfaceなどの特定のJavaコンストラクトには、引数なしのコンストラクターが必要です。このアノテーションは、主に@Dataまたはアノテーションを生成する他のコンストラクターのいずれかと組み合わせて役立ちます。

17
Tim

@NonNullフィールドで@Dataを使用していて、それでもnoargsコンストラクターが必要な場合は、3つのアノテーションすべてを一緒に追加してみてください。

@NoArgsConstructor
@RequiredArgsConstructor
@AllArgsConstructor

どうやら古い intelliJ EclipseKeplerとlombokv0.11.4で複製したバグ

1
Jules Martel

そのビットはあなたが正しいと矛盾しています。私はこれまでLombokを使用したことがありませんが、Beanを作成して永続化できるようにする場合は、休止状態で、私が知る限り、上記のデフォルトのコンストラクターが必要です。これは、Constructor.newInstance()を使用して新しいオブジェクトをインスタンス化します。

これは、より詳細に説明する休止状態のドキュメントです。

Hibernateドキュメント

1
DeliveryNinja
@NoArgsConstructor, 
@RequiredArgsConstructor, 
@AllArgsConstructor

引数をとらないコンストラクター、final/null以外のフィールドごとに1つの引数、またはフィールドごとに1つの引数を生成します。これを読んでください lombok-project

@Data
@RequiredArgsConstructor /*Duplicate method Someclass() in type Someclass*/
@NoArgsConstructor(access=AccessLevel.PRIVATE, force=true)  /*Duplicate method Someclass() in type Someclass*/
@Entity
public class Someclass {      
    @Id
    private  String id;
    private  String name;
    private  Type type; 

    public static enum Type { X , Y, Z}
}

メンバー変数をfinalにすることで修正しました

@Data
@RequiredArgsConstructor 
@NoArgsConstructor(access=AccessLevel.PRIVATE, force=true)
@Entity
public class Someclass {

    @Id
    private final String id;
    private final String name;
    private final Type type; 
    public static enum Type { X , Y, Z}
}
0
zee