दृढ़ता के दौरान एक जेपीए क्षेत्र को अनदेखा करने का सबसे आसान तरीका क्या है?


281

मैं अनिवार्य रूप से एक "@Ignore" प्रकार एनोटेशन की तलाश कर रहा हूं जिसके साथ मैं किसी विशेष क्षेत्र को बनाए रखने से रोक सकता हूं। यह कैसे हासिल किया जा सकता है?

जवाबों:


450

@Transient अपनी आवश्यकताओं का अनुपालन करता है।


20
लेकिन तब जैक्सन JSON को परिवर्तित करते समय क्षेत्र को क्रमबद्ध नहीं करेगा ... कैसे हल करें?
मोबाइलमोन

यह आपके एप के डिसिंग पर निर्भर करता है। यदि आप अपनी इकाई वर्ग को एनोटेट करते हैं - यह हर जगह लागू होता है; लेकिन अगर आप इकाई का उपयोग करने वाले डाओ को एनोटेट करते हैं - यह एक और कहानी है। संक्षेप में: जब आपके पास कई भंडार हों तो DAO का उपयोग करें
Andrii Plotnikov

सूची फ़ील्ड पर काम नहीं करता है। संग्रह प्रकार फ़ील्ड के लिए, हाइबरनेट वास्तव में एक नया मध्यवर्ती तालिका बनाता है। उसके लिए कोई वर्कअराउंड?
zulkarnain shah

@MobileMon आप इसे हल कर सकते हैं, मेरा उत्तर जाँच stackoverflow.com/a/41850392/3871754
कामिल Nekanowicz

@MobileMon अधिमानतः आप डेटाबेस और एपीआई उद्देश्यों (एकल जिम्मेदारी) दोनों के लिए एक ही इकाई का उपयोग नहीं करना चाहिए।
जसेक ok आलिमोक

127

किसी फ़ील्ड को अनदेखा करने के लिए, उसे एनोटेट करें @Transientताकि उसे हाइबरनेट द्वारा मैप न किया जा सके।

लेकिन तब जैक्सन JSON में परिवर्तित होने पर क्षेत्र को क्रमबद्ध नहीं करेगा

आप JSON साथ जेपीए मिश्रण की जरूरत है (जेपीए द्वारा छोड़ देते हैं, लेकिन अभी भी जैक्सन में शामिल हैं) का उपयोग करें @JsonInclude:

@JsonInclude()
@Transient
private String token;

सुझाव:

आप JsonInclude.Include.NON_NULL का उपयोग भी कर सकते हैं और डीसरीकरण के दौरान JSON में फ़ील्ड छिपा सकते हैं token == null:

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

3
मैं JAX-RS 2.0.1 / जर्सी 2.25.1 / जैक्सन 2.8.7 चला रहा हूं और इसके साथ ही स्टैक @JsonIncludeआवश्यक नहीं है: @Transientफ़ील्ड अभी भी JSON में शामिल हैं। (आपने अभी भी मेरा वोट प्राप्त किया है: तकनीक स्वयं अन्य परिस्थितियों में बहुत उपयोगी हो सकती है)।
DKroot

2
मैंने इसे स्प्रिंग बूट पर किया
कामिल नेकानोविच ने

नमस्ते, मैं इस का उपयोग करने की कोशिश कर रहा हूँ, लेकिन यह @ क्षेत्र के साथ धारावाहिक नहीं हो रहा है
मोहम्मद

@ मोहम्मद ने एनोटेशन जोड़ा @JsonInclude ()
Kamil Nekanowicz

स्प्रिंग बूट 2.1.7 में यह कोशिश की, लेकिन काम नहीं किया। लेकिन फिर भी आपको मेरा वोट मिलता है क्योंकि यह अन्य परिदृश्यों में काम कर सकता है।
आदित्य एकबोटे


19

यह उत्तर थोड़ी देर से आता है, लेकिन यह प्रतिक्रिया को पूरा करता है।

एक इकाई से एक क्षेत्र को डीबी में बनाए रखने के लिए दो तंत्रों में से एक का उपयोग करने के लिए:

@ ट्रैंसिएंट - जेपीए एनोटेशन एक क्षेत्र के रूप में चिह्नित करने योग्य नहीं है

जावा में क्षणिक खोजशब्द। खबरदार - इस कीवर्ड का उपयोग करने से, जावा से किसी भी क्रमिक तंत्र के साथ उपयोग किए जाने वाले क्षेत्र को रोका जा सकेगा। इसलिए, यदि क्षेत्र को क्रमबद्ध किया जाना चाहिए तो आप सिर्फ @ ट्रांसेन्ट एनोटेशनका बेहतर उपयोग करेंगे


