Lombok @Builder和JPA默认构造函数

克尔扎科夫:

我正在将Lombok项目与Spring Data JPA一起使用。有什么方法可以将Lombok @Builder与JPA默认构造函数连接

码:

@Entity 
@Builder
class Person {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
}

据我所知,JPA需要默认构造函数,该构造函数会被@Builder注释覆盖有什么解决方法吗?

这段代码给我错误: org.hibernate.InstantiationException: No default constructor for entity: : app.domain.model.Person

杰夫:

更新

根据反馈和John的回答,我已更新了不再使用@Tolerateor 的答案@Data,而是通过@Getter创建访问器和变异器,通过@Setter创建默认构造函数@NoArgsConstructor,最后,通过构建器创建了构建器所需的所有args构造函数@AllArgsConstructor

因为您想使用构建器模式,所以我想您想限制构造函数和mutators方法的可见性。为此,我们package private通过注释上的属性以及注释上的access属性将可见性设置为@NoArgsConstructor@AllArgsConstructorvalue@Setter

重要

记住要正确重写toStringequalshashCode有关详细信息,请参见Vlad Mihalcea的以下帖子:

package com.stackoverflow.SO34299054;

import static org.junit.Assert.*;

import java.util.Random;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

import org.junit.Test;

import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

@SuppressWarnings("javadoc")
public class Answer {

    @Entity
    @Builder(toBuilder = true)
    @AllArgsConstructor(access = AccessLevel.PACKAGE)
    @NoArgsConstructor(access = AccessLevel.PACKAGE)
    @Setter(value = AccessLevel.PACKAGE)
    @Getter
    public static class Person {

        @Id
        @GeneratedValue(strategy = GenerationType.AUTO)
        private Long id;

        /*
         * IMPORTANT:
         * Set toString, equals, and hashCode as described in these
         * documents:
         * - https://vladmihalcea.com/the-best-way-to-implement-equals-hashcode-and-tostring-with-jpa-and-hibernate/
         * - https://vladmihalcea.com/how-to-implement-equals-and-hashcode-using-the-jpa-entity-identifier/
         * - https://vladmihalcea.com/hibernate-facts-equals-and-hashcode/
         */
    }

    /**
     * Test person builder.
     */
    @Test
    public void testPersonBuilder() {

        final Long expectedId = new Random().nextLong();
        final Person fromBuilder = Person.builder()
            .id(expectedId)
            .build();
        assertEquals(expectedId, fromBuilder.getId());

    }

    /**
     * Test person constructor.
     */
    @Test
    public void testPersonConstructor() {

        final Long expectedId = new Random().nextLong();
        final Person fromNoArgConstructor = new Person();
        fromNoArgConstructor.setId(expectedId);
        assertEquals(expectedId, fromNoArgConstructor.getId());
    }
}

使用@Tolerate和的旧版本@Data

使用@Toleratework允许添加noarg构造函数。

因为您想使用构建器模式,所以我想您想控制setter方法的可见性。

@Data注解使得生成的制定者public,应用@Setter(value = AccessLevel.PROTECTED)的领域,因此他们protected

记住要正确重写toStringequalshashCode有关详细信息,请参见Vlad Mihalcea的以下帖子:

package lombok.javac.handlers.stackoverflow;

import static org.junit.Assert.*;

import java.util.Random;

import javax.persistence.GenerationType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;

import lombok.AccessLevel;
import lombok.Builder;
import lombok.Data;
import lombok.Setter;
import lombok.experimental.Tolerate;

import org.junit.Test;

public class So34241718 {

    @Builder
    @Data
    public static class Person {

        @Id
        @GeneratedValue(strategy = GenerationType.AUTO)
        @Setter(value = AccessLevel.PROTECTED)
        Long id;

        @Tolerate
        Person() {}

       /* IMPORTANT:
          Override toString, equals, and hashCode as described in these 
          documents:
          - https://vladmihalcea.com/the-best-way-to-implement-equals-hashcode-and-tostring-with-jpa-and-hibernate/
          - https://vladmihalcea.com/how-to-implement-equals-and-hashcode-using-the-jpa-entity-identifier/
          - https://vladmihalcea.com/hibernate-facts-equals-and-hashcode/
          */
    }

    @Test
    public void testPersonBuilder() {

        Long expectedId = new Random().nextLong();
        final Person fromBuilder = Person.builder()
            .id(expectedId)
            .build();
        assertEquals(expectedId, fromBuilder.getId());

    }

    @Test
    public void testPersonConstructor() {

        Long expectedId = new Random().nextLong();
        final Person fromNoArgConstructor = new Person();
        fromNoArgConstructor .setId(expectedId);
        assertEquals(expectedId, fromNoArgConstructor.getId());
    }
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

不同的构造函数(LOMBOK)

Lombok Builder和Jackson的默认值

为什么在使用默认构造函数创建对象时,Lombok的@Builder会删除默认字段值?

Lombok Builder可以处理可能引发异常的构造函数吗?

在构造函数注释中使用builder(lombok)时出错

使用Lombok Builder注入构造函数依赖项

捕获?使用Lombok Builder

Lombok @Builder的必需参数

@Builder Lombok - 继承

Lombok和Spock:@RequiredArgsConstructor不会为具有接口类型的字段隐藏默认的无参数构造函数

Jackson2和Lombok @Builder

Lombok builder()方法未显示

lombok @Builder类型转换错误

从 Lombok @Builder 中排除 toString()

为什么在Lombok的@Builder中有包私有构造函数?

在子类的构造函数上使用时,lombok @Builder(toBuilder = true)编译错误

Lombok的@NonNull注释是否允许默认构造函数提供空值?

杰克逊反序列化失败,因为lombok创建了非默认构造函数

如何通过Spring Boot使用Lombok访问JPA实体的Builder()?

使用lombok生成参数接受其他参数的构造函数

如何在构造函数上使用 lombok 的 @Tolerate

在Intellij中查找lombok生成的构造函数的用法

Lombok:RequiredArgsConstructor 在生成构造函数时出错

找不到派生类的 Lombok 构造函数

Stacktrace中包含的Lombok Builder异常

Lombok @Builder - 对性能有好处吗?

自定义Lombok生成的Builder

IntelliJ 14 + Lombok插件+ @Builder =错误

Lombok @Builder未初始化集合