অধ্যবসায় চলাকালীন জেপিএ ক্ষেত্রটিকে উপেক্ষা করার সহজ উপায় কী?


281

আমি মূলত একটি "@ উপেক্ষা করুন" প্রকারের টীকাটি খুঁজছি যার সাহায্যে আমি একটি নির্দিষ্ট ক্ষেত্রকে স্থির রাখতে বাধা দিতে পারি। কিভাবে এটা অর্জন করা যেতে পারে?

উত্তর:


450

@Transient আপনার প্রয়োজন মেনে চলা।


20
তবে জ্যাকসন জেএসএনে রূপান্তর করার সময় মাঠকে সিরিয়াল করবেন না ... কীভাবে সমাধান করবেন?
মোবাইলমন

এটি আপনার অ্যাপ্লিকেশন ডেসিংয়ের উপর নির্ভর করে। যদি আপনি নিজের সত্তা শ্রেণিকে টীকায়িত করেন - এটি সর্বত্র প্রযোজ্য; তবে আপনি যদি সত্তা ব্যবহার করেন এমন দাওকে anotate করেন - এটি অন্য গল্প। সংক্ষেপে: আপনার একাধিক স্টোর থাকলে ডিএও ব্যবহার করুন
আন্দ্রেই প্লটনিকিকভ

তালিকার ক্ষেত্রগুলিতে কাজ করে না। সংগ্রহের ধরণের ক্ষেত্রগুলির জন্য, হাইবারনেট আসলে একটি নতুন মধ্যবর্তী টেবিল তৈরি করে। তার জন্য কোনও কর্মসূচী?
জুলকরনাইন শাহ

@MobileMon আপনি এটা সমাধান করতে পারে, আমার উত্তর চেক stackoverflow.com/a/41850392/3871754
কামিল Nekanowicz

@ মোটরমন: আপনার ডাটাবেস এবং এপিআই উভয় উদ্দেশ্যে (একক দায়বদ্ধতা) জন্য একই সত্তা ব্যবহার করা উচিত নয়।
জাসেক ইলিমোক

127

কোনও ক্ষেত্রকে অগ্রাহ্য করতে, এটিকে এনারেট করুন @Transientযাতে এটি হাইবারনেট দ্বারা ম্যাপ করা যায় না।

তবে জ্যাকসন জেএসএনে রূপান্তর করার সময় ক্ষেত্রটিকে সিরিয়ালাইজ করবেন না

আপনার যদি জেএসএনের সাথে জেপিএ মিশ্রণের প্রয়োজন হয় (জেপিএ বাদ দিয়ে তবে জ্যাকসনের মধ্যে অন্তর্ভুক্ত) ব্যবহার করুন @JsonInclude:

@JsonInclude()
@Transient
private String token;

পরামর্শ:

আপনি জেসনআইনক্লিউডও অন্তর্ভুক্ত করুন ONনোন_নুল এবং ডিএসরিয়ালেসনের সময় জেএসএন-তে ক্ষেত্রগুলি লুকিয়ে রাখতে পারেন যখন token == null:

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

3
আমি জ্যাক্স-আরএস ২.০.১ / জার্সি ২.২৫.১ / জ্যাকসন ২.৮. running চালাচ্ছি এবং সেই স্ট্যাকটি @JsonIncludeপ্রয়োজনীয় নয়: @Transientক্ষেত্রগুলি এখনও জেএসএনে অন্তর্ভুক্ত রয়েছে। (আপনি এখনও আমার ভোট পেয়েছেন: কৌশলটি নিজেও অন্যান্য পরিস্থিতিতে খুব কার্যকর হতে পারে)।
DKroot

2
আমি স্প্রিং
বুটে

হাই, আমি এটি ব্যবহারের চেষ্টা করছি, তবে এটি @ ট্রান্সিয়েন্ট ক্ষেত্রের সাথে সিরিয়ালযুক্ত হচ্ছে না
মোহাম্মদ

@ মোহাম্মদ টীকা যোগ করুন @ জসনআইনক্লুড ()
কামিল নেকানোভিজ

স্প্রিং বুট ২.১..7 এ এটি ব্যবহার করে দেখুন কিন্তু কার্যকর হয়নি। তবে এখনও আপনি আমার ভোট পান কারণ এটি অন্যান্য পরিস্থিতিতে কাজ করতে পারে।
আদিত্য একবোট


19

এই উত্তরটি একটু দেরিতে আসে তবে এটি প্রতিক্রিয়াটি সম্পূর্ণ করে।

কোনও সত্তা থেকে ক্ষেত্র এড়াতে ডিবিতে টিকে থাকার জন্য যে কোনও একটি দুটি পদ্ধতির ব্যবহার করতে পারেন:

@ ট্রান্সিয়েন্ট - জেপিএ টিকা স্থির হিসাবে স্থির হিসাবে চিহ্নিত করছে

জাভাতে ক্ষণস্থায়ী কীওয়ার্ড। সাবধান - এই কীওয়ার্ডটি ব্যবহার করে, ফিল্ডটি জাভা থেকে কোনও সিরিয়ালাইজেশন প্রক্রিয়া ব্যবহার করতে বাধা দেবে। সুতরাং, ক্ষেত্রটি অবশ্যই ক্রমিক করা উচিত যদি আপনি কেবলমাত্র @ ট্রান্সিয়েন্ট টীকাটিব্যবহার করতে পারেন।


1
আমি কীভাবে কেবল পদ্ধতিটি পাওয়ার বিষয়ে দৃ method়তা উপেক্ষা করতে চাই? উদাহরণস্বরূপ: myjparepository.save () উইলটি যথারীতি মডেলটি সংরক্ষণ করবে এবং myjparepository.find (id) আমার যে ক্ষেত্রটি চান তা উপেক্ষা করবে?
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সেগুলি নির্বাচন, সন্নিবেশ আপডেট করে এবং মোছে এসকিউএল স্টেটমেন্ট থেকে বাদ দেওয়ার।

সুতরাং, মৌলিক বৈশিষ্ট্যের জন্য, @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সারণী প্রাথমিক কী কলামের মানের যত্ন নেয়।

সুতরাং, যখন সত্তা শনাক্তকারী এবং কোনও সমিতি একই কলামটি ভাগ করে, আপনি @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

উপরের উত্তরগুলি সম্পূর্ণ করতে, আমার কাছে একটি এক্সএমএল ম্যাপিং ফাইল ব্যবহার করে কেস করা হয়েছে যেখানে না @Transientউভয়ই transientকাজ করেনি ... আমাকে এক্সএমএল ফাইলটিতে ক্ষণস্থায়ী তথ্য রাখতে হয়েছিল:

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

2

উপরের উত্তরগুলির মধ্যে আমার পক্ষে হাইবারনেট 5.2.10, জার্সি 2.25.1 এবং জ্যাকসন 2.8.9 ব্যবহার করে কাজ করা হয়নি। পরিশেষে আমি উত্তর পাওয়া (সাজানোর, তারা hibernate4module রেফারেন্স কিন্তু এতে 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);  

হাইবারনেট 5 মডুলের জন্য এখানে নির্ভরতা রয়েছে:

<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)

একটি ভাল দৃশ্যটি যখন নির্দিষ্ট কলামটি অন্য কলামের মান ব্যবহার করে স্বয়ংক্রিয়ভাবে গণনা করা হয়

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.