使用 Lombok 的显式构造函数?

发布于 2024-09-26 07:57:57 字数 1556 浏览 4 评论 0原文

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

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

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

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

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?

@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. Am I missing something or is this a bit contradictory?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

邮友 2024-10-03 07:57:57

查看@NoArgsConstructor、@RequiredArgsConstructor、@AllArgsConstructor

@Data 的构造函数行为类似于 @RequiredArgsConstructor

@RequiredArgsConstructor 生成一个
每个构造函数有 1 个参数
需要特殊处理的领域。
所有最终字段都有一个参数,如
以及任何标记为的字段
@NonNull 未初始化的地方
它们已被声明。

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

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

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

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

The constructor behavior of @Data is like @RequiredArgsConstructor:

@RequiredArgsConstructor generates a
constructor with 1 parameter for each
field that requires special handling.
All final fields get a parameter, as
well as any fields that are marked as
@NonNull that aren't initialized where
they are declared.

Given that none of your fields are either final or @NonNull, this will result in a no-argument constructor. 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:

Certain java constructs, such as
hibernate and the Service Provider
Interface require a no-args
constructor. This annotation is useful
primarily in combination with either
@Data or one of the other constructor
generating annotations.

东京女 2024-10-03 07:57:57

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

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

Hibernate 文档

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. It uses Constructor.newInstance() to instantiate new objects.

Here is some hibernate documentation which goes into more detail.

Hibernate Documentation

手长情犹 2024-10-03 07:57:57

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

@NoArgsConstructor
@RequiredArgsConstructor
@AllArgsConstructor

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

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

@NoArgsConstructor
@RequiredArgsConstructor
@AllArgsConstructor

Apparently an old intelliJ bug which I did replicate in Eclipse Kepler and lombok v0.11.4

旧梦荧光笔 2024-10-03 07:57:57
@NoArgsConstructor, 
@RequiredArgsConstructor, 
@AllArgsConstructor

生成不带参数、每个最终/非空字段一个参数或每个字段一个参数的构造函数。阅读此 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}
}

通过将成员变量设为最终值来修复它

@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}
}
@NoArgsConstructor, 
@RequiredArgsConstructor, 
@AllArgsConstructor

Generate constructors that take no arguments, one argument per final / non-null field, or one argument for every field. Read this 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}
}

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}
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文