1
कैसे के बारे में मैं सिर्फ पाने के तरीके पर दृढ़ता को अनदेखा करना चाहता हूँ ?. उदाहरण के लिए: myjparepository.save () wil मॉडल को हमेशा की तरह सहेजता है, और myjparepository.find (id) उस फ़ील्ड को अनदेखा कर देगा जो मुझे चाहिए?
xtiger

@xtiger आप उस कार्यक्षमता को संग्रहीत करने के लिए एक कस्टम क्वेरी बना सकते हैं। यहां एक उदाहरण लिंक है
मोहले

7

इकाई विशेषता प्रकार के आधार पर कई समाधान हैं।

मूल गुण

निम्नलिखित 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उनका चयन, सम्मिलित करें, अपडेट करें और हटाएं SQL कथन से बाहर करने के लिए।

इसलिए, मूलभूत विशेषताओं के लिए, आपको @Transientदी गई संपत्ति को बनाए रखने से बाहर रखने के लिए उपयोग करने की आवश्यकता है ।

गणना की गई इकाई विशेषताओं के बारे में अधिक जानकारी के लिए, इस लेख को देखें

संघों

मान लें कि आपके पास निम्नलिखित postऔर post_commentटेबल हैं:

पोस्ट और पोस्ट_कॉममेंट टेबल

आप इकाई में नवीनतम इकाई के लिए lastestCommentएसोसिएशन को मैप करना चाहते हैं जिसे जोड़ा गया था।PostPostComment

ऐसा करने के लिए, आप @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एसोसिएशन तालिका का ध्यान रखता है प्राथमिक कुंजी स्तंभ मान।

इसलिए, जब इकाई पहचानकर्ता और एक एसोसिएशन समान कॉलम साझा करते हैं, तो आप @MapsIdइकाई पहचानकर्ता विशेषता को अनदेखा करने के लिए उपयोग कर सकते हैं और इसके बजाय एसोसिएशन का उपयोग कर सकते हैं ।

के बारे में अधिक जानकारी के लिए @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();
        }
    }
}

insertableऔर updatableकी विशेषताओं @JoinColumnएनोटेशन की अनदेखी करने के हाइबरनेट निर्देश देगा postइकाई पहचानकर्ता का ख्याल रखता है के बाद से संघ post_idप्राथमिक कुंजी स्तंभ।


ध्यान दें कि दोनों आईडी विशेषता और पोस्ट एसोसिएशन एक ही डेटाबेस कॉलम को मैप करते हैं, जो कि पोस्ट_कॉममेंट प्राथमिक कुंजी कॉलम है। क्या यह उदाहरण के रूप में postऔर post_detailsतालिकाओं के संदर्भ में सही है ?
डेविड

1
इसे जगह देने के लिए धन्यवाद। मैंने ठीक कर दिया।
व्लाद मिहालसी

3

इसके बाद के संस्करण जवाब पूरा करने के लिए, मैं मामले में एक XML मैपिंग फ़ाइल का उपयोग करते हुए किया था जहां न तो @Transientहै और न ही transientकाम किया ... मैं xml फ़ाइल में क्षणिक जानकारी डाल करने के लिए किया था:

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

2

उपरोक्त उत्तरों में से किसी ने भी मेरे लिए हाइबरनेट 5.2.10, जर्सी 2.25.1 और जैक्सन 2.8.9 का उपयोग करके काम किया। मुझे अंत में उत्तर मिला (जैसे, वे हाइबरनेट 4module का संदर्भ देते हैं लेकिन यह यहां भी 5 के लिए काम करता है) । जोंस के किसी भी एनोटेशन ने बिल्कुल भी काम नहीं किया @Transient। जाहिरा तौर पर जैक्सन 2 'स्मार्ट' है, @Transientजब तक आप स्पष्ट रूप से इसे नहीं बताएंगे, तब तक कृपया उस पर ध्यान न दें। कुंजी हाइबरनेट 5 मॉड्यूल को जोड़ने के लिए थी (जिसका उपयोग मैं अन्य हाइबरनेट एनोटेशन से निपटने के लिए कर रहा था) और USE_TRANSIENT_ANNOTATIONअपने जर्सी एप्लिकेशन में सुविधा को अक्षम कर रहा हूं:

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>

ऊपर वर्णित हर दूसरे तरीके की कोशिश करने के बाद और @JsonProperty @JsonInclude @JsonSerialize + @JsonDeserialize mapper.configure(MapperFeature.PROPAGATE_TRANSIENT_MARKER, false));इस समाधान ने आखिरकार काम किया। धन्यवाद!
ऐसोलाइन

1

कभी-कभी आप चाहते हैं:

  1. एक कॉलम को सीरीज़ करें
  2. स्तंभ को बनाए रखने से अनदेखा करें:

उपयोग @Column(name = "columnName", insertable = false, updatable = false)

एक अच्छा परिदृश्य तब होता है जब एक निश्चित स्तंभ की गणना स्वचालित रूप से अन्य स्तंभ मानों का उपयोग करके की जाती है

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.