opt*_*lic 7 java hibernate jpa lombok
我有@Entity20 个字段,包括索引和由 Hibernate 更新的时间戳:
@Entity
public class MyEntity {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@UpdateTimestamp
private LocalDateTime updatedTime;
private String ....
private String ....
Run Code Online (Sandbox Code Playgroud)
我有一个 Hibernate 的默认构造函数和一个辅助构造函数来设置除 id 和 UpdatedTime 之外的所有内容。
我不需要(或想要)id 或updatedTime 的setter,因为我只希望Hibernate 设置它们,并且它通过反射来实现。
我想尝试一下 Lombok,看看是否可以避免这里涉及的大量样板,但@Data添加了 getter 和 setter,并且不创建相同的构造函数。
我还担心 Lomboks 生成的 equals/hashCode 和 toString 方法可能会导致 Hibernate 出现微妙的问题。
这意味着我必须结合使用其他 Lombok 注释来执行此操作。
如何像这样使用 Lombok 安全地创建实体?
我是否必须混合使用注释和手动方法?
一些 lombok 注释例如@EqualsAndHashCode和@ToString有Exclude选项。但两者都没有@Data类似@AllArgsConstructor的选择。但会为尚未定义 setter 的@Data所有字段生成 setter 。因此,您可以为必填字段定义一个设置器,如下所示,但它不执行任何操作。
private void setId(Long id) {
// Do nothing
}
Run Code Online (Sandbox Code Playgroud)
@AllArgsConstructor您可以使用代替@RequiredArgsConstructor,但可以使用 注释构造函数中的所有字段@NonNull(或者该字段应该是最终字段)。
请参阅此答案以获得RequiredArgsConstructor。
我建议的方法:另一种方法是使用@Builder注释与@AllArgsConstructor(access = AccessLevel.PRIVATE). (注意:默认情况下,Builder 添加一个私有的所有参数构造函数,但只有在没有其他构造函数时才会这样做。但在您的情况下,存在默认构造函数,您需要显式提及所有参数注释。)
这将阻止从外部使用构造函数,但同时允许您使用构建器创建对象。此时,您可以将值设置为id并updateTime使用构建器。为了防止这种情况,您还需要添加以下代码。
public static class MyEntityBuilder {
// access is restricted using
// these private dummy methods.
private MyEntityBuilder id(Long id) {
return this;
}
private MyEntityBuilder updateTime(LocalDateTime time) {
return this;
}
}
Run Code Online (Sandbox Code Playgroud)
因此,即使不可能直接实现您的要求,您也可以通过在构建器类中添加两个虚拟 setter 方法和另外两个虚拟方法来实现。
我们有 @NoArgsConstructor @AllArgsConstructor 用于使用 lombok 生成构造函数。
这就是我创建它们的方式。
@Entity
@Table(schema = "S25", name = "bank")
@NoArgsConstructor
@AllArgsConstructor
@ToString
@Getter
@Setter
public class Bank {
@Id
@SequenceGenerator(name = "bankEntitySeq", sequenceName = "SEQ_BANKS", allocationSize = 1)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "bankSeq")
@Column(name = "bank_id")
private Long bankId;
@Column(name = "bank_name")
private String bankName;
@Column(name = "created_on")
private Date createdOn =
new Date(); //Date.from(Instant.now().atZone(ZoneId.of("UTC")).toInstant());
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
22105 次 |
| 最近记录: |