Imagine I have an Account entity which has a collection of
Payment entities and a transient field
sumPaid:
Code:
/** */
@Entity
@Table(name = "account")
public class Account {
...
@Column(name = "summ", nullable = false)
private BigDecimal summ;
...
@OneToMany(mappedBy = "account")
private Set<Payment> payments = new HashSet<Payment>();
@Transient
private BigDecimal sumPaid;
...
}
sumPaid is a transient calculated field it's being calculated in the following way:
Code:
..
List<Object[]> tuple = new ArrayList<Object[]>();
tuple = session.createQuery("select distinct acc, (select sum(pays.income) from acc.payments pays) from Account as acc left join fetch acc.payments ").list();
for (Object[] obj : tuple) {
Account acc = (Account)obj[0];
BigDecimal sumIncome = (BigDecimal)obj[1];
acc.setSumPaid(sumIncome);
}
...
The problem is: the resulting list contains duplicated Account objects, all rows, fetched from db seem not to be grouped by Account. What I mean:
Imagine I have 2 Account objects and 4 Payment objects (each Account is referenced by two Payments):
Account1 <- Payment1
Account1 <- Payment2
Account2 <- Payment3
Account2 <- Payment4
so, if I use a select of this type:
Code:
session.createQuery("select distinct acc from Account as acc left join fetch acc.payments ").list();
I recieve two Account objects with each with its own collection of Payment objects:
Account1: payments = (Payment1, Payment2), sumPaid=null
Account2: payments = (Payment3, Payment4), sumPaid=null
But when I use the mentioned query with additional parameter in select
Code:
session.createQuery("select distinct acc, (select sum(pays.income) from acc.payments pays) from Account as acc left join fetch acc.payments ").list();
I recieve 4 Account objects, two of which are totally equall:
Account1: payments = (Payment1, Payment2), sumPaid=100
Account2: payments = (Payment1, Payment2), sumPaid=100
Account3: payments = (Payment3, Payment4), sumPaid=200
Account4: payments = (Payment3, Payment4), sumPaid=200
It seems that
distinct word works in Hibernate only when select has the object itself, but when smth else is selected, all rows are fetched directly as from db select.
Thanks to everyone for the help! It seem's that the answer is quite simple, but so far I will have to remove duplicated objects from the resulting list manually