19

我正在重写一些管理数据库的杂乱代码,并看到原始程序员创建了一个映射到数据库的类,如下所示:

(我已经删除了在这个问题中没有目的的不必要的代码)

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

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

4

4 回答 4

20

看看@NoArgsConstructor, @RequiredArgsConstructor, @AllArgsConstructor

的构造函数行为@Data如下@RequiredArgsConstructor

@RequiredArgsConstructor 为每个需要特殊处理的字段生成一个带有 1 个参数的构造函数。所有 final 字段都有一个参数,以及任何标记为 @NonNull 且未在声明它们的位置初始化的字段。

鉴于您的所有字段都不是finalor @NonNull,这将导致无参数构造函数。然而,这并不是实现这种行为的最有表现力的方式。

在这种情况下,您可能想要的是 a @NoArgsConstructor(可选地与 a 结合使用@AllArgsConstructor),以清楚地传达预期的行为,如文档中所示:

某些 java 构造,例如 hibernate 和服务提供者接口需要一个无参数构造函数。此注释主要与 @Data 或其他生成注释的构造函数之一结合使用。

于 2010-10-05T17:28:29.047 回答
1

那一点是矛盾的,你是对的。我以前没有使用过 Lombok,但是如果你想能够创建一个 bean 并坚持使用 hibernate,那么据我所知,你需要上面给出的默认构造函数。它使用 Constructor.newInstance() 来实例化新对象。

这是一些更详细的休眠文档。

休眠文档

于 2010-10-05T14:09:02.703 回答
1

如果您将 @Data 与 @NonNull 字段一起使用并且仍然想要一个 noargs-constructor,您可能想尝试将所有 3 个注释一起添加

@NoArgsConstructor
@RequiredArgsConstructor
@AllArgsConstructor

显然,我在 Eclipse Kepler 和 lombok v0.11.4 中复制了一个旧的intelliJ错误

于 2014-04-11T10:52:46.617 回答
0
@NoArgsConstructor, 
@RequiredArgsConstructor, 
@AllArgsConstructor

生成不带参数、每个最终/非空字段一个参数或每个字段一个参数的构造函数。阅读这个龙目岛项目

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

通过使成员变量最终修复它

@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}
}
于 2019-02-02T20:22:51.060 回答