2010-10-05 798 views
13

我重写管理数据库有些凌乱的代码,看到原来的程序员创建映射到数据库,像这样一类:使用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()); 
} 

此外,该代码的原来的程序员说,他允许标题是“空”,但他明确创建需要为头值的构造函数。我错过了什么,或者这有点矛盾吗?

回答

12

看一看@NoArgsConstructor, @RequiredArgsConstructor, @AllArgsConstructor

@Data构造行为就像@RequiredArgsConstructor

@RequiredArgsConstructor生成 构造与1个参数为每个 的领域,需要进行特殊处理。 所有最终字段都会得到一个参数,如 以及任何标记为 的@NonNull未初始化的字段,其中 已声明。

鉴于关你的字段或者是final@NonNull,这将导致一个无参数的构造函数。但是,这不是实现这种行为的最具表现力的方式。

你可能会想在这种情况下,什么是@NoArgsConstructor(任选一@AllArgsConstructor相结合),清楚地传达预期的行为,因为在文档中还表示:

一定Java结构,如作为 休眠和服务提供商 接口需要一个无参数 构造函数。此注释主要结合 @Data或其他构造函数 生成注释时有用。

+0

是的,我阅读了@RequiredArgsConstructor,但由于它在@Data中是标准的,我没有添加它。我的问题是,自从原始程序员使用Lombok以来,是否正确使用了注释,但没有使用@NonNull注释,而是使用了显式构造函数。你说我的字段都不是@NonNull,但仔细查看我的代码(第二个框),我用@NonNull注解了accessionCode和日期字段。现在因为Hibernate确实似乎需要一个无参数构造函数,这是否是一种很好的风格? @Data @NoArgsConstructor(access = AccessLevel.PROTECTED) @RequiredArgsConstructor – FinalArt2005 2010-10-06 11:41:07

+0

是的,这将是要走的路.. – Tim 2010-10-06 12:00:08

+3

好吧,只是对于任何人也开始使用龙目岛,我刚才听说@RequiredArgsConstructor不是非常健壮,它需要类中的字段的顺序来构建构造函数,所以如果其他人更改此顺序,调用构造函数的代码将停止工作,所以显式构造函数仍然是更好的选择。但是,如果您使用Hibernate,则@NoArgsConstructor(access = AccessLevel.PROTECTED)似乎很有用。谢谢大家的帮助。 – FinalArt2005 2010-10-06 12:20:53

1

这一点是矛盾的,你是对的。我之前没有使用过Lombok,但是如果你想创建一个bean并持久化,你需要上面给出的默认构造函数,就像我知道的那样。它使用Constructor.newInstance()来实例化新的对象。

下面是一些hibernate文档,其中有更详细的介绍。

Hibernate Documentation

+0

正如我所知,正好在类def上方的@Data注释将创建此默认构造函数,并且从我迄今为止所了解到的字段上方的@NonNull注释将导致Lombok使这些字段参数构造函数,这样你就必须给它们赋值,并且还会检查它们是否为null。但是由于我对此很陌生,所以想知道是否只是我或者原程序员在这里犯了一些小错误。 – FinalArt2005 2010-10-05 14:41:37

1

如果使用@Data与@NonNull领域,仍然需要一个noargs构造函数,你可能会想尝试添加所有3注释一起

@NoArgsConstructor 
@RequiredArgsConstructor 
@AllArgsConstructor 

显然老intelliJ的错误,我做到了在Eclipse Kepler和lombok v0.11中复制。4

相关问题