Skip to content

Commit 8a0a48a

Browse files
committed
Using jpa metamodel
1 parent 5bfe9a3 commit 8a0a48a

File tree

3 files changed

+87
-28
lines changed

3 files changed

+87
-28
lines changed

pom.xml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,14 @@
3232
<groupId>org.hibernate</groupId>
3333
<artifactId>hibernate-entitymanager</artifactId>
3434
</dependency>
35+
36+
<!-- we need to add the target/generated-sources/annotations folder to the classpath of our IDE,
37+
as by default, the classes will be generated in this folder only -->
38+
<dependency>
39+
<groupId>org.hibernate</groupId>
40+
<artifactId>hibernate-jpamodelgen</artifactId>
41+
</dependency>
42+
3543
<dependency>
3644
<groupId>mysql</groupId>
3745
<artifactId>mysql-connector-java</artifactId>

src/main/java/net/javaci/dbsample/springdatajpa1/dao/impl/ApplicationDAOImpl.java

Lines changed: 53 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,10 @@
1414

1515
import net.javaci.dbsample.springdatajpa1.dao.ApplicationDAO;
1616
import net.javaci.dbsample.springdatajpa1.entity.Application;
17-
import net.javaci.dbsample.springdatajpa1.entity.Ticket;
17+
import net.javaci.dbsample.springdatajpa1.entity.Application_;
18+
import net.javaci.dbsample.springdatajpa1.entity.Release_;
19+
import net.javaci.dbsample.springdatajpa1.entity.Ticket_;
1820
import net.javaci.dbsample.springdatajpa1.entity.dto.ApplicationDTO;
19-
import net.javaci.dbsample.springdatajpa1.entity.dto.TicketStatsByStatusDTO;
2021

