@@ -0,0 +1,4 @@
|
|||||||
|
### Relevant Articles:
|
||||||
|
|
||||||
|
- [Boruvka’s Algorithm for Minimum Spanning Trees](https://www.baeldung.com/java-boruvka-algorithm)
|
||||||
|
- [Gradient Descent in Java](https://www.baeldung.com/java-gradient-descent)
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
## Atomikos
|
||||||
|
|
||||||
|
This module contains articles about Atomikos
|
||||||
|
|
||||||
|
### Relevant Articles:
|
||||||
|
|
||||||
|
- [Guide Transactions Using Atomikos]()
|
||||||
@@ -0,0 +1,119 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<artifactId>atomikos</artifactId>
|
||||||
|
<name>atomikos</name>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<groupId>com.baeldung</groupId>
|
||||||
|
<artifactId>parent-modules</artifactId>
|
||||||
|
<version>1.0.0-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.atomikos</groupId>
|
||||||
|
<artifactId>transactions-jdbc</artifactId>
|
||||||
|
<version>${atomikos-version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.atomikos</groupId>
|
||||||
|
<artifactId>transactions-jms</artifactId>
|
||||||
|
<version>${atomikos-version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.atomikos</groupId>
|
||||||
|
<artifactId>transactions-hibernate4</artifactId>
|
||||||
|
<version>${atomikos-version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework</groupId>
|
||||||
|
<artifactId>spring-context</artifactId>
|
||||||
|
<version>${spring-version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework</groupId>
|
||||||
|
<artifactId>spring-tx</artifactId>
|
||||||
|
<version>${spring-version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.data</groupId>
|
||||||
|
<artifactId>spring-data-jpa</artifactId>
|
||||||
|
<version>1.11.23.RELEASE</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework</groupId>
|
||||||
|
<artifactId>spring-test</artifactId>
|
||||||
|
<version>${spring-version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.hibernate</groupId>
|
||||||
|
<artifactId>hibernate-entitymanager</artifactId>
|
||||||
|
<version>${hibernate.version}</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
<exclusions>
|
||||||
|
<exclusion>
|
||||||
|
<groupId>javax.transaction</groupId>
|
||||||
|
<artifactId>jta</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
</exclusions>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.activemq</groupId>
|
||||||
|
<artifactId>activemq-core</artifactId>
|
||||||
|
<version>5.7.0</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.derby</groupId>
|
||||||
|
<artifactId>derby</artifactId>
|
||||||
|
<version>10.8.1.2</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>junit</groupId>
|
||||||
|
<artifactId>junit</artifactId>
|
||||||
|
<version>4.12</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<!-- the JTA API -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>javax.transaction</groupId>
|
||||||
|
<artifactId>jta</artifactId>
|
||||||
|
<version>1.1</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.geronimo.specs</groupId>
|
||||||
|
<artifactId>geronimo-jta_1.0.1B_spec</artifactId>
|
||||||
|
<version>1.0</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>javax.validation</groupId>
|
||||||
|
<artifactId>validation-api</artifactId>
|
||||||
|
<version>2.0.1.Final</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.hibernate.validator</groupId>
|
||||||
|
<artifactId>hibernate-validator</artifactId>
|
||||||
|
<version>6.1.2.Final</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>javax.el</groupId>
|
||||||
|
<artifactId>javax.el-api</artifactId>
|
||||||
|
<version>3.0.0</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.glassfish.web</groupId>
|
||||||
|
<artifactId>javax.el</artifactId>
|
||||||
|
<version>2.2.4</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<atomikos-version>5.0.6</atomikos-version>
|
||||||
|
<spring-version>5.1.6.RELEASE</spring-version>
|
||||||
|
<hibernate.version>5.4.3.Final</hibernate.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
</project>
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
package com.baeldung.atomikos.direct;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.Statement;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import javax.sql.DataSource;
|
||||||
|
|
||||||
|
import com.atomikos.icatch.jta.UserTransactionImp;
|
||||||
|
|
||||||
|
public class Application {
|
||||||
|
|
||||||
|
private DataSource inventoryDataSource;
|
||||||
|
private DataSource orderDataSource;
|
||||||
|
|
||||||
|
public Application(DataSource inventoryDataSource, DataSource orderDataSource) {
|
||||||
|
this.inventoryDataSource = inventoryDataSource;
|
||||||
|
this.orderDataSource = orderDataSource;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void placeOrder(String productId, int amount) throws Exception {
|
||||||
|
|
||||||
|
UserTransactionImp utx = new UserTransactionImp();
|
||||||
|
String orderId = UUID.randomUUID()
|
||||||
|
.toString();
|
||||||
|
boolean rollback = false;
|
||||||
|
try {
|
||||||
|
utx.begin();
|
||||||
|
Connection inventoryConnection = inventoryDataSource.getConnection();
|
||||||
|
Connection orderConnection = orderDataSource.getConnection();
|
||||||
|
Statement s1 = inventoryConnection.createStatement();
|
||||||
|
String q1 = "update Inventory set balance = balance - " + amount + " where productId ='" + productId + "'";
|
||||||
|
s1.executeUpdate(q1);
|
||||||
|
s1.close();
|
||||||
|
Statement s2 = orderConnection.createStatement();
|
||||||
|
String q2 = "insert into Orders values ( '" + orderId + "', '" + productId + "', " + amount + " )";
|
||||||
|
s2.executeUpdate(q2);
|
||||||
|
s2.close();
|
||||||
|
inventoryConnection.close();
|
||||||
|
orderConnection.close();
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.out.println(e.getMessage());
|
||||||
|
rollback = true;
|
||||||
|
} finally {
|
||||||
|
if (!rollback)
|
||||||
|
utx.commit();
|
||||||
|
else
|
||||||
|
utx.rollback();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
package com.baeldung.atomikos.spring;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.Statement;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import javax.sql.DataSource;
|
||||||
|
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
public class Application {
|
||||||
|
|
||||||
|
private DataSource inventoryDataSource;
|
||||||
|
private DataSource orderDataSource;
|
||||||
|
|
||||||
|
public Application(DataSource inventoryDataSource, DataSource orderDataSource) {
|
||||||
|
this.inventoryDataSource = inventoryDataSource;
|
||||||
|
this.orderDataSource = orderDataSource;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public void placeOrder(String productId, int amount) throws Exception {
|
||||||
|
|
||||||
|
String orderId = UUID.randomUUID()
|
||||||
|
.toString();
|
||||||
|
Connection inventoryConnection = inventoryDataSource.getConnection();
|
||||||
|
Connection orderConnection = orderDataSource.getConnection();
|
||||||
|
Statement s1 = inventoryConnection.createStatement();
|
||||||
|
String q1 = "update Inventory set balance = balance - " + amount + " where productId ='" + productId + "'";
|
||||||
|
s1.executeUpdate(q1);
|
||||||
|
s1.close();
|
||||||
|
Statement s2 = orderConnection.createStatement();
|
||||||
|
String q2 = "insert into Orders values ( '" + orderId + "', '" + productId + "', " + amount + " )";
|
||||||
|
s2.executeUpdate(q2);
|
||||||
|
s2.close();
|
||||||
|
inventoryConnection.close();
|
||||||
|
orderConnection.close();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
package com.baeldung.atomikos.spring.config;
|
||||||
|
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
import javax.transaction.SystemException;
|
||||||
|
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.transaction.annotation.EnableTransactionManagement;
|
||||||
|
import org.springframework.transaction.jta.JtaTransactionManager;
|
||||||
|
|
||||||
|
import com.atomikos.icatch.jta.UserTransactionManager;
|
||||||
|
import com.atomikos.jdbc.AtomikosDataSourceBean;
|
||||||
|
import com.baeldung.atomikos.spring.Application;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@EnableTransactionManagement
|
||||||
|
public class Config {
|
||||||
|
|
||||||
|
@Bean(initMethod = "init", destroyMethod = "close")
|
||||||
|
public AtomikosDataSourceBean inventoryDataSource() {
|
||||||
|
AtomikosDataSourceBean dataSource = new AtomikosDataSourceBean();
|
||||||
|
dataSource.setLocalTransactionMode(true);
|
||||||
|
dataSource.setUniqueResourceName("db1");
|
||||||
|
dataSource.setXaDataSourceClassName("org.apache.derby.jdbc.EmbeddedXADataSource");
|
||||||
|
Properties xaProperties = new Properties();
|
||||||
|
xaProperties.put("databaseName", "db1");
|
||||||
|
xaProperties.put("createDatabase", "create");
|
||||||
|
dataSource.setXaProperties(xaProperties);
|
||||||
|
dataSource.setPoolSize(10);
|
||||||
|
return dataSource;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean(initMethod = "init", destroyMethod = "close")
|
||||||
|
public AtomikosDataSourceBean orderDataSource() {
|
||||||
|
AtomikosDataSourceBean dataSource = new AtomikosDataSourceBean();
|
||||||
|
dataSource.setLocalTransactionMode(true);
|
||||||
|
dataSource.setUniqueResourceName("db2");
|
||||||
|
dataSource.setXaDataSourceClassName("org.apache.derby.jdbc.EmbeddedXADataSource");
|
||||||
|
Properties xaProperties = new Properties();
|
||||||
|
xaProperties.put("databaseName", "db2");
|
||||||
|
xaProperties.put("createDatabase", "create");
|
||||||
|
dataSource.setXaProperties(xaProperties);
|
||||||
|
dataSource.setPoolSize(10);
|
||||||
|
return dataSource;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean(initMethod = "init", destroyMethod = "close")
|
||||||
|
public UserTransactionManager userTransactionManager() throws SystemException {
|
||||||
|
UserTransactionManager userTransactionManager = new UserTransactionManager();
|
||||||
|
userTransactionManager.setTransactionTimeout(300);
|
||||||
|
userTransactionManager.setForceShutdown(true);
|
||||||
|
return userTransactionManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public JtaTransactionManager jtaTransactionManager() throws SystemException {
|
||||||
|
JtaTransactionManager jtaTransactionManager = new JtaTransactionManager();
|
||||||
|
jtaTransactionManager.setTransactionManager(userTransactionManager());
|
||||||
|
jtaTransactionManager.setUserTransaction(userTransactionManager());
|
||||||
|
return jtaTransactionManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public Application application() {
|
||||||
|
return new Application(inventoryDataSource(), orderDataSource());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
package com.baeldung.atomikos.spring.jpa;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import javax.validation.ConstraintViolation;
|
||||||
|
import javax.validation.Validation;
|
||||||
|
import javax.validation.Validator;
|
||||||
|
import javax.validation.ValidatorFactory;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import com.baeldung.atomikos.spring.jpa.inventory.Inventory;
|
||||||
|
import com.baeldung.atomikos.spring.jpa.inventory.InventoryRepository;
|
||||||
|
import com.baeldung.atomikos.spring.jpa.order.Order;
|
||||||
|
import com.baeldung.atomikos.spring.jpa.order.OrderRepository;
|
||||||
|
|
||||||
|
public class Application {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private InventoryRepository inventoryRepository;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private OrderRepository orderRepository;
|
||||||
|
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public void placeOrder(String productId, int amount) throws Exception {
|
||||||
|
|
||||||
|
String orderId = UUID.randomUUID()
|
||||||
|
.toString();
|
||||||
|
Inventory inventory = inventoryRepository.findOne(productId);
|
||||||
|
inventory.setBalance(inventory.getBalance() - amount);
|
||||||
|
inventoryRepository.save(inventory);
|
||||||
|
Order order = new Order();
|
||||||
|
order.setOrderId(orderId);
|
||||||
|
order.setProductId(productId);
|
||||||
|
order.setAmount(new Long(amount));
|
||||||
|
ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
|
||||||
|
Validator validator = factory.getValidator();
|
||||||
|
Set<ConstraintViolation<Order>> violations = validator.validate(order);
|
||||||
|
if (violations.size() > 0)
|
||||||
|
throw new Exception("Invalid instance of an order.");
|
||||||
|
orderRepository.save(order);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
package com.baeldung.atomikos.spring.jpa.config;
|
||||||
|
|
||||||
|
import javax.transaction.SystemException;
|
||||||
|
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.transaction.annotation.EnableTransactionManagement;
|
||||||
|
import org.springframework.transaction.jta.JtaTransactionManager;
|
||||||
|
|
||||||
|
import com.atomikos.icatch.jta.UserTransactionManager;
|
||||||
|
import com.baeldung.atomikos.spring.jpa.Application;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@EnableTransactionManagement
|
||||||
|
public class Config {
|
||||||
|
|
||||||
|
@Bean(initMethod = "init", destroyMethod = "close")
|
||||||
|
public UserTransactionManager userTransactionManager() throws SystemException {
|
||||||
|
UserTransactionManager userTransactionManager = new UserTransactionManager();
|
||||||
|
userTransactionManager.setTransactionTimeout(300);
|
||||||
|
userTransactionManager.setForceShutdown(true);
|
||||||
|
return userTransactionManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public JtaTransactionManager transactionManager() throws SystemException {
|
||||||
|
JtaTransactionManager jtaTransactionManager = new JtaTransactionManager();
|
||||||
|
jtaTransactionManager.setTransactionManager(userTransactionManager());
|
||||||
|
jtaTransactionManager.setUserTransaction(userTransactionManager());
|
||||||
|
return jtaTransactionManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public Application application() {
|
||||||
|
return new Application();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
package com.baeldung.atomikos.spring.jpa.inventory;
|
||||||
|
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Table(name = "INVENTORY")
|
||||||
|
public class Inventory {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
private String productId;
|
||||||
|
private Long balance;
|
||||||
|
|
||||||
|
public String getProductId() {
|
||||||
|
return productId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setProductId(String productId) {
|
||||||
|
this.productId = productId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getBalance() {
|
||||||
|
return balance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBalance(Long balance) {
|
||||||
|
this.balance = balance;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+53
@@ -0,0 +1,53 @@
|
|||||||
|
package com.baeldung.atomikos.spring.jpa.inventory;
|
||||||
|
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
import javax.persistence.EntityManagerFactory;
|
||||||
|
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
|
||||||
|
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
|
||||||
|
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
|
||||||
|
|
||||||
|
import com.atomikos.jdbc.AtomikosDataSourceBean;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@EnableJpaRepositories(basePackages = "com.baeldung.atomikos.spring.jpa.inventory", entityManagerFactoryRef = "inventoryEntityManager", transactionManagerRef = "transactionManager")
|
||||||
|
public class InventoryConfig {
|
||||||
|
|
||||||
|
@Bean(initMethod = "init", destroyMethod = "close")
|
||||||
|
public AtomikosDataSourceBean inventoryDataSource() {
|
||||||
|
AtomikosDataSourceBean dataSource = new AtomikosDataSourceBean();
|
||||||
|
dataSource.setLocalTransactionMode(true);
|
||||||
|
dataSource.setUniqueResourceName("db1");
|
||||||
|
dataSource.setXaDataSourceClassName("org.apache.derby.jdbc.EmbeddedXADataSource");
|
||||||
|
Properties xaProperties = new Properties();
|
||||||
|
xaProperties.put("databaseName", "db1");
|
||||||
|
xaProperties.put("createDatabase", "create");
|
||||||
|
dataSource.setXaProperties(xaProperties);
|
||||||
|
dataSource.setPoolSize(10);
|
||||||
|
return dataSource;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public EntityManagerFactory inventoryEntityManager() {
|
||||||
|
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
|
||||||
|
LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
|
||||||
|
factory.setJpaVendorAdapter(vendorAdapter);
|
||||||
|
factory.setPackagesToScan("com.baeldung.atomikos.spring.jpa.inventory");
|
||||||
|
factory.setDataSource(inventoryDataSource());
|
||||||
|
Properties jpaProperties = new Properties();
|
||||||
|
//jpaProperties.put("hibernate.show_sql", "true");
|
||||||
|
//jpaProperties.put("hibernate.format_sql", "true");
|
||||||
|
jpaProperties.put("hibernate.dialect", "org.hibernate.dialect.DerbyDialect");
|
||||||
|
jpaProperties.put("hibernate.current_session_context_class", "jta");
|
||||||
|
jpaProperties.put("javax.persistence.transactionType", "jta");
|
||||||
|
jpaProperties.put("hibernate.transaction.manager_lookup_class", "com.atomikos.icatch.jta.hibernate3.TransactionManagerLookup");
|
||||||
|
jpaProperties.put("hibernate.hbm2ddl.auto", "create-drop");
|
||||||
|
factory.setJpaProperties(jpaProperties);
|
||||||
|
factory.afterPropertiesSet();
|
||||||
|
return factory.getObject();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+9
@@ -0,0 +1,9 @@
|
|||||||
|
package com.baeldung.atomikos.spring.jpa.inventory;
|
||||||
|
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
|
@Repository
|
||||||
|
public interface InventoryRepository extends JpaRepository<Inventory, String> {
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
package com.baeldung.atomikos.spring.jpa.order;
|
||||||
|
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
import javax.validation.constraints.Max;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Table(name = "ORDERS")
|
||||||
|
public class Order {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
private String orderId;
|
||||||
|
private String productId;
|
||||||
|
@Max(5)
|
||||||
|
private Long amount;
|
||||||
|
|
||||||
|
public String getOrderId() {
|
||||||
|
return orderId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOrderId(String orderId) {
|
||||||
|
this.orderId = orderId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getProductId() {
|
||||||
|
return productId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setProductId(String productId) {
|
||||||
|
this.productId = productId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getAmount() {
|
||||||
|
return amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAmount(Long amount) {
|
||||||
|
this.amount = amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
package com.baeldung.atomikos.spring.jpa.order;
|
||||||
|
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
import javax.persistence.EntityManagerFactory;
|
||||||
|
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
|
||||||
|
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
|
||||||
|
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
|
||||||
|
|
||||||
|
import com.atomikos.jdbc.AtomikosDataSourceBean;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@EnableJpaRepositories(basePackages = "com.baeldung.atomikos.spring.jpa.order", entityManagerFactoryRef = "orderEntityManager", transactionManagerRef = "transactionManager")
|
||||||
|
public class OrderConfig {
|
||||||
|
|
||||||
|
@Bean(initMethod = "init", destroyMethod = "close")
|
||||||
|
public AtomikosDataSourceBean orderDataSource() {
|
||||||
|
AtomikosDataSourceBean dataSource = new AtomikosDataSourceBean();
|
||||||
|
dataSource.setLocalTransactionMode(true);
|
||||||
|
dataSource.setUniqueResourceName("db2");
|
||||||
|
dataSource.setXaDataSourceClassName("org.apache.derby.jdbc.EmbeddedXADataSource");
|
||||||
|
Properties xaProperties = new Properties();
|
||||||
|
xaProperties.put("databaseName", "db2");
|
||||||
|
xaProperties.put("createDatabase", "create");
|
||||||
|
dataSource.setXaProperties(xaProperties);
|
||||||
|
dataSource.setPoolSize(10);
|
||||||
|
return dataSource;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public EntityManagerFactory orderEntityManager() {
|
||||||
|
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
|
||||||
|
LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
|
||||||
|
factory.setJpaVendorAdapter(vendorAdapter);
|
||||||
|
factory.setPackagesToScan("com.baeldung.atomikos.spring.jpa.order");
|
||||||
|
factory.setDataSource(orderDataSource());
|
||||||
|
Properties jpaProperties = new Properties();
|
||||||
|
//jpaProperties.put("hibernate.show_sql", "true");
|
||||||
|
//jpaProperties.put("hibernate.format_sql", "true");
|
||||||
|
jpaProperties.put("hibernate.dialect", "org.hibernate.dialect.DerbyDialect");
|
||||||
|
jpaProperties.put("hibernate.current_session_context_class", "jta");
|
||||||
|
jpaProperties.put("javax.persistence.transactionType", "jta");
|
||||||
|
jpaProperties.put("hibernate.transaction.manager_lookup_class", "com.atomikos.icatch.jta.hibernate3.TransactionManagerLookup");
|
||||||
|
jpaProperties.put("hibernate.hbm2ddl.auto", "create-drop");
|
||||||
|
factory.setJpaProperties(jpaProperties);
|
||||||
|
factory.afterPropertiesSet();
|
||||||
|
return factory.getObject();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
package com.baeldung.atomikos.spring.jpa.order;
|
||||||
|
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
|
@Repository
|
||||||
|
public interface OrderRepository extends JpaRepository<Order, String> {
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<configuration>
|
||||||
|
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||||
|
<encoder>
|
||||||
|
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
|
||||||
|
</pattern>
|
||||||
|
</encoder>
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
<root level="INFO">
|
||||||
|
<appender-ref ref="STDOUT" />
|
||||||
|
</root>
|
||||||
|
</configuration>
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
CREATE TABLE INVENTORY (
|
||||||
|
productId VARCHAR PRIMARY KEY,
|
||||||
|
balance INT
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE ORDERS (
|
||||||
|
orderId VARCHAR PRIMARY KEY,
|
||||||
|
productId VARCHAR,
|
||||||
|
amount INT NOT NULL CHECK (amount <= 5)
|
||||||
|
);
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
com.atomikos.icatch.file=logs
|
||||||
@@ -0,0 +1,118 @@
|
|||||||
|
package com.baeldung.atomikos.direct;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.sql.Statement;
|
||||||
|
import java.util.Properties;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import javax.sql.DataSource;
|
||||||
|
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.Ignore;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import com.atomikos.icatch.jta.UserTransactionImp;
|
||||||
|
import com.atomikos.jdbc.AtomikosDataSourceBean;
|
||||||
|
|
||||||
|
public class ApplicationUnitTest {
|
||||||
|
|
||||||
|
private static DataSource inventoryDataSource;
|
||||||
|
private static DataSource orderDataSource;
|
||||||
|
|
||||||
|
private static String productId = UUID.randomUUID()
|
||||||
|
.toString();
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Ignore
|
||||||
|
public void testPlaceOrderSuccess() throws Exception {
|
||||||
|
int amount = 1;
|
||||||
|
long initialBalance = getBalance(inventoryDataSource, productId);
|
||||||
|
Application application = new Application(inventoryDataSource, orderDataSource);
|
||||||
|
application.placeOrder(productId, amount);
|
||||||
|
long finalBalance = getBalance(inventoryDataSource, productId);
|
||||||
|
assertEquals(initialBalance - amount, finalBalance);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Ignore
|
||||||
|
public void testPlaceOrderFailure() throws Exception {
|
||||||
|
int amount = 10;
|
||||||
|
long initialBalance = getBalance(inventoryDataSource, productId);
|
||||||
|
Application application = new Application(inventoryDataSource, orderDataSource);
|
||||||
|
application.placeOrder(productId, amount);
|
||||||
|
long finalBalance = getBalance(inventoryDataSource, productId);
|
||||||
|
assertEquals(initialBalance, finalBalance);
|
||||||
|
}
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void setUp() throws SQLException {
|
||||||
|
|
||||||
|
inventoryDataSource = getDataSource("db1");
|
||||||
|
orderDataSource = getDataSource("db2");
|
||||||
|
Connection inventoryConnection = inventoryDataSource.getConnection();
|
||||||
|
Connection orderConnection = orderDataSource.getConnection();
|
||||||
|
String createInventoryTable = "create table Inventory ( " + " productId VARCHAR ( 100 ) PRIMARY KEY, balance INT )";
|
||||||
|
String createInventoryRow = "insert into Inventory values ( '" + productId + "', 10000 )";
|
||||||
|
Statement s1 = inventoryConnection.createStatement();
|
||||||
|
try {
|
||||||
|
s1.executeUpdate(createInventoryTable);
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.out.println("Inventory table exists");
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
s1.executeUpdate(createInventoryRow);
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.out.println("Product row exists");
|
||||||
|
}
|
||||||
|
s1.close();
|
||||||
|
String createOrderTable = "create table Orders ( orderId VARCHAR ( 100 ) PRIMARY KEY, productId VARCHAR ( 100 ), amount INT NOT NULL CHECK (amount <= 5) )";
|
||||||
|
Statement s2 = orderConnection.createStatement();
|
||||||
|
try {
|
||||||
|
s2.executeUpdate(createOrderTable);
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.out.println("Orders table exists");
|
||||||
|
}
|
||||||
|
s2.close();
|
||||||
|
inventoryConnection.close();
|
||||||
|
orderConnection.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static DataSource getDataSource(String db) {
|
||||||
|
|
||||||
|
DataSource ds;
|
||||||
|
AtomikosDataSourceBean ads = new AtomikosDataSourceBean();
|
||||||
|
ads.setXaDataSourceClassName("org.apache.derby.jdbc.EmbeddedXADataSource");
|
||||||
|
Properties properties = new Properties();
|
||||||
|
properties.put("databaseName", db);
|
||||||
|
properties.put("createDatabase", "create");
|
||||||
|
ads.setXaProperties(properties);
|
||||||
|
ads.setUniqueResourceName(db);
|
||||||
|
ads.setPoolSize(10); // optional
|
||||||
|
ads.setBorrowConnectionTimeout(10); // optional
|
||||||
|
ds = ads;
|
||||||
|
return ds;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static long getBalance(DataSource inventoryDataSource, String productId) throws Exception {
|
||||||
|
|
||||||
|
UserTransactionImp utx = new UserTransactionImp();
|
||||||
|
utx.begin();
|
||||||
|
Connection inventoryConnection = inventoryDataSource.getConnection();
|
||||||
|
Statement s1 = inventoryConnection.createStatement();
|
||||||
|
String q1 = "select balance from Inventory where productId='" + productId + "'";
|
||||||
|
ResultSet rs1 = s1.executeQuery(q1);
|
||||||
|
if (rs1 == null || !rs1.next())
|
||||||
|
throw new Exception("Product not found: " + productId);
|
||||||
|
long balance = rs1.getLong(1);
|
||||||
|
inventoryConnection.close();
|
||||||
|
utx.commit();
|
||||||
|
return balance;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,108 @@
|
|||||||
|
package com.baeldung.atomikos.spring;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.sql.Statement;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import javax.sql.DataSource;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Ignore;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.test.context.ContextConfiguration;
|
||||||
|
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||||
|
|
||||||
|
import com.baeldung.atomikos.spring.config.Config;
|
||||||
|
|
||||||
|
@RunWith(SpringJUnit4ClassRunner.class)
|
||||||
|
@ContextConfiguration(classes = { Config.class })
|
||||||
|
public class ApplicationUnitTest {
|
||||||
|
|
||||||
|
private static String productId = UUID.randomUUID()
|
||||||
|
.toString();
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
Application application;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
DataSource inventoryDataSource;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
DataSource orderDataSource;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Ignore
|
||||||
|
public void testPlaceOrderSuccess() throws Exception {
|
||||||
|
int amount = 1;
|
||||||
|
long initialBalance = getBalance(inventoryDataSource, productId);
|
||||||
|
application.placeOrder(productId, amount);
|
||||||
|
long finalBalance = getBalance(inventoryDataSource, productId);
|
||||||
|
assertEquals(initialBalance - amount, finalBalance);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Ignore
|
||||||
|
public void testPlaceOrderFailure() throws Exception {
|
||||||
|
int amount = 10;
|
||||||
|
long initialBalance = getBalance(inventoryDataSource, productId);
|
||||||
|
try {
|
||||||
|
application.placeOrder(productId, amount);
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.out.println(e.getMessage());
|
||||||
|
}
|
||||||
|
long finalBalance = getBalance(inventoryDataSource, productId);
|
||||||
|
assertEquals(initialBalance, finalBalance);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() throws SQLException {
|
||||||
|
|
||||||
|
Connection inventoryConnection = inventoryDataSource.getConnection();
|
||||||
|
Connection orderConnection = orderDataSource.getConnection();
|
||||||
|
String createInventoryTable = "create table Inventory ( " + " productId VARCHAR ( 100 ) PRIMARY KEY, balance INT )";
|
||||||
|
String createInventoryRow = "insert into Inventory values ( '" + productId + "', 10000 )";
|
||||||
|
Statement s1 = inventoryConnection.createStatement();
|
||||||
|
try {
|
||||||
|
s1.executeUpdate(createInventoryTable);
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.out.println("Inventory table exists");
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
s1.executeUpdate(createInventoryRow);
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.out.println("Product row exists");
|
||||||
|
}
|
||||||
|
s1.close();
|
||||||
|
String createOrderTable = "create table Orders ( orderId VARCHAR ( 100 ) PRIMARY KEY, productId VARCHAR ( 100 ), amount INT NOT NULL CHECK (amount <= 5) )";
|
||||||
|
Statement s2 = orderConnection.createStatement();
|
||||||
|
try {
|
||||||
|
s2.executeUpdate(createOrderTable);
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.out.println("Orders table exists");
|
||||||
|
}
|
||||||
|
s2.close();
|
||||||
|
inventoryConnection.close();
|
||||||
|
orderConnection.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static long getBalance(DataSource inventoryDataSource, String productId) throws Exception {
|
||||||
|
|
||||||
|
Connection inventoryConnection = inventoryDataSource.getConnection();
|
||||||
|
Statement s1 = inventoryConnection.createStatement();
|
||||||
|
String q1 = "select balance from Inventory where productId='" + productId + "'";
|
||||||
|
ResultSet rs1 = s1.executeQuery(q1);
|
||||||
|
if (rs1 == null || !rs1.next())
|
||||||
|
throw new Exception("Product not found: " + productId);
|
||||||
|
long balance = rs1.getLong(1);
|
||||||
|
inventoryConnection.close();
|
||||||
|
return balance;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,80 @@
|
|||||||
|
package com.baeldung.atomikos.spring.jpa;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Ignore;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.test.context.ContextConfiguration;
|
||||||
|
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||||
|
|
||||||
|
import com.baeldung.atomikos.spring.jpa.config.Config;
|
||||||
|
import com.baeldung.atomikos.spring.jpa.inventory.Inventory;
|
||||||
|
import com.baeldung.atomikos.spring.jpa.inventory.InventoryConfig;
|
||||||
|
import com.baeldung.atomikos.spring.jpa.inventory.InventoryRepository;
|
||||||
|
import com.baeldung.atomikos.spring.jpa.order.OrderConfig;
|
||||||
|
import com.baeldung.atomikos.spring.jpa.order.OrderRepository;
|
||||||
|
|
||||||
|
@RunWith(SpringJUnit4ClassRunner.class)
|
||||||
|
@ContextConfiguration(classes = { Config.class, InventoryConfig.class, OrderConfig.class })
|
||||||
|
public class ApplicationUnitTest {
|
||||||
|
|
||||||
|
private static String productId = UUID.randomUUID()
|
||||||
|
.toString();
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
Application application;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
InventoryRepository inventoryRepository;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
OrderRepository orderRepository;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Ignore
|
||||||
|
public void testPlaceOrderSuccess() throws Exception {
|
||||||
|
int amount = 1;
|
||||||
|
long initialBalance = getBalance(inventoryRepository, productId);
|
||||||
|
application.placeOrder(productId, amount);
|
||||||
|
long finalBalance = getBalance(inventoryRepository, productId);
|
||||||
|
assertEquals(initialBalance - amount, finalBalance);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Ignore
|
||||||
|
public void testPlaceOrderFailure() throws Exception {
|
||||||
|
int amount = 10;
|
||||||
|
long initialBalance = getBalance(inventoryRepository, productId);
|
||||||
|
try {
|
||||||
|
application.placeOrder(productId, amount);
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.out.println(e.getMessage());
|
||||||
|
}
|
||||||
|
long finalBalance = getBalance(inventoryRepository, productId);
|
||||||
|
assertEquals(initialBalance, finalBalance);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() throws SQLException {
|
||||||
|
|
||||||
|
Inventory inventory = new Inventory();
|
||||||
|
inventory.setProductId(productId);
|
||||||
|
inventory.setBalance(new Long(10000));
|
||||||
|
inventoryRepository.save(inventory);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static long getBalance(InventoryRepository inventoryRepository, String productId) throws Exception {
|
||||||
|
|
||||||
|
return inventoryRepository.findOne(productId)
|
||||||
|
.getBalance();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<configuration>
|
||||||
|
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||||
|
<encoder>
|
||||||
|
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
|
||||||
|
</pattern>
|
||||||
|
</encoder>
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
<root level="INFO">
|
||||||
|
<appender-ref ref="STDOUT" />
|
||||||
|
</root>
|
||||||
|
</configuration>
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
com.atomikos.icatch.file=logs
|
||||||
@@ -0,0 +1,110 @@
|
|||||||
|
package com.baeldung.stringtoint
|
||||||
|
|
||||||
|
import org.junit.Test
|
||||||
|
|
||||||
|
import java.text.DecimalFormat
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals
|
||||||
|
import static org.junit.Assert.assertNull
|
||||||
|
|
||||||
|
class ConvertStringToInt {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenString_whenUsingAsInteger_thenConvertToInteger() {
|
||||||
|
def stringNum = "123"
|
||||||
|
def invalidString = "123a"
|
||||||
|
Integer expectedInteger = 123
|
||||||
|
Integer integerNum = stringNum as Integer
|
||||||
|
def intNum = invalidString?.isInteger() ? invalidString as Integer : null
|
||||||
|
|
||||||
|
assertNull(null, intNum)
|
||||||
|
assertEquals(integerNum, expectedInteger)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenString_whenUsingAsInt_thenConvertToInt() {
|
||||||
|
def stringNum = "123"
|
||||||
|
int expectedInt = 123
|
||||||
|
int intNum = stringNum as int
|
||||||
|
|
||||||
|
assertEquals(intNum, expectedInt)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenString_whenUsingToInteger_thenConvertToInteger() {
|
||||||
|
def stringNum = "123"
|
||||||
|
int expectedInt = 123
|
||||||
|
int intNum = stringNum.toInteger()
|
||||||
|
|
||||||
|
assertEquals(intNum, expectedInt)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenString_whenUsingParseInt_thenConvertToInteger() {
|
||||||
|
def stringNum = "123"
|
||||||
|
int expectedInt = 123
|
||||||
|
int intNum = Integer.parseInt(stringNum)
|
||||||
|
|
||||||
|
assertEquals(intNum, expectedInt)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenString_whenUsingValueOf_thenConvertToInteger() {
|
||||||
|
def stringNum = "123"
|
||||||
|
int expectedInt = 123
|
||||||
|
int intNum = Integer.valueOf(stringNum)
|
||||||
|
|
||||||
|
assertEquals(intNum, expectedInt)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenString_whenUsingIntValue_thenConvertToInteger() {
|
||||||
|
def stringNum = "123"
|
||||||
|
int expectedInt = 123
|
||||||
|
int intNum = new Integer(stringNum).intValue()
|
||||||
|
|
||||||
|
assertEquals(intNum, expectedInt)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenString_whenUsingNewInteger_thenConvertToInteger() {
|
||||||
|
def stringNum = "123"
|
||||||
|
int expectedInt = 123
|
||||||
|
int intNum = new Integer(stringNum)
|
||||||
|
|
||||||
|
assertEquals(intNum, expectedInt)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenString_whenUsingDecimalFormat_thenConvertToInteger() {
|
||||||
|
def stringNum = "123"
|
||||||
|
int expectedInt = 123
|
||||||
|
DecimalFormat decimalFormat = new DecimalFormat("#")
|
||||||
|
int intNum = decimalFormat.parse(stringNum).intValue()
|
||||||
|
|
||||||
|
assertEquals(intNum, expectedInt)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = NumberFormatException.class)
|
||||||
|
void givenInvalidString_whenUsingAs_thenThrowNumberFormatException() {
|
||||||
|
def invalidString = "123a"
|
||||||
|
invalidString as Integer
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = NullPointerException.class)
|
||||||
|
void givenNullString_whenUsingToInteger_thenThrowNullPointerException() {
|
||||||
|
def invalidString = null
|
||||||
|
invalidString.toInteger()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenString_whenUsingIsInteger_thenCheckIfCorrectValue() {
|
||||||
|
def invalidString = "123a"
|
||||||
|
def validString = "123"
|
||||||
|
def invalidNum = invalidString?.isInteger() ? invalidString as Integer : false
|
||||||
|
def correctNum = validString?.isInteger() ? validString as Integer : false
|
||||||
|
|
||||||
|
assertEquals(false, invalidNum)
|
||||||
|
assertEquals(123, correctNum)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -7,3 +7,4 @@ This module contains articles about Java 14.
|
|||||||
- [Guide to the @Serial Annotation in Java 14](https://www.baeldung.com/java-14-serial-annotation)
|
- [Guide to the @Serial Annotation in Java 14](https://www.baeldung.com/java-14-serial-annotation)
|
||||||
- [Java Text Blocks](https://www.baeldung.com/java-text-blocks)
|
- [Java Text Blocks](https://www.baeldung.com/java-text-blocks)
|
||||||
- [Pattern Matching for instanceof in Java 14](https://www.baeldung.com/java-pattern-matching-instanceof)
|
- [Pattern Matching for instanceof in Java 14](https://www.baeldung.com/java-pattern-matching-instanceof)
|
||||||
|
- [Helpful NullPointerExceptions in Java 14](https://www.baeldung.com/java-14-nullpointerexception)
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ This module contains articles about Map data structures in Java.
|
|||||||
|
|
||||||
### Relevant Articles:
|
### Relevant Articles:
|
||||||
- [Guide to the Guava BiMap](https://www.baeldung.com/guava-bimap)
|
- [Guide to the Guava BiMap](https://www.baeldung.com/guava-bimap)
|
||||||
- [A Guide to Java HashMap](https://www.baeldung.com/java-hashmap)
|
|
||||||
- [A Guide to LinkedHashMap in Java](https://www.baeldung.com/java-linked-hashmap)
|
- [A Guide to LinkedHashMap in Java](https://www.baeldung.com/java-linked-hashmap)
|
||||||
- [A Guide to TreeMap in Java](https://www.baeldung.com/java-treemap)
|
- [A Guide to TreeMap in Java](https://www.baeldung.com/java-treemap)
|
||||||
- [How to Store Duplicate Keys in a Map in Java?](https://www.baeldung.com/java-map-duplicate-keys)
|
- [How to Store Duplicate Keys in a Map in Java?](https://www.baeldung.com/java-map-duplicate-keys)
|
||||||
|
|||||||
@@ -10,4 +10,5 @@ This module contains articles about advanced topics about multithreading with co
|
|||||||
- [Guide to RejectedExecutionHandler](https://www.baeldung.com/java-rejectedexecutionhandler)
|
- [Guide to RejectedExecutionHandler](https://www.baeldung.com/java-rejectedexecutionhandler)
|
||||||
- [Guide to Work Stealing in Java](https://www.baeldung.com/java-work-stealing)
|
- [Guide to Work Stealing in Java](https://www.baeldung.com/java-work-stealing)
|
||||||
- [Asynchronous Programming in Java](https://www.baeldung.com/java-asynchronous-programming)
|
- [Asynchronous Programming in Java](https://www.baeldung.com/java-asynchronous-programming)
|
||||||
|
- [Java Thread Deadlock and Livelock](https://www.baeldung.com/java-deadlock-livelock)
|
||||||
- [[<-- previous]](/core-java-modules/core-java-concurrency-advanced-2)
|
- [[<-- previous]](/core-java-modules/core-java-concurrency-advanced-2)
|
||||||
|
|||||||
@@ -8,4 +8,5 @@ This module contains articles about basic Java concurrency
|
|||||||
- [Difference Between Wait and Sleep in Java](https://www.baeldung.com/java-wait-and-sleep)
|
- [Difference Between Wait and Sleep in Java](https://www.baeldung.com/java-wait-and-sleep)
|
||||||
- [Guide to the Synchronized Keyword in Java](https://www.baeldung.com/java-synchronized)
|
- [Guide to the Synchronized Keyword in Java](https://www.baeldung.com/java-synchronized)
|
||||||
- [Life Cycle of a Thread in Java](https://www.baeldung.com/java-thread-lifecycle)
|
- [Life Cycle of a Thread in Java](https://www.baeldung.com/java-thread-lifecycle)
|
||||||
- [[<-- Prev]](/core-java-modules/core-java-concurrency-basic)
|
- [Guide to AtomicMarkableReference](https://www.baeldung.com/java-atomicmarkablereference)
|
||||||
|
- [[<-- Prev]](/core-java-modules/core-java-concurrency-basic)
|
||||||
|
|||||||
@@ -1,26 +0,0 @@
|
|||||||
*.class
|
|
||||||
|
|
||||||
0.*
|
|
||||||
|
|
||||||
#folders#
|
|
||||||
/target
|
|
||||||
/neoDb*
|
|
||||||
/data
|
|
||||||
/src/main/webapp/WEB-INF/classes
|
|
||||||
*/META-INF/*
|
|
||||||
.resourceCache
|
|
||||||
|
|
||||||
# Packaged files #
|
|
||||||
*.jar
|
|
||||||
*.war
|
|
||||||
*.ear
|
|
||||||
|
|
||||||
# Files generated by integration tests
|
|
||||||
*.txt
|
|
||||||
backup-pom.xml
|
|
||||||
/bin/
|
|
||||||
/temp
|
|
||||||
|
|
||||||
#IntelliJ specific
|
|
||||||
.idea/
|
|
||||||
*.iml
|
|
||||||
@@ -1,93 +1,93 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<artifactId>core-java-concurrency-testing</artifactId>
|
<artifactId>core-java-concurrency-testing</artifactId>
|
||||||
<version>0.1.0-SNAPSHOT</version>
|
<version>0.1.0-SNAPSHOT</version>
|
||||||
<name>core-java-concurrency-testing</name>
|
<name>core-java-concurrency-testing</name>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>com.baeldung</groupId>
|
<groupId>com.baeldung</groupId>
|
||||||
<artifactId>parent-java</artifactId>
|
<artifactId>parent-java</artifactId>
|
||||||
<version>0.0.1-SNAPSHOT</version>
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
<relativePath>../../parent-java</relativePath>
|
<relativePath>../../parent-java</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>junit</groupId>
|
<groupId>junit</groupId>
|
||||||
<artifactId>junit</artifactId>
|
<artifactId>junit</artifactId>
|
||||||
<version>4.13</version>
|
<version>4.13</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.googlecode.thread-weaver</groupId>
|
<groupId>com.googlecode.thread-weaver</groupId>
|
||||||
<artifactId>threadweaver</artifactId>
|
<artifactId>threadweaver</artifactId>
|
||||||
<version>0.2</version>
|
<version>0.2</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.google.code.tempus-fugit</groupId>
|
<groupId>com.google.code.tempus-fugit</groupId>
|
||||||
<artifactId>tempus-fugit</artifactId>
|
<artifactId>tempus-fugit</artifactId>
|
||||||
<version>1.1</version>
|
<version>1.1</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.googlecode.multithreadedtc</groupId>
|
<groupId>com.googlecode.multithreadedtc</groupId>
|
||||||
<artifactId>multithreadedtc</artifactId>
|
<artifactId>multithreadedtc</artifactId>
|
||||||
<version>1.01</version>
|
<version>1.01</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.openjdk.jcstress</groupId>
|
<groupId>org.openjdk.jcstress</groupId>
|
||||||
<artifactId>jcstress-core</artifactId>
|
<artifactId>jcstress-core</artifactId>
|
||||||
<version>0.5</version>
|
<version>0.5</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
<plugins>
|
<plugins>
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-compiler-plugin</artifactId>
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
<version>3.1</version>
|
<version>3.1</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
<compilerVersion>${javac.target}</compilerVersion>
|
<compilerVersion>${javac.target}</compilerVersion>
|
||||||
<source>${javac.target}</source>
|
<source>${javac.target}</source>
|
||||||
<target>${javac.target}</target>
|
<target>${javac.target}</target>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-shade-plugin</artifactId>
|
<artifactId>maven-shade-plugin</artifactId>
|
||||||
<version>2.2</version>
|
<version>2.2</version>
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
<id>main</id>
|
<id>main</id>
|
||||||
<phase>package</phase>
|
<phase>package</phase>
|
||||||
<goals>
|
<goals>
|
||||||
<goal>shade</goal>
|
<goal>shade</goal>
|
||||||
</goals>
|
</goals>
|
||||||
<configuration>
|
<configuration>
|
||||||
<finalName>jcstress</finalName>
|
<finalName>jcstress</finalName>
|
||||||
<transformers>
|
<transformers>
|
||||||
<transformer
|
<transformer
|
||||||
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
|
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
|
||||||
<mainClass>org.openjdk.jcstress.Main</mainClass>
|
<mainClass>org.openjdk.jcstress.Main</mainClass>
|
||||||
</transformer>
|
</transformer>
|
||||||
<transformer
|
<transformer
|
||||||
implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
|
implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
|
||||||
<resource>META-INF/TestList</resource>
|
<resource>META-INF/TestList</resource>
|
||||||
</transformer>
|
</transformer>
|
||||||
</transformers>
|
</transformers>
|
||||||
</configuration>
|
</configuration>
|
||||||
</execution>
|
</execution>
|
||||||
</executions>
|
</executions>
|
||||||
</plugin>
|
</plugin>
|
||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
|||||||
@@ -7,4 +7,5 @@ This module contains articles about date operations in Java.
|
|||||||
- [Checking If Two Java Dates Are on the Same Day](https://www.baeldung.com/java-check-two-dates-on-same-day)
|
- [Checking If Two Java Dates Are on the Same Day](https://www.baeldung.com/java-check-two-dates-on-same-day)
|
||||||
- [Converting Java Date to OffsetDateTime](https://www.baeldung.com/java-convert-date-to-offsetdatetime)
|
- [Converting Java Date to OffsetDateTime](https://www.baeldung.com/java-convert-date-to-offsetdatetime)
|
||||||
- [How to Set the JVM Time Zone](https://www.baeldung.com/java-jvm-time-zone)
|
- [How to Set the JVM Time Zone](https://www.baeldung.com/java-jvm-time-zone)
|
||||||
|
- [How to determine day of week by passing specific date in Java?](https://www.baeldung.com/java-get-day-of-week)
|
||||||
- [[<-- Prev]](/core-java-modules/core-java-date-operations-1)
|
- [[<-- Prev]](/core-java-modules/core-java-date-operations-1)
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user