[java] 지속성 동안 JPA 필드를 무시하는 가장 쉬운 방법은 무엇입니까?

본질적으로 특정 필드가 유지되는 것을 막을 수있는 “@ 무시”유형 주석을 찾고 있습니다. 이것이 어떻게 달성 될 수 있습니까?



답변

@Transient 당신의 요구를 준수합니다.


답변

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

하지만 잭슨은 직렬화되지 않습니다 JSON으로 변환 할 때 필드.

JPA와 JSON을 혼합해야하는 경우 (JPA에서는 생략했지만 여전히 Jackson에 포함) 다음을 사용하십시오 @JsonInclude.

@JsonInclude()
@Transient
private String token;

팁:

다음 과 같은 경우 JsonInclude.Include.NON_NULL 을 사용하여 역 직렬화 중에 JSON에서 필드를 숨길 수도 있습니다 token == null.

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


답변

필드를 무시하려면 필드에 주석을 달아서 @Transient최대 절전 모드로 매핑되지 않습니다.
출처 : 최대 절전 모드 주석 .


답변

이 답변은 약간 늦었지만 답변을 완료했습니다.

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

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

자바의 임시 키워드. 이 키워드를 사용하면 필드가 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 SQL 문에서 제외 할 수 있습니다.

따라서 기본 속성의 @Transient경우 주어진 속성이 유지되지 않도록 제외하기 위해 사용해야 합니다.

계산 된 엔터티 속성에 대한 자세한 내용은 이 문서를 확인 하십시오 .

협회

다음 postpost_comment테이블 이 있다고 가정합니다 .

post 및 post_comment 테이블

엔터티 의 lastestComment연결을 추가 된 Post최신 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속성과 post연결 모두 post_details기본 키 열인 동일한 데이터베이스 열을 매핑합니다 .

id속성 을 제외하기 위해 @MapsId어노테이션은 post연관이 테이블 기본 키 열 값을 처리 함을 Hibernate에게 알려 줍니다.

따라서 엔티티 ID와 연관이 동일한 열을 공유하는 @MapsId경우 엔티티 ID 속성을 무시하고 대신 연관을 사용할 수 있습니다.

자세한 내용은 이 기사를@MapsId 확인 하십시오 .

사용 insertable = false, updatable = false

또 다른 옵션은 insertable = false, updatable = false최대 절전 모드에서 무시하려는 연결에 사용하는 것입니다.

예를 들어, 이전의 일대일 연관을 다음과 같이 맵핑 할 수 있습니다.

@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();
        }
    }
}

엔티티 식별자가 기본 키 열을 처리하므로 주석 의 insertableupdatable속성은 @JoinColumnHibernate에게 post연결 을 무시하도록 지시 post_id합니다.


답변

위의 답변을 완료하려면, 나는 XML 매핑 파일을 사용하는 경우가 있었다 어디 어느 것도 @Transient아니다 transient내가 xml 파일에 과도 정보를 넣어했다 … 일 :

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


답변

위의 답변 중 어느 것도 Hibernate 5.2.10, Jersey 2.25.1 및 Jackson 2.8.9를 사용하여 효과가 없었습니다. 나는 마침내 대답을 찾았습니다 ( 여기 , 그들은 hibernate4module을 참조하지만 5에서도 작동합니다) . Json 주석은 전혀 작동하지 않았습니다 @Transient. 분명히 Jackson2는 @Transient명시 적으로 지시하지 않는 한 표시가있는 것을 친절하게 무시할만큼 ‘스마트’ 합니다. 열쇠는 hibernate5 모듈 (다른 Hibernate 주석을 처리하는 데 사용했던)을 추가하고 USE_TRANSIENT_ANNOTATIONJersey 응용 프로그램에서 기능을 비활성화하는 것입니다.

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

Hibernate5Module의 종속성은 다음과 같습니다.

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