Lombok @Builder 및 JPA 기본 생성자
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
갱신필
피드백과 존의 답변을 바탕으로 더 이상 사용하지 않겠다는 답변을 업데이트했습니다.@Tolerate
또는@Data
대신 접근자 및 변이자를 만듭니다.@Getter
그리고.@Setter
, 를 사용하여 기본 컨스트럭터를 만듭니다.@NoArgsConstructor
마지막으로 빌더가 필요로 하는 모든 args 컨스트럭터를 만듭니다.@AllArgsConstructor
.
빌더 패턴을 사용하고 싶기 때문에 컨스트럭터와 뮤테이터 메서드의 가시성을 제한하고 싶다고 생각합니다.이를 실현하기 위해 델에서는package private
경유로access
의 속성@NoArgsConstructor
그리고.@AllArgsConstructor
주석 및value
의 속성@Setter
주석입니다.
중요한
올바르게 덮어쓰는 것을 잊지 마세요.toString
,equals
,그리고.hashCode
상세한 것에 대하여는, Vlad Mihalcea의 다음의 투고를 참조해 주세요.
- best-way-to-code-and-to-string-with-jpa-and-certificate
- how-to-display-code-using-the-jpa-display-identifier
- 휴지 상태, 휴지 상태, 휴지 상태, 휴지 상태, 휴지 상태 코드
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
:
사용.@Tolerate
noarg 컨스트럭터를 추가할 수 있도록 했습니다.
빌더 패턴을 사용하고 싶기 때문에 세터 방식의 가시성을 제어하고 싶다고 생각합니다.
그@Data
주석으로 인해 생성된 세터가 생성됩니다.public
, 적용하다@Setter(value = AccessLevel.PROTECTED)
들판으로 가는 것은 그들을 만든다.protected
.
올바르게 덮어쓰는 것을 잊지 마세요.toString
,equals
,그리고.hashCode
상세한 것에 대하여는, Vlad Mihalcea의 다음의 투고를 참조해 주세요.
- best-way-to-code-and-to-string-with-jpa-and-certificate
- how-to-display-code-using-the-jpa-display-identifier
- 휴지 상태, 휴지 상태, 휴지 상태, 휴지 상태, 휴지 상태 코드
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());
}
}
또한 다음과 같이 명시적으로 해결할 수 있습니다.@Data @Builder @NoArgsConstructor @AllArgsConstructor
클래스 정의에서 결합됩니다.
여기서는 주석 순서가 중요한 것 같습니다.주석은 같지만 순서가 다르면 코드를 사용할 수도 있고 사용할 수도 없습니다.
동작하지 않는 예를 다음에 나타냅니다.
@AllArgsConstructor
@Builder
@Data
@Entity
@EqualsAndHashCode
@NoArgsConstructor
@RequiredArgsConstructor
@Table
@ToString
public class Person implements Serializable {
private String name;
}
다음은 작동 예를 제시하겠습니다.
@Builder
@Data
@Entity
@EqualsAndHashCode
@AllArgsConstructor
@NoArgsConstructor
@RequiredArgsConstructor
@Table
@ToString
public class Person implements Serializable {
private String name;
}
맨 위에 @Builder 주석이 있는지 확인하십시오.이 경우 주석을 알파벳 순으로 정렬하려고 이 오류가 발생했습니다.
주석이 롬복일 경우.컨스트럭터 및 javax.validation.constraints에서 허용됩니다.일부 속성에서는 Not Null이 동시에 사용됩니다.Sonarqube는 이를 중대한 오류로 마킹합니다.PROPERTY는 "javax.validation.constraints"로 마킹됩니다.Not Null"이지만 이 생성자에서는 초기화되지 않았습니다.
프로젝트가 JPA와 함께 SpringData를 사용하는 경우 org.springframework.data.notation을 사용하여 해결할 수 있습니다.PersistenceConstructor(스프링 주석, JPA 아님)
그러면 Lombok과 조합하여 다음과 같이 주석을 달 수 있습니다.
@RequiredArgsConstructor(onConstructor = @__(@PersistenceConstructor))
Lombok Builder의 경우 다음 항목도 추가해야 합니다.
@Builder
@AllArgsConstructor
다음 조합을 사용하려면
- 롬복
- JPA
- 크러드
@EqualsAndHashCode
- 불변성 - 최종 공개 필드
- 노게터
- 셋터 없음
- 의한
@Builder
★★★★★★★★★★★★★★★★★」@With
사용:
//Lombok & JPA
//https://stackoverflow.com/questions/34241718/lombok-builder-and-jpa-default-constructor
//Mandatory in conjunction with JPA: an equal based on fields is not desired
@lombok.EqualsAndHashCode(onlyExplicitlyIncluded = true)
//Mandatory in conjunction with JPA: force is needed to generate default values for final fields, that will be overriden by JPA
@lombok.NoArgsConstructor(access = AccessLevel.PRIVATE, force = true)
//Hides the constructor to force usage of the Builder.
@lombok.AllArgsConstructor(access = AccessLevel.PRIVATE)
@lombok.ToString
//Good to just modify some values
@lombok.With
//Mandatory in conjunction with JPA: Some suggest that the Builder should be above Entity - https://stackoverflow.com/a/52048267/99248
//Good to be used to modify all values
@lombok.Builder(toBuilder = true)
//final fields needed for imutability, the default access to public - since are final is safe
@lombok.experimental.FieldDefaults(makeFinal = true, level = AccessLevel.PUBLIC)
//no getters and setters
@lombok.Getter(value = AccessLevel.NONE)
@lombok.Setter(value = AccessLevel.NONE)
//JPA
@javax.persistence.Entity
@javax.persistence.Table(name = "PERSON_WITH_MOTTO")
//jpa should use field access
@javax.persistence.Access(AccessType.FIELD)
public class Person {
@javax.persistence.Id
@javax.persistence.GeneratedValue
//Used also automatically as JPA
@lombok.EqualsAndHashCode.Include
Long id;
String name;
String motto;
}
「」를 사용합니다.@NoArgsConstructor
★★★★★★★★★★★★★★★★★」@AllArgsContructor
하는 데 .@Builder
예
@Entity
@Builder
@NoArgsConstructor
@AllArgsContructor
class Person {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
}
그 이유는@Builder
에는 모든 인수 생성자가 필요하며 기본 생성자만 지정하면 문제가 발생합니다.
자세한 설명은 https://github.com/rzwitserloot/lombok/issues/1389#issuecomment-369404719 입니다.
저는 이 모든 주석을 사용하여 이 문제를 해결했습니다.
@Data
@Builder
@AllArgsConstructor(access = AccessLevel.PACKAGE)
@NoArgsConstructor(access = AccessLevel.PACKAGE)
Jeff의 답변은 정상적으로 동작하지만, @Builder는 아직 자기 참조 관계를 지원하지 않습니다.
상세한 것에 대하여는, 다음의 질문을 참조해 주세요.
JPA @Onto두 열이 null이 아닌 하나의 자체 참조 관계입니다.
언급URL : https://stackoverflow.com/questions/34241718/lombok-builder-and-jpa-default-constructor
'programing' 카테고리의 다른 글
MySQL 쿼리에서 IF ELSE 문을 쓰는 방법 (0) | 2023.02.06 |
---|---|
소수점 두 자리로 플로트를 표시하는 방법은 무엇입니까? (0) | 2023.02.06 |
자동 완성을 위해 MYSQL과 PHP의 회사 이름을 애매하게 일치시키는 방법은 무엇입니까? (0) | 2023.02.02 |
네임스페이스가 뭐죠? (0) | 2023.02.02 |
포함할 PHP pass 변수 (0) | 2023.02.02 |