commit
						13ce413ed2
					
				
							
								
								
									
										4
									
								
								algorithms-miscellaneous-6/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								algorithms-miscellaneous-6/README.md
									
									
									
									
									
										Normal file
									
								
							| @ -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) | ||||
							
								
								
									
										7
									
								
								atomikos/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								atomikos/README.md
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,7 @@ | ||||
| ## Atomikos | ||||
| 
 | ||||
| This module contains articles about Atomikos | ||||
| 
 | ||||
| ### Relevant Articles:  | ||||
| 
 | ||||
| - [Guide Transactions Using Atomikos]() | ||||
							
								
								
									
										119
									
								
								atomikos/pom.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										119
									
								
								atomikos/pom.xml
									
									
									
									
									
										Normal file
									
								
							| @ -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> { | ||||
| 
 | ||||
| } | ||||
							
								
								
									
										13
									
								
								atomikos/src/main/resources/logback.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								atomikos/src/main/resources/logback.xml
									
									
									
									
									
										Normal file
									
								
							| @ -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> | ||||
							
								
								
									
										10
									
								
								atomikos/src/main/resources/schema.sql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								atomikos/src/main/resources/schema.sql
									
									
									
									
									
										Normal file
									
								
							| @ -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) | ||||
| ); | ||||
							
								
								
									
										1
									
								
								atomikos/src/main/resources/transactions.properties
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								atomikos/src/main/resources/transactions.properties
									
									
									
									
									
										Normal file
									
								
							| @ -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(); | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
| } | ||||
							
								
								
									
										13
									
								
								atomikos/src/test/resources/logback.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								atomikos/src/test/resources/logback.xml
									
									
									
									
									
										Normal file
									
								
							| @ -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> | ||||
							
								
								
									
										1
									
								
								atomikos/src/test/resources/transactions.properties
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								atomikos/src/test/resources/transactions.properties
									
									
									
									
									
										Normal file
									
								
							| @ -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) | ||||
|  | ||||
							
								
								
									
										8
									
								
								java-collections-maps-3/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								java-collections-maps-3/README.md
									
									
									
									
									
										Normal file
									
								
							| @ -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) | ||||
							
								
								
									
										43
									
								
								java-collections-maps-3/pom.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								java-collections-maps-3/pom.xml
									
									
									
									
									
										Normal file
									
								
							| @ -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) | ||||
|  | ||||
							
								
								
									
										3
									
								
								libraries-concurrency/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								libraries-concurrency/README.md
									
									
									
									
									
										Normal file
									
								
							| @ -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)); | ||||
|     } | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										9
									
								
								libraries-testing/src/test/resources/dbunit/data.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								libraries-testing/src/test/resources/dbunit/data.xml
									
									
									
									
									
										Normal file
									
								
							| @ -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> | ||||
							
								
								
									
										8
									
								
								libraries-testing/src/test/resources/dbunit/items.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								libraries-testing/src/test/resources/dbunit/items.xml
									
									
									
									
									
										Normal file
									
								
							| @ -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> | ||||
							
								
								
									
										28
									
								
								libraries-testing/src/test/resources/dbunit/schema.sql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								libraries-testing/src/test/resources/dbunit/schema.sql
									
									
									
									
									
										Normal file
									
								
							| @ -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 | ||||
| ); | ||||
							
								
								
									
										6
									
								
								libraries-testing/src/test/resources/dbunit/users.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								libraries-testing/src/test/resources/dbunit/users.xml
									
									
									
									
									
										Normal file
									
								
							| @ -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); | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										2
									
								
								persistence-modules/spring-data-jpa-4/create.sql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								persistence-modules/spring-data-jpa-4/create.sql
									
									
									
									
									
										Normal file
									
								
							| @ -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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user