Skip to content

Commit 9e334e9

Browse files
committed
Update jpa-orders
1 parent 90aec41 commit 9e334e9

File tree

11 files changed

+176
-53
lines changed

11 files changed

+176
-53
lines changed

roach-data-jpa-orders/src/main/java/io/roach/data/jpa/JpaOrdersApplication.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,13 @@
88
import org.springframework.boot.builder.SpringApplicationBuilder;
99
import org.springframework.context.annotation.ComponentScan;
1010
import org.springframework.context.annotation.Configuration;
11-
import org.springframework.context.annotation.EnableAspectJAutoProxy;
1211

1312
@Configuration
1413
@EnableAutoConfiguration(exclude = {
1514
TransactionAutoConfiguration.class,
1615
DataSourceTransactionManagerAutoConfiguration.class,
1716
DataSourceAutoConfiguration.class
1817
})
19-
@EnableAspectJAutoProxy(proxyTargetClass = true)
2018
@ComponentScan(basePackages = "io.roach")
2119
public class JpaOrdersApplication {
2220
public static void main(String[] args) {

roach-data-jpa-orders/src/main/java/io/roach/data/jpa/OrderClient.java

Lines changed: 0 additions & 36 deletions
This file was deleted.
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package io.roach.data.jpa;
2+
3+
import org.slf4j.Logger;
4+
import org.slf4j.LoggerFactory;
5+
import org.springframework.beans.factory.annotation.Autowired;
6+
import org.springframework.boot.CommandLineRunner;
7+
import org.springframework.stereotype.Component;
8+
9+
import io.roach.data.jpa.service.OrderSystem;
10+
11+
@Component
12+
public class OrderSystemClient implements CommandLineRunner {
13+
protected final Logger logger = LoggerFactory.getLogger(getClass());
14+
15+
@Autowired
16+
private OrderSystem orderSystem;
17+
18+
@Override
19+
public void run(String... args) {
20+
logger.info("Clear all...");
21+
orderSystem.clearAll();
22+
23+
logger.info(">> Creating products...");
24+
orderSystem.createProductInventory();
25+
26+
logger.info(">> Creating customers...");
27+
orderSystem.createCustomers();
28+
29+
logger.info(">> Creating orders...");
30+
orderSystem.createOrders();
31+
32+
logger.info(">> Listing orders...");
33+
orderSystem.listOrders();
34+
35+
logger.info(">> Find by sku: {}", orderSystem.findProductBySku("CRDB-UL-ED1"));
36+
37+
logger.info(">> Get total order price: {}", orderSystem.getTotalOrderPrice());
38+
39+
// logger.info("Removing orders...");
40+
// orderSystem.removeOrders();
41+
}
42+
}

roach-data-jpa-orders/src/main/java/io/roach/data/jpa/repository/ProductRepository.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,21 @@
33
import java.util.Optional;
44
import java.util.UUID;
55

6+
import javax.persistence.LockModeType;
7+
68
import org.springframework.data.jpa.repository.JpaRepository;
9+
import org.springframework.data.jpa.repository.Lock;
10+
import org.springframework.data.jpa.repository.Query;
11+
import org.springframework.data.repository.query.Param;
712
import org.springframework.stereotype.Repository;
813

914
import io.roach.data.jpa.domain.Product;
1015

1116
@Repository
1217
public interface ProductRepository extends JpaRepository<Product, UUID> {
18+
@Lock(LockModeType.PESSIMISTIC_READ)
1319
Optional<Product> findProductBySku(String sku);
20+
21+
@Query("select p from Product p where p.sku=:sku")
22+
Optional<Product> findProductBySkuNoLock(@Param("sku") String sku);
1423
}

roach-data-jpa-orders/src/main/java/io/roach/data/jpa/config/JpaConfiguration.java renamed to roach-data-jpa-orders/src/main/java/io/roach/data/jpa/service/JpaConfiguration.java

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package io.roach.data.jpa.config;
1+
package io.roach.data.jpa.service;
22

33
import java.util.Properties;
44

@@ -8,11 +8,15 @@
88
import org.hibernate.cache.internal.NoCachingRegionFactory;
99
import org.hibernate.cfg.Environment;
1010
import org.hibernate.dialect.CockroachDB201Dialect;
11+
import org.postgresql.ds.PGSimpleDataSource;
12+
import org.slf4j.Logger;
13+
import org.slf4j.LoggerFactory;
1114
import org.springframework.beans.factory.annotation.Autowired;
1215
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
1316
import org.springframework.boot.context.properties.ConfigurationProperties;
1417
import org.springframework.context.annotation.Bean;
1518
import org.springframework.context.annotation.Configuration;
19+
import org.springframework.context.annotation.EnableAspectJAutoProxy;
1620
import org.springframework.context.annotation.Primary;
1721
import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor;
1822
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
@@ -24,16 +28,18 @@
2428
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
2529
import org.springframework.transaction.PlatformTransactionManager;
2630
import org.springframework.transaction.annotation.EnableTransactionManagement;
27-
28-
import com.zaxxer.hikari.HikariDataSource;
31+
import org.springframework.transaction.support.TransactionTemplate;
2932

3033
import net.ttddyy.dsproxy.listener.logging.SLF4JLogLevel;
3134
import net.ttddyy.dsproxy.support.ProxyDataSourceBuilder;
3235

3336
@Configuration
3437
@EnableTransactionManagement(proxyTargetClass = true)
38+
@EnableAspectJAutoProxy(proxyTargetClass = true)
3539
@EnableJpaRepositories(basePackages = {"io.roach"})
3640
public class JpaConfiguration {
41+
private final Logger logger = LoggerFactory.getLogger(getClass());
42+
3743
@Bean
3844
@ConfigurationProperties("spring.datasource")
3945
public DataSourceProperties dataSourceProperties() {
@@ -42,18 +48,18 @@ public DataSourceProperties dataSourceProperties() {
4248

4349
@Bean
4450
@ConfigurationProperties("spring.datasource.hikari")
45-
public HikariDataSource hikariDataSource() {
51+
public PGSimpleDataSource primaryDataSource() {
4652
return dataSourceProperties()
4753
.initializeDataSourceBuilder()
48-
.type(HikariDataSource.class)
54+
.type(PGSimpleDataSource.class)
4955
.build();
5056
}
5157

5258
@Bean
5359
@Primary
5460
public DataSource dataSource() {
5561
return ProxyDataSourceBuilder
56-
.create(hikariDataSource())
62+
.create(primaryDataSource())
5763
.name("SQL-Trace")
5864
.asJson()
5965
.logQueryBySlf4j(SLF4JLogLevel.TRACE, "io.roach.SQL_TRACE")
@@ -84,6 +90,11 @@ public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
8490
return emf;
8591
}
8692

93+
@Bean
94+
public TransactionTemplate transactionTemplate(EntityManagerFactory entityManagerFactory) {
95+
return new TransactionTemplate(transactionManager(entityManagerFactory));
96+
}
97+
8798
private Properties jpaVendorProperties() {
8899
return new Properties() {
89100
{
@@ -99,6 +110,7 @@ private Properties jpaVendorProperties() {
99110
setProperty(Environment.FORMAT_SQL, Boolean.FALSE.toString());
100111
// Mutes Postgres JPA Error (Method org.postgresql.jdbc.PgConnection.createClob() is not yet implemented).
101112
setProperty(Environment.NON_CONTEXTUAL_LOB_CREATION, Boolean.TRUE.toString());
113+
// setProperty(Environment.CONNECTION_PROVIDER_DISABLES_AUTOCOMMIT, Boolean.TRUE.toString());
102114
}
103115
};
104116
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package io.roach.data.jpa.service;
2+
3+
import java.math.BigDecimal;
4+
import java.util.List;
5+
6+
import org.springframework.beans.factory.annotation.Autowired;
7+
import org.springframework.stereotype.Service;
8+
import org.springframework.transaction.annotation.Propagation;
9+
import org.springframework.transaction.annotation.Transactional;
10+
11+
import io.roach.data.jpa.domain.Order;
12+
import io.roach.data.jpa.repository.OrderRepository;
13+
14+
@Service
15+
public class OrderService {
16+
@Autowired
17+
private OrderRepository orderRepository;
18+
19+
@Transactional(propagation = Propagation.REQUIRES_NEW,readOnly = true)
20+
public BigDecimal getTotalOrderPrice() {
21+
BigDecimal price = BigDecimal.ZERO;
22+
List<Order> orders = orderRepository.findAll();
23+
for (Order order : orders) {
24+
price = price.add(order.getTotalPrice());
25+
}
26+
return price;
27+
}
28+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package io.roach.data.jpa.service;
2+
3+
import java.math.BigDecimal;
4+
5+
import io.roach.data.jpa.domain.Product;
6+
7+
public interface OrderSystem {
8+
void clearAll();
9+
10+
void createProductInventory();
11+
12+
void createCustomers();
13+
14+
void createOrders();
15+
16+
void listOrders();
17+
18+
Product findProductBySku(String sku);
19+
20+
BigDecimal getTotalOrderPrice();
21+
22+
void removeOrders();
23+
}

roach-data-jpa-orders/src/main/java/io/roach/data/jpa/OrderSystemFacade.java renamed to roach-data-jpa-orders/src/main/java/io/roach/data/jpa/service/OrderSystemImpl.java

Lines changed: 49 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package io.roach.data.jpa;
1+
package io.roach.data.jpa.service;
22

33
import java.math.BigDecimal;
44
import java.util.Optional;
@@ -7,11 +7,16 @@
77
import org.slf4j.LoggerFactory;
88
import org.springframework.beans.factory.annotation.Autowired;
99
import org.springframework.stereotype.Service;
10+
import org.springframework.transaction.PlatformTransactionManager;
11+
import org.springframework.transaction.TransactionStatus;
1012
import org.springframework.transaction.annotation.Propagation;
1113
import org.springframework.transaction.annotation.Transactional;
14+
import org.springframework.transaction.support.TransactionCallback;
1215
import org.springframework.transaction.support.TransactionSynchronizationManager;
16+
import org.springframework.transaction.support.TransactionTemplate;
1317
import org.springframework.util.Assert;
1418

19+
import io.roach.data.jpa.JpaOrdersApplication;
1520
import io.roach.data.jpa.domain.Customer;
1621
import io.roach.data.jpa.domain.Order;
1722
import io.roach.data.jpa.domain.Product;
@@ -20,7 +25,7 @@
2025
import io.roach.data.jpa.repository.ProductRepository;
2126

2227
@Service
23-
public class OrderSystemFacade {
28+
public class OrderSystemImpl implements OrderSystem {
2429
protected static final Logger logger = LoggerFactory.getLogger(JpaOrdersApplication.class);
2530

2631
@Autowired
@@ -32,6 +37,10 @@ public class OrderSystemFacade {
3237
@Autowired
3338
private OrderRepository orderRepository;
3439

40+
@Autowired
41+
private OrderService orderService;
42+
43+
@Override
3544
@Transactional(propagation = Propagation.REQUIRES_NEW)
3645
public void clearAll() {
3746
Assert.isTrue(TransactionSynchronizationManager.isActualTransactionActive(), "TX not active");
@@ -40,6 +49,7 @@ public void clearAll() {
4049
customerRepository.deleteAll();
4150
}
4251

52+
@Override
4353
@Transactional(propagation = Propagation.REQUIRES_NEW)
4454
public void createProductInventory() {
4555
Product p1 = Product.builder()
@@ -60,6 +70,7 @@ public void createProductInventory() {
6070
productRepository.save(p2);
6171
}
6272

73+
@Override
6374
@Transactional(propagation = Propagation.REQUIRES_NEW)
6475
public void createCustomers() {
6576
Customer c1 = Customer.builder()
@@ -78,6 +89,7 @@ public void createCustomers() {
7889
customerRepository.save(c2);
7990
}
8091

92+
@Override
8193
@Transactional(propagation = Propagation.REQUIRES_NEW)
8294
public void createOrders() {
8395
Optional<Product> p1 = productRepository.findProductBySku("CRDB-UL-ED1");
@@ -120,7 +132,8 @@ public void createOrders() {
120132
orderRepository.save(o2);
121133
}
122134

123-
@Transactional(propagation = Propagation.REQUIRES_NEW)
135+
@Override
136+
@Transactional(propagation = Propagation.REQUIRES_NEW, readOnly = true)
124137
public void listOrders() {
125138
logger.info("Placed orders:");
126139

@@ -145,6 +158,39 @@ public void listOrders() {
145158

146159
}
147160

161+
@Autowired
162+
private PlatformTransactionManager transactionManager;
163+
164+
@Override
165+
@Transactional(propagation = Propagation.NEVER, readOnly = true)
166+
public Product findProductBySku(String sku) {
167+
Assert.isTrue(TransactionSynchronizationManager.isCurrentTransactionReadOnly(),"Not read-only");
168+
Assert.isTrue(!TransactionSynchronizationManager.isActualTransactionActive(),"No tx");
169+
170+
TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager);
171+
transactionTemplate.setReadOnly(true);
172+
173+
Product p= transactionTemplate.execute(new TransactionCallback<Product>() {
174+
@Override
175+
public Product doInTransaction(TransactionStatus status) {
176+
Optional<Product> p1 = productRepository.findProductBySkuNoLock(sku);
177+
Product p = p1.orElseThrow(() -> new IllegalArgumentException("Not found"));
178+
p.setPrice(BigDecimal.ZERO);
179+
return p;
180+
181+
}
182+
});
183+
productRepository.saveAndFlush(p);
184+
return p;
185+
}
186+
187+
@Override
188+
@Transactional(propagation = Propagation.REQUIRES_NEW, readOnly = false)
189+
public BigDecimal getTotalOrderPrice() {
190+
return orderService.getTotalOrderPrice();
191+
}
192+
193+
@Override
148194
@Transactional(propagation = Propagation.REQUIRES_NEW)
149195
public void removeOrders() {
150196
orderRepository.findOrdersByUserName("adolfo").forEach(order -> {

roach-data-jpa-orders/src/main/resources/application.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ spring:
1414
enabled: true
1515
clean-on-validation-error: true
1616
ignore-pending-migrations: true
17+
baseline-on-migrate: true
1718
datasource:
1819
url: jdbc:postgresql://localhost:26257/roach_data?sslmode=disable
1920
driver-class-name: org.postgresql.Driver
@@ -23,6 +24,7 @@ spring:
2324
connection-test-query: SELECT 1
2425
maximum-pool-size: 20
2526
minimum-idle: 20
27+
auto-commit: false
2628
jpa:
2729
open-in-view: false
2830
properties:

0 commit comments

Comments
 (0)