Reputation: 2755
Many time I have to get the SQL aggregate query result inside the Entity Object itself. As of now I could able to achive the same by the following code
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Tuple> q = cb.createTupleQuery();
Root<Test> c = q.from(Test.class);
q.multiselect(c, cb.count(c));
q.groupBy(c.get("type"));
TypedQuery<Tuple> t = em.createQuery(q);
List<Tuple> resultList = t.getResultList();
List<Test> list = new ArrayList<>();
for(Tuple tuple : resultList){
Test te = (Test) tuple.get(0);
te.setQuantity((long)tuple.get(1));
list.add(te);
}
But I want to know what could be the best way. My Test Entity is as
@Entity
@Table(name = "test")
public class Test {
@Id
@Column(name = "id")
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
@Column(name = "name")
private String name;
@Column(name = "type")
private Integer type = 0;
@Transient
private long quantity;
}
Upvotes: 1
Views: 1408
Reputation: 23226
If you cannot use @Formula
then I'd suggest create a database view basic on your select and mapping an additional entity to that. You can then map this to your existing entity using either as a @OneToOne
or by using @SecondaryTable
.
This has the added advantage of being JPA compliant (i.e. not using Hibernate's propreitary @Formula) and would look something like:
@Entity
@Table(name = "test")
public class Test {
@Id
@Column(name = "id")
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
@Column(name = "name")
private String name;
@Column(name = "type")
private Integer type = 0;
@OneToOne//or via secondary table
private TestSummaryInfo summaryInfo;
public long getQuantity(){
return summaryInfo.getQuantity();
}
}
Summary mapped to a view:
@Entity
@Table(name = "vw_test_summary")
public class TestSummaryInfo {
@Id
@Column(name = "id")
private Integer id;
@Column(name = "quantity")
private Long quantity;
}
Upvotes: 1