กลุ่มเกณฑ์ jpa ตามค่ารวม

ฉันต้องการแบบสอบถามเพื่อแปลงเวลา (มิลลิวินาที) เป็นการแจกแจงรายชั่วโมง

ตารางของฉันมีคอลัมน์ที่เรียกว่าการประทับเวลา : ค่าเป็นมิลลิวินาที เพื่อจัดกลุ่มเป็นชั่วโมงฉันต้องทำการหารต่อไปนี้ด้วย 1,000 -> วินาทีหารด้วย 3600 -> ชั่วโมง -> mod 24 -> รับชั่วโมงของวันที่สร้างบันทึก

การประทับเวลามีความยาว:

    public static volatile SingularAttribute<VersionJpa, Long> timestamp;

จากนั้นฉันสามารถแสดงผลแบบกระจายภายในวันได้ อย่างไรก็ตาม วิธีนี้ใช้ไม่ได้ผล จัดกลุ่มโดยไม่ทำงาน และฉันได้รับรายการทั้งหมดที่ไม่ได้จัดกลุ่มและไม่นับ

    CriteriaBuilder cb = em.getCriteriaBuilder();
    CriteriaQuery<Tuple> cq = cb.createTupleQuery();
    Root<VersionJpa> root = cq.from(VersionJpa.class);
    cq.where(p);
    Expression<Integer> group = cb.mod(cb.toInteger(cb.quot(root.get(VersionJpa_.timestamp), 3600000)),24);
    cq.multiselect(group, cb.count(root));
    cq.groupBy(group);
    TypedQuery<Tuple> tq = em.createQuery(cq);
    return tq.getResultList();

SQL (mysql) นี้สร้างผลลัพธ์ที่ถูกต้อง JPA มีพื้นเทียบเท่ากันหรือไม่ พยายามเป็น (จำนวนเต็ม) || เป็นจำนวนเต็ม()

    select mod(floor(stamp/3600000), 24) , count(*) from versions group by mod(floor(stamp/3600000), 24);

ฉันพบว่าในระหว่างการทดสอบหน่วย (บน Derby) สิ่งนี้ทำงานได้ดี แต่ในการผลิตที่มากขึ้นเช่นการตั้งค่า (MySQL) จะไม่แปลงผลรวมภายในส่วนใหญ่เป็นจำนวนเต็ม ดังนั้นกลุ่มจึงดำเนินการกับค่าลอยตัวและไม่ใช่ใน 24 (0 , 1, .. 23) ค่าที่เป็นไปได้ (ส่งคืนพันกลุ่ม)

    Expression<Integer> hours = cb.mod(cb.quot(root.get(VersionJpa_.timestamp).as(Integer.class), 3600000).as(Integer.class),24).as(Integer.class);
    cq.multiselect(hours, cb.count(root));
    cq.groupBy(hours);

การเพิ่มการสนับสนุน PostgreSQL และการทดสอบนำไปสู่ข้อผิดพลาดอื่นที่บังคับให้ฉันคิดว่าแบบสอบถามของฉันผิด:

    RuntimeException Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.5.0.v20130507-3faac2b): org.eclipse.persistence.exceptions.DatabaseException Internal Exception: org.postgresql.util.PSQLException: ERROR: column "versions.stamp" must appear in the GROUP BY clause or be used in an aggregate function Position: 13 Error Code: 0 Call: SELECT MOD((STAMP / ?), ?), COUNT(ID) FROM VERSIONS GROUP BY MOD((STAMP / ?), ?) LIMIT ? OFFSET ? bind => [6 parameters bound] Query: TupleQuery(referenceClass=VersionJpa sql="SELECT MOD((STAMP / ?), ?), COUNT(ID) FROM VERSIONS GROUP BY MOD((STAMP / ?), ?) LIMIT ? OFFSET ?")

ความช่วยเหลือใด ๆ ที่ชื่นชม


person Gadi    schedule 02.08.2013    source แหล่งที่มา


คำตอบ (2)


คุณสามารถใช้เมธอด function() เพื่อเรียกใช้ฟังก์ชันฐานข้อมูลใดก็ได้

โปรดดู http://java-persistence-Performance.blogspot.com/2012/05/jpql-vs-sql-have-both-with-eclipselink.html

ดูเหมือนว่า Postgres จะบ่นมากขึ้นเกี่ยวกับการใช้ฟังก์ชั่นในกลุ่มโดยใน JPQL คุณสามารถลองได้

Select mod((v.timestamp / 3600000), 24) h, count(v) from Version v group by h
person James    schedule 07.08.2013
comment
ขอบคุณครับ ผมลองกับพื้นแล้วไม่ได้ผล ฉันต้องทำงานกับเกณฑ์เพราะฉันเพิ่มการกรอง/เลือกแบบไดนามิกมากขึ้น มันเป็นข้อผิดพลาดของ eclipse หรือฉันแค่ใช้ไวยากรณ์ผิด? - person Gadi; 08.08.2013

สำหรับใครก็ตามที่ประสบปัญหานี้ ฉันพบวิธีแก้ปัญหาโดยอิงตามคอลัมน์ฐานข้อมูลและไม่ซับซ้อนในการสืบค้น การแจ้งเตือน ปัญหาคือไม่รับประกันการสนับสนุนผู้ขายรายอื่น มันใช้งานได้กับ Derby แต่ล้มเหลวบน MySQL

ฉันสร้างคอลัมน์ใหม่สำหรับแต่ละเมตริกที่ฉันสนใจ:

  • ปี
  • เดือน
  • วันในสัปดาห์
  • วันของเดือน
  • ชั่วโมงของวัน (24)

จากนั้นเติมปฏิทินที่เริ่มต้นด้วยการตั้งค่าและเวลาของระบบ

    Calendar now = Calendar.getInstance();
    now.setTimeInMillis(timestamp);
    this.year = now.get(Calendar.YEAR);
    logger.trace("Year : [{}]", year);
    this.month = now.get(Calendar.MONTH);
    logger.trace("Month : [{}]", month);
    this.weekOfYear = now.get(Calendar.WEEK_OF_YEAR);
    logger.trace("Week of Year : [{}]", weekOfYear);
    this.dayOfMonth = now.get(Calendar.DAY_OF_MONTH);
    logger.trace("Day of Month : [{}]", dayOfMonth);
    this.dayOfWeek = now.get(Calendar.DAY_OF_WEEK);
    logger.trace("Day of Week : [{}]", dayOfWeek);
    this.hourOfDay = now.get(Calendar.HOUR_OF_DAY);
    logger.trace("Hour of Day : [{}]", hourOfDay);

หวังว่านี่จะช่วยใครบางคนได้ ไชโย

person Gadi    schedule 09.08.2013