JPA:是否需要为空的默认构造函数?

use*_*568 6 java constructor jpa eclipselink

使用JPA时,默认的构造函数是否为空?由于我不知道JPA内部是如何工作的,所以我担心JPA会错误地初始化一个对象,当默认的构造函数自己做一些事情时就像用默认值等填充属性一样.

谢谢.

Ric*_*tze 9

要通过JPA最小化运行时开销,但在用户代码中创建新实例时强制执行约束:

  • 使用受保护的无参数构造函数,没有/很少的代码,以促进最快的路径实现,以及
  • 客户端代码的n-arg构造函数,包含按约束实例化新对象所需的代码.


Ste*_*n C 6

最简洁的答案是不.它不需要是空的.

但是,您需要注意,当JPA实现从持久性实现实例时,它将在no-args构造函数完成后对实例执行操作.这可能会撤消构造函数所做的事情.

要了解构造函数是否需要为空,您需要考虑在两种情况下调用构造函数.

  • 在创建"新"对象时,构造函数需要生成一个足够初始化的对象,以供普通代码使用.应该处理需要初始化为非默认状态的字段.

  • 当JPA从持久性存储中实现对象时,实现将用于"填充新构造的实例的细节".这通常会覆盖构造对象的对象状态.

当然,您的代码可能被设计为不直接使用no-args构造函数.这使得第一个场景没有实际意义,并且还使得可能发生的潜在浪费的"双重初始化"无法实现.

  • @RichardSitze - 这是一个考虑因素.但一般来说,与实现对象所花费的时间相比,花在不必要的初始化上的时间是微不足道的. (2认同)

JB *_*zet 5

更长的答案是:在大多数情况下,它不应为空。例如,假设以下实体:

@Entity
public class Team {
    @Id
    private Long id;

    @OneToMany
    private Set<Player> players;

    // getters
}
Run Code Online (Sandbox Code Playgroud)

通过JPA加载实例时,players设置永远不会为null。它可以为空,但不能为null。但是,当您创建一个新团队时,或在单元测试中使用团队实例时,也应确保该不变性。因此,该类应写为

@Entity
public class Team {
    @Id
    private Long id;

    @OneToMany
    private Set<Player> players = new HashSet<Player>(0);

    // getters
}
Run Code Online (Sandbox Code Playgroud)

相当于

@Entity
public class Team {
    @Id
    private Long id;

    @OneToMany
    private Set<Player> players;

    public Team() {
        this.players = new HashSet<Player>(0);
    }
    // getters
}
Run Code Online (Sandbox Code Playgroud)