[BAEL-1381] Add JPA Examples (#6369) · initialcommit-io/tutorials@6c237aa · GitHub
Skip to content

Commit 6c237aa

Browse files
psevestremaibin
authored andcommitted
[BAEL-1381] Add JPA Examples (eugenp#6369)
* BAEL-1381 * [BAEL-1381] * [BAEL-1381] New module name * [BAEL-1381] software-security module * [BAEL-1381] Add JPA examples
1 parent cf25075 commit 6c237aa

11 files changed

Lines changed: 246 additions & 51 deletions

File tree

core-java-collections/src/test/java/com/baeldung/queueinterface/CustomBaeldungQueueUnitTest.java renamed to core-java-collections/src/test/java/com/baeldung/queueInterface/CustomBaeldungQueueUnitTest.java

File renamed without changes.

core-java-collections/src/test/java/com/baeldung/queueinterface/PriorityQueueUnitTest.java renamed to core-java-collections/src/test/java/com/baeldung/queueInterface/PriorityQueueUnitTest.java

File renamed without changes.

‎software-security/sql-injection-samples/pom.xml‎

Lines changed: 14 additions & 1 deletion
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/**
2+
*
3+
*/
4+
package com.baeldung.examples.security.sql;
5+
6+
import java.math.BigDecimal;
7+
8+
import javax.persistence.Entity;
9+
import javax.persistence.GeneratedValue;
10+
import javax.persistence.GenerationType;
11+
import javax.persistence.Id;
12+
import javax.persistence.Table;
13+
14+
import lombok.Data;
15+
16+
/**
17+
* @author Philippe
18+
*
19+
*/
20+
@Entity
21+
@Table(name="Accounts")
22+
@Data
23+
public class Account {
24+
25+
@Id
26+
@GeneratedValue(strategy=GenerationType.IDENTITY)
27+
private Long id;
28+
29+
private String customerId;
30+
private String accNumber;
31+
private String branchId;
32+
private BigDecimal balance;
33+
34+
}

‎software-security/sql-injection-samples/src/main/java/com/baeldung/examples/security/sql/AccountDAO.java‎

Lines changed: 150 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,24 @@
77
import java.sql.PreparedStatement;
88
import java.sql.ResultSet;
99
import java.sql.SQLException;
10+
import java.util.AbstractMap;
1011
import java.util.ArrayList;
1112
import java.util.Collections;
1213
import java.util.HashSet;
1314
import java.util.List;
15+
import java.util.Map;
1416
import java.util.Set;
1517
import java.util.stream.Collectors;
1618
import java.util.stream.Stream;
1719

20+
import javax.persistence.EntityManager;
21+
import javax.persistence.Query;
22+
import javax.persistence.TypedQuery;
23+
import javax.persistence.criteria.CriteriaBuilder;
24+
import javax.persistence.criteria.CriteriaQuery;
25+
import javax.persistence.criteria.Order;
26+
import javax.persistence.criteria.Root;
27+
import javax.persistence.metamodel.SingularAttribute;
1828
import javax.sql.DataSource;
1929

2030
import org.springframework.stereotype.Component;
@@ -27,9 +37,11 @@
2737
public class AccountDAO {
2838

2939
private final DataSource dataSource;
40+
private final EntityManager em;
3041

31-
public AccountDAO(DataSource dataSource) {
42+
public AccountDAO(DataSource dataSource, EntityManager em) {
3243
this.dataSource = dataSource;
44+
this.em = em;
3345
}
3446

3547
/**
@@ -63,6 +75,26 @@ public List<AccountDTO> unsafeFindAccountsByCustomerId(String customerId) {
6375
}
6476
}
6577

78+
/**
79+
* Return all accounts owned by a given customer,given his/her external id - JPA version
80+
*
81+
* @param customerId
82+
* @return
83+
*/
84+
public List<AccountDTO> unsafeJpaFindAccountsByCustomerId(String customerId) {
85+
String jql = "from Account where customerId = '" + customerId + "'";
86+
TypedQuery<Account> q = em.createQuery(jql, Account.class);
87+
return q.getResultList()
88+
.stream()
89+
.map(a -> AccountDTO.builder()
90+
.accNumber(a.getAccNumber())
91+
.balance(a.getBalance())
92+
.branchId(a.getAccNumber())
93+
.customerId(a.getCustomerId())
94+
.build())
95+
.collect(Collectors.toList());
96+
}
97+
6698
/**
6799
* Return all accounts owned by a given customer,given his/her external id
68100
*
@@ -71,7 +103,7 @@ public List<AccountDTO> unsafeFindAccountsByCustomerId(String customerId) {
71103
*/
72104
public List<AccountDTO> safeFindAccountsByCustomerId(String customerId) {
73105

74-
String sql = "select " + "customer_id,acc_number,branch_id,balance from Accounts where customer_id = ?";
106+
String sql = "select customer_id, branch_id,acc_number,balance from Accounts where customer_id = ?";
75107

76108
try (Connection c = dataSource.getConnection(); PreparedStatement p = c.prepareStatement(sql)) {
77109
p.setString(1, customerId);
@@ -93,23 +125,73 @@ public List<AccountDTO> safeFindAccountsByCustomerId(String customerId) {
93125
}
94126
}
95127

128+
/**
129+
* Return all accounts owned by a given customer,given his/her external id - JPA version
130+
*
131+
* @param customerId
132+
* @return
133+
*/
134+
public List<AccountDTO> safeJpaFindAccountsByCustomerId(String customerId) {
135+
136+
String jql = "from Account where customerId = :customerId";
137+
TypedQuery<Account> q = em.createQuery(jql, Account.class)
138+
.setParameter("customerId", customerId);
139+
140+
return q.getResultList()
141+
.stream()
142+
.map(a -> AccountDTO.builder()
143+
.accNumber(a.getAccNumber())
144+
.balance(a.getBalance())
145+
.branchId(a.getAccNumber())
146+
.customerId(a.getCustomerId())
147+
.build())
148+
.collect(Collectors.toList());
149+
}
150+
151+
/**
152+
* Return all accounts owned by a given customer,given his/her external id - JPA version
153+
*
154+
* @param customerId
155+
* @return
156+
*/
157+
public List<AccountDTO> safeJpaCriteriaFindAccountsByCustomerId(String customerId) {
158+
159+
CriteriaBuilder cb = em.getCriteriaBuilder();
160+
CriteriaQuery<Account> cq = cb.createQuery(Account.class);
161+
Root<Account> root = cq.from(Account.class);
162+
cq.select(root)
163+
.where(cb.equal(root.get(Account_.customerId), customerId));
164+
165+
TypedQuery<Account> q = em.createQuery(cq);
166+
167+
return q.getResultList()
168+
.stream()
169+
.map(a -> AccountDTO.builder()
170+
.accNumber(a.getAccNumber())
171+
.balance(a.getBalance())
172+
.branchId(a.getAccNumber())
173+
.customerId(a.getCustomerId())
174+
.build())
175+
.collect(Collectors.toList());
176+
}
177+
96178
private static final Set<String> VALID_COLUMNS_FOR_ORDER_BY = Stream.of("acc_number", "branch_id", "balance")
97179
.collect(Collectors.toCollection(HashSet::new));
98180

181+
99182
/**
100183
* Return all accounts owned by a given customer,given his/her external id
101184
*
102185
* @param customerId
103186
* @return
104187
*/
105-
public List<AccountDTO> safeFindAccountsByCustomerId(String customerId, String orderBy) {
188+
public List<AccountDTO> safeFindAccountsByCustomerId(String customerId, String orderBy) {
106189

107190
String sql = "select " + "customer_id,acc_number,branch_id,balance from Accounts where customer_id = ? ";
108191

109192
if (VALID_COLUMNS_FOR_ORDER_BY.contains(orderBy)) {
110193
sql = sql + " order by " + orderBy;
111-
}
112-
else {
194+
} else {
113195
throw new IllegalArgumentException("Nice try!");
114196
}
115197

@@ -135,35 +217,82 @@ public List<AccountDTO> safeFindAccountsByCustomerId(String customerId, String o
135217
}
136218
}
137219

220+
221+
private static final Map<String,SingularAttribute<Account,?>> VALID_JPA_COLUMNS_FOR_ORDER_BY = Stream.of(
222+
new AbstractMap.SimpleEntry<>(Account_.ACC_NUMBER, Account_.accNumber),
223+
new AbstractMap.SimpleEntry<>(Account_.BRANCH_ID, Account_.branchId),
224+
new AbstractMap.SimpleEntry<>(Account_.BALANCE, Account_.balance)
225+
)
226+
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
227+
228+
/**
229+
* Return all accounts owned by a given customer,given his/her external id
230+
*
231+
* @param customerId
232+
* @return
233+
*/
234+
public List<AccountDTO> safeJpaFindAccountsByCustomerId(String customerId, String orderBy) {
235+
236+
SingularAttribute<Account,?> orderByAttribute = VALID_JPA_COLUMNS_FOR_ORDER_BY.get(orderBy);
237+
if ( orderByAttribute == null) {
238+
throw new IllegalArgumentException("Nice try!");
239+
}
240+
241+
CriteriaBuilder cb = em.getCriteriaBuilder();
242+
CriteriaQuery<Account> cq = cb.createQuery(Account.class);
243+
Root<Account> root = cq.from(Account.class);
244+
cq.select(root)
245+
.where(cb.equal(root.get(Account_.customerId), customerId))
246+
.orderBy(cb.asc(root.get(orderByAttribute)));
247+
248+
TypedQuery<Account> q = em.createQuery(cq);
249+
250+
return q.getResultList()
251+
.stream()
252+
.map(a -> AccountDTO.builder()
253+
.accNumber(a.getAccNumber())
254+
.balance(a.getBalance())
255+
.branchId(a.getAccNumber())
256+
.customerId(a.getCustomerId())
257+
.build())
258+
.collect(Collectors.toList());
259+
260+
}
261+
138262
/**
139263
* Invalid placeholder usage example
140264
*
141265
* @param tableName
142266
* @return
143267
*/
144-
public List<AccountDTO> wrongCountRecordsByTableName(String tableName) {
268+
public Long wrongCountRecordsByTableName(String tableName) {
269+
270+
try (Connection c = dataSource.getConnection(); PreparedStatement p = c.prepareStatement("select count(*) from ?")) {
145271

146-
try (Connection c = dataSource.getConnection();
147-
PreparedStatement p = c.prepareStatement("select count(*) from ?")) {
148-
149272
p.setString(1, tableName);
150273
ResultSet rs = p.executeQuery();
151-
List<AccountDTO> accounts = new ArrayList<>();
152-
while (rs.next()) {
153-
AccountDTO acc = AccountDTO.builder()
154-
.customerId(rs.getString("customerId"))
155-
.branchId(rs.getString("branch_id"))
156-
.accNumber(rs.getString("acc_number"))
157-
.balance(rs.getBigDecimal("balance"))
158-
.build();
159-
160-
accounts.add(acc);
161-
}
274+
rs.next();
275+
return rs.getLong(1);
162276

163-
return accounts;
164277
} catch (SQLException ex) {
165278
throw new RuntimeException(ex);
166279
}
167280
}
168281

282+
/**
283+
* Invalid placeholder usage example - JPA
284+
*
285+
* @param tableName
286+
* @return
287+
*/
288+
public Long wrongJpaCountRecordsByTableName(String tableName) {
289+
290+
String jql = "select count(*) from :tableName";
291+
TypedQuery<Long> q = em.createQuery(jql, Long.class)
292+
.setParameter("tableName", tableName);
293+
294+
return q.getSingleResult();
295+
296+
}
297+
169298
}
Lines changed: 1 addition & 0 deletions

‎software-security/sql-injection-samples/src/main/resources/db/changelog/create-tables.xml‎

Lines changed: 0 additions & 19 deletions
This file was deleted.

‎software-security/sql-injection-samples/src/main/resources/db/master-changelog.xml‎

Lines changed: 0 additions & 8 deletions
This file was deleted.

0 commit comments

Comments
 (0)