Skip to content

Commit 8525c14

Browse files
committed
Added more docs and demo code alignment
1 parent 096736e commit 8525c14

File tree

9 files changed

+66
-78
lines changed

9 files changed

+66
-78
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ Common Spring Boot features in all demos:
2323
- Hypermedia API via Spring HATEOAS and HAL media type
2424
- Simple HTTP client invoking commands
2525

26-
The most documented demo is the JDBC version. It also includes an extra aspect for setting
27-
transaction attributes including time travel / follower reads.
26+
The most documented demo is the JDBC version. It includes an extra aspect for setting transaction attributes such
27+
as time travel / follower reads.
2828

2929
## Prerequisites
3030

jdbc/README.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# Roach Demo Data :: JDBC
22

3-
Spring Boot Demo using CockroachDB with vanilla spring-data-jdbc.
3+
A CockroachDB Spring Boot Demo using [Spring Data JDBC](https://spring.io/projects/spring-data-jdbc)
4+
for data access.
5+
6+
Spring Data JDBC provides a simpler, yet powerful model than JPA or any other ORM frameworks. It's considered a good
7+
fit for data access logic that doesn't involve large, complex domain model mapping or any of the advanced features
8+
of JPA, such as lazy loading, second level caching, auto-batching and transparent persistence.
49

10+
The JDBC demo has most code comments and also provides a few extra features compared to the other modules.
511

jdbc/pom.xml

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,6 @@
3535
<groupId>org.springframework.boot</groupId>
3636
<artifactId>spring-boot-starter-actuator</artifactId>
3737
</dependency>
38-
<!--
39-
<dependency>
40-
<groupId>org.springframework.data</groupId>
41-
<artifactId>spring-data-commons</artifactId>
42-
</dependency>
43-
-->
4438
<dependency>
4539
<groupId>org.liquibase</groupId>
4640
<artifactId>liquibase-core</artifactId>
@@ -58,16 +52,6 @@
5852
<plugin>
5953
<groupId>org.springframework.boot</groupId>
6054
<artifactId>spring-boot-maven-plugin</artifactId>
61-
<!--
62-
<executions>
63-
<execution>
64-
<configuration>
65-
<executable>true</executable>
66-
<mainClass>io.roach.demo.data.JdbcApplication</mainClass>
67-
</configuration>
68-
</execution>
69-
</executions>
70-
-->
7155
</plugin>
7256
</plugins>
7357
</build>

jdbc/src/main/java/io/roach/demo/data/JdbcApplication.java

Lines changed: 34 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,9 @@ public static void main(String[] args) {
106106
testClient();
107107
}
108108

109+
/**
110+
* Client logic that submits money transfer requests to the REST API.
111+
*/
109112
public static void testClient() {
110113
logger.info("Lets move some $$ around!");
111114

@@ -164,6 +167,9 @@ enum AccountType {
164167
expense
165168
}
166169

170+
/**
171+
* Domain entity mapped to the account table.
172+
*/
167173
class Account {
168174
@Id
169175
private Long id;
@@ -191,6 +197,9 @@ public BigDecimal getBalance() {
191197
}
192198
}
193199

200+
/**
201+
* Account resource represented in HAL+JSON via REST API.
202+
*/
194203
@Relation(value = "account", collectionRelation = "accounts")
195204
class AccountModel extends RepresentationModel<AccountModel> {
196205
private String name;
@@ -225,27 +234,24 @@ public void setBalance(BigDecimal balance) {
225234
}
226235

227236
/**
228-
* Pagination is not available in spring-data-jdbc yet so we create a separate
229-
* repository to provide basic limit+offset pagination of accounts.
237+
* Pagination is not available in spring-data-jdbc (yet) so we create a separate
238+
* repository to provide basic limit+offset pagination queries for accounts.
230239
*/
231240
interface PagedAccountRepository {
232241
Page<Account> findAll(Pageable pageable);
233242
}
234243

235244
@Repository
236245
interface PagedAccountHelper extends org.springframework.data.repository.Repository<Account, Long> {
237-
/**
238-
* Selects a page of accounts using follower reads.
239-
*/
240246
@Query("SELECT * FROM account LIMIT :pageSize OFFSET :offset")
241247
List<Account> findAll(@Param("pageSize") int pageSize, @Param("offset") long offset);
242248

243-
@Query("SELECT count(id) from account")
249+
@Query("SELECT count(id) FROM account")
244250
long countAll();
245251
}
246252

247253
@Repository
248-
// @Transactional is not needed, only here for clarity since we want the repo to always be called from a tx context
254+
// @Transactional is not needed but here for clarity since we want repos to always be called from a tx context
249255
@Transactional(propagation = MANDATORY)
250256
class PagedAccountRepositoryImpl implements PagedAccountRepository {
251257
@Autowired
@@ -262,15 +268,17 @@ public Page<Account> findAll(Pageable pageable) {
262268
/**
263269
* The main account repository, notice there's no implementation needed since its auto-proxied by
264270
* spring-data.
271+
* <p>
272+
* Should have extended PagingAndSortingRepository in normal cases.
265273
*/
266274
@Repository
267275
@Transactional(propagation = MANDATORY)
268276
interface AccountRepository extends CrudRepository<Account, Long>, PagedAccountRepository {
269-
@Query(value = "select balance from account where id=:id")
277+
@Query(value = "SELECT balance FROM account WHERE id=:id")
270278
BigDecimal getBalance(@Param("id") Long id);
271279

272280
@Modifying
273-
@Query("update account set balance = balance + :balance where id=:id")
281+
@Query("UPDATE account SET balance = balance + :balance WHERE id=:id")
274282
void updateBalance(@Param("id") Long id, @Param("balance") BigDecimal balance);
275283
}
276284

@@ -285,7 +293,7 @@ public NegativeBalanceException(String message) {
285293
}
286294

287295
/**
288-
* Annotation marking a transaction boundary to use time travel.
296+
* Annotation marking a transaction boundary to use follower reads (time travel).
289297
* See https://www.cockroachlabs.com/docs/stable/follower-reads.html
290298
*/
291299
@Inherited
@@ -299,12 +307,16 @@ public NegativeBalanceException(String message) {
299307
/**
300308
* Main remoting and transaction boundary in the form of a REST controller. The discipline
301309
* when following the entity-control-boundary (ECB) pattern is that only service boundaries
302-
* are allowed to start and end transactions. That is enforced by the REQUIRES_NEW propagation
303-
* attribute of transactional controller methods. Between the web container's HTTP listener
304-
* and the transaction proxy there's also another transparent proxy in the form of a
305-
* retry loop advice with exponential backoff. It takes care of retrying transactions that
306-
* are aborted by transient SQL errors, rather than having these propagate all the way
307-
* over the wire to the HTTP client. See RetryableTransactionAspect below.
310+
* are allowed to start and end transactions. A service boundary can be a controller, business
311+
* service facade or service activator (JMS/Kafka listener).
312+
* <p>
313+
* This is enforced by the REQUIRES_NEW propagation attribute of @Transactional annotated
314+
* controller methods. Between the web container's HTTP listener and the transaction proxy,
315+
* there's yet another transparent proxy in the form of a retry loop advice with exponential
316+
* backoff. It takes care of retrying transactions that are aborted by transient SQL errors,
317+
* rather than having these propagate all the way over the wire to the client / user agent.
318+
*
319+
* @see RetryableTransactionAspect
308320
*/
309321
@RestController
310322
class AccountController {
@@ -325,10 +337,11 @@ public ResponseEntity<RepresentationModel> index() {
325337
// Type-safe way to generate URLs bound to controller methods
326338
index.add(linkTo(methodOn(AccountController.class)
327339
.listAccounts(PageRequest.of(0, 5)))
328-
.withRel("accounts"));
340+
.withRel("accounts")); // Lets skip curies and affordances for now
329341

330-
// This essentially informs the client that a POST to a href with this rel
331-
// and value parameters will transfer funds between accounts.
342+
// This rel essentially informs the client that a POST to its href with
343+
// form parameters will transfer funds between referenced accounts.
344+
// (its only a demo)
332345
index.add(linkTo(AccountController.class)
333346
.slash("transfer{?fromId,toId,amount}")
334347
.withRel("transfer"));
@@ -350,7 +363,7 @@ public ResponseEntity<RepresentationModel> index() {
350363
*/
351364
@GetMapping("/account")
352365
@Transactional(propagation = REQUIRES_NEW)
353-
@TimeTravel
366+
@TimeTravel // We dont need the result to be authoritative, so any follower replica can service the read
354367
public HttpEntity<PagedModel<AccountModel>> listAccounts(
355368
@PageableDefault(size = 5, direction = Sort.Direction.ASC) Pageable page) {
356369
return ResponseEntity
@@ -361,7 +374,7 @@ public HttpEntity<PagedModel<AccountModel>> listAccounts(
361374
* Provides a point lookup of a given account.
362375
*/
363376
@GetMapping(value = "/account/{id}")
364-
@Transactional(propagation = REQUIRES_NEW, readOnly = true)
377+
@Transactional(propagation = REQUIRES_NEW, readOnly = true) // Notice its marked read-only
365378
public HttpEntity<AccountModel> getAccount(@PathVariable("id") Long accountId) {
366379
return new ResponseEntity<>(accountModelAssembler().toModel(
367380
accountRepository.findById(accountId)

jooq/README.md

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
# Roach Demo Data :: jOOQ
22

3-
Spring Boot Demo using CockroachDB with jOOQ.
3+
A CockroachDB Spring Boot Demo using [jOOQ](https://www.jooq.org/) for data access.
44

55
## Generate jOOQ classes
66

7-
First create a DB schema:
7+
First create the DB schema:
88

99
create table account
1010
(
@@ -14,21 +14,13 @@ First create a DB schema:
1414
type varchar(25) not null
1515
);
1616

17-
Then generate the code by activating a Maven profile called generate:
17+
Then generate code by activating a Maven profile called _generate_:
1818

1919
mvn -P generate clean install
2020

2121
(Note: this will fail with an error when using CRDB even if classes are generated correctly)
2222

23-
Finally drop the table:
23+
Finally drop the table
2424

2525
drop table account cascade;
2626

27-
## Run
28-
29-
java -jar target/roach-demo-data.jar
30-
31-
Run with custom db URL:
32-
33-
java -jar target/roach-demo-data.jar --spring.datasource.url=jdbc:postgresql://localhost:26257/roach_demo_data?sslmode=disable
34-

jpa/README.md

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
# Roach Demo Data :: JPA/Hibernate
22

3-
Spring Boot Demo using CockroachDB with JPA/Hibernate.
4-
5-
## Run
6-
7-
java -jar target/roach-demo-data.jar
3+
A CockroachDB Spring Boot Demo using [Spring Data JPA](https://spring.io/projects/spring-data-jpa)
4+
with Hibernate for data access.
85

9-
With a custom DB URL:
6+
Spring Data JPA provides a powerful model for using ORM frameworks such as Hibernate. It's considered a good
7+
fit for data access logic that involve large, complex domain model mapping. Spring Data JPA essentially
8+
removes the need for application code to bind directly to Hibernate APIs. It also unlocks many advanced
9+
features of JPA.
10+
1011

11-
java -jar target/roach-demo-data.jar --spring.datasource.url=jdbc:postgresql://localhost:26257/roach_demo_data?sslmode=disable
12-
12+

jpa/src/main/java/io/roach/demo/data/JpaApplication.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ enum AccountType {
155155

156156
@Entity
157157
@Table(name = "account")
158-
class AccountEntity {
158+
class Account {
159159
@Id
160160
@Column
161161
@GeneratedValue(strategy = GenerationType.IDENTITY)
@@ -223,14 +223,14 @@ public void setBalance(BigDecimal balance) {
223223

224224
@Repository
225225
@Transactional(propagation = MANDATORY)
226-
interface AccountRepository extends JpaRepository<AccountEntity, Long>,
227-
JpaSpecificationExecutor<AccountEntity> {
226+
interface AccountRepository extends JpaRepository<Account, Long>,
227+
JpaSpecificationExecutor<Account> {
228228

229-
@Query(value = "select balance from AccountEntity where id=?1")
229+
@Query(value = "select balance from Account where id=?1")
230230
BigDecimal getBalance(Long id);
231231

232232
@Modifying
233-
@Query("update AccountEntity set balance = balance + ?2 where id=?1")
233+
@Query("update Account set balance = balance + ?2 where id=?1")
234234
void updateBalance(Long id, BigDecimal balance);
235235
}
236236

@@ -247,7 +247,7 @@ class AccountController {
247247
private AccountRepository accountRepository;
248248

249249
@Autowired
250-
private PagedResourcesAssembler<AccountEntity> pagedResourcesAssembler;
250+
private PagedResourcesAssembler<Account> pagedResourcesAssembler;
251251

252252
@GetMapping
253253
public ResponseEntity<RepresentationModel> index() {
@@ -305,7 +305,7 @@ public HttpEntity<BigDecimal> transfer(
305305
return ResponseEntity.ok().build();
306306
}
307307

308-
private RepresentationModelAssembler<AccountEntity, AccountModel> accountModelAssembler() {
308+
private RepresentationModelAssembler<Account, AccountModel> accountModelAssembler() {
309309
return (entity) -> {
310310
AccountModel model = new AccountModel();
311311
model.setName(entity.getName());

mybatis/README.md

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,5 @@
11
# Roach Demo Data :: MyBatis
22

3-
Spring Boot Demo using CockroachDB with MyBatis/JDBC.
4-
5-
## Run
6-
7-
java -jar target/roach-demo-data.jar
8-
9-
With a custom db URL:
10-
11-
java -jar target/roach-demo-data.jar --spring.datasource.url=jdbc:postgresql://localhost:26257/roach_demo_data?sslmode=disable
12-
3+
A CockroachDB Spring Boot Demo using [MyBatis](https://mybatis.org/mybatis-3/)
4+
integrated with [Spring Data JDBC](https://docs.spring.io/spring-data/jdbc/docs/1.1.6.RELEASE/reference/html/#jdbc.mybatis)
5+
for data access.

mybatis/src/main/java/io/roach/demo/data/MyBatisApplication.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,7 @@ interface AccountRepository extends CrudRepository<Account, Long>, PagedAccountR
263263
@Query("SELECT balance FROM account WHERE id = :id")
264264
BigDecimal getBalance(@Param("id") Long id);
265265

266-
@Query("UPDATE Account set balance = balance + :balance where id=:id")
266+
@Query("UPDATE account SET balance = balance + :balance WHERE id=:id")
267267
@Modifying
268268
void updateBalance(@Param("id") Long id, @Param("balance") BigDecimal balance);
269269
}

0 commit comments

Comments
 (0)