2122
@Transactional
2223
@Repository
@@ -38,17 +39,20 @@ public Application getApplicationById(int applicationId) {
3839
@Override
3940
public Application getApplicationWithTicketsAndReleases(int applicationId) {
4041

41-
String jpql = "SELECT a from Application a "
42-
+ "INNER JOIN FETCH a.tickets t "
43-
+ "INNER JOIN FETCH a.releasesToDeploy r "
44-
+ "WHERE a.id=?";
42+
String a_id_param = "a_id_param";
43+
44+
// SELECT a from Application a INNER JOIN FETCH a.tickets t INNER JOIN FETCH a.releasesToDeploy r WHERE a.id=:a_id_param
45+
String jpql = "SELECT a from " + Application.class.getSimpleName() + " a "
46+
+ "INNER JOIN FETCH a." + Application_.tickets.getName() + " t "
47+
+ "INNER JOIN FETCH a." + Application_.releasesToDeploy.getName() + " r "
48+
+ "WHERE a." + Application_.id.getName() + "=" + ":" + a_id_param;
4549

4650
// with fetch only one select is executed
4751
// https://www.logicbig.com/tutorials/java-ee-tutorial/jpa/fetch-join.html
4852

4953
Application result = entityManager
5054
.createQuery(jpql, Application.class)
51-
.setParameter(0, applicationId)
55+
.setParameter(a_id_param, applicationId)
5256
.getSingleResult();
5357

5458
// Real select:
@@ -75,8 +79,8 @@ public Application getApplicationWithTicketsAndReleasesV2(int applicationId) {
7579
CriteriaQuery<Application> cq = cb.createQuery(Application.class);
7680

7781
Root<Application> root = cq.from(Application.class);
78-
root.fetch("tickets", JoinType.INNER);
79-
root.fetch("releasesToDeploy", JoinType.INNER);
82+
root.fetch(Application_.tickets, JoinType.INNER);
83+
root.fetch(Application_.releasesToDeploy, JoinType.INNER);
8084

8185
cq.where( cb.equal(root.<Set<Integer>>get("id"), applicationId) );
8286

@@ -106,33 +110,59 @@ public Application getApplicationWithTicketsAndReleasesV2(int applicationId) {
106110
@Override
107111
public ApplicationDTO getApplicationWithTicketsAndReleasesV3(int applicationId) {
108112

109-
String jpql = "SELECT"
110-
+ " new " + ApplicationDTO.class.getCanonicalName() + "( "
111-
+ " a.name, a.owner, max(t.id), max(r.id) "
113+
String a_id_param = "a_id_param";
114+
115+
String jpqlTemplate = "SELECT"
116+
+ " new %s ( " // ApplicationDTO
117+
+ " a.%s, a.%s, max(t.%s), max(r.%s) " // a.name, a.owner, max(t.id), max(r.id)
112118
+ " )"
113-
+ " FROM " + Application.class.getSimpleName() + " a"
114-
+ " INNER JOIN a.tickets t "
115-
+ " INNER JOIN a.releasesToDeploy r "
116-
+ " GROUP BY a.id, a.name, a.owner"
117-
+ " HAVING a.id=?";
119+
+ " FROM %s a" // Application
120+
+ " INNER JOIN a.%s t " // a.tickets
121+
+ " INNER JOIN a.%s r " // a.releasesToDeploy
122+
+ " GROUP BY a.%s, a.%s, a.%s" // a.id, a.name, a.owner
123+
+ " HAVING a.%s= :" + a_id_param; // a.id
124+
125+
String jpql = String.format(jpqlTemplate,
126+
ApplicationDTO.class.getCanonicalName(),
127+
Application_.name.getName(),
128+
Application_.owner.getName(),
129+
Ticket_.id.getName(),
130+
Release_.id.getName(),
131+
Application.class.getSimpleName(),
132+
Application_.tickets.getName(),
133+
Application_.releasesToDeploy.getName(),
134+
Application_.id.getName(),
135+
Application_.name.getName(),
136+
Application_.owner.getName(),
137+
Application_.id.getName()
138+
);
118139

119140
ApplicationDTO result = entityManager
120141
.createQuery(jpql, ApplicationDTO.class)
121-
.setParameter(0, applicationId)
142+
.setParameter(a_id_param, applicationId)
122143
.getSingleResult();
123144

124145
return result;
125146
}
126147

127148
@Override
128149
public boolean applicationExists(String name, String owner) {
150+
151+
String a_name_param = "a_name_param";
152+
String a_owner_param = "a_owner_param";
153+
129154
// note application is the class name; not the table name;
130155
// class name is case sensitive; use class field names - column names
131-
String jpql = "from Application as a WHERE a.name = ? and a.owner = ?";
156+
String jpql = "from " + Application.class.getSimpleName() + " as a "
157+
+ "WHERE "
158+
+ "a." + Application_.name.getName() + " = :" + a_name_param + " "
159+
+ "and a." + Application_.owner.getName() + " = :" + a_owner_param;
160+
161+
// from Application as a WHERE a.name = ? and a.owner = ?
132162
int count = entityManager
133163
.createQuery(jpql)
134-
.setParameter(0, name)
135-
.setParameter(1, owner)
164+
.setParameter(a_name_param, name)
165+
.setParameter(a_owner_param, owner)
136166
.getResultList()
137167
.size();
138168
return count > 0;
@@ -148,8 +178,8 @@ public boolean applicationReallyExists(String name, String owner) {
148178

149179
cq.select(root).where(
150180
cb.and(
151-
cb.equal(root.<Set<String>>get("name"), name),
152-
cb.equal(root.<Set<String>>get("owner"), owner)
181+
cb.equal(root.get(Application_.name), name),
182+
cb.equal(root.get(Application_.owner), owner)
153183
)
154184
);
155185

src/main/java/net/javaci/dbsample/springdatajpa1/dao/impl/TicketDAOImpl.java

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
package net.javaci.dbsample.springdatajpa1.dao.impl;
22

3+
import static net.javaci.dbsample.springdatajpa1.entity.Ticket_.createDateTime;
4+
import static net.javaci.dbsample.springdatajpa1.entity.Ticket_.id;
5+
import static net.javaci.dbsample.springdatajpa1.entity.Ticket_.status;
6+
37
import java.util.List;
48

59
import javax.persistence.EntityManager;
@@ -32,16 +36,33 @@ public Ticket getTicketById(int ticketId) {
3236

3337
@Override
3438
public List<TicketStatsByStatusDTO> findTicketStats() {
39+
40+
String t_ = "t";
41+
String t_name = t_ + "." + id.getName();
42+
String t_createDateTime = t_ + "." + createDateTime.getName();
43+
String t_status = t_ + "." + status.getName();
44+
Class<TicketStatsByStatusDTO> ticketStatsByStatusDTOClass = TicketStatsByStatusDTO.class;
45+
String ticketStatsByStatusDTO_ = ticketStatsByStatusDTOClass.getCanonicalName();
46+
String t_class_ = Ticket.class.getSimpleName();
47+
48+
/*-- SELECT new net.javaci.dbsample.springdatajpa1.entity.dto.TicketStatsByStatusDTO
49+
* ( t.status, count(t.id), min(t.createDateTime), max(t.createDateTime))
50+
* FROM Ticket t GROUP BY t.status
51+
*/
52+
3553
String jpql =
3654
"SELECT "
37-
+ "new " + TicketStatsByStatusDTO.class.getCanonicalName() + "("
38-
+ " t.status, count(t.id), min(t.createDateTime), max(t.createDateTime)"
55+
+ "new " + ticketStatsByStatusDTO_ + "( "
56+
+ t_status + ", "
57+
+ "count(" + t_name + "), "
58+
+ "min(" + t_createDateTime + "), "
59+
+ "max(" + t_createDateTime + ") "
3960
+ ") "
40-
+ "FROM " + Ticket.class.getSimpleName() + " t "
41-
+ "GROUP BY t.status";
61+
+ "FROM " + t_class_ + " " + t_ + " " // class name; not the table name
62+
+ "GROUP BY " + t_status;
4263

4364
List<TicketStatsByStatusDTO> resultList = entityManager
44-
.createQuery(jpql, TicketStatsByStatusDTO.class)
65+
.createQuery(jpql, ticketStatsByStatusDTOClass)
4566
.getResultList();
4667

4768
return resultList;

0 commit comments

Comments
 (0)