-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 6 posts ] 
Author Message
 Post subject: ScrollableResults's scroll() method show wrong totalRecords
PostPosted: Thu Nov 03, 2016 12:06 am 
Newbie

Joined: Wed Nov 02, 2016 10:51 pm
Posts: 4
I'm quite new for Hibernate. I have table A, B and C as following below

As condition: C have foreignKey of B and B have foreignKey of A.
I use ScrollableResults class to get total Records for performance improvements.
Code:
    ScrollableResults resultScroll = query.setCacheMode(CacheMode.IGNORE).scroll();
    resultScroll.last(); // get last records
    int totalRecords = resultScroll.getRowNumber() + 1;
    if (resultScroll != null)
        resultScroll.close();


If i use first hql, scrollableResults show correct total records, my data is 31 records as show below
Code:
    Select at from A at inner join fetch at.bf


If i use second hql, scrollableResults show wrong total records, it is 38 records as shown below.
Code:
    Select at from
         A at inner join fetch at.bf bt
         inner join fetch bt.cf


If i use third hql, scrollableResults show wrong total records, it is 31 records as shown below.
Code:
   Select at from
         A at inner join fetch at.bf bt
         inner join bt.cf 


If i use getResultList(), it always get 31 records. I think that scroll() has something wrong with two-level fetch but it work both of one-level fetch and without fetch.

Table A
Code:
@Entity
@Table(name = "A")
public class A implements Serializable {

   private int aId;
        private String aName;
   private List<B> bf= new ArrayList<B>();

   public A() {
   }

   public A(int aId, String aName) {
      this.aId= aId;
      this.aName= aName;
   }

   @Id

   @Column(name = "A_ID", unique = true, nullable = false)
   public int getAId() {
      return this.aId;
   }

   public void setAId(int aId) {
      this.aId= aId;
   }

   @Column(name = "A_NAME", nullable = false)
   public String getAName() {
      return this.aName;
   }

   public void setAName(String aName) {
      this.aName = aName;
   }

   @OneToMany(fetch = FetchType.LAZY, mappedBy = "bf")
   public Set<B> getBF() {
      return this.bf;
   }

   public void setBF(Set<B> bf) {
      this.bf = bf;
   }



Table B
Code:
@Entity
@Table(name = "B")
public class B implements Serializable {

   private int bId;
        private String bName;
   private A af;
   private List<C> cf= new ArrayList<C>();

   public B() {
   }

   public B(int bId, String bName) {
      this.bId= bId;
      this.bName= bName;
   }

   @Id

   @Column(name = "B_ID", unique = true, nullable = false)
   public int getBId() {
      return this.bId;
   }

   public void setBId(int bId) {
      this.bId= bId;
   }

   @Column(name = "B_NAME", nullable = false)
   public String getBName() {
      return this.bName;
   }

   public void setBName(String bName) {
      this.bName = bName;
   }

        @ManyToOne(fetch = FetchType.LAZY)
        @JoinColumn(name = "A_ID")
   public A getAF() {
      return this.af;
   }

   public void setAF(A af) {
      this.af= af;
   }         

   @OneToMany(fetch = FetchType.LAZY, mappedBy = "cf")
   public Set<C> getCF() {
      return this.cf;
   }

   public void setCF(Set<C> cf) {
      this.cf= cf;
   }



Table C
Code:
@Entity
@Table(name = "C")
public class C implements Serializable {

   private int cId;
        private String cName;
   private B bf;

   public C() {
   }

   public C(int cId, String cName) {
      this.cId= cId;
      this.cName= cName;
   }

   @Id

   @Column(name = "C_ID", unique = true, nullable = false)
   public int getCId() {
      return this.cId;
   }

   public void setCId(int cId) {
      this.cId= cId;
   }

   @Column(name = "C_NAME", nullable = false)
   public String getCName() {
      return this.cName;
   }

   public void setCName(String cName) {
      this.cName = cName;
   }

   @ManyToOne(fetch = FetchType.LAZY)
        @JoinColumn(name = "B_ID")
   public B getBF() {
      return this.bf;
   }

   public void setBF(B bf) {
      this.bf= bf;
   }



Best Regards


Top
 Profile  
 
 Post subject: Re: ScrollableResults's scroll() method show wrong totalRecords
PostPosted: Thu Nov 03, 2016 1:39 am 
Hibernate Team
Hibernate Team

Joined: Thu Sep 11, 2014 2:50 am
Posts: 1628
Location: Romania
When you JOIN FETCH collections, you need to use the DISTINCT keyword to remove deduplication:

Code:
Select DISTINCT at from A at
inner join fetch at.bf bt
inner join fetch bt.cf


and

Code:
Select DISTINCT at from A at
inner join fetch at.bf bt
inner join bt.cf


Top
 Profile  
 
 Post subject: Re: ScrollableResults's scroll() method show wrong totalRecords
PostPosted: Thu Nov 03, 2016 2:56 am 
Newbie

Joined: Wed Nov 02, 2016 10:51 pm
Posts: 4
Thank you very much for your reply, i will try it.
I try to contact you an e-mail a long time. I just bought your book High-Performance Java Persistence. Thank you again for your book.


Top
 Profile  
 
 Post subject: Re: ScrollableResults's scroll() method show wrong totalRecords
PostPosted: Thu Nov 03, 2016 3:07 am 
Newbie

Joined: Wed Nov 02, 2016 10:51 pm
Posts: 4
I've already used DISTINCT keyword. I just forgot it in my post. totalRecord from scroll() method still be wrong value.


Top
 Profile  
 
 Post subject: Re: ScrollableResults's scroll() method show wrong totalRecords
PostPosted: Thu Nov 03, 2016 4:34 am 
Hibernate Team
Hibernate Team

Joined: Thu Sep 11, 2014 2:50 am
Posts: 1628
Location: Romania
Thanks for buying the book. I'm sure you are going to love it.

As for scroll, if you think there's an issue, you should open a Jira issue. Just make sure that you have a replicating test case.


Top
 Profile  
 
 Post subject: Re: ScrollableResults's scroll() method show wrong totalRecords
PostPosted: Thu Nov 03, 2016 5:16 am 
Newbie

Joined: Wed Nov 02, 2016 10:51 pm
Posts: 4
Thank you for your recommendation. I'll do it. For now, i can skip this problem but i still use ScrollableResults.
I have to createQuery 2 times as following below
1) create hql without join fetch for getting totalRecord from ScrollableResults.
Code:
   Select DISTINCT at from A at
   inner join fetch at.bf bt
   inner join bt.cf


2) create hql with join fetch to retrieve data.
Code:
    Select DISTINCT at from A at
    inner join fetch at.bf bt
    inner join fetch bt.cf


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 6 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
cron
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.