source

지속성 중에 JPA 필드를 무시하는 가장 쉬운 방법은 무엇입니까?

factcode 2022. 11. 26. 13:53
반응형

지속성 중에 JPA 필드를 무시하는 가장 쉬운 방법은 무엇입니까?

기본적으로 특정 필드의 지속을 중지할 수 있는 "@Ignore" 유형의 주석을 찾고 있습니다.어떻게 하면 좋을까요?

@Transient 니즈에 준거합니다.

필드를 무시하려면 필드에 주석을 달아 최대 절전 모드로 매핑되지 않도록 합니다.

JSON으로 변환할 때 잭슨은 필드를 시리얼화하지 않습니다.

JPA와 JSON을 혼재시켜야 하는 경우(JPA에 의해 생략되지만 Jackson에 포함됨)는 다음과 같습니다.

@JsonInclude()
@Transient
private String token;

힌트:

JsonInclude를 사용할 수도 있습니다.포함하다.NON_NULL 및 역직렬화 중 JSON 필드 숨기기:token == null:

@JsonInclude(JsonInclude.Include.NON_NULL)
@Transient
private String token;

하려면 필드에 을 붙입니다.@Transient동면 상태로 매핑되지 않습니다.
출처:휴지 상태 주석

이 답변은 조금 늦게 오지만 응답을 완료합니다.

엔티티의 필드가 DB에 유지되는 것을 피하기 위해 다음 두 가지 메커니즘 중 하나를 사용할 수 있습니다.

@Transient - 필드를 지속 불가능으로 마크하는 JPA 주석

transient 키워드(자바).주의 - 이 키워드를 사용하면 필드가 Java의 시리얼화 메커니즘과 함께 사용되는 것을 방지할 수 있습니다.따라서 필드를 직렬화해야 할 경우 @Transient 주석만 사용하는 것이 좋습니다.

엔티티 속성 유형에 따라 여러 솔루션이 있습니다.

기본 속성

, 것이 생각해 보세요.account 삭제:

계정 테이블

account 있습니다.Account다음과 같이 합니다.

@Entity(name = "Account")
public class Account {

    @Id
    private Long id;

    @ManyToOne
    private User owner;

    private String iban;

    private long cents;

    private double interestRate;

    private Timestamp createdOn;

    @Transient
    private double dollars;

    @Transient
    private long interestCents;

    @Transient
    private double interestDollars;

    @PostLoad
    private void postLoad() {
        this.dollars = cents / 100D;

        long months = createdOn.toLocalDateTime()
            .until(LocalDateTime.now(), ChronoUnit.MONTHS);
        double interestUnrounded = ( ( interestRate / 100D ) * cents * months ) / 12;
        this.interestCents = BigDecimal.valueOf(interestUnrounded)
            .setScale(0, BigDecimal.ROUND_HALF_EVEN).longValue();

        this.interestDollars = interestCents / 100D;
    }

    //Getters and setters omitted for brevity
}

열에 열에서 수 .id,iban,cents기본 아트리뷰트입니다.

그...dollars,interestCents , , , , 입니다.interestDollars주석을 .@TransientSELECT, INSERT, UPDATE delete DELETE SQL 、 DELETE SQL 、 DELETE SQL 、 DELETE SQL の sql sql sql sql

때문에 기본에는 '아트리뷰트'를 .@Transient이치노

어소시에이션

것이 요.post ★★★★★★★★★★★★★★★★★」post_comment★★★★★★★★★★★★★★★★★★:

투고 및 투고_댓글 테이블

을 만들고 latestCommentPost 엔티티로PostComment추가된 엔티티

하려면 , 「 」를 해 주세요.@JoinFormula★★★★

@Entity(name = "Post")
@Table(name = "post")
public class Post {
 
    @Id
    private Long id;
 
    private String title;
 
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinFormula("(" +
        "SELECT pc.id " +
        "FROM post_comment pc " +
        "WHERE pc.post_id = id " +
        "ORDER BY pc.created_on DESC " +
        "LIMIT 1" +
    ")")
    private PostComment latestComment;
 
    //Getters and setters omitted for brevity
}

「 」를 할 때Post즉 엔티티, 즉 엔티티, 엔티티, 엔티티, 엔티티, 엔티티, 엔티티.latestComment수입하다, 수입하다

연관지을 는 '어소시에이션을 할 수 .@JoinFormula연결 읽기를 허용하면서 쓰기 작업을 무시합니다.

@MapsId

또 다른 은 " "를 사용하는 입니다.@MapsId.

예를 들어 다음과 같은 일대일 테이블 관계를 고려합니다.

post 및 post_details 테이블

PostDetails엔티티는 다음과 같이 매핑됩니다.

@Entity(name = "PostDetails")
@Table(name = "post_details")
public class PostDetails {
 
    @Id
    private Long id;
 
    @Column(name = "created_on")
    private Date createdOn;
 
