জেপিএ এবং হাইবারনেট দিয়ে গণনা করা বৈশিষ্ট্যগুলি কীভাবে মানচিত্র করা যায়


104

আমার জাভা বিনের একটি চাইল্ডকাউন্ট সম্পত্তি রয়েছে। এই সম্পত্তিটি একটি ডেটাবেস কলামে ম্যাপ করা হয়নি । পরিবর্তে, এটি আমার জাভা বিন এবং এর বাচ্চাদের যোগদানের ক্রিয়াকলাপের সাহায্যে ডাটাবেস দ্বারা গণনা করাCOUNT() উচিত । এটি আরও ভাল হবে যদি এই সম্পত্তিটি চাহিদা / "অলসভাবে" গণনা করা যায় তবে এটি বাধ্যতামূলক নয়।

সবচেয়ে খারাপ পরিস্থিতিতে, আমি এই শিমের সম্পত্তি এইচকিউএল বা ক্রেটারিয়া এপিআই দিয়ে সেট করতে পারি, তবে আমি তা পছন্দ করব না।

হাইবারনেট @Formulaটীকাগুলি সাহায্য করতে পারে তবে আমি সবেমাত্র কোনও ডকুমেন্টেশন সন্ধান করতে পারি।

যে কোনও সহায়তা প্রশংসিত ধন্যবাদ।

উত্তর:


162

জেপিএ উদ্ভূত সম্পত্তিটির জন্য কোনও সমর্থন সরবরাহ করে না সুতরাং আপনাকে কোনও সরবরাহকারীর নির্দিষ্ট এক্সটেনশন ব্যবহার করতে হবে। যেমন আপনি উল্লেখ করেছেন, @Formulaহাইবারনেট ব্যবহার করার সময় এটি উপযুক্ত perfect আপনি একটি এসকিউএল খণ্ড ব্যবহার করতে পারেন:

@Formula("PRICE*1.155")
private float finalPrice;

অথবা অন্যান্য টেবিলগুলিতে এমনকি জটিল প্রশ্ন:

@Formula("(select min(o.creation_date) from Orders o where o.customer_id = id)")
private Date firstOrderDate;

কোথায় idহয় idবর্তমান সত্তা।

নিম্নলিখিত ব্লগ পোস্টটি পড়ার জন্য মূল্যবান: হাইবারনেট ডেরাইভড প্রোপার্টি - পারফরম্যান্স এবং বহনযোগ্যতা

আরও বিশদ ছাড়াই, আমি আরও সুনির্দিষ্ট উত্তর দিতে পারি না তবে উপরের লিঙ্কটি সহায়ক হওয়া উচিত।

আরো দেখুন:


