当前位置: 首页 > 面试题库 >

Lombok @Builder和JPA默认构造函数

洪永长
2023-03-14
问题内容

我正在将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创建默认构造函数via@NoArgsConstructor,最后我们创建了构建器通过via所需的所有args构造函数@AllArgsConstructor

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

重要

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

  • 最佳的实现方式,将哈希码和字符串与jpa并休眠
  • 如何使用jpa实体标识符实现等于和哈希码
  • 休眠事实等于哈希码
    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的以下帖子:

  • 最佳的实现方式,将哈希码和字符串与jpa并休眠
  • 如何使用jpa实体标识符实现等于和哈希码
  • 休眠事实等于哈希码
    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());
        }
    }


 类似资料:
  • 我使用默认构造函数从子类中设置recordId的值,最初没有使用lombok。最终我决定在这里使用构建器,但现在的问题是lombok构建器在内部覆盖了我的默认构建器,因此从未设置值。

  • 我将Lombok项目与Spring Data JPA一起使用。有没有办法将Lombok与JPA默认构造函数连接起来? 代码: 据我所知,JPA需要默认构造函数,该构造函数由注释覆盖。有什么解决办法吗? 这段代码给我错误:< code > org . hibernate . instantiation exception:entity::app . domain . model . person没有

  • 正如JPA所要求的,类应该有一个默认的(非参数)构造函数,以便在从数据库检索对象时实例化它们。 在Kotlin中,属性在主构造函数内声明非常方便,如下例所示: 但是当非arg构造函数被声明为次要构造函数时,它需要传递主构造函数的值,因此它们需要一些有效的值,如下所示: 如果属性具有比和更复杂的类型,并且它们是不可为空的,那么为它们提供值看起来是非常糟糕的,特别是当主构造函数和块中有很多代码,并且当

  • 问题内容: 不知何故,在下面的Node类中,and变量在Node的所有实例之间共享。 有什么办法可以让我继续使用构造函数参数的默认值(在这种情况下为空列表),但要同时获取它们和拥有其自身的变量以及变量? 我正在使用python 3.1.2。 问题答案: 可变的默认参数通常不会执行您想要的操作。相反,请尝试以下操作:

  • 问题内容: 我有一个对象 我用两种方式初始化它 这是输出 似乎builder没有获得默认值。我在属性中添加了注释,对象现在看起来像这样 这是控制台输出 我怎样才能使他们俩都成为? 问题答案: 我的猜测是,这是不可能的(没有删除代码)。但是,为什么不仅仅实现所需的构造函数呢?Lombok旨在使您的生活更轻松,如果Lombok无法解决某些问题,请按照老式的方式进行操作。 控制台输出:

  • 问题内容: 默认构造函数到底是什么?你能告诉我以下哪个是默认构造函数,它与其他构造函数有何不同? 问题答案: 他们都不是。如果定义,则不是默认值。 除非你定义另一个构造函数,否则默认构造函数是自动生成的无参数构造函数。任何未初始化的字段都将设置为其默认值。对于你的榜样,它看起来像这样假设的类型String,int以及int,那类本身是公共的: 这与 完全没有构造函数。但是,如果定义至少一个构造函数