    @Column(name = "created_by")
    private String createdBy;
 
    @OneToOne(fetch = FetchType.LAZY)
    @MapsId
    private Post post;
 
    public PostDetails() {}
 
    public PostDetails(String createdBy) {
        createdOn = new Date();
        this.createdBy = createdBy;
    }
 
    //Getters and setters omitted for brevity
}

" ""에 주의해 주세요.id 및 "Atribute"와 "Atribute"를 합니다.post은 동일한 컬럼을 이 컬럼은 '어소시에이션'입니다.post_details[프라이머리 키]

「」를 id 「」, 「」, 「Atribute」,@MapsId을 붙이면 을 알 수 있습니다.post[ association ]프라이머리 키

엔티티 컬럼을 ID를 사용할 수 .@MapsId아이디 Attribut 을 at티 。

「」를 사용합니다.insertable = false, updatable = false

하나의 은 ' 낫다'를 하는 것입니다.insertable = false, updatable = false동면하다

예를 들어, 다음과 같이 이전의 1 대 1 어소시에이션을 매핑할 수 있습니다.

@Entity(name = "PostDetails")
@Table(name = "post_details")
public class PostDetails {

    @Id
    @Column(name = "post_id")
    private Long id;

    @Column(name = "created_on")
    private Date createdOn;

    @Column(name = "created_by")
    private String createdBy;

    @OneToOne
    @JoinColumn(name = "post_id", insertable = false, updatable = false)
    private Post post;

    //Getters and setters omitted for brevity

    public void setPost(Post post) {
        this.post = post;
        if (post != null) {
            this.id = post.getId();
        }
    }
}

insertable ★★★★★★★★★★★★★★★★★」updatable@JoinColumn으로 인해 휴지 에서는 "를 하도록 지시됩니다.post가 「」를 처리하기 때문에, .post_id[프라이머리 키]

다음과 같은 경우가 있습니다.

  1. 열을 직렬화하다
  2. 열 지속 무시:

@Column(name = "columnName", insertable = false, updatable = false)

좋은 시나리오는 특정 열이 다른 열 값을 사용하여 자동으로 계산되는 경우입니다.

JPA가 필드를 무시하도록 하려면 @Transient를 사용합니다.

하지만! 잭슨은 그 필드도 연재하지 않습니다.해결하려면 @JsonProperty를 추가합니다.

@Transient
@JsonProperty
private boolean locked;

답변을 .XML 파일에는 맵핑파일이 되어 있지 .@Transient 않다transient xml .xml을 사용합니다.

<attributes>
(...)
    <transient name="field" />
</attributes>

Hibernate 5.2.10, Jersey 2.25.1 및 Jackson 2.8.9에서는 위의 답변 중 어느 것도 작동하지 않았습니다.드디어 답을 찾았습니다(hibernate4 module을 참조하고 있습니다만, 5분 동안 동작합니다).Json의 주석 중 어느 것도 이 명령어를 사용하여 동작하지 않았습니다.@Transient는 Jackson2의 「Smart 것은, 「Smart」라고 마크 되어 있는 하는 것 @Transient하고 hibernate5 모듈(disabled) 무효로 하는 것이 였습니다.USE_TRANSIENT_ANNOTATION기능을 제공합니다. 다음 중 하나:

ObjectMapper jacksonObjectMapper = new ObjectMapper();
Hibernate5Module jacksonHibernateModule = new Hibernate5Module();
jacksonHibernateModule.disable(Hibernate5Module.Feature.USE_TRANSIENT_ANNOTATION);
jacksonObjectMapper.registerModule(jacksonHibernateModule);  

Hibernate5 모듈 의존관계는 다음과 같습니다.

<dependency>
    <groupId>com.fasterxml.jackson.datatype</groupId>
    <artifactId>jackson-datatype-hibernate5</artifactId>
    <version>2.8.9</version>
</dependency>

Hibernate5 Module을 사용하면 Object Mapper를 사용하면 @Transient는 시리얼화되지 않습니다.제거하면 됩니다.

import javax.persistence.Transient;

import org.junit.Test;

import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class TransientFieldTest {

    @Test
    public void Print_Json() throws JsonProcessingException {

        ObjectMapper objectEntityMapper = new ObjectMapper();
        //objectEntityMapper.registerModule(new Hibernate5Module());
        objectEntityMapper.setSerializationInclusion(Include.NON_NULL);

        log.info("object: {}", objectEntityMapper.writeValueAsString( //
                SampleTransient.builder()
                               .id("id")
                               .transientField("transientField")
                               .build()));

    }

    @Getter
    @Setter
    @Builder
    private static class SampleTransient {

        private String id;

        @Transient
        private String transientField;

        private String nullField;

    }
}

언급URL : https://stackoverflow.com/questions/1281952/what-is-the-easiest-way-to-ignore-a-jpa-field-during-persistence

반응형