ধন্যবাদ পাস্কাল নিম্নলিখিতগুলি কেন কাজ করছে না আপনার কোনও ধারণা আছে? @ ফারমুলা (মান = "(নির্বাচন করুন গণনা ( ) নির্বাচন করুন আইসির অভ্যন্তরীণ জোড় সি থেকে যেখানে আইস.এইচটিগ্রি_আইডি = সি.আইডি এবং সি.আইডি = আইডি)") পাবলিক পূর্ণসংখ্যা getCountIntern () count ফেরত কাউন্টি অভ্যন্তরীণ; Query ক্যোয়ারী ঠিক আছে এবং আমি দেখতে পাচ্ছি এটি লগগুলিতে চালিত হচ্ছে। ম্যাপিংটি ঠিক আছে বলে মনে হচ্ছে: প্রধান org.hibernate.cfg.Ejb3 কলাম - বাঁধাই সূত্র (নির্বাচন করুন গণনা ( ) ব্লা ব্লা ব্লাহ তবে গণনা অভ্যন্তরীণ অবধি এর প্রাথমিক মানতে সেট করা হয়েছে (-1) :( আমি ভেটো টীকাগুলির পরিবর্তে ফিল্ড টীকা ব্যবহার করার চেষ্টা করেছি, তবে এটি এখনও কাজ করে না
ফ্রাঙ্কোইস

ধন্যবাদ, এটি আমার কার্যক্রমে সত্যই আমাকে অনেক সাহায্য করেছে!
মিথিল

13
@ নীলম্যাকগুইগান: টিকাটি এইচকিউএল @Formulaনয় এস এসকিউএল ব্যবহার করে।
ব্যবহারকারী 1438038

7
ক্যোরির চারপাশে প্রথম বন্ধনী থাকা কতটা গুরুত্বপূর্ণ তা কেবল শিখেছি। সর্বদা একটি এসকিউএল ব্যতিক্রম সহ শেষ হয়, যেহেতু হোস্ট অবজেক্টটি লোড হওয়ার পরে অবশ্যই এই কোয়েরিটি সাবকিউরি হয়ে যায়। মাইএসকিউএল প্রথম বন্ধনী ছাড়া ইনলাইন নির্বাচন পছন্দ করে নি।
দুঃখিত

1
নিবন্ধটির নতুন লিঙ্কটি হ'ল: blog.eyallupu.com/2009/07/hibernate-deriv-properties.html
আদনান

53

এই নিবন্ধে ব্যাখ্যা হিসাবে , আপনার কাছে তিনটি বিকল্প রয়েছে:

  • হয় আপনি কোনও @Transientপদ্ধতি ব্যবহার করে গুণাবলী গণনা করছেন
  • আপনি @PostLoadসত্তা শ্রোতাও ব্যবহার করতে পারেন
  • অথবা আপনি হাইবারনেট নির্দিষ্ট @Formulaটীকাটি ব্যবহার করতে পারেন

হাইবারনেট আপনাকে জেপিএর সাহায্যে @ ফর্মুলা ব্যবহার করার অনুমতি দেয় , আপনি কিছু গণনার ফলাফলের সাথে একটি ক্ষণস্থায়ী সম্পত্তি পপুলেট করতে @ পোষ্টলয়েড কলব্যাক ব্যবহার করতে পারেন :

@Column(name = "price")
private Double price;

@Column(name = "tax_percentage")
private Double taxes;

@Transient
private Double priceWithTaxes;

@PostLoad
private void onLoad() {
    this.priceWithTaxes = price * taxes;
}

আরও জটিল প্রশ্নের জন্য, আপনি হাইবারনেটটি ব্যবহার করতে পারেন @Formula, যেমন এই নিবন্ধে ব্যাখ্যা করা হয়েছে :

@Formula(
    "round(" +
    "   (interestRate::numeric / 100) * " +
    "   cents * " +
    "   date_part('month', age(now(), createdOn)" +
    ") " +
    "/ 12) " +
    "/ 100::numeric")
private double interestDollars;

7
এটি তবে আরও জটিল প্রশ্নের জন্য মঞ্জুরি দেয় না
হুবার্ট গ্রাজেকোইয়াক

2
আমি উত্তর আপডেট করেছি তাই এখন আপনার কাছে আরও জটিল প্রশ্নগুলির সমাধান রয়েছে।
ভ্লাদ মিহলসিয়া

1

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

এখানে ম্যাপিং একটি উদাহরণ

@EntityView(Order.class)
interface OrderSummary {
  Integer getId();
  @Mapping("SUM(orderPositions.price * orderPositions.amount * orderPositions.tax)")
  BigDecimal getOrderAmount();
  @Mapping("COUNT(orderPositions)")
  Long getItemCount();
}

এটি আনতে এর অনুরূপ একটি জেপিকিউএল / এইচকিউএল কোয়েরি তৈরি করা হবে

SELECT
  o.id,
  SUM(p.price * p.amount * p.tax),
  COUNT(p.id)
FROM
  Order o
LEFT JOIN
  o.orderPositions p
GROUP BY
  o.id

এখানে কাস্টম সাবকিউরি সরবরাহকারীদের সম্পর্কে একটি ব্লগ পোস্ট রয়েছে যা আপনার কাছে আকর্ষণীয়ও হতে পারে: https://blazebit.com/blog/2017/entity-view-mapping-subqueries.html


0

আমি আমার কোড এ চেষ্টা করেছি

 @Formula(value = "(select DATEDIFF(expiry_date,issue_date)  from document_storage)")
    private String  myColumn;

আমি যখন দৌড়ানোর সময় আমার ত্রুটিগুলি পাই এবং গোঁফের উপরে কলামটি প্রদর্শনের চেষ্টা করার আগে আমার দৃশ্য প্রদর্শন করি তখন এটি এমনই কিছু

java.lang.NullPointerException
    at java.base/java.lang.String$CaseInsensitiveComparator.compare(String.java:1241)
    at java.base/java.lang.String$CaseInsensitiveComparator.compare(String.java:1235)
    at java.base/java.util.TreeMap.getEntryUsingComparator(TreeMap.java:374)
    at java.base/java.util.TreeMap.getEntry(TreeMap.java:343)
    at java.base/java.util.TreeMap.get(TreeMap.java:277)
    at com.mysql.cj.result.DefaultColumnDefinition.findColumn(DefaultColumnDefinition.java:182)

আমি যে প্রশ্নটি জিজ্ঞাসা করেছি তা কি মাইএসকিউএল দিয়ে জেপিএ / হাইবারনেট ব্যবহার করে গণনা কলামের মান পাওয়ার উপায় আছে?

আমি কি ভুল করছি ?

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