简体   繁体   English

使用Lombok的显式构造函数?

[英]Explicit constructor using Lombok?

I'm rewriting some messy code that manages a database, and saw that the original programmer created a class mapped to the database like so: 我正在重写一些管理数据库的混乱代码,并看到原始程序员创建了一个映射到数据库的类,如下所示:

(I've removed unnecessary code that has no purpose in this question) (我删除了在这个问题上没有用处的不必要的代码)

@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;
    }
}

I am still a beginner at Hibernate and using Lombok, but wouldn't this do the same thing and wouldn't Lombok automatically create the needed constructor for you? 我仍然是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());
}

Also, the original programmer of this code says he allows for the header to be 'null', yet he explicitly created a constructor that needs a value for header. 此外,此代码的原始程序员说他允许标头为“null”,但他明确地创建了一个需要标头值的构造函数。 Am I missing something or is this a bit contradictory? 我错过了什么或者这有点矛盾吗?

Have a look at @NoArgsConstructor, @RequiredArgsConstructor, @AllArgsConstructor . 看看@ @NoArgsConstructor, @RequiredArgsConstructor, @AllArgsConstructor

The constructor behavior of @Data is like @RequiredArgsConstructor : @Data的构造函数行为类似于@RequiredArgsConstructor

@RequiredArgsConstructor generates a constructor with 1 parameter for each field that requires special handling. @RequiredArgsConstructor为每个需要特殊处理的字段生成一个带有1个参数的构造函数。 All final fields get a parameter, as well as any fields that are marked as @NonNull that aren't initialized where they are declared. 所有final字段都会获得一个参数,以及标记为@NonNull的任何字段,这些字段在声明它们的位置未初始化。

Given that none of your fields are either final or @NonNull , this will result in a no-argument constructor. 鉴于您的字段都不是final@NonNull ,这将导致无参数构造函数。 However, this is not the most expressive way to achieve this behavior. 但是,这不是实现此行为的最具表现力的方式。

What you'll probably want in this case is a @NoArgsConstructor (optionally combined with a @AllArgsConstructor ), to clearly communicate the intended behavior, as is also indicated in the documentation: 在这种情况下,您可能需要的是@NoArgsConstructor (可选地与@AllArgsConstructor结合使用),以清楚地传达预期的行为,如文档中所示:

Certain java constructs, such as hibernate and the Service Provider Interface require a no-args constructor. 某些java构造(例如hibernate和Service Provider Interface)需要no-args构造函数。 This annotation is useful primarily in combination with either @Data or one of the other constructor generating annotations. 此注释主要与@Data或生成注释的其他构造函数组合使用。

If you are using @Data with a @NonNull field and still want a noargs-constructor, you might wanna try to add all 3 annotation together 如果你正在使用带有@NonNull字段的@Data并且仍然想要一个noargs构造函数,你可能想尝试将所有3个注释一起添加

@NoArgsConstructor
@RequiredArgsConstructor
@AllArgsConstructor

Apparently an old intelliJ bug which I did replicate in Eclipse Kepler and lombok v0.11.4 显然是一个旧的intelliJ错误,我在Eclipse Kepler和lombok v0.11.4中进行了复制

That bit is contradictory you're right. 这一点是矛盾的你是对的。 I've not used Lombok before but with hibernate if you want to be able to create a bean and persist you need the default constructor as given above as far I was aware. 我之前没有使用过Lombok,但是如果你想要能够创建一个bean并且持久存在你需要上面给出的默认构造函数,我就知道了。 It uses Constructor.newInstance() to instantiate new objects. 它使用Constructor.newInstance()来实例化新对象。

Here is some hibernate documentation which goes into more detail. 这是一些更详细的hibernate文档。

Hibernate Documentation Hibernate文档

@NoArgsConstructor, 
@RequiredArgsConstructor, 
@AllArgsConstructor

Generate constructors that take no arguments, one argument per final / non-null field, or one argument for every field. 生成不带参数的构造函数,每个final / non-null字段一个参数,或每个字段一个参数。 Read this lombok-project 阅读这个lombok项目

@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}
}

Fixed it by making member variables 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}
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM