본질적으로 특정 필드가 유지되는 것을 막을 수있는 “@ 무시”유형 주석을 찾고 있습니다. 이것이 어떻게 달성 될 수 있습니까?
답변
@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
당신이 그들을 주석, 그래서 특성을 계산 @Transient
SELECT, INSERT, UPDATE 및 DELETE SQL 문에서 제외 할 수 있습니다.
따라서 기본 속성의
@Transient
경우 주어진 속성이 유지되지 않도록 제외하기 위해 사용해야 합니다.
협회
다음 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
입니다.
예를 들어, 다음의 일대일 테이블 관계를 고려하십시오.
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 속성을 무시하고 대신 연관을 사용할 수 있습니다.
사용 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();
}
}
}
엔티티 식별자가 기본 키 열을 처리하므로 주석 의 insertable
및 updatable
속성은 @JoinColumn
Hibernate에게 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_ANNOTATION
Jersey 응용 프로그램에서 기능을 비활성화하는 것입니다.
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>