commit
13ce413ed2
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
|
@ -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)
|
||||
- [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)
|
||||
- [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:
|
||||
- [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 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)
|
||||
|
|
|
@ -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 Work Stealing in Java](https://www.baeldung.com/java-work-stealing)
|
||||
- [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)
|
||||
|
|
|
@ -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)
|
||||
- [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)
|
||||
- [[<-- 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"?>
|
||||
<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/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>core-java-concurrency-testing</artifactId>
|
||||
<version>0.1.0-SNAPSHOT</version>
|
||||
<name>core-java-concurrency-testing</name>
|
||||
<packaging>jar</packaging>
|
||||
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">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>core-java-concurrency-testing</artifactId>
|
||||
<version>0.1.0-SNAPSHOT</version>
|
||||
<name>core-java-concurrency-testing</name>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>parent-java</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<relativePath>../../parent-java</relativePath>
|
||||
</parent>
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>parent-java</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<relativePath>../../parent-java</relativePath>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.13</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.googlecode.thread-weaver</groupId>
|
||||
<artifactId>threadweaver</artifactId>
|
||||
<version>0.2</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.code.tempus-fugit</groupId>
|
||||
<artifactId>tempus-fugit</artifactId>
|
||||
<version>1.1</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.googlecode.multithreadedtc</groupId>
|
||||
<artifactId>multithreadedtc</artifactId>
|
||||
<version>1.01</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.openjdk.jcstress</groupId>
|
||||
<artifactId>jcstress-core</artifactId>
|
||||
<version>0.5</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.13</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.googlecode.thread-weaver</groupId>
|
||||
<artifactId>threadweaver</artifactId>
|
||||
<version>0.2</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.code.tempus-fugit</groupId>
|
||||
<artifactId>tempus-fugit</artifactId>
|
||||
<version>1.1</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.googlecode.multithreadedtc</groupId>
|
||||
<artifactId>multithreadedtc</artifactId>
|
||||
<version>1.01</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.openjdk.jcstress</groupId>
|
||||
<artifactId>jcstress-core</artifactId>
|
||||
<version>0.5</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.1</version>
|
||||
<configuration>
|
||||
<compilerVersion>${javac.target}</compilerVersion>
|
||||
<source>${javac.target}</source>
|
||||
<target>${javac.target}</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.1</version>
|
||||
<configuration>
|
||||
<compilerVersion>${javac.target}</compilerVersion>
|
||||
<source>${javac.target}</source>
|
||||
<target>${javac.target}</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
<version>2.2</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>main</id>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>shade</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<finalName>jcstress</finalName>
|
||||
<transformers>
|
||||
<transformer
|
||||
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
|
||||
<mainClass>org.openjdk.jcstress.Main</mainClass>
|
||||
</transformer>
|
||||
<transformer
|
||||
implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
|
||||
<resource>META-INF/TestList</resource>
|
||||
</transformer>
|
||||
</transformers>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
<version>2.2</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>main</id>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>shade</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<finalName>jcstress</finalName>
|
||||
<transformers>
|
||||
<transformer
|
||||
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
|
||||
<mainClass>org.openjdk.jcstress.Main</mainClass>
|
||||
</transformer>
|
||||
<transformer
|
||||
implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
|
||||
<resource>META-INF/TestList</resource>
|
||||
</transformer>
|
||||
</transformers>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</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)
|
||||
- [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 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)
|
||||
|
|
|
@ -10,4 +10,5 @@ This module contains articles about core features in the Java language
|
|||
- [How to Return Multiple Values From a Java Method](https://www.baeldung.com/java-method-return-multiple-values)
|
||||
- [Guide to the Java finally Keyword](https://www.baeldung.com/java-finally-keyword)
|
||||
- [The Java Headless Mode](https://www.baeldung.com/java-headless-mode)
|
||||
- [Comparing Long Values in Java](https://www.baeldung.com/java-compare-long-values)
|
||||
- [[<-- Prev]](/core-java-modules/core-java-lang)
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
package com.baeldung.orelseoptional;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
public class ItemsProvider {
|
||||
|
||||
Optional<String> getEmptyItem() {
|
||||
System.out.println("Returning an empty item");
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
Optional<String> getNail() {
|
||||
System.out.println("Returning a nail");
|
||||
return Optional.of("nail");
|
||||
}
|
||||
|
||||
Optional<String> getHammer() {
|
||||
System.out.println("Returning a hammer");
|
||||
return Optional.of("hammer");
|
||||
}
|
||||
}
|
|
@ -1,10 +1,10 @@
|
|||
package com.baeldung.orelseoptional;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import org.junit.Test;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
public class OrElseOptionalUnitTest {
|
||||
|
||||
|
@ -25,6 +25,28 @@ public class OrElseOptionalUnitTest {
|
|||
assertEquals(fallbackOptionalString, OptionalUtils.or(optionalString, fallbackOptionalString));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenTwoOptionalMethods_whenFirstEmpty_thenSecondEvaluated() {
|
||||
ItemsProvider itemsProvider = new ItemsProvider();
|
||||
|
||||
Optional<String> item = itemsProvider.getEmptyItem()
|
||||
.map(Optional::of)
|
||||
.orElseGet(itemsProvider::getNail);
|
||||
|
||||
assertEquals(Optional.of("nail"), item);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenTwoOptionalMethods_whenFirstNonEmpty_thenSecondNotEvaluated() {
|
||||
ItemsProvider itemsProvider = new ItemsProvider();
|
||||
|
||||
Optional<String> item = itemsProvider.getNail()
|
||||
.map(Optional::of)
|
||||
.orElseGet(itemsProvider::getHammer);
|
||||
|
||||
assertEquals(Optional.of("nail"), item);
|
||||
}
|
||||
|
||||
// Uncomment code when code base is compatible with Java 9
|
||||
// @Test
|
||||
// public void givenOptional_whenEmptyValue_thenCustomMessage() {
|
||||
|
|
|
@ -9,3 +9,4 @@
|
|||
- [Pre-compile Regex Patterns Into Pattern Objects](https://www.baeldung.com/java-regex-pre-compile)
|
||||
- [Difference Between Java Matcher find() and matches()](https://www.baeldung.com/java-matcher-find-vs-matches)
|
||||
- [How to Use Regular Expressions to Replace Tokens in Strings](https://www.baeldung.com/java-regex-token-replacement)
|
||||
- [Regular Expressions \s and \s+ in Java](https://www.baeldung.com/java-regex-s-splus)
|
||||
|
|
|
@ -8,4 +8,5 @@ This module contains articles about core Java Security
|
|||
- [MD5 Hashing in Java](http://www.baeldung.com/java-md5)
|
||||
- [Hashing a Password in Java](https://www.baeldung.com/java-password-hashing)
|
||||
- [SHA-256 and SHA3-256 Hashing in Java](https://www.baeldung.com/sha-256-hashing-java)
|
||||
- [Checksums in Java](https://www.baeldung.com/java-checksums)
|
||||
- More articles: [[<-- prev]](/core-java-modules/core-java-security)
|
||||
|
|
|
@ -9,4 +9,5 @@ This module contains articles about the Stream API in Java.
|
|||
- [Guide to Java 8’s Collectors](https://www.baeldung.com/java-8-collectors)
|
||||
- [Primitive Type Streams in Java 8](https://www.baeldung.com/java-8-primitive-streams)
|
||||
- [Debugging Java 8 Streams with IntelliJ](https://www.baeldung.com/intellij-debugging-java-streams)
|
||||
- [Add BigDecimals using the Stream API](https://www.baeldung.com/java-stream-add-bigdecimals)
|
||||
- More articles: [[<-- prev>]](/../core-java-streams-2)
|
||||
|
|
|
@ -11,4 +11,5 @@ This module contains articles about string operations.
|
|||
- [Case-Insensitive String Matching in Java](https://www.baeldung.com/java-case-insensitive-string-matching)
|
||||
- [L-Trim and R-Trim in Java](https://www.baeldung.com/l-trim-and-r-trim-in-java)
|
||||
- [L-Trim and R-Trim Alternatives in Java](https://www.baeldung.com/java-trim-alternatives)
|
||||
- [Java Convert PDF to Base64](https://www.baeldung.com/java-convert-pdf-to-base64)
|
||||
- More articles: [[<-- prev]](../core-java-string-operations)
|
||||
|
|
|
@ -12,3 +12,4 @@ This module contains articles about strings in Java.
|
|||
- [Java String Interview Questions and Answers](https://www.baeldung.com/java-string-interview-questions)
|
||||
- [Java Multi-line String](https://www.baeldung.com/java-multiline-string)
|
||||
- [Guide to Java String Pool](https://www.baeldung.com/java-string-pool)
|
||||
- [Fixing “constant string too long” Build Error](https://www.baeldung.com/java-constant-string-too-long-error)
|
||||
|
|
|
@ -8,3 +8,4 @@ This module contains articles about core Kotlin collections.
|
|||
- [Overview of Kotlin Collections API](https://www.baeldung.com/kotlin-collections-api)
|
||||
- [Converting a List to Map in Kotlin](https://www.baeldung.com/kotlin-list-to-map)
|
||||
- [Filtering Kotlin Collections](https://www.baeldung.com/kotlin-filter-collection)
|
||||
- [Collection Transformations in Kotlin](https://www.baeldung.com/kotlin-collection-transformations)
|
||||
|
|
|
@ -142,7 +142,7 @@ public class BinaryTree {
|
|||
nodes.add(node.left);
|
||||
}
|
||||
|
||||
if (node.left != null) {
|
||||
if (node.right != null) {
|
||||
nodes.add(node.right);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,4 +9,5 @@ This module contains articles about map collections in Guava
|
|||
- [Guide to Guava Multimap](https://www.baeldung.com/guava-multimap)
|
||||
- [Guide to Guava RangeMap](https://www.baeldung.com/guava-rangemap)
|
||||
- [Initialize a HashMap in Java](https://www.baeldung.com/java-initialize-hashmap)
|
||||
- [Guide to Guava ClassToInstanceMap](https://www.baeldung.com/guava-class-to-instance-map)
|
||||
- [Guide to Guava ClassToInstanceMap](https://www.baeldung.com/guava-class-to-instance-map)
|
||||
- [Using Guava’s MapMaker](https://www.baeldung.com/guava-mapmaker)
|
||||
|
|
|
@ -12,4 +12,4 @@ This module contains articles a Google Guava
|
|||
- [Guide to Mathematical Utilities in Guava](https://www.baeldung.com/guava-math)
|
||||
- [Bloom Filter in Java using Guava](https://www.baeldung.com/guava-bloom-filter)
|
||||
- [Quick Guide to the Guava RateLimiter](https://www.baeldung.com/guava-rate-limiter)
|
||||
|
||||
- [Introduction to Guava Throwables](https://www.baeldung.com/guava-throwables)
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
## Java Collections Cookbooks and Examples
|
||||
|
||||
This module contains articles about Map data structures in Java.
|
||||
|
||||
### Relevant Articles:
|
||||
|
||||
- More articles: [[<-- prev>]](/../java-collections-maps)
|
||||
- More articles: [[<-- prev>]](/../java-collections-maps-2)
|
|
@ -0,0 +1,43 @@
|
|||
<?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/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>parent-java</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<relativePath>../parent-java</relativePath>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>java-collections-maps-3</artifactId>
|
||||
<version>0.1.0-SNAPSHOT</version>
|
||||
<name>java-collections-maps-3</name>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-core</artifactId>
|
||||
<version>${spring.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.assertj</groupId>
|
||||
<artifactId>assertj-core</artifactId>
|
||||
<version>${assertj.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-collections4</artifactId>
|
||||
<version>${commons-collections4.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<properties>
|
||||
<commons-collections4.version>4.1</commons-collections4.version>
|
||||
<assertj.version>3.6.1</assertj.version>
|
||||
<spring.version>5.2.5.RELEASE</spring.version>
|
||||
</properties>
|
||||
</project>
|
|
@ -0,0 +1,94 @@
|
|||
package com.baeldung.map.caseinsensitivekeys;
|
||||
|
||||
import org.apache.commons.collections4.map.CaseInsensitiveMap;
|
||||
import org.junit.Test;
|
||||
import org.springframework.util.LinkedCaseInsensitiveMap;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
public class CaseInsensitiveMapUnitTest {
|
||||
@Test
|
||||
public void givenCaseInsensitiveTreeMap_whenTwoEntriesAdded_thenSizeIsOne(){
|
||||
Map<String, Integer> treeMap = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
|
||||
treeMap.put("abc", 1);
|
||||
treeMap.put("ABC", 2);
|
||||
|
||||
assertEquals(1, treeMap.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenCommonsCaseInsensitiveMap_whenTwoEntriesAdded_thenSizeIsOne(){
|
||||
Map<String, Integer> commonsHashMap = new CaseInsensitiveMap<>();
|
||||
commonsHashMap.put("abc", 1);
|
||||
commonsHashMap.put("ABC", 2);
|
||||
|
||||
assertEquals(1, commonsHashMap.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenLinkedCaseInsensitiveMap_whenTwoEntriesAdded_thenSizeIsOne(){
|
||||
Map<String, Integer> linkedHashMap = new LinkedCaseInsensitiveMap<>();
|
||||
linkedHashMap.put("abc", 1);
|
||||
linkedHashMap.put("ABC", 2);
|
||||
|
||||
assertEquals(1, linkedHashMap.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenCaseInsensitiveTreeMap_whenSameEntryAdded_thenValueUpdated(){
|
||||
Map<String, Integer> treeMap = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
|
||||
treeMap.put("abc", 1);
|
||||
treeMap.put("ABC", 2);
|
||||
|
||||
assertEquals(2, treeMap.get("aBc").intValue());
|
||||
assertEquals(2, treeMap.get("ABc").intValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenCommonsCaseInsensitiveMap_whenSameEntryAdded_thenValueUpdated(){
|
||||
Map<String, Integer> commonsHashMap = new CaseInsensitiveMap<>();
|
||||
commonsHashMap.put("abc", 1);
|
||||
commonsHashMap.put("ABC", 2);
|
||||
|
||||
assertEquals(2, commonsHashMap.get("aBc").intValue());
|
||||
assertEquals(2, commonsHashMap.get("ABc").intValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenLinkedCaseInsensitiveMap_whenSameEntryAdded_thenValueUpdated(){
|
||||
Map<String, Integer> linkedHashMap = new LinkedCaseInsensitiveMap<>();
|
||||
linkedHashMap.put("abc", 1);
|
||||
linkedHashMap.put("ABC", 2);
|
||||
|
||||
assertEquals(2, linkedHashMap.get("aBc").intValue());
|
||||
assertEquals(2, linkedHashMap.get("ABc").intValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenCaseInsensitiveTreeMap_whenEntryRemoved_thenSizeIsZero(){
|
||||
Map<String, Integer> treeMap = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
|
||||
treeMap.put("abc", 3);
|
||||
treeMap.remove("aBC");
|
||||
|
||||
assertEquals(0, treeMap.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenCommonsCaseInsensitiveMap_whenEntryRemoved_thenSizeIsZero(){
|
||||
Map<String, Integer> commonsHashMap = new CaseInsensitiveMap<>();
|
||||
commonsHashMap.put("abc", 3);
|
||||
commonsHashMap.remove("aBC");
|
||||
|
||||
assertEquals(0, commonsHashMap.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenLinkedCaseInsensitiveMap_whenEntryRemoved_thenSizeIsZero(){
|
||||
Map<String, Integer> linkedHashMap = new LinkedCaseInsensitiveMap<>();
|
||||
linkedHashMap.put("abc", 3);
|
||||
linkedHashMap.remove("aBC");
|
||||
|
||||
assertEquals(0, linkedHashMap.size());
|
||||
}
|
||||
}
|
|
@ -10,4 +10,5 @@ This module contains articles about numbers in Java.
|
|||
- [Generating Random Numbers in a Range in Java](https://www.baeldung.com/java-generating-random-numbers-in-range)
|
||||
- [Listing Numbers Within a Range in Java](https://www.baeldung.com/java-listing-numbers-within-a-range)
|
||||
- [Fibonacci Series in Java](https://www.baeldung.com/java-fibonacci)
|
||||
- [Guide to the Number Class in Java](https://www.baeldung.com/java-number-class)
|
||||
- More articles: [[<-- prev]](/java-numbers-2)
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
<version>0.0.1-SNAPSHOT</version>
|
||||
<packaging>war</packaging>
|
||||
<name>Bookstore</name>
|
||||
|
||||
|
||||
<parent>
|
||||
<artifactId>jhipster-5</artifactId>
|
||||
<groupId>com.baeldung.jhipster</groupId>
|
||||
|
@ -982,7 +982,7 @@
|
|||
<pluginExecution>
|
||||
<pluginExecutionFilter>
|
||||
<groupId>com.github.eirslett</groupId>
|
||||
<artifactId>frontend-maven-plugin</artifactId>
|
||||
<artifactId>frontend-maven-plugin</artifactId>
|
||||
<versionRange>${frontend-maven-plugin.version}</versionRange>
|
||||
<goals>
|
||||
<goal>install-node-and-npm</goal>
|
||||
|
|
|
@ -26,7 +26,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
|||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(classes = BookstoreApp.class)
|
||||
public class UserMapperUnitTest {
|
||||
public class UserMapperIntegrationTest {
|
||||
|
||||
private static final String DEFAULT_LOGIN = "johndoe";
|
||||
|
|
@ -16,3 +16,4 @@ Remember, for advanced libraries like [Jackson](/jackson) and [JUnit](/testing-m
|
|||
- [Introduction to Takes](https://www.baeldung.com/java-takes)
|
||||
- [Using NullAway to Avoid NullPointerExceptions](https://www.baeldung.com/java-nullaway)
|
||||
- [Introduction to Alibaba Arthas](https://www.baeldung.com/java-alibaba-arthas-intro)
|
||||
- [Quick Guide to Spring Cloud Circuit Breaker](https://www.baeldung.com/spring-cloud-circuit-breaker)
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
### Relevant Articles:
|
||||
|
||||
- [Intro to Coroutines with Quasar](https://www.baeldung.com/java-quasar-coroutines)
|
|
@ -11,3 +11,4 @@ This module contains articles about test libraries.
|
|||
- [Introduction to Awaitlity](https://www.baeldung.com/awaitlity-testing)
|
||||
- [Introduction to Hoverfly in Java](https://www.baeldung.com/hoverfly)
|
||||
- [Testing with Hamcrest](https://www.baeldung.com/java-junit-hamcrest-guide)
|
||||
- [Introduction To DBUnit](https://www.baeldung.com/dbunit)
|
||||
|
|
|
@ -130,6 +130,27 @@
|
|||
<version>${asciidoctor.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.dbunit</groupId>
|
||||
<artifactId>dbunit</artifactId>
|
||||
<version>${dbunit.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.h2database</groupId>
|
||||
<artifactId>h2</artifactId>
|
||||
<version>${h2.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.assertj</groupId>
|
||||
<artifactId>assertj-core</artifactId>
|
||||
<version>${assertj-core.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
@ -150,6 +171,16 @@
|
|||
</executions>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>${maven-compiler-plugin.version}</version>
|
||||
<configuration>
|
||||
<source>${maven-compiler-plugin.source}</source>
|
||||
<target>${maven-compiler-plugin.target}</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
|
@ -166,6 +197,12 @@
|
|||
<spring-mock-mvc.version>4.1.1</spring-mock-mvc.version>
|
||||
<assertj.version>3.6.2</assertj.version>
|
||||
<java-hamcrest.version>2.0.0.0</java-hamcrest.version>
|
||||
<h2.version>1.4.200</h2.version>
|
||||
<dbunit.version>2.7.0</dbunit.version>
|
||||
<assertj-core.version>3.14.0</assertj-core.version>
|
||||
<maven-compiler-plugin.target>1.8</maven-compiler-plugin.target>
|
||||
<maven-compiler-plugin.source>1.8</maven-compiler-plugin.source>
|
||||
<maven-compiler-plugin.version>3.8.1</maven-compiler-plugin.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
package com.baeldung.dbunit;
|
||||
|
||||
public class ConnectionSettings {
|
||||
public static final String JDBC_DRIVER = org.h2.Driver.class.getName();
|
||||
public static final String JDBC_URL = "jdbc:h2:mem:default;DB_CLOSE_DELAY=-1;init=runscript from 'classpath:dbunit/schema.sql'";
|
||||
public static final String USER = "sa";
|
||||
public static final String PASSWORD = "";
|
||||
}
|
|
@ -0,0 +1,168 @@
|
|||
package com.baeldung.dbunit;
|
||||
|
||||
import org.dbunit.Assertion;
|
||||
import org.dbunit.DataSourceBasedDBTestCase;
|
||||
import org.dbunit.assertion.DiffCollectingFailureHandler;
|
||||
import org.dbunit.assertion.Difference;
|
||||
import org.dbunit.dataset.IDataSet;
|
||||
import org.dbunit.dataset.ITable;
|
||||
import org.dbunit.dataset.xml.FlatXmlDataSetBuilder;
|
||||
import org.dbunit.operation.DatabaseOperation;
|
||||
import org.h2.jdbcx.JdbcDataSource;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.platform.commons.logging.Logger;
|
||||
import org.junit.platform.commons.logging.LoggerFactory;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.JUnit4;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
import java.io.InputStream;
|
||||
import java.sql.Connection;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import static com.baeldung.dbunit.ConnectionSettings.JDBC_URL;
|
||||
import static java.util.stream.Collectors.joining;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.dbunit.Assertion.assertEqualsIgnoreCols;
|
||||
|
||||
@RunWith(JUnit4.class)
|
||||
public class DataSourceDBUnitTest extends DataSourceBasedDBTestCase {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(DataSourceDBUnitTest.class);
|
||||
|
||||
@Override
|
||||
protected DataSource getDataSource() {
|
||||
JdbcDataSource dataSource = new JdbcDataSource();
|
||||
dataSource.setURL(JDBC_URL);
|
||||
dataSource.setUser("sa");
|
||||
dataSource.setPassword("");
|
||||
return dataSource;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected IDataSet getDataSet() throws Exception {
|
||||
try (InputStream resourceAsStream = getClass().getClassLoader().getResourceAsStream("dbunit/data.xml")) {
|
||||
return new FlatXmlDataSetBuilder().build(resourceAsStream);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected DatabaseOperation getSetUpOperation() {
|
||||
return DatabaseOperation.REFRESH;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected DatabaseOperation getTearDownOperation() {
|
||||
return DatabaseOperation.DELETE_ALL;
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
super.tearDown();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenDataSet_whenSelect_thenFirstTitleIsGreyTShirt() throws SQLException {
|
||||
final Connection connection = getDataSource().getConnection();
|
||||
|
||||
final ResultSet rs = connection.createStatement().executeQuery("select * from ITEMS where id = 1");
|
||||
|
||||
assertThat(rs.next()).isTrue();
|
||||
assertThat(rs.getString("title")).isEqualTo("Grey T-Shirt");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenDataSetEmptySchema_whenDataSetCreated_thenTablesAreEqual() throws Exception {
|
||||
final IDataSet expectedDataSet = getDataSet();
|
||||
final ITable expectedTable = expectedDataSet.getTable("CLIENTS");
|
||||
final IDataSet databaseDataSet = getConnection().createDataSet();
|
||||
final ITable actualTable = databaseDataSet.getTable("CLIENTS");
|
||||
Assertion.assertEquals(expectedTable, actualTable);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenDataSet_whenInsert_thenTableHasNewClient() throws Exception {
|
||||
try (final InputStream is = getClass().getClassLoader().getResourceAsStream("dbunit/expected-user.xml")) {
|
||||
final IDataSet expectedDataSet = new FlatXmlDataSetBuilder().build(is);
|
||||
final ITable expectedTable = expectedDataSet.getTable("CLIENTS");
|
||||
final Connection conn = getDataSource().getConnection();
|
||||
|
||||
conn.createStatement()
|
||||
.executeUpdate(
|
||||
"INSERT INTO CLIENTS (first_name, last_name) VALUES ('John', 'Jansen')");
|
||||
final ITable actualData = getConnection()
|
||||
.createQueryTable(
|
||||
"result_name",
|
||||
"SELECT * FROM CLIENTS WHERE last_name='Jansen'");
|
||||
|
||||
assertEqualsIgnoreCols(expectedTable, actualData, new String[] { "id" });
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenDataSet_whenDelete_thenItemIsDeleted() throws Exception {
|
||||
final Connection connection = getConnection().getConnection();
|
||||
|
||||
try (final InputStream is = DataSourceDBUnitTest.class.getClassLoader().getResourceAsStream("dbunit/items_exp_delete.xml")) {
|
||||
ITable expectedTable = (new FlatXmlDataSetBuilder().build(is)).getTable("ITEMS");
|
||||
|
||||
connection.createStatement().executeUpdate("delete from ITEMS where id = 2");
|
||||
|
||||
final IDataSet databaseDataSet = getConnection().createDataSet();
|
||||
ITable actualTable = databaseDataSet.getTable("ITEMS");
|
||||
|
||||
Assertion.assertEquals(expectedTable, actualTable);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenDataSet_whenUpdate_thenItemHasNewName() throws Exception {
|
||||
final Connection connection = getConnection().getConnection();
|
||||
|
||||
try (final InputStream is = DataSourceDBUnitTest.class.getClassLoader().getResourceAsStream("dbunit/items_exp_rename.xml")) {
|
||||
ITable expectedTable = (new FlatXmlDataSetBuilder().build(is)).getTable("ITEMS");
|
||||
|
||||
connection.createStatement().executeUpdate("update ITEMS set title='new name' where id = 1");
|
||||
|
||||
final IDataSet databaseDataSet = getConnection().createDataSet();
|
||||
ITable actualTable = databaseDataSet.getTable("ITEMS");
|
||||
|
||||
Assertion.assertEquals(expectedTable, actualTable);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenDataSet_whenInsertUnexpectedData_thenFailOnAllUnexpectedValues() throws Exception {
|
||||
try (final InputStream is = getClass().getClassLoader().getResourceAsStream("dbunit/expected-multiple-failures.xml")) {
|
||||
final IDataSet expectedDataSet = new FlatXmlDataSetBuilder().build(is);
|
||||
final ITable expectedTable = expectedDataSet.getTable("ITEMS");
|
||||
final Connection conn = getDataSource().getConnection();
|
||||
final DiffCollectingFailureHandler collectingHandler = new DiffCollectingFailureHandler();
|
||||
|
||||
conn.createStatement().executeUpdate(
|
||||
"INSERT INTO ITEMS (title, price) VALUES ('Battery', '1000000')");
|
||||
final ITable actualData = getConnection().createDataSet().getTable("ITEMS");
|
||||
|
||||
Assertion.assertEquals(expectedTable, actualData, collectingHandler);
|
||||
if (!collectingHandler.getDiffList().isEmpty()) {
|
||||
String message = (String) collectingHandler
|
||||
.getDiffList()
|
||||
.stream()
|
||||
.map(d -> formatDifference((Difference) d)).collect(joining("\n"));
|
||||
logger.error(() -> message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static String formatDifference(Difference diff) {
|
||||
return "expected value in " + diff.getExpectedTable().getTableMetaData().getTableName() + "." + diff.getColumnName() + " row " + diff.getRowIndex() + ":" + diff.getExpectedValue() + ", but was: " + diff.getActualValue();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,159 @@
|
|||
package com.baeldung.dbunit;
|
||||
|
||||
import org.dbunit.Assertion;
|
||||
import org.dbunit.IDatabaseTester;
|
||||
import org.dbunit.JdbcDatabaseTester;
|
||||
import org.dbunit.dataset.IDataSet;
|
||||
import org.dbunit.dataset.ITable;
|
||||
import org.dbunit.dataset.filter.DefaultColumnFilter;
|
||||
import org.dbunit.dataset.xml.FlatXmlDataSetBuilder;
|
||||
import org.dbunit.operation.DatabaseOperation;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.JUnit4;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.sql.Connection;
|
||||
import java.sql.ResultSet;
|
||||
|
||||
import static com.baeldung.dbunit.ConnectionSettings.JDBC_DRIVER;
|
||||
import static com.baeldung.dbunit.ConnectionSettings.JDBC_URL;
|
||||
import static com.baeldung.dbunit.ConnectionSettings.PASSWORD;
|
||||
import static com.baeldung.dbunit.ConnectionSettings.USER;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.dbunit.Assertion.assertEquals;
|
||||
|
||||
@RunWith(JUnit4.class)
|
||||
public class OldSchoolDbUnitTest {
|
||||
|
||||
private static IDatabaseTester tester = null;
|
||||
|
||||
@BeforeClass
|
||||
public static void setUp() throws Exception {
|
||||
tester = initDatabaseTester();
|
||||
}
|
||||
|
||||
private static IDatabaseTester initDatabaseTester() throws Exception {
|
||||
final JdbcDatabaseTester tester = new JdbcDatabaseTester(JDBC_DRIVER, JDBC_URL, USER, PASSWORD);
|
||||
tester.setDataSet(initDataSet());
|
||||
tester.setSetUpOperation(DatabaseOperation.REFRESH);
|
||||
tester.setTearDownOperation(DatabaseOperation.DELETE_ALL);
|
||||
return tester;
|
||||
}
|
||||
|
||||
private static IDataSet initDataSet() throws Exception {
|
||||
try (final InputStream is = OldSchoolDbUnitTest.class.getClassLoader().getResourceAsStream("dbunit/data.xml")) {
|
||||
return new FlatXmlDataSetBuilder().build(is);
|
||||
}
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setup() throws Exception {
|
||||
tester.onSetup();
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
tester.onTearDown();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenDataSet_whenSelect_thenFirstTitleIsGreyTShirt() throws Exception {
|
||||
final Connection connection = tester.getConnection().getConnection();
|
||||
|
||||
final ResultSet rs = connection.createStatement().executeQuery("select * from ITEMS where id = 1");
|
||||
|
||||
assertThat(rs.next()).isTrue();
|
||||
assertThat(rs.getString("title")).isEqualTo("Grey T-Shirt");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenDataSet_whenInsert_thenGetResultsAreStillEqualIfIgnoringColumnsWithDifferentProduced() throws Exception {
|
||||
final Connection connection = tester.getConnection().getConnection();
|
||||
final String[] excludedColumns = { "id", "produced" };
|
||||
try (final InputStream is = getClass().getClassLoader().getResourceAsStream("dbunit/expected-ignoring-registered_at.xml")) {
|
||||
final IDataSet expectedDataSet = new FlatXmlDataSetBuilder().build(is);
|
||||
final ITable expectedTable = DefaultColumnFilter.excludedColumnsTable(
|
||||
expectedDataSet.getTable("ITEMS"), excludedColumns);
|
||||
|
||||
connection.createStatement().executeUpdate(
|
||||
"INSERT INTO ITEMS (title, price, produced) VALUES('Necklace', 199.99, now())");
|
||||
|
||||
final IDataSet databaseDataSet = tester.getConnection().createDataSet();
|
||||
final ITable actualTable = DefaultColumnFilter.excludedColumnsTable(
|
||||
databaseDataSet.getTable("ITEMS"), excludedColumns);
|
||||
|
||||
Assertion.assertEquals(expectedTable, actualTable);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenDataSet_whenDelete_thenItemIsRemoved() throws Exception {
|
||||
final Connection connection = tester.getConnection().getConnection();
|
||||
|
||||
try (final InputStream is = OldSchoolDbUnitTest.class.getClassLoader().getResourceAsStream("dbunit/items_exp_delete.xml")) {
|
||||
ITable expectedTable = new FlatXmlDataSetBuilder().build(is).getTable("ITEMS");
|
||||
|
||||
connection.createStatement().executeUpdate("delete from ITEMS where id = 2");
|
||||
|
||||
final IDataSet databaseDataSet = tester.getConnection().createDataSet();
|
||||
ITable actualTable = databaseDataSet.getTable("ITEMS");
|
||||
|
||||
assertEquals(expectedTable, actualTable);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenDataSet_whenDelete_thenItemIsRemovedAndResultsEqualIfProducedIsIgnored() throws Exception {
|
||||
final Connection connection = tester.getConnection().getConnection();
|
||||
|
||||
try (final InputStream is = OldSchoolDbUnitTest.class.getClassLoader().getResourceAsStream("dbunit/items_exp_delete_no_produced.xml")) {
|
||||
final ITable expectedTable = new FlatXmlDataSetBuilder().build(is).getTable("ITEMS");
|
||||
|
||||
connection.createStatement().executeUpdate("delete from ITEMS where id = 2");
|
||||
|
||||
final IDataSet databaseDataSet = tester.getConnection().createDataSet();
|
||||
ITable actualTable = databaseDataSet.getTable("ITEMS");
|
||||
actualTable = DefaultColumnFilter.excludedColumnsTable(actualTable, new String[] { "produced" });
|
||||
|
||||
assertEquals(expectedTable, actualTable);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenDataSet_whenUpdate_thenItemHasNewName() throws Exception {
|
||||
final Connection connection = tester.getConnection().getConnection();
|
||||
|
||||
try (final InputStream is = OldSchoolDbUnitTest.class.getClassLoader().getResourceAsStream("dbunit/items_exp_rename.xml")) {
|
||||
final ITable expectedTable = new FlatXmlDataSetBuilder().build(is).getTable("ITEMS");
|
||||
|
||||
connection.createStatement().executeUpdate("update ITEMS set title='new name' where id = 1");
|
||||
|
||||
final IDataSet databaseDataSet = tester.getConnection().createDataSet();
|
||||
ITable actualTable = databaseDataSet.getTable("ITEMS");
|
||||
|
||||
assertEquals(expectedTable, actualTable);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenDataSet_whenUpdateWithNoProduced_thenItemHasNewName() throws Exception {
|
||||
final Connection connection = tester.getConnection().getConnection();
|
||||
|
||||
try (final InputStream is = OldSchoolDbUnitTest.class.getClassLoader().getResourceAsStream("dbunit/items_exp_rename_no_produced.xml")) {
|
||||
ITable expectedTable = new FlatXmlDataSetBuilder().build(is).getTable("ITEMS");
|
||||
expectedTable = DefaultColumnFilter.excludedColumnsTable(expectedTable, new String[] { "produced" });
|
||||
|
||||
connection.createStatement().executeUpdate("update ITEMS set title='new name' where id = 1");
|
||||
|
||||
final IDataSet databaseDataSet = tester.getConnection().createDataSet();
|
||||
ITable actualTable = databaseDataSet.getTable("ITEMS");
|
||||
actualTable = DefaultColumnFilter.excludedColumnsTable(actualTable, new String[] { "produced" });
|
||||
assertEquals(expectedTable, actualTable);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -78,10 +78,10 @@ public class JsonAssertUnitTest {
|
|||
|
||||
@Test
|
||||
public void givenArray_whenComparing_thenOrderMustMatchForStrict() throws JSONException {
|
||||
String result = "[Alex, Barbera, Charlie, Xavier]";
|
||||
JSONAssert.assertEquals("[Charlie, Alex, Xavier, Barbera]", result, JSONCompareMode.LENIENT);
|
||||
JSONAssert.assertEquals("[Alex, Barbera, Charlie, Xavier]", result, JSONCompareMode.STRICT);
|
||||
JSONAssert.assertNotEquals("[Charlie, Alex, Xavier, Barbera]", result, JSONCompareMode.STRICT);
|
||||
String result = "[Alex, Barbera, Charlie, Wolf]";
|
||||
JSONAssert.assertEquals("[Charlie, Alex, Wolf, Barbera]", result, JSONCompareMode.LENIENT);
|
||||
JSONAssert.assertEquals("[Alex, Barbera, Charlie, Wolf]", result, JSONCompareMode.STRICT);
|
||||
JSONAssert.assertNotEquals("[Charlie, Alex, Wolf, Barbera]", result, JSONCompareMode.STRICT);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -94,7 +94,7 @@ public class JsonAssertUnitTest {
|
|||
|
||||
@Test
|
||||
public void whenComparingSizeOfArray_thenPass() throws JSONException {
|
||||
String names = "{names:[Alex, Barbera, Charlie, Xavier]}";
|
||||
String names = "{names:[Alex, Barbera, Charlie, Wolf]}";
|
||||
JSONAssert.assertEquals("{names:[4]}", names, new ArraySizeComparator(JSONCompareMode.LENIENT));
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<dataset>
|
||||
<CLIENTS id='1' first_name='Charles' last_name='Wolf'/>
|
||||
<ITEMS id='1' title='Grey T-Shirt' price='17.99' produced='2019-03-20'/>
|
||||
<ITEMS id='2' title='Fitted Hat' price='29.99' produced='2019-03-21'/>
|
||||
<ITEMS id='3' title='Backpack' price='54.99' produced='2019-03-22'/>
|
||||
<ITEMS id='4' title='Earrings' price='14.99' produced='2019-03-23'/>
|
||||
<ITEMS id='5' title='Socks' price='9.99'/>
|
||||
</dataset>
|
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<dataset>
|
||||
<ITEMS id='1' title='Grey T-Shirt' price='17.99' produced='2019-03-20'/>
|
||||
<ITEMS id='2' title='Fitted Hat' price='29.99' produced='2019-03-21'/>
|
||||
<ITEMS id='3' title='Backpack' price='54.99' produced='2019-03-22'/>
|
||||
<ITEMS id='4' title='Earrings' price='14.99' produced='2019-03-23'/>
|
||||
<ITEMS id='5' title='Socks' price='9.99'/>
|
||||
<ITEMS id='6' title='Necklace' price='199.99' produced='2019-03-23'/>
|
||||
</dataset>
|
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<dataset>
|
||||
<ITEMS id='1' title='Grey T-Shirt' price='17.99' produced='2019-03-20'/>
|
||||
<ITEMS id='2' title='Fitted Hat' price='29.99' produced='2019-03-21'/>
|
||||
<ITEMS id='3' title='Backpack' price='54.99' produced='2019-03-22'/>
|
||||
<ITEMS id='4' title='Earrings' price='14.99' produced='2019-03-23'/>
|
||||
<ITEMS id='5' title='Socks' price='9.99'/>
|
||||
<ITEMS id='6' title='Necklace' price='199.99' produced='2019-03-23'/>
|
||||
</dataset>
|
|
@ -0,0 +1,4 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<dataset>
|
||||
<CLIENTS id='2' first_name='John' last_name='Jansen'/>
|
||||
</dataset>
|
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<dataset>
|
||||
<ITEMS id='1' title='Grey T-Shirt' price='17.99' produced='2019-03-20'/>
|
||||
<ITEMS id='2' title='Fitted Hat' price='29.99' produced='2019-03-21'/>
|
||||
<ITEMS id='3' title='Backpack' price='54.99' produced='2019-03-22'/>
|
||||
<ITEMS id='4' title='Earrings' price='14.99' produced='2019-03-23'/>
|
||||
<ITEMS id='5' title='Socks' price='9.99'/>
|
||||
</dataset>
|
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<dataset>
|
||||
<ITEMS id='1' title='Grey T-Shirt' price='17.99' produced='2019-03-20'/>
|
||||
<ITEMS id='3' title='Backpack' price='54.99' produced='2019-03-22'/>
|
||||
<ITEMS id='4' title='Earrings' price='14.99' produced='2019-03-23'/>
|
||||
<ITEMS id='5' title='Socks' price='9.99'/>
|
||||
</dataset>
|
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<dataset>
|
||||
<ITEMS id='1' title='Grey T-Shirt' price='17.99'/>
|
||||
<ITEMS id='3' title='Backpack' price='54.99'/>
|
||||
<ITEMS id='4' title='Earrings' price='14.99'/>
|
||||
<ITEMS id='5' title='Socks' price='9.99'/>
|
||||
</dataset>
|
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<dataset>
|
||||
<ITEMS id='1' title='new name' price='17.99' produced='2019-03-20'/>
|
||||
<ITEMS id='2' title='Fitted Hat' price='29.99' produced='2019-03-21'/>
|
||||
<ITEMS id='3' title='Backpack' price='54.99' produced='2019-03-22'/>
|
||||
<ITEMS id='4' title='Earrings' price='14.99' produced='2019-03-23'/>
|
||||
<ITEMS id='5' title='Socks' price='9.99'/>
|
||||
</dataset>
|
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<dataset>
|
||||
<ITEMS id='1' title='new name' price='17.99' produced='2019-03-20'/>
|
||||
<ITEMS id='2' title='Fitted Hat' price='29.99'/>
|
||||
<ITEMS id='3' title='Backpack' price='54.99'/>
|
||||
<ITEMS id='4' title='Earrings' price='14.99'/>
|
||||
<ITEMS id='5' title='Socks' price='9.99'/>
|
||||
</dataset>
|
|
@ -0,0 +1,28 @@
|
|||
CREATE TABLE IF NOT EXISTS CLIENTS
|
||||
(
|
||||
`id` int AUTO_INCREMENT NOT NULL,
|
||||
`first_name` varchar(100) NOT NULL,
|
||||
`last_name` varchar(100) NOT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS ITEMS
|
||||
(
|
||||
`id` int AUTO_INCREMENT NOT NULL,
|
||||
`title` varchar(100) NOT NULL,
|
||||
`produced` date,
|
||||
`price` float,
|
||||
PRIMARY KEY (`id`)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS PURCHASES
|
||||
(
|
||||
`id` int NOT NULL AUTO_INCREMENT,
|
||||
`id_user` int NOT NULL,
|
||||
`id_item` int NOT NULL,
|
||||
`total_price` float NOT NULL,
|
||||
`quantity` int(11) NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
FOREIGN KEY (`id_user`) REFERENCES CLIENTS (`id`) ON DELETE CASCADE,
|
||||
FOREIGN KEY (`id_item`) REFERENCES ITEMS (`id`) ON DELETE CASCADE ON UPDATE CASCADE
|
||||
);
|
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<dataset>
|
||||
<CLIENTS id='1' first_name='Charles' last_name='Wolf'/>
|
||||
<CLIENTS id='2' first_name='Scott' last_name='Summers'/>
|
||||
<CLIENTS id='3' first_name='Jean' last_name='Grey'/>
|
||||
</dataset>
|
|
@ -0,0 +1,5 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<dataset>
|
||||
<CLIENTS id='1' first_name='Charles' last_name='Wolf'/>
|
||||
<CLIENTS id='3' first_name='Jean' last_name='Grey'/>
|
||||
</dataset>
|
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<dataset>
|
||||
<CLIENTS id='1' first_name='new name' last_name='Wolf'/>
|
||||
<CLIENTS id='2' first_name='Scott' last_name='Summers'/>
|
||||
<CLIENTS id='3' first_name='Jean' last_name='Grey'/>
|
||||
</dataset>
|
|
@ -13,3 +13,4 @@ This module contains articles specific to use of Hibernate as a JPA implementati
|
|||
- [Enabling Transaction Locks in Spring Data JPA](https://www.baeldung.com/java-jpa-transaction-locks)
|
||||
- [TransactionRequiredException Error](https://www.baeldung.com/jpa-transaction-required-exception)
|
||||
- [JPA/Hibernate Persistence Context](https://www.baeldung.com/jpa-hibernate-persistence-context)
|
||||
- [Quick Guide to EntityManager#getReference()](https://www.baeldung.com/jpa-entity-manager-get-reference)
|
||||
|
|
|
@ -18,6 +18,12 @@
|
|||
<artifactId>cassandra-driver-core</artifactId>
|
||||
<version>${cassandra-driver-core.version}</version>
|
||||
<optional>true</optional>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<!-- https://mvnrepository.com/artifact/org.cassandraunit/cassandra-unit -->
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
cluster_name: 'Test Cluster'
|
||||
hinted_handoff_enabled: true
|
||||
max_hint_window_in_ms: 10800000
|
||||
hinted_handoff_throttle_in_kb: 1024
|
||||
max_hints_delivery_threads: 2
|
||||
hints_directory: target/embeddedCassandra/hints
|
||||
authenticator: AllowAllAuthenticator
|
||||
authorizer: AllowAllAuthorizer
|
||||
permissions_validity_in_ms: 2000
|
||||
partitioner: RandomPartitioner
|
||||
data_file_directories:
|
||||
- target/embeddedCassandra/data
|
||||
commitlog_directory: target/embeddedCassandra/commitlog
|
||||
cdc_raw_directory: target/embeddedCassandra/cdc
|
||||
disk_failure_policy: stop
|
||||
key_cache_size_in_mb:
|
||||
key_cache_save_period: 14400
|
||||
row_cache_size_in_mb: 0
|
||||
row_cache_save_period: 0
|
||||
saved_caches_directory: target/embeddedCassandra/saved_caches
|
||||
commitlog_sync: periodic
|
||||
commitlog_sync_period_in_ms: 10000
|
||||
commitlog_segment_size_in_mb: 32
|
||||
concurrent_reads: 32
|
||||
concurrent_writes: 32
|
||||
trickle_fsync: false
|
||||
trickle_fsync_interval_in_kb: 10240
|
||||
thrift_framed_transport_size_in_mb: 15
|
||||
thrift_max_message_length_in_mb: 16
|
||||
incremental_backups: false
|
||||
snapshot_before_compaction: false
|
||||
auto_snapshot: false
|
||||
column_index_size_in_kb: 64
|
||||
compaction_throughput_mb_per_sec: 16
|
||||
read_request_timeout_in_ms: 5000
|
||||
range_request_timeout_in_ms: 10000
|
||||
write_request_timeout_in_ms: 2000
|
||||
cas_contention_timeout_in_ms: 1000
|
||||
truncate_request_timeout_in_ms: 60000
|
||||
request_timeout_in_ms: 10000
|
||||
cross_node_timeout: false
|
||||
endpoint_snitch: SimpleSnitch
|
||||
dynamic_snitch_update_interval_in_ms: 100
|
||||
dynamic_snitch_reset_interval_in_ms: 600000
|
||||
dynamic_snitch_badness_threshold: 0.1
|
||||
request_scheduler: org.apache.cassandra.scheduler.NoScheduler
|
||||
index_interval: 128
|
||||
seed_provider:
|
||||
- class_name: org.apache.cassandra.locator.SimpleSeedProvider
|
||||
parameters:
|
||||
- seeds: "127.0.0.1"
|
|
@ -10,3 +10,4 @@ This module contains articles about MongoDB in Java.
|
|||
- [Geospatial Support in MongoDB](https://www.baeldung.com/mongodb-geospatial-support)
|
||||
- [Introduction to Morphia – Java ODM for MongoDB](https://www.baeldung.com/mongodb-morphia)
|
||||
- [MongoDB Aggregations Using Java](https://www.baeldung.com/java-mongodb-aggregations)
|
||||
- [MongoDB BSON to JSON](https://www.baeldung.com/bson-to-json)
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package com.baeldung.morphia.domain;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
|
@ -29,28 +31,13 @@ public class Book {
|
|||
private double cost;
|
||||
@Reference
|
||||
private Set<Book> companionBooks;
|
||||
@Property
|
||||
private LocalDateTime publishDate;
|
||||
|
||||
public Book() {
|
||||
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public String getAuthor() {
|
||||
return author;
|
||||
}
|
||||
|
||||
public double getCost() {
|
||||
return cost;
|
||||
}
|
||||
|
||||
public void addCompanionBooks(Book book) {
|
||||
if (companionBooks != null)
|
||||
this.companionBooks.add(book);
|
||||
}
|
||||
|
||||
public Book(String isbn, String title, String author, double cost, Publisher publisher) {
|
||||
this.isbn = isbn;
|
||||
this.title = title;
|
||||
|
@ -60,6 +47,71 @@ public class Book {
|
|||
this.companionBooks = new HashSet<>();
|
||||
}
|
||||
|
||||
// Getters and setters ...
|
||||
public String getIsbn() {
|
||||
return isbn;
|
||||
}
|
||||
|
||||
public Book setIsbn(String isbn) {
|
||||
this.isbn = isbn;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public Book setTitle(String title) {
|
||||
this.title = title;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getAuthor() {
|
||||
return author;
|
||||
}
|
||||
|
||||
public Book setAuthor(String author) {
|
||||
this.author = author;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Publisher getPublisher() {
|
||||
return publisher;
|
||||
}
|
||||
|
||||
public Book setPublisher(Publisher publisher) {
|
||||
this.publisher = publisher;
|
||||
return this;
|
||||
}
|
||||
|
||||
public double getCost() {
|
||||
return cost;
|
||||
}
|
||||
|
||||
public Book setCost(double cost) {
|
||||
this.cost = cost;
|
||||
return this;
|
||||
}
|
||||
|
||||
public LocalDateTime getPublishDate() {
|
||||
return publishDate;
|
||||
}
|
||||
|
||||
public Book setPublishDate(LocalDateTime publishDate) {
|
||||
this.publishDate = publishDate;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Set<Book> getCompanionBooks() {
|
||||
return companionBooks;
|
||||
}
|
||||
|
||||
public Book addCompanionBooks(Book book) {
|
||||
if (companionBooks != null)
|
||||
this.companionBooks.add(book);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Book [isbn=" + isbn + ", title=" + title + ", author=" + author + ", publisher=" + publisher + ", cost=" + cost + "]";
|
||||
|
@ -113,4 +165,4 @@ public class Book {
|
|||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,142 @@
|
|||
package com.baeldung.bsontojson;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.sql.Timestamp;
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.Date;
|
||||
import java.util.TimeZone;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.bson.Document;
|
||||
import org.bson.json.Converter;
|
||||
import org.bson.json.JsonMode;
|
||||
import org.bson.json.JsonWriterSettings;
|
||||
import org.bson.json.StrictJsonWriter;
|
||||
import org.bson.types.ObjectId;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.baeldung.morphia.domain.Book;
|
||||
import com.baeldung.morphia.domain.Publisher;
|
||||
import com.mongodb.MongoClient;
|
||||
import com.mongodb.client.MongoDatabase;
|
||||
|
||||
import dev.morphia.Datastore;
|
||||
import dev.morphia.Morphia;
|
||||
|
||||
public class BsonToJsonIntegrationTest {
|
||||
|
||||
private static final String DB_NAME = "library";
|
||||
private static Datastore datastore;
|
||||
|
||||
@BeforeClass
|
||||
public static void setUp() {
|
||||
Morphia morphia = new Morphia();
|
||||
morphia.mapPackage("com.baeldung.morphia");
|
||||
datastore = morphia.createDatastore(new MongoClient(), DB_NAME);
|
||||
datastore.ensureIndexes();
|
||||
|
||||
datastore.save(new Book()
|
||||
.setIsbn("isbn")
|
||||
.setTitle("title")
|
||||
.setAuthor("author")
|
||||
.setCost(3.95)
|
||||
.setPublisher(new Publisher(new ObjectId("fffffffffffffffffffffffa"),"publisher"))
|
||||
.setPublishDate(LocalDateTime.parse("2020-01-01T18:13:32Z", DateTimeFormatter.ISO_DATE_TIME))
|
||||
.addCompanionBooks(new Book().setIsbn("isbn2")));
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void tearDown() {
|
||||
datastore.delete(datastore.createQuery(Book.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenBsonDocument_whenUsingStandardJsonTransformation_thenJsonDateIsObjectEpochTime() {
|
||||
|
||||
String json = null;
|
||||
try (MongoClient mongoClient = new MongoClient()) {
|
||||
MongoDatabase mongoDatabase = mongoClient.getDatabase(DB_NAME);
|
||||
Document bson = mongoDatabase.getCollection("Books").find().first();
|
||||
json = bson.toJson();
|
||||
}
|
||||
|
||||
String expectedJson = "{\"_id\": \"isbn\", " +
|
||||
"\"className\": \"com.baeldung.morphia.domain.Book\", " +
|
||||
"\"title\": \"title\", " +
|
||||
"\"author\": \"author\", " +
|
||||
"\"publisher\": {\"_id\": {\"$oid\": \"fffffffffffffffffffffffa\"}, " +
|
||||
"\"name\": \"publisher\"}, " +
|
||||
"\"price\": 3.95, " +
|
||||
"\"publishDate\": {\"$date\": 1577898812000}}";
|
||||
|
||||
assertNotNull(json);
|
||||
|
||||
assertEquals(expectedJson, json);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void givenBsonDocument_whenUsingRelaxedJsonTransformation_thenJsonDateIsObjectIsoDate() {
|
||||
|
||||
String json = null;
|
||||
try (MongoClient mongoClient = new MongoClient()) {
|
||||
MongoDatabase mongoDatabase = mongoClient.getDatabase(DB_NAME);
|
||||
Document bson = mongoDatabase.getCollection("Books").find().first();
|
||||
json = bson.toJson(JsonWriterSettings
|
||||
.builder()
|
||||
.outputMode(JsonMode.RELAXED)
|
||||
.build());
|
||||
}
|
||||
|
||||
String expectedJson = "{\"_id\": \"isbn\", " +
|
||||
"\"className\": \"com.baeldung.morphia.domain.Book\", " +
|
||||
"\"title\": \"title\", " +
|
||||
"\"author\": \"author\", " +
|
||||
"\"publisher\": {\"_id\": {\"$oid\": \"fffffffffffffffffffffffa\"}, " +
|
||||
"\"name\": \"publisher\"}, " +
|
||||
"\"price\": 3.95, " +
|
||||
"\"publishDate\": {\"$date\": \"2020-01-01T17:13:32Z\"}}";
|
||||
|
||||
assertNotNull(json);
|
||||
|
||||
assertEquals(expectedJson, json);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenBsonDocument_whenUsingCustomJsonTransformation_thenJsonDateIsStringField() {
|
||||
|
||||
String json = null;
|
||||
try (MongoClient mongoClient = new MongoClient()) {
|
||||
MongoDatabase mongoDatabase = mongoClient.getDatabase(DB_NAME);
|
||||
Document bson = mongoDatabase.getCollection("Books").find().first();
|
||||
json = bson.toJson(JsonWriterSettings
|
||||
.builder()
|
||||
.dateTimeConverter(new JsonDateTimeConverter())
|
||||
.build());
|
||||
}
|
||||
|
||||
String expectedJson = "{\"_id\": \"isbn\", " +
|
||||
"\"className\": \"com.baeldung.morphia.domain.Book\", " +
|
||||
"\"title\": \"title\", " +
|
||||
"\"author\": \"author\", " +
|
||||
"\"publisher\": {\"_id\": {\"$oid\": \"fffffffffffffffffffffffa\"}, " +
|
||||
"\"name\": \"publisher\"}, " +
|
||||
"\"price\": 3.95, " +
|
||||
"\"publishDate\": \"2020-01-01T17:13:32Z\"}";
|
||||
|
||||
assertEquals(expectedJson, json);
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
package com.baeldung.bsontojson;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.time.ZoneId;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.Date;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import org.bson.json.Converter;
|
||||
import org.bson.json.StrictJsonWriter;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class JsonDateTimeConverter implements Converter<Long> {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(JsonDateTimeConverter.class);
|
||||
static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ISO_INSTANT
|
||||
.withZone(ZoneId.of("UTC"));
|
||||
|
||||
@Override
|
||||
public void convert(Long value, StrictJsonWriter writer) {
|
||||
try {
|
||||
Instant instant = new Date(value).toInstant();
|
||||
String s = DATE_TIME_FORMATTER.format(instant);
|
||||
writer.writeString(s);
|
||||
} catch (Exception e) {
|
||||
LOGGER.error(String.format("Fail to convert offset %d to JSON date", value), e);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
create table PERSON (ID int8 not null, FIRST_NAME varchar(255), LAST_NAME varchar(255), primary key (ID))
|
||||
create table person (id int8 not null, first_name varchar(255), last_name varchar(255), primary key (id))
|
|
@ -33,6 +33,11 @@
|
|||
<artifactId>mysql-connector-java</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.postgresql</groupId>
|
||||
<artifactId>postgresql</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.h2database</groupId>
|
||||
<artifactId>h2</artifactId>
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
package com.baeldung.namingstrategy;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
|
||||
@Entity
|
||||
public class Person {
|
||||
@Id
|
||||
private Long id;
|
||||
|
||||
private String firstName;
|
||||
|
||||
private String lastName;
|
||||
|
||||
public Person() {}
|
||||
|
||||
public Person(Long id, String firstName, String lastName) {
|
||||
this.id = id;
|
||||
this.firstName = firstName;
|
||||
this.lastName = lastName;
|
||||
}
|
||||
|
||||
public Long id() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String firstName() {
|
||||
return firstName;
|
||||
}
|
||||
|
||||
public String lastName() {
|
||||
return lastName;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
package com.baeldung.namingstrategy;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
|
||||
public interface PersonRepository extends JpaRepository<Person, Long> {
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
package com.baeldung.namingstrategy;
|
||||
|
||||
import org.hibernate.boot.model.naming.Identifier;
|
||||
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
|
||||
import org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy;
|
||||
|
||||
public class QuotedLowerCaseNamingStrategy extends SpringPhysicalNamingStrategy {
|
||||
@Override
|
||||
protected Identifier getIdentifier(String name, boolean quoted, JdbcEnvironment jdbcEnvironment) {
|
||||
return new Identifier(name.toLowerCase(), true);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
package com.baeldung.namingstrategy;
|
||||
|
||||
import org.hibernate.boot.model.naming.Identifier;
|
||||
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
|
||||
import org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy;
|
||||
|
||||
public class QuotedUpperCaseNamingStrategy extends SpringPhysicalNamingStrategy {
|
||||
@Override
|
||||
protected Identifier getIdentifier(String name, boolean quoted, JdbcEnvironment jdbcEnvironment) {
|
||||
return new Identifier(name.toUpperCase(), true);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
package com.baeldung.namingstrategy;
|
||||
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
public class SpringDataJpaNamingConventionApplication {
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
package com.baeldung.namingstrategy;
|
||||
|
||||
import org.hibernate.boot.model.naming.Identifier;
|
||||
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
|
||||
import org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy;
|
||||
|
||||
public class UnquotedLowerCaseNamingStrategy extends SpringPhysicalNamingStrategy {
|
||||
@Override
|
||||
protected Identifier getIdentifier(String name, boolean quoted, JdbcEnvironment jdbcEnvironment) {
|
||||
return new Identifier(name.toLowerCase(), false);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
package com.baeldung.namingstrategy;
|
||||
|
||||
import org.hibernate.boot.model.naming.Identifier;
|
||||
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
|
||||
import org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy;
|
||||
|
||||
public class UnquotedUpperCaseNamingStrategy extends SpringPhysicalNamingStrategy {
|
||||
@Override
|
||||
protected Identifier getIdentifier(String name, boolean quoted, JdbcEnvironment jdbcEnvironment) {
|
||||
return new Identifier(name.toUpperCase(), false);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,81 @@
|
|||
package com.baeldung.namingstrategy;
|
||||
|
||||
import org.hibernate.exception.SQLGrammarException;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.ValueSource;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.autoconfigure.jdbc.TestDatabaseAutoConfiguration;
|
||||
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
|
||||
import org.springframework.test.context.TestPropertySource;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.PersistenceContext;
|
||||
import javax.persistence.Query;
|
||||
import java.math.BigInteger;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
@DataJpaTest(excludeAutoConfiguration = TestDatabaseAutoConfiguration.class)
|
||||
@TestPropertySource("quoted-lower-case-naming-strategy.properties")
|
||||
class QuotedLowerCaseNamingStrategyH2IntegrationTest {
|
||||
|
||||
@PersistenceContext
|
||||
private EntityManager entityManager;
|
||||
|
||||
@Autowired
|
||||
private PersonRepository personRepository;
|
||||
|
||||
@BeforeEach
|
||||
void insertPeople() {
|
||||
personRepository.saveAll(Arrays.asList(
|
||||
new Person(1L, "John", "Doe"),
|
||||
new Person(2L, "Jane", "Doe"),
|
||||
new Person(3L, "Ted", "Mosby")
|
||||
));
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(strings = {"person", "PERSON", "Person"})
|
||||
void givenPeopleAndLowerCaseNamingStrategy_whenQueryPersonUnquoted_thenException(String tableName) {
|
||||
Query query = entityManager.createNativeQuery("select * from " + tableName);
|
||||
|
||||
// Unexpected result
|
||||
assertThrows(SQLGrammarException.class, query::getResultStream);
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenPeopleAndLowerCaseNamingStrategy_whenQueryPersonQuotedUpperCase_thenException() {
|
||||
Query query = entityManager.createNativeQuery("select * from \"PERSON\"");
|
||||
|
||||
// Expected result
|
||||
assertThrows(SQLGrammarException.class, query::getResultStream);
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenPeopleAndLowerCaseNamingStrategy_whenQueryPersonQuotedLowerCase_thenResult() {
|
||||
Query query = entityManager.createNativeQuery("select * from \"person\"");
|
||||
|
||||
// Expected result
|
||||
List<Person> result = (List<Person>) query.getResultStream()
|
||||
.map(this::fromDatabase)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
assertThat(result).isNotEmpty();
|
||||
}
|
||||
|
||||
public Person fromDatabase(Object databaseRow) {
|
||||
Object[] typedDatabaseRow = (Object[]) databaseRow;
|
||||
|
||||
return new Person(
|
||||
((BigInteger) typedDatabaseRow[0]).longValue(),
|
||||
(String) typedDatabaseRow[1],
|
||||
(String) typedDatabaseRow[2]
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,85 @@
|
|||
package com.baeldung.namingstrategy;
|
||||
|
||||
import org.hibernate.exception.SQLGrammarException;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.ValueSource;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.autoconfigure.jdbc.TestDatabaseAutoConfiguration;
|
||||
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
|
||||
import org.springframework.test.context.TestPropertySource;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.PersistenceContext;
|
||||
import javax.persistence.Query;
|
||||
import java.math.BigInteger;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
@DataJpaTest(excludeAutoConfiguration = TestDatabaseAutoConfiguration.class)
|
||||
@TestPropertySource("quoted-lower-case-naming-strategy-on-postgres.properties")
|
||||
class QuotedLowerCaseNamingStrategyPostgresLiveTest {
|
||||
|
||||
@PersistenceContext
|
||||
private EntityManager entityManager;
|
||||
|
||||
@Autowired
|
||||
private PersonRepository personRepository;
|
||||
|
||||
@BeforeEach
|
||||
void insertPeople() {
|
||||
personRepository.saveAll(Arrays.asList(
|
||||
new Person(1L, "John", "Doe"),
|
||||
new Person(2L, "Jane", "Doe"),
|
||||
new Person(3L, "Ted", "Mosby")
|
||||
));
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(strings = {"person", "PERSON", "Person"})
|
||||
void givenPeopleAndLowerCaseNamingStrategy_whenQueryPersonUnquoted_thenResult(String tableName) {
|
||||
Query query = entityManager.createNativeQuery("select * from " + tableName);
|
||||
|
||||
// Expected result
|
||||
List<Person> result = (List<Person>) query.getResultStream()
|
||||
.map(this::fromDatabase)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
assertThat(result).isNotEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenPeopleAndLowerCaseNamingStrategy_whenQueryPersonQuotedUpperCase_thenException() {
|
||||
Query query = entityManager.createNativeQuery("select * from \"PERSON\"");
|
||||
|
||||
// Expected result
|
||||
assertThrows(SQLGrammarException.class, query::getResultStream);
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenPeopleAndLowerCaseNamingStrategy_whenQueryPersonQuotedLowerCase_thenResult() {
|
||||
Query query = entityManager.createNativeQuery("select * from \"person\"");
|
||||
|
||||
// Expected result
|
||||
List<Person> result = (List<Person>) query.getResultStream()
|
||||
.map(this::fromDatabase)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
assertThat(result).isNotEmpty();
|
||||
}
|
||||
|
||||
public Person fromDatabase(Object databaseRow) {
|
||||
Object[] typedDatabaseRow = (Object[]) databaseRow;
|
||||
|
||||
return new Person(
|
||||
((BigInteger) typedDatabaseRow[0]).longValue(),
|
||||
(String) typedDatabaseRow[1],
|
||||
(String) typedDatabaseRow[2]
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,85 @@
|
|||
package com.baeldung.namingstrategy;
|
||||
|
||||
import org.hibernate.exception.SQLGrammarException;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.ValueSource;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.autoconfigure.jdbc.TestDatabaseAutoConfiguration;
|
||||
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
|
||||
import org.springframework.test.context.TestPropertySource;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.PersistenceContext;
|
||||
import javax.persistence.Query;
|
||||
import java.math.BigInteger;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
@DataJpaTest(excludeAutoConfiguration = TestDatabaseAutoConfiguration.class)
|
||||
@TestPropertySource("quoted-upper-case-naming-strategy.properties")
|
||||
class QuotedUpperCaseNamingStrategyH2IntegrationTest {
|
||||
|
||||
@PersistenceContext
|
||||
private EntityManager entityManager;
|
||||
|
||||
@Autowired
|
||||
private PersonRepository personRepository;
|
||||
|
||||
@BeforeEach
|
||||
void insertPeople() {
|
||||
personRepository.saveAll(Arrays.asList(
|
||||
new Person(1L, "John", "Doe"),
|
||||
new Person(2L, "Jane", "Doe"),
|
||||
new Person(3L, "Ted", "Mosby")
|
||||
));
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(strings = {"person", "PERSON", "Person"})
|
||||
void givenPeopleAndUpperCaseNamingStrategy_whenQueryPersonUnquoted_thenException(String tableName) {
|
||||
Query query = entityManager.createNativeQuery("select * from " + tableName);
|
||||
|
||||
// Expected result
|
||||
List<Person> result = (List<Person>) query.getResultStream()
|
||||
.map(this::fromDatabase)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
assertThat(result).isNotEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenPeopleAndUpperCaseNamingStrategy_whenQueryPersonQuotedUpperCase_thenResult() {
|
||||
Query query = entityManager.createNativeQuery("select * from \"PERSON\"");
|
||||
|
||||
// Expected result
|
||||
List<Person> result = (List<Person>) query.getResultStream()
|
||||
.map(this::fromDatabase)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
assertThat(result).isNotEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenPeopleAndUpperCaseNamingStrategy_whenQueryPersonQuotedLowerCase_thenException() {
|
||||
Query query = entityManager.createNativeQuery("select * from \"person\"");
|
||||
|
||||
// Expected result
|
||||
assertThrows(SQLGrammarException.class, query::getResultStream);
|
||||
}
|
||||
|
||||
public Person fromDatabase(Object databaseRow) {
|
||||
Object[] typedDatabaseRow = (Object[]) databaseRow;
|
||||
|
||||
return new Person(
|
||||
((BigInteger) typedDatabaseRow[0]).longValue(),
|
||||
(String) typedDatabaseRow[1],
|
||||
(String) typedDatabaseRow[2]
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,81 @@
|
|||
package com.baeldung.namingstrategy;
|
||||
|
||||
import org.hibernate.exception.SQLGrammarException;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.ValueSource;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.autoconfigure.jdbc.TestDatabaseAutoConfiguration;
|
||||
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
|
||||
import org.springframework.test.context.TestPropertySource;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.PersistenceContext;
|
||||
import javax.persistence.Query;
|
||||
import java.math.BigInteger;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
@DataJpaTest(excludeAutoConfiguration = TestDatabaseAutoConfiguration.class)
|
||||
@TestPropertySource("quoted-upper-case-naming-strategy-on-postgres.properties")
|
||||
class QuotedUpperCaseNamingStrategyPostgresLiveTest {
|
||||
|
||||
@PersistenceContext
|
||||
private EntityManager entityManager;
|
||||
|
||||
@Autowired
|
||||
private PersonRepository personRepository;
|
||||
|
||||
@BeforeEach
|
||||
void insertPeople() {
|
||||
personRepository.saveAll(Arrays.asList(
|
||||
new Person(1L, "John", "Doe"),
|
||||
new Person(2L, "Jane", "Doe"),
|
||||
new Person(3L, "Ted", "Mosby")
|
||||
));
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(strings = {"person", "PERSON", "Person"})
|
||||
void givenPeopleAndUpperCaseNamingStrategy_whenQueryPersonUnquoted_thenResult(String tableName) {
|
||||
Query query = entityManager.createNativeQuery("select * from " + tableName);
|
||||
|
||||
// Unexpected result
|
||||
assertThrows(SQLGrammarException.class, query::getResultStream);
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenPeopleAndUpperCaseNamingStrategy_whenQueryPersonQuotedUpperCase_thenException() {
|
||||
Query query = entityManager.createNativeQuery("select * from \"PERSON\"");
|
||||
|
||||
// Expected result
|
||||
List<Person> result = (List<Person>) query.getResultStream()
|
||||
.map(this::fromDatabase)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
assertThat(result).isNotEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenPeopleAndUpperCaseNamingStrategy_whenQueryPersonQuotedLowerCase_thenResult() {
|
||||
Query query = entityManager.createNativeQuery("select * from \"person\"");
|
||||
|
||||
// Expected result
|
||||
assertThrows(SQLGrammarException.class, query::getResultStream);
|
||||
}
|
||||
|
||||
public Person fromDatabase(Object databaseRow) {
|
||||
Object[] typedDatabaseRow = (Object[]) databaseRow;
|
||||
|
||||
return new Person(
|
||||
((BigInteger) typedDatabaseRow[0]).longValue(),
|
||||
(String) typedDatabaseRow[1],
|
||||
(String) typedDatabaseRow[2]
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,85 @@
|
|||
package com.baeldung.namingstrategy;
|
||||
|
||||
import org.hibernate.exception.SQLGrammarException;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.ValueSource;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.autoconfigure.jdbc.TestDatabaseAutoConfiguration;
|
||||
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
|
||||
import org.springframework.test.context.TestPropertySource;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.PersistenceContext;
|
||||
import javax.persistence.Query;
|
||||
import java.math.BigInteger;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
@DataJpaTest(excludeAutoConfiguration = TestDatabaseAutoConfiguration.class)
|
||||
@TestPropertySource("spring-physical-naming-strategy.properties")
|
||||
class SpringPhysicalNamingStrategyH2IntegrationTest {
|
||||
|
||||
@PersistenceContext
|
||||
private EntityManager entityManager;
|
||||
|
||||
@Autowired
|
||||
private PersonRepository personRepository;
|
||||
|
||||
@BeforeEach
|
||||
void insertPeople() {
|
||||
personRepository.saveAll(Arrays.asList(
|
||||
new Person(1L, "John", "Doe"),
|
||||
new Person(2L, "Jane", "Doe"),
|
||||
new Person(3L, "Ted", "Mosby")
|
||||
));
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(strings = {"person", "PERSON", "Person"})
|
||||
void givenPeopleAndSpringNamingStrategy_whenQueryPersonUnquoted_thenResult(String tableName) {
|
||||
Query query = entityManager.createNativeQuery("select * from " + tableName);
|
||||
|
||||
// Expected result
|
||||
List<Person> result = (List<Person>) query.getResultStream()
|
||||
.map(this::fromDatabase)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
assertThat(result).isNotEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenPeopleAndSpringNamingStrategy_whenQueryPersonQuotedUpperCase_thenResult() {
|
||||
Query query = entityManager.createNativeQuery("select * from \"PERSON\"");
|
||||
|
||||
// Unexpected result
|
||||
List<Person> result = (List<Person>) query.getResultStream()
|
||||
.map(this::fromDatabase)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
assertThat(result).isNotEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenPeopleAndSpringNamingStrategy_whenQueryPersonQuotedLowerCase_thenException() {
|
||||
Query query = entityManager.createNativeQuery("select * from \"person\"");
|
||||
|
||||
// Unexpected result
|
||||
assertThrows(SQLGrammarException.class, query::getResultStream);
|
||||
}
|
||||
|
||||
public Person fromDatabase(Object databaseRow) {
|
||||
Object[] typedDatabaseRow = (Object[]) databaseRow;
|
||||
|
||||
return new Person(
|
||||
((BigInteger) typedDatabaseRow[0]).longValue(),
|
||||
(String) typedDatabaseRow[1],
|
||||
(String) typedDatabaseRow[2]
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,85 @@
|
|||
package com.baeldung.namingstrategy;
|
||||
|
||||
import org.hibernate.exception.SQLGrammarException;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.ValueSource;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.autoconfigure.jdbc.TestDatabaseAutoConfiguration;
|
||||
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
|
||||
import org.springframework.test.context.TestPropertySource;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.PersistenceContext;
|
||||
import javax.persistence.Query;
|
||||
import java.math.BigInteger;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
@DataJpaTest(excludeAutoConfiguration = TestDatabaseAutoConfiguration.class)
|
||||
@TestPropertySource("spring-physical-naming-strategy-on-postgres.properties")
|
||||
class SpringPhysicalNamingStrategyPostgresLiveTest {
|
||||
|
||||
@PersistenceContext
|
||||
private EntityManager entityManager;
|
||||
|
||||
@Autowired
|
||||
private PersonRepository personRepository;
|
||||
|
||||
@BeforeEach
|
||||
void insertPeople() {
|
||||
personRepository.saveAll(Arrays.asList(
|
||||
new Person(1L, "John", "Doe"),
|
||||
new Person(2L, "Jane", "Doe"),
|
||||
new Person(3L, "Ted", "Mosby")
|
||||
));
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(strings = {"person", "PERSON", "Person"})
|
||||
void givenPeopleAndSpringNamingStrategy_whenQueryPersonUnquoted_thenResult(String tableName) {
|
||||
Query query = entityManager.createNativeQuery("select * from " + tableName);
|
||||
|
||||
// Expected result
|
||||
List<Person> result = (List<Person>) query.getResultStream()
|
||||
.map(this::fromDatabase)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
assertThat(result).isNotEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenPeopleAndSpringNamingStrategy_whenQueryPersonQuotedUpperCase_thenException() {
|
||||
Query query = entityManager.createNativeQuery("select * from \"PERSON\"");
|
||||
|
||||
// Expected result
|
||||
assertThrows(SQLGrammarException.class, query::getResultStream);
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenPeopleAndSpringNamingStrategy_whenQueryPersonQuotedLowerCase_thenResult() {
|
||||
Query query = entityManager.createNativeQuery("select * from \"person\"");
|
||||
|
||||
// Expected result
|
||||
List<Person> result = (List<Person>) query.getResultStream()
|
||||
.map(this::fromDatabase)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
assertThat(result).isNotEmpty();
|
||||
}
|
||||
|
||||
public Person fromDatabase(Object databaseRow) {
|
||||
Object[] typedDatabaseRow = (Object[]) databaseRow;
|
||||
|
||||
return new Person(
|
||||
((BigInteger) typedDatabaseRow[0]).longValue(),
|
||||
(String) typedDatabaseRow[1],
|
||||
(String) typedDatabaseRow[2]
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,86 @@
|
|||
package com.baeldung.namingstrategy;
|
||||
|
||||
import org.hibernate.exception.SQLGrammarException;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.ValueSource;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.autoconfigure.jdbc.TestDatabaseAutoConfiguration;
|
||||
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
|
||||
import org.springframework.test.context.TestPropertySource;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.PersistenceContext;
|
||||
import javax.persistence.Query;
|
||||
import java.math.BigInteger;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
@DataJpaTest(excludeAutoConfiguration = TestDatabaseAutoConfiguration.class)
|
||||
@TestPropertySource("unquoted-lower-case-naming-strategy.properties")
|
||||
class UnquotedLowerCaseNamingStrategyH2IntegrationTest {
|
||||
|
||||
@PersistenceContext
|
||||
private EntityManager entityManager;
|
||||
|
||||
@Autowired
|
||||
private PersonRepository personRepository;
|
||||
|
||||
@BeforeEach
|
||||
void insertPeople() {
|
||||
personRepository.saveAll(Arrays.asList(
|
||||
new Person(1L, "John", "Doe"),
|
||||
new Person(2L, "Jane", "Doe"),
|
||||
new Person(3L, "Ted", "Mosby")
|
||||
));
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(strings = {"person", "PERSON", "Person"})
|
||||
void givenPeopleAndLowerCaseNamingStrategy_whenQueryPersonUnquoted_thenResult(String tableName) {
|
||||
Query query = entityManager.createNativeQuery("select * from " + tableName);
|
||||
|
||||
// Expected result
|
||||
List<Person> result = (List<Person>) query.getResultStream()
|
||||
.map(this::fromDatabase)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
assertThat(result).isNotEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenPeopleAndLowerCaseNamingStrategy_whenQueryPersonQuotedUpperCase_thenResult() {
|
||||
Query query = entityManager.createNativeQuery("select * from \"PERSON\"");
|
||||
|
||||
// Unexpected result
|
||||
List<Person> result = (List<Person>) query.getResultStream()
|
||||
.map(this::fromDatabase)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
assertThat(result).isNotEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenPeopleAndLowerCaseNamingStrategy_whenQueryPersonQuotedLowerCase_thenException() {
|
||||
Query query = entityManager.createNativeQuery("select * from \"person\"");
|
||||
|
||||
// Unexpected result
|
||||
assertThrows(SQLGrammarException.class, query::getResultStream);
|
||||
}
|
||||
|
||||
public Person fromDatabase(Object databaseRow) {
|
||||
Object[] typedDatabaseRow = (Object[]) databaseRow;
|
||||
|
||||
return new Person(
|
||||
((BigInteger) typedDatabaseRow[0]).longValue(),
|
||||
(String) typedDatabaseRow[1],
|
||||
(String) typedDatabaseRow[2]
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,85 @@
|
|||
package com.baeldung.namingstrategy;
|
||||
|
||||
import org.hibernate.exception.SQLGrammarException;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.ValueSource;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.autoconfigure.jdbc.TestDatabaseAutoConfiguration;
|
||||
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
|
||||
import org.springframework.test.context.TestPropertySource;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.PersistenceContext;
|
||||
import javax.persistence.Query;
|
||||
import java.math.BigInteger;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
@DataJpaTest(excludeAutoConfiguration = TestDatabaseAutoConfiguration.class)
|
||||
@TestPropertySource("unquoted-lower-case-naming-strategy-on-postgres.properties")
|
||||
class UnquotedLowerCaseNamingStrategyPostgresLiveTest {
|
||||
|
||||
@PersistenceContext
|
||||
private EntityManager entityManager;
|
||||
|
||||
@Autowired
|
||||
private PersonRepository personRepository;
|
||||
|
||||
@BeforeEach
|
||||
void insertPeople() {
|
||||
personRepository.saveAll(Arrays.asList(
|
||||
new Person(1L, "John", "Doe"),
|
||||
new Person(2L, "Jane", "Doe"),
|
||||
new Person(3L, "Ted", "Mosby")
|
||||
));
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(strings = {"person", "PERSON", "Person"})
|
||||
void givenPeopleAndLowerCaseNamingStrategy_whenQueryPersonUnquoted_thenResult(String tableName) {
|
||||
Query query = entityManager.createNativeQuery("select * from " + tableName);
|
||||
|
||||
// Expected result
|
||||
List<Person> result = (List<Person>) query.getResultStream()
|
||||
.map(this::fromDatabase)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
assertThat(result).isNotEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenPeopleAndLowerCaseNamingStrategy_whenQueryPersonQuotedUpperCase_thenException() {
|
||||
Query query = entityManager.createNativeQuery("select * from \"PERSON\"");
|
||||
|
||||
// Expected result
|
||||
assertThrows(SQLGrammarException.class, query::getResultStream);
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenPeopleAndLowerCaseNamingStrategy_whenQueryPersonQuotedLowerCase_thenResult() {
|
||||
Query query = entityManager.createNativeQuery("select * from \"person\"");
|
||||
|
||||
// Expected result
|
||||
List<Person> result = (List<Person>) query.getResultStream()
|
||||
.map(this::fromDatabase)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
assertThat(result).isNotEmpty();
|
||||
}
|
||||
|
||||
public Person fromDatabase(Object databaseRow) {
|
||||
Object[] typedDatabaseRow = (Object[]) databaseRow;
|
||||
|
||||
return new Person(
|
||||
((BigInteger) typedDatabaseRow[0]).longValue(),
|
||||
(String) typedDatabaseRow[1],
|
||||
(String) typedDatabaseRow[2]
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,85 @@
|
|||
package com.baeldung.namingstrategy;
|
||||
|
||||
import org.hibernate.exception.SQLGrammarException;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.ValueSource;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.autoconfigure.jdbc.TestDatabaseAutoConfiguration;
|
||||
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
|
||||
import org.springframework.test.context.TestPropertySource;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.PersistenceContext;
|
||||
import javax.persistence.Query;
|
||||
import java.math.BigInteger;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
@DataJpaTest(excludeAutoConfiguration = TestDatabaseAutoConfiguration.class)
|
||||
@TestPropertySource("unquoted-upper-case-naming-strategy.properties")
|
||||
class UnquotedUpperCaseNamingStrategyH2IntegrationTest {
|
||||
|
||||
@PersistenceContext
|
||||
private EntityManager entityManager;
|
||||
|
||||
@Autowired
|
||||
private PersonRepository personRepository;
|
||||
|
||||
@BeforeEach
|
||||
void insertPeople() {
|
||||
personRepository.saveAll(Arrays.asList(
|
||||
new Person(1L, "John", "Doe"),
|
||||
new Person(2L, "Jane", "Doe"),
|
||||
new Person(3L, "Ted", "Mosby")
|
||||
));
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(strings = {"person", "PERSON", "Person"})
|
||||
void givenPeopleAndUpperCaseNamingStrategy_whenQueryPersonUnquoted_thenResult(String tableName) {
|
||||
Query query = entityManager.createNativeQuery("select * from " + tableName);
|
||||
|
||||
// Expected result
|
||||
List<Person> result = (List<Person>) query.getResultStream()
|
||||
.map(this::fromDatabase)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
assertThat(result).isNotEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenPeopleAndUpperCaseNamingStrategy_whenQueryPersonQuotedUpperCase_thenResult() {
|
||||
Query query = entityManager.createNativeQuery("select * from \"PERSON\"");
|
||||
|
||||
// Expected result
|
||||
List<Person> result = (List<Person>) query.getResultStream()
|
||||
.map(this::fromDatabase)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
assertThat(result).isNotEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenPeopleAndUpperCaseNamingStrategy_whenQueryPersonQuotedLowerCase_thenException() {
|
||||
Query query = entityManager.createNativeQuery("select * from \"person\"");
|
||||
|
||||
// Expected result
|
||||
assertThrows(SQLGrammarException.class, query::getResultStream);
|
||||
}
|
||||
|
||||
public Person fromDatabase(Object databaseRow) {
|
||||
Object[] typedDatabaseRow = (Object[]) databaseRow;
|
||||
|
||||
return new Person(
|
||||
((BigInteger) typedDatabaseRow[0]).longValue(),
|
||||
(String) typedDatabaseRow[1],
|
||||
(String) typedDatabaseRow[2]
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,85 @@
|
|||
package com.baeldung.namingstrategy;
|
||||
|
||||
import org.hibernate.exception.SQLGrammarException;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.ValueSource;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.autoconfigure.jdbc.TestDatabaseAutoConfiguration;
|
||||
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
|
||||
import org.springframework.test.context.TestPropertySource;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.PersistenceContext;
|
||||
import javax.persistence.Query;
|
||||
import java.math.BigInteger;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
@DataJpaTest(excludeAutoConfiguration = TestDatabaseAutoConfiguration.class)
|
||||
@TestPropertySource("unquoted-upper-case-naming-strategy-on-postgres.properties")
|
||||
class UnquotedUpperCaseNamingStrategyPostgresLiveTest {
|
||||
|
||||
@PersistenceContext
|
||||
private EntityManager entityManager;
|
||||
|
||||
@Autowired
|
||||
private PersonRepository personRepository;
|
||||
|
||||
@BeforeEach
|
||||
void insertPeople() {
|
||||
personRepository.saveAll(Arrays.asList(
|
||||
new Person(1L, "John", "Doe"),
|
||||
new Person(2L, "Jane", "Doe"),
|
||||
new Person(3L, "Ted", "Mosby")
|
||||
));
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(strings = {"person", "PERSON", "Person"})
|
||||
void givenPeopleAndUpperCaseNamingStrategy_whenQueryPersonUnquoted_thenResult(String tableName) {
|
||||
Query query = entityManager.createNativeQuery("select * from " + tableName);
|
||||
|
||||
// Expected result
|
||||
List<Person> result = (List<Person>) query.getResultStream()
|
||||
.map(this::fromDatabase)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
assertThat(result).isNotEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenPeopleAndUpperCaseNamingStrategy_whenQueryPersonQuotedUpperCase_thenException() {
|
||||
Query query = entityManager.createNativeQuery("select * from \"PERSON\"");
|
||||
|
||||
// Unexpected result
|
||||
assertThrows(SQLGrammarException.class, query::getResultStream);
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenPeopleAndUpperCaseNamingStrategy_whenQueryPersonQuotedLowerCase_thenResult() {
|
||||
Query query = entityManager.createNativeQuery("select * from \"person\"");
|
||||
|
||||
// Unexpected result
|
||||
List<Person> result = (List<Person>) query.getResultStream()
|
||||
.map(this::fromDatabase)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
assertThat(result).isNotEmpty();
|
||||
}
|
||||
|
||||
public Person fromDatabase(Object databaseRow) {
|
||||
Object[] typedDatabaseRow = (Object[]) databaseRow;
|
||||
|
||||
return new Person(
|
||||
((BigInteger) typedDatabaseRow[0]).longValue(),
|
||||
(String) typedDatabaseRow[1],
|
||||
(String) typedDatabaseRow[2]
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
spring.datasource.url=jdbc:postgresql://localhost:5432/quoted-lower-case-strategy
|
||||
spring.datasource.username=postgres
|
||||
spring.datasource.password=root
|
||||
|
||||
spring.jpa.hibernate.ddl-auto=create-drop
|
||||
spring.jpa.hibernate.naming.physical-strategy=com.baeldung.namingstrategy.QuotedLowerCaseNamingStrategy
|
||||
#spring.jpa.properties.javax.persistence.schema-generation.create-source=metadata
|
||||
#spring.jpa.properties.javax.persistence.schema-generation.scripts.action=create
|
||||
#spring.jpa.properties.javax.persistence.schema-generation.scripts.create-target=upper-case-naming-strategy-ddl.sql
|
|
@ -0,0 +1,9 @@
|
|||
spring.datasource.url=jdbc:h2:mem:quoted-lower-case-strategy
|
||||
spring.datasource.username=sa
|
||||
spring.datasource.password=
|
||||
|
||||
spring.jpa.hibernate.ddl-auto=create-drop
|
||||
spring.jpa.hibernate.naming.physical-strategy=com.baeldung.namingstrategy.QuotedLowerCaseNamingStrategy
|
||||
#spring.jpa.properties.javax.persistence.schema-generation.create-source=metadata
|
||||
#spring.jpa.properties.javax.persistence.schema-generation.scripts.action=create
|
||||
#spring.jpa.properties.javax.persistence.schema-generation.scripts.create-target=upper-case-naming-strategy-ddl.sql
|
|
@ -0,0 +1,9 @@
|
|||
spring.datasource.url=jdbc:postgresql://localhost:5432/quoted-upper-case-strategy
|
||||
spring.datasource.username=postgres
|
||||
spring.datasource.password=root
|
||||
|
||||
spring.jpa.hibernate.ddl-auto=create-drop
|
||||
spring.jpa.hibernate.naming.physical-strategy=com.baeldung.namingstrategy.QuotedUpperCaseNamingStrategy
|
||||
#spring.jpa.properties.javax.persistence.schema-generation.create-source=metadata
|
||||
#spring.jpa.properties.javax.persistence.schema-generation.scripts.action=create
|
||||
#spring.jpa.properties.javax.persistence.schema-generation.scripts.create-target=upper-case-naming-strategy-ddl.sql
|
|
@ -0,0 +1,9 @@
|
|||
spring.datasource.url=jdbc:h2:mem:quoted-upper-case-strategy
|
||||
spring.datasource.username=sa
|
||||
spring.datasource.password=
|
||||
|
||||
spring.jpa.hibernate.ddl-auto=create-drop
|
||||
spring.jpa.hibernate.naming.physical-strategy=com.baeldung.namingstrategy.QuotedUpperCaseNamingStrategy
|
||||
#spring.jpa.properties.javax.persistence.schema-generation.create-source=metadata
|
||||
#spring.jpa.properties.javax.persistence.schema-generation.scripts.action=create
|
||||
#spring.jpa.properties.javax.persistence.schema-generation.scripts.create-target=upper-case-naming-strategy-ddl.sql
|
|
@ -0,0 +1,9 @@
|
|||
spring.datasource.url=jdbc:postgresql://localhost:5432/spring-strategy
|
||||
spring.datasource.username=postgres
|
||||
spring.datasource.password=root
|
||||
|
||||
spring.jpa.hibernate.ddl-auto=create-drop
|
||||
spring.jpa.hibernate.naming.physical-strategy=org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy
|
||||
#spring.jpa.properties.javax.persistence.schema-generation.create-source=metadata
|
||||
#spring.jpa.properties.javax.persistence.schema-generation.scripts.action=create
|
||||
#spring.jpa.properties.javax.persistence.schema-generation.scripts.create-target=default-naming-strategy-ddl.sql
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue