Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
7aa28761d3
|
@ -13,6 +13,5 @@ This module contains articles about algorithms. Some classes of algorithms, e.g.
|
||||||
- [Checking if a Java Graph has a Cycle](https://www.baeldung.com/java-graph-has-a-cycle)
|
- [Checking if a Java Graph has a Cycle](https://www.baeldung.com/java-graph-has-a-cycle)
|
||||||
- [A Guide to the Folding Technique in Java](https://www.baeldung.com/folding-hashing-technique)
|
- [A Guide to the Folding Technique in Java](https://www.baeldung.com/folding-hashing-technique)
|
||||||
- [Creating a Triangle with for Loops in Java](https://www.baeldung.com/java-print-triangle)
|
- [Creating a Triangle with for Loops in Java](https://www.baeldung.com/java-print-triangle)
|
||||||
- [Efficient Word Frequency Calculator in Java](https://www.baeldung.com/java-word-frequency)
|
|
||||||
- [The K-Means Clustering Algorithm in Java](https://www.baeldung.com/java-k-means-clustering-algorithm)
|
- [The K-Means Clustering Algorithm in Java](https://www.baeldung.com/java-k-means-clustering-algorithm)
|
||||||
- More articles: [[<-- prev]](/algorithms-miscellaneous-2) [[next -->]](/algorithms-miscellaneous-4)
|
- More articles: [[<-- prev]](/algorithms-miscellaneous-2) [[next -->]](/algorithms-miscellaneous-4)
|
||||||
|
|
|
@ -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)
|
|
@ -1,3 +0,0 @@
|
||||||
### Relevant Articles:
|
|
||||||
|
|
||||||
- [Intro to OData with Olingo](https://www.baeldung.com/olingo)
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
## Atomikos
|
||||||
|
|
||||||
|
This module contains articles about Atomikos
|
||||||
|
|
||||||
|
### Relevant Articles:
|
||||||
|
|
||||||
|
- [Guide Transactions Using Atomikos]()
|
|
@ -0,0 +1,119 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<artifactId>atomikos</artifactId>
|
||||||
|
<name>atomikos</name>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<groupId>com.baeldung</groupId>
|
||||||
|
<artifactId>parent-modules</artifactId>
|
||||||
|
<version>1.0.0-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.atomikos</groupId>
|
||||||
|
<artifactId>transactions-jdbc</artifactId>
|
||||||
|
<version>${atomikos-version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.atomikos</groupId>
|
||||||
|
<artifactId>transactions-jms</artifactId>
|
||||||
|
<version>${atomikos-version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.atomikos</groupId>
|
||||||
|
<artifactId>transactions-hibernate4</artifactId>
|
||||||
|
<version>${atomikos-version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework</groupId>
|
||||||
|
<artifactId>spring-context</artifactId>
|
||||||
|
<version>${spring-version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework</groupId>
|
||||||
|
<artifactId>spring-tx</artifactId>
|
||||||
|
<version>${spring-version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.data</groupId>
|
||||||
|
<artifactId>spring-data-jpa</artifactId>
|
||||||
|
<version>1.11.23.RELEASE</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework</groupId>
|
||||||
|
<artifactId>spring-test</artifactId>
|
||||||
|
<version>${spring-version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.hibernate</groupId>
|
||||||
|
<artifactId>hibernate-entitymanager</artifactId>
|
||||||
|
<version>${hibernate.version}</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
<exclusions>
|
||||||
|
<exclusion>
|
||||||
|
<groupId>javax.transaction</groupId>
|
||||||
|
<artifactId>jta</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
</exclusions>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.activemq</groupId>
|
||||||
|
<artifactId>activemq-core</artifactId>
|
||||||
|
<version>5.7.0</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.derby</groupId>
|
||||||
|
<artifactId>derby</artifactId>
|
||||||
|
<version>10.8.1.2</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>junit</groupId>
|
||||||
|
<artifactId>junit</artifactId>
|
||||||
|
<version>4.12</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<!-- the JTA API -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>javax.transaction</groupId>
|
||||||
|
<artifactId>jta</artifactId>
|
||||||
|
<version>1.1</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.geronimo.specs</groupId>
|
||||||
|
<artifactId>geronimo-jta_1.0.1B_spec</artifactId>
|
||||||
|
<version>1.0</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>javax.validation</groupId>
|
||||||
|
<artifactId>validation-api</artifactId>
|
||||||
|
<version>2.0.1.Final</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.hibernate.validator</groupId>
|
||||||
|
<artifactId>hibernate-validator</artifactId>
|
||||||
|
<version>6.1.2.Final</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>javax.el</groupId>
|
||||||
|
<artifactId>javax.el-api</artifactId>
|
||||||
|
<version>3.0.0</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.glassfish.web</groupId>
|
||||||
|
<artifactId>javax.el</artifactId>
|
||||||
|
<version>2.2.4</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<atomikos-version>5.0.6</atomikos-version>
|
||||||
|
<spring-version>5.1.6.RELEASE</spring-version>
|
||||||
|
<hibernate.version>5.4.3.Final</hibernate.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
</project>
|
|
@ -0,0 +1,53 @@
|
||||||
|
package com.baeldung.atomikos.direct;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.Statement;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import javax.sql.DataSource;
|
||||||
|
|
||||||
|
import com.atomikos.icatch.jta.UserTransactionImp;
|
||||||
|
|
||||||
|
public class Application {
|
||||||
|
|
||||||
|
private DataSource inventoryDataSource;
|
||||||
|
private DataSource orderDataSource;
|
||||||
|
|
||||||
|
public Application(DataSource inventoryDataSource, DataSource orderDataSource) {
|
||||||
|
this.inventoryDataSource = inventoryDataSource;
|
||||||
|
this.orderDataSource = orderDataSource;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void placeOrder(String productId, int amount) throws Exception {
|
||||||
|
|
||||||
|
UserTransactionImp utx = new UserTransactionImp();
|
||||||
|
String orderId = UUID.randomUUID()
|
||||||
|
.toString();
|
||||||
|
boolean rollback = false;
|
||||||
|
try {
|
||||||
|
utx.begin();
|
||||||
|
Connection inventoryConnection = inventoryDataSource.getConnection();
|
||||||
|
Connection orderConnection = orderDataSource.getConnection();
|
||||||
|
Statement s1 = inventoryConnection.createStatement();
|
||||||
|
String q1 = "update Inventory set balance = balance - " + amount + " where productId ='" + productId + "'";
|
||||||
|
s1.executeUpdate(q1);
|
||||||
|
s1.close();
|
||||||
|
Statement s2 = orderConnection.createStatement();
|
||||||
|
String q2 = "insert into Orders values ( '" + orderId + "', '" + productId + "', " + amount + " )";
|
||||||
|
s2.executeUpdate(q2);
|
||||||
|
s2.close();
|
||||||
|
inventoryConnection.close();
|
||||||
|
orderConnection.close();
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.out.println(e.getMessage());
|
||||||
|
rollback = true;
|
||||||
|
} finally {
|
||||||
|
if (!rollback)
|
||||||
|
utx.commit();
|
||||||
|
else
|
||||||
|
utx.rollback();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
package com.baeldung.atomikos.spring;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.Statement;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import javax.sql.DataSource;
|
||||||
|
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
public class Application {
|
||||||
|
|
||||||
|
private DataSource inventoryDataSource;
|
||||||
|
private DataSource orderDataSource;
|
||||||
|
|
||||||
|
public Application(DataSource inventoryDataSource, DataSource orderDataSource) {
|
||||||
|
this.inventoryDataSource = inventoryDataSource;
|
||||||
|
this.orderDataSource = orderDataSource;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public void placeOrder(String productId, int amount) throws Exception {
|
||||||
|
|
||||||
|
String orderId = UUID.randomUUID()
|
||||||
|
.toString();
|
||||||
|
Connection inventoryConnection = inventoryDataSource.getConnection();
|
||||||
|
Connection orderConnection = orderDataSource.getConnection();
|
||||||
|
Statement s1 = inventoryConnection.createStatement();
|
||||||
|
String q1 = "update Inventory set balance = balance - " + amount + " where productId ='" + productId + "'";
|
||||||
|
s1.executeUpdate(q1);
|
||||||
|
s1.close();
|
||||||
|
Statement s2 = orderConnection.createStatement();
|
||||||
|
String q2 = "insert into Orders values ( '" + orderId + "', '" + productId + "', " + amount + " )";
|
||||||
|
s2.executeUpdate(q2);
|
||||||
|
s2.close();
|
||||||
|
inventoryConnection.close();
|
||||||
|
orderConnection.close();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,68 @@
|
||||||
|
package com.baeldung.atomikos.spring.config;
|
||||||
|
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
import javax.transaction.SystemException;
|
||||||
|
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.transaction.annotation.EnableTransactionManagement;
|
||||||
|
import org.springframework.transaction.jta.JtaTransactionManager;
|
||||||
|
|
||||||
|
import com.atomikos.icatch.jta.UserTransactionManager;
|
||||||
|
import com.atomikos.jdbc.AtomikosDataSourceBean;
|
||||||
|
import com.baeldung.atomikos.spring.Application;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@EnableTransactionManagement
|
||||||
|
public class Config {
|
||||||
|
|
||||||
|
@Bean(initMethod = "init", destroyMethod = "close")
|
||||||
|
public AtomikosDataSourceBean inventoryDataSource() {
|
||||||
|
AtomikosDataSourceBean dataSource = new AtomikosDataSourceBean();
|
||||||
|
dataSource.setLocalTransactionMode(true);
|
||||||
|
dataSource.setUniqueResourceName("db1");
|
||||||
|
dataSource.setXaDataSourceClassName("org.apache.derby.jdbc.EmbeddedXADataSource");
|
||||||
|
Properties xaProperties = new Properties();
|
||||||
|
xaProperties.put("databaseName", "db1");
|
||||||
|
xaProperties.put("createDatabase", "create");
|
||||||
|
dataSource.setXaProperties(xaProperties);
|
||||||
|
dataSource.setPoolSize(10);
|
||||||
|
return dataSource;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean(initMethod = "init", destroyMethod = "close")
|
||||||
|
public AtomikosDataSourceBean orderDataSource() {
|
||||||
|
AtomikosDataSourceBean dataSource = new AtomikosDataSourceBean();
|
||||||
|
dataSource.setLocalTransactionMode(true);
|
||||||
|
dataSource.setUniqueResourceName("db2");
|
||||||
|
dataSource.setXaDataSourceClassName("org.apache.derby.jdbc.EmbeddedXADataSource");
|
||||||
|
Properties xaProperties = new Properties();
|
||||||
|
xaProperties.put("databaseName", "db2");
|
||||||
|
xaProperties.put("createDatabase", "create");
|
||||||
|
dataSource.setXaProperties(xaProperties);
|
||||||
|
dataSource.setPoolSize(10);
|
||||||
|
return dataSource;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean(initMethod = "init", destroyMethod = "close")
|
||||||
|
public UserTransactionManager userTransactionManager() throws SystemException {
|
||||||
|
UserTransactionManager userTransactionManager = new UserTransactionManager();
|
||||||
|
userTransactionManager.setTransactionTimeout(300);
|
||||||
|
userTransactionManager.setForceShutdown(true);
|
||||||
|
return userTransactionManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public JtaTransactionManager jtaTransactionManager() throws SystemException {
|
||||||
|
JtaTransactionManager jtaTransactionManager = new JtaTransactionManager();
|
||||||
|
jtaTransactionManager.setTransactionManager(userTransactionManager());
|
||||||
|
jtaTransactionManager.setUserTransaction(userTransactionManager());
|
||||||
|
return jtaTransactionManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public Application application() {
|
||||||
|
return new Application(inventoryDataSource(), orderDataSource());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,48 @@
|
||||||
|
package com.baeldung.atomikos.spring.jpa;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import javax.validation.ConstraintViolation;
|
||||||
|
import javax.validation.Validation;
|
||||||
|
import javax.validation.Validator;
|
||||||
|
import javax.validation.ValidatorFactory;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import com.baeldung.atomikos.spring.jpa.inventory.Inventory;
|
||||||
|
import com.baeldung.atomikos.spring.jpa.inventory.InventoryRepository;
|
||||||
|
import com.baeldung.atomikos.spring.jpa.order.Order;
|
||||||
|
import com.baeldung.atomikos.spring.jpa.order.OrderRepository;
|
||||||
|
|
||||||
|
public class Application {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private InventoryRepository inventoryRepository;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private OrderRepository orderRepository;
|
||||||
|
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public void placeOrder(String productId, int amount) throws Exception {
|
||||||
|
|
||||||
|
String orderId = UUID.randomUUID()
|
||||||
|
.toString();
|
||||||
|
Inventory inventory = inventoryRepository.findOne(productId);
|
||||||
|
inventory.setBalance(inventory.getBalance() - amount);
|
||||||
|
inventoryRepository.save(inventory);
|
||||||
|
Order order = new Order();
|
||||||
|
order.setOrderId(orderId);
|
||||||
|
order.setProductId(productId);
|
||||||
|
order.setAmount(new Long(amount));
|
||||||
|
ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
|
||||||
|
Validator validator = factory.getValidator();
|
||||||
|
Set<ConstraintViolation<Order>> violations = validator.validate(order);
|
||||||
|
if (violations.size() > 0)
|
||||||
|
throw new Exception("Invalid instance of an order.");
|
||||||
|
orderRepository.save(order);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
package com.baeldung.atomikos.spring.jpa.config;
|
||||||
|
|
||||||
|
import javax.transaction.SystemException;
|
||||||
|
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.transaction.annotation.EnableTransactionManagement;
|
||||||
|
import org.springframework.transaction.jta.JtaTransactionManager;
|
||||||
|
|
||||||
|
import com.atomikos.icatch.jta.UserTransactionManager;
|
||||||
|
import com.baeldung.atomikos.spring.jpa.Application;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@EnableTransactionManagement
|
||||||
|
public class Config {
|
||||||
|
|
||||||
|
@Bean(initMethod = "init", destroyMethod = "close")
|
||||||
|
public UserTransactionManager userTransactionManager() throws SystemException {
|
||||||
|
UserTransactionManager userTransactionManager = new UserTransactionManager();
|
||||||
|
userTransactionManager.setTransactionTimeout(300);
|
||||||
|
userTransactionManager.setForceShutdown(true);
|
||||||
|
return userTransactionManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public JtaTransactionManager transactionManager() throws SystemException {
|
||||||
|
JtaTransactionManager jtaTransactionManager = new JtaTransactionManager();
|
||||||
|
jtaTransactionManager.setTransactionManager(userTransactionManager());
|
||||||
|
jtaTransactionManager.setUserTransaction(userTransactionManager());
|
||||||
|
return jtaTransactionManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public Application application() {
|
||||||
|
return new Application();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
package com.baeldung.atomikos.spring.jpa.inventory;
|
||||||
|
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Table(name = "INVENTORY")
|
||||||
|
public class Inventory {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
private String productId;
|
||||||
|
private Long balance;
|
||||||
|
|
||||||
|
public String getProductId() {
|
||||||
|
return productId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setProductId(String productId) {
|
||||||
|
this.productId = productId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getBalance() {
|
||||||
|
return balance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBalance(Long balance) {
|
||||||
|
this.balance = balance;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,53 @@
|
||||||
|
package com.baeldung.atomikos.spring.jpa.inventory;
|
||||||
|
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
import javax.persistence.EntityManagerFactory;
|
||||||
|
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
|
||||||
|
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
|
||||||
|
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
|
||||||
|
|
||||||
|
import com.atomikos.jdbc.AtomikosDataSourceBean;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@EnableJpaRepositories(basePackages = "com.baeldung.atomikos.spring.jpa.inventory", entityManagerFactoryRef = "inventoryEntityManager", transactionManagerRef = "transactionManager")
|
||||||
|
public class InventoryConfig {
|
||||||
|
|
||||||
|
@Bean(initMethod = "init", destroyMethod = "close")
|
||||||
|
public AtomikosDataSourceBean inventoryDataSource() {
|
||||||
|
AtomikosDataSourceBean dataSource = new AtomikosDataSourceBean();
|
||||||
|
dataSource.setLocalTransactionMode(true);
|
||||||
|
dataSource.setUniqueResourceName("db1");
|
||||||
|
dataSource.setXaDataSourceClassName("org.apache.derby.jdbc.EmbeddedXADataSource");
|
||||||
|
Properties xaProperties = new Properties();
|
||||||
|
xaProperties.put("databaseName", "db1");
|
||||||
|
xaProperties.put("createDatabase", "create");
|
||||||
|
dataSource.setXaProperties(xaProperties);
|
||||||
|
dataSource.setPoolSize(10);
|
||||||
|
return dataSource;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public EntityManagerFactory inventoryEntityManager() {
|
||||||
|
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
|
||||||
|
LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
|
||||||
|
factory.setJpaVendorAdapter(vendorAdapter);
|
||||||
|
factory.setPackagesToScan("com.baeldung.atomikos.spring.jpa.inventory");
|
||||||
|
factory.setDataSource(inventoryDataSource());
|
||||||
|
Properties jpaProperties = new Properties();
|
||||||
|
//jpaProperties.put("hibernate.show_sql", "true");
|
||||||
|
//jpaProperties.put("hibernate.format_sql", "true");
|
||||||
|
jpaProperties.put("hibernate.dialect", "org.hibernate.dialect.DerbyDialect");
|
||||||
|
jpaProperties.put("hibernate.current_session_context_class", "jta");
|
||||||
|
jpaProperties.put("javax.persistence.transactionType", "jta");
|
||||||
|
jpaProperties.put("hibernate.transaction.manager_lookup_class", "com.atomikos.icatch.jta.hibernate3.TransactionManagerLookup");
|
||||||
|
jpaProperties.put("hibernate.hbm2ddl.auto", "create-drop");
|
||||||
|
factory.setJpaProperties(jpaProperties);
|
||||||
|
factory.afterPropertiesSet();
|
||||||
|
return factory.getObject();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
package com.baeldung.atomikos.spring.jpa.inventory;
|
||||||
|
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
|
@Repository
|
||||||
|
public interface InventoryRepository extends JpaRepository<Inventory, String> {
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
package com.baeldung.atomikos.spring.jpa.order;
|
||||||
|
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
import javax.validation.constraints.Max;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Table(name = "ORDERS")
|
||||||
|
public class Order {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
private String orderId;
|
||||||
|
private String productId;
|
||||||
|
@Max(5)
|
||||||
|
private Long amount;
|
||||||
|
|
||||||
|
public String getOrderId() {
|
||||||
|
return orderId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOrderId(String orderId) {
|
||||||
|
this.orderId = orderId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getProductId() {
|
||||||
|
return productId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setProductId(String productId) {
|
||||||
|
this.productId = productId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getAmount() {
|
||||||
|
return amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAmount(Long amount) {
|
||||||
|
this.amount = amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,53 @@
|
||||||
|
package com.baeldung.atomikos.spring.jpa.order;
|
||||||
|
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
import javax.persistence.EntityManagerFactory;
|
||||||
|
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
|
||||||
|
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
|
||||||
|
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
|
||||||
|
|
||||||
|
import com.atomikos.jdbc.AtomikosDataSourceBean;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@EnableJpaRepositories(basePackages = "com.baeldung.atomikos.spring.jpa.order", entityManagerFactoryRef = "orderEntityManager", transactionManagerRef = "transactionManager")
|
||||||
|
public class OrderConfig {
|
||||||
|
|
||||||
|
@Bean(initMethod = "init", destroyMethod = "close")
|
||||||
|
public AtomikosDataSourceBean orderDataSource() {
|
||||||
|
AtomikosDataSourceBean dataSource = new AtomikosDataSourceBean();
|
||||||
|
dataSource.setLocalTransactionMode(true);
|
||||||
|
dataSource.setUniqueResourceName("db2");
|
||||||
|
dataSource.setXaDataSourceClassName("org.apache.derby.jdbc.EmbeddedXADataSource");
|
||||||
|
Properties xaProperties = new Properties();
|
||||||
|
xaProperties.put("databaseName", "db2");
|
||||||
|
xaProperties.put("createDatabase", "create");
|
||||||
|
dataSource.setXaProperties(xaProperties);
|
||||||
|
dataSource.setPoolSize(10);
|
||||||
|
return dataSource;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public EntityManagerFactory orderEntityManager() {
|
||||||
|
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
|
||||||
|
LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
|
||||||
|
factory.setJpaVendorAdapter(vendorAdapter);
|
||||||
|
factory.setPackagesToScan("com.baeldung.atomikos.spring.jpa.order");
|
||||||
|
factory.setDataSource(orderDataSource());
|
||||||
|
Properties jpaProperties = new Properties();
|
||||||
|
//jpaProperties.put("hibernate.show_sql", "true");
|
||||||
|
//jpaProperties.put("hibernate.format_sql", "true");
|
||||||
|
jpaProperties.put("hibernate.dialect", "org.hibernate.dialect.DerbyDialect");
|
||||||
|
jpaProperties.put("hibernate.current_session_context_class", "jta");
|
||||||
|
jpaProperties.put("javax.persistence.transactionType", "jta");
|
||||||
|
jpaProperties.put("hibernate.transaction.manager_lookup_class", "com.atomikos.icatch.jta.hibernate3.TransactionManagerLookup");
|
||||||
|
jpaProperties.put("hibernate.hbm2ddl.auto", "create-drop");
|
||||||
|
factory.setJpaProperties(jpaProperties);
|
||||||
|
factory.afterPropertiesSet();
|
||||||
|
return factory.getObject();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
package com.baeldung.atomikos.spring.jpa.order;
|
||||||
|
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
|
@Repository
|
||||||
|
public interface OrderRepository extends JpaRepository<Order, String> {
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<configuration>
|
||||||
|
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||||
|
<encoder>
|
||||||
|
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
|
||||||
|
</pattern>
|
||||||
|
</encoder>
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
<root level="INFO">
|
||||||
|
<appender-ref ref="STDOUT" />
|
||||||
|
</root>
|
||||||
|
</configuration>
|
|
@ -0,0 +1,10 @@
|
||||||
|
CREATE TABLE INVENTORY (
|
||||||
|
productId VARCHAR PRIMARY KEY,
|
||||||
|
balance INT
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE ORDERS (
|
||||||
|
orderId VARCHAR PRIMARY KEY,
|
||||||
|
productId VARCHAR,
|
||||||
|
amount INT NOT NULL CHECK (amount <= 5)
|
||||||
|
);
|
|
@ -0,0 +1 @@
|
||||||
|
com.atomikos.icatch.file=logs
|
|
@ -0,0 +1,118 @@
|
||||||
|
package com.baeldung.atomikos.direct;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.sql.Statement;
|
||||||
|
import java.util.Properties;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import javax.sql.DataSource;
|
||||||
|
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.Ignore;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import com.atomikos.icatch.jta.UserTransactionImp;
|
||||||
|
import com.atomikos.jdbc.AtomikosDataSourceBean;
|
||||||
|
|
||||||
|
public class ApplicationUnitTest {
|
||||||
|
|
||||||
|
private static DataSource inventoryDataSource;
|
||||||
|
private static DataSource orderDataSource;
|
||||||
|
|
||||||
|
private static String productId = UUID.randomUUID()
|
||||||
|
.toString();
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Ignore
|
||||||
|
public void testPlaceOrderSuccess() throws Exception {
|
||||||
|
int amount = 1;
|
||||||
|
long initialBalance = getBalance(inventoryDataSource, productId);
|
||||||
|
Application application = new Application(inventoryDataSource, orderDataSource);
|
||||||
|
application.placeOrder(productId, amount);
|
||||||
|
long finalBalance = getBalance(inventoryDataSource, productId);
|
||||||
|
assertEquals(initialBalance - amount, finalBalance);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Ignore
|
||||||
|
public void testPlaceOrderFailure() throws Exception {
|
||||||
|
int amount = 10;
|
||||||
|
long initialBalance = getBalance(inventoryDataSource, productId);
|
||||||
|
Application application = new Application(inventoryDataSource, orderDataSource);
|
||||||
|
application.placeOrder(productId, amount);
|
||||||
|
long finalBalance = getBalance(inventoryDataSource, productId);
|
||||||
|
assertEquals(initialBalance, finalBalance);
|
||||||
|
}
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void setUp() throws SQLException {
|
||||||
|
|
||||||
|
inventoryDataSource = getDataSource("db1");
|
||||||
|
orderDataSource = getDataSource("db2");
|
||||||
|
Connection inventoryConnection = inventoryDataSource.getConnection();
|
||||||
|
Connection orderConnection = orderDataSource.getConnection();
|
||||||
|
String createInventoryTable = "create table Inventory ( " + " productId VARCHAR ( 100 ) PRIMARY KEY, balance INT )";
|
||||||
|
String createInventoryRow = "insert into Inventory values ( '" + productId + "', 10000 )";
|
||||||
|
Statement s1 = inventoryConnection.createStatement();
|
||||||
|
try {
|
||||||
|
s1.executeUpdate(createInventoryTable);
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.out.println("Inventory table exists");
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
s1.executeUpdate(createInventoryRow);
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.out.println("Product row exists");
|
||||||
|
}
|
||||||
|
s1.close();
|
||||||
|
String createOrderTable = "create table Orders ( orderId VARCHAR ( 100 ) PRIMARY KEY, productId VARCHAR ( 100 ), amount INT NOT NULL CHECK (amount <= 5) )";
|
||||||
|
Statement s2 = orderConnection.createStatement();
|
||||||
|
try {
|
||||||
|
s2.executeUpdate(createOrderTable);
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.out.println("Orders table exists");
|
||||||
|
}
|
||||||
|
s2.close();
|
||||||
|
inventoryConnection.close();
|
||||||
|
orderConnection.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static DataSource getDataSource(String db) {
|
||||||
|
|
||||||
|
DataSource ds;
|
||||||
|
AtomikosDataSourceBean ads = new AtomikosDataSourceBean();
|
||||||
|
ads.setXaDataSourceClassName("org.apache.derby.jdbc.EmbeddedXADataSource");
|
||||||
|
Properties properties = new Properties();
|
||||||
|
properties.put("databaseName", db);
|
||||||
|
properties.put("createDatabase", "create");
|
||||||
|
ads.setXaProperties(properties);
|
||||||
|
ads.setUniqueResourceName(db);
|
||||||
|
ads.setPoolSize(10); // optional
|
||||||
|
ads.setBorrowConnectionTimeout(10); // optional
|
||||||
|
ds = ads;
|
||||||
|
return ds;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static long getBalance(DataSource inventoryDataSource, String productId) throws Exception {
|
||||||
|
|
||||||
|
UserTransactionImp utx = new UserTransactionImp();
|
||||||
|
utx.begin();
|
||||||
|
Connection inventoryConnection = inventoryDataSource.getConnection();
|
||||||
|
Statement s1 = inventoryConnection.createStatement();
|
||||||
|
String q1 = "select balance from Inventory where productId='" + productId + "'";
|
||||||
|
ResultSet rs1 = s1.executeQuery(q1);
|
||||||
|
if (rs1 == null || !rs1.next())
|
||||||
|
throw new Exception("Product not found: " + productId);
|
||||||
|
long balance = rs1.getLong(1);
|
||||||
|
inventoryConnection.close();
|
||||||
|
utx.commit();
|
||||||
|
return balance;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,108 @@
|
||||||
|
package com.baeldung.atomikos.spring;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.sql.Statement;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import javax.sql.DataSource;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Ignore;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.test.context.ContextConfiguration;
|
||||||
|
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||||
|
|
||||||
|
import com.baeldung.atomikos.spring.config.Config;
|
||||||
|
|
||||||
|
@RunWith(SpringJUnit4ClassRunner.class)
|
||||||
|
@ContextConfiguration(classes = { Config.class })
|
||||||
|
public class ApplicationUnitTest {
|
||||||
|
|
||||||
|
private static String productId = UUID.randomUUID()
|
||||||
|
.toString();
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
Application application;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
DataSource inventoryDataSource;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
DataSource orderDataSource;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Ignore
|
||||||
|
public void testPlaceOrderSuccess() throws Exception {
|
||||||
|
int amount = 1;
|
||||||
|
long initialBalance = getBalance(inventoryDataSource, productId);
|
||||||
|
application.placeOrder(productId, amount);
|
||||||
|
long finalBalance = getBalance(inventoryDataSource, productId);
|
||||||
|
assertEquals(initialBalance - amount, finalBalance);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Ignore
|
||||||
|
public void testPlaceOrderFailure() throws Exception {
|
||||||
|
int amount = 10;
|
||||||
|
long initialBalance = getBalance(inventoryDataSource, productId);
|
||||||
|
try {
|
||||||
|
application.placeOrder(productId, amount);
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.out.println(e.getMessage());
|
||||||
|
}
|
||||||
|
long finalBalance = getBalance(inventoryDataSource, productId);
|
||||||
|
assertEquals(initialBalance, finalBalance);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() throws SQLException {
|
||||||
|
|
||||||
|
Connection inventoryConnection = inventoryDataSource.getConnection();
|
||||||
|
Connection orderConnection = orderDataSource.getConnection();
|
||||||
|
String createInventoryTable = "create table Inventory ( " + " productId VARCHAR ( 100 ) PRIMARY KEY, balance INT )";
|
||||||
|
String createInventoryRow = "insert into Inventory values ( '" + productId + "', 10000 )";
|
||||||
|
Statement s1 = inventoryConnection.createStatement();
|
||||||
|
try {
|
||||||
|
s1.executeUpdate(createInventoryTable);
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.out.println("Inventory table exists");
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
s1.executeUpdate(createInventoryRow);
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.out.println("Product row exists");
|
||||||
|
}
|
||||||
|
s1.close();
|
||||||
|
String createOrderTable = "create table Orders ( orderId VARCHAR ( 100 ) PRIMARY KEY, productId VARCHAR ( 100 ), amount INT NOT NULL CHECK (amount <= 5) )";
|
||||||
|
Statement s2 = orderConnection.createStatement();
|
||||||
|
try {
|
||||||
|
s2.executeUpdate(createOrderTable);
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.out.println("Orders table exists");
|
||||||
|
}
|
||||||
|
s2.close();
|
||||||
|
inventoryConnection.close();
|
||||||
|
orderConnection.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static long getBalance(DataSource inventoryDataSource, String productId) throws Exception {
|
||||||
|
|
||||||
|
Connection inventoryConnection = inventoryDataSource.getConnection();
|
||||||
|
Statement s1 = inventoryConnection.createStatement();
|
||||||
|
String q1 = "select balance from Inventory where productId='" + productId + "'";
|
||||||
|
ResultSet rs1 = s1.executeQuery(q1);
|
||||||
|
if (rs1 == null || !rs1.next())
|
||||||
|
throw new Exception("Product not found: " + productId);
|
||||||
|
long balance = rs1.getLong(1);
|
||||||
|
inventoryConnection.close();
|
||||||
|
return balance;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,80 @@
|
||||||
|
package com.baeldung.atomikos.spring.jpa;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Ignore;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.test.context.ContextConfiguration;
|
||||||
|
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||||
|
|
||||||
|
import com.baeldung.atomikos.spring.jpa.config.Config;
|
||||||
|
import com.baeldung.atomikos.spring.jpa.inventory.Inventory;
|
||||||
|
import com.baeldung.atomikos.spring.jpa.inventory.InventoryConfig;
|
||||||
|
import com.baeldung.atomikos.spring.jpa.inventory.InventoryRepository;
|
||||||
|
import com.baeldung.atomikos.spring.jpa.order.OrderConfig;
|
||||||
|
import com.baeldung.atomikos.spring.jpa.order.OrderRepository;
|
||||||
|
|
||||||
|
@RunWith(SpringJUnit4ClassRunner.class)
|
||||||
|
@ContextConfiguration(classes = { Config.class, InventoryConfig.class, OrderConfig.class })
|
||||||
|
public class ApplicationUnitTest {
|
||||||
|
|
||||||
|
private static String productId = UUID.randomUUID()
|
||||||
|
.toString();
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
Application application;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
InventoryRepository inventoryRepository;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
OrderRepository orderRepository;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Ignore
|
||||||
|
public void testPlaceOrderSuccess() throws Exception {
|
||||||
|
int amount = 1;
|
||||||
|
long initialBalance = getBalance(inventoryRepository, productId);
|
||||||
|
application.placeOrder(productId, amount);
|
||||||
|
long finalBalance = getBalance(inventoryRepository, productId);
|
||||||
|
assertEquals(initialBalance - amount, finalBalance);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Ignore
|
||||||
|
public void testPlaceOrderFailure() throws Exception {
|
||||||
|
int amount = 10;
|
||||||
|
long initialBalance = getBalance(inventoryRepository, productId);
|
||||||
|
try {
|
||||||
|
application.placeOrder(productId, amount);
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.out.println(e.getMessage());
|
||||||
|
}
|
||||||
|
long finalBalance = getBalance(inventoryRepository, productId);
|
||||||
|
assertEquals(initialBalance, finalBalance);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() throws SQLException {
|
||||||
|
|
||||||
|
Inventory inventory = new Inventory();
|
||||||
|
inventory.setProductId(productId);
|
||||||
|
inventory.setBalance(new Long(10000));
|
||||||
|
inventoryRepository.save(inventory);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static long getBalance(InventoryRepository inventoryRepository, String productId) throws Exception {
|
||||||
|
|
||||||
|
return inventoryRepository.findOne(productId)
|
||||||
|
.getBalance();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<configuration>
|
||||||
|
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||||
|
<encoder>
|
||||||
|
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
|
||||||
|
</pattern>
|
||||||
|
</encoder>
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
<root level="INFO">
|
||||||
|
<appender-ref ref="STDOUT" />
|
||||||
|
</root>
|
||||||
|
</configuration>
|
|
@ -0,0 +1 @@
|
||||||
|
com.atomikos.icatch.file=logs
|
|
@ -1,146 +0,0 @@
|
||||||
CAS Overlay Template [![Build Status](https://travis-ci.org/apereo/cas-overlay-template.svg?branch=master)](https://travis-ci.org/apereo/cas-overlay-template)
|
|
||||||
=======================
|
|
||||||
|
|
||||||
Generic CAS WAR overlay to exercise the latest versions of CAS. This overlay could be freely used as a starting template for local CAS war overlays.
|
|
||||||
|
|
||||||
# Versions
|
|
||||||
|
|
||||||
- CAS `6.1.x`
|
|
||||||
- JDK `11`
|
|
||||||
|
|
||||||
# Overview
|
|
||||||
|
|
||||||
To build the project, use:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Use --refresh-dependencies to force-update SNAPSHOT versions
|
|
||||||
./gradlew[.bat] clean build
|
|
||||||
```
|
|
||||||
|
|
||||||
To see what commands are available to the build script, run:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
./gradlew[.bat] tasks
|
|
||||||
```
|
|
||||||
|
|
||||||
To launch into the CAS command-line shell:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
./gradlew[.bat] downloadShell runShell
|
|
||||||
```
|
|
||||||
|
|
||||||
To fetch and overlay a CAS resource or view, use:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
./gradlew[.bat] getResource -PresourceName=[resource-name]
|
|
||||||
```
|
|
||||||
|
|
||||||
To list all available CAS views and templates:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
./gradlew[.bat] listTemplateViews
|
|
||||||
```
|
|
||||||
|
|
||||||
To unzip and explode the CAS web application file and the internal resources jar:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
./gradlew[.bat] explodeWar
|
|
||||||
```
|
|
||||||
|
|
||||||
# Configuration
|
|
||||||
|
|
||||||
- The `etc` directory contains the configuration files and directories that need to be copied to `/etc/cas/config`.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
./gradlew[.bat] copyCasConfiguration
|
|
||||||
```
|
|
||||||
|
|
||||||
- The specifics of the build are controlled using the `gradle.properties` file.
|
|
||||||
|
|
||||||
## Adding Modules
|
|
||||||
|
|
||||||
CAS modules may be specified under the `dependencies` block of the [Gradle build script](build.gradle):
|
|
||||||
|
|
||||||
```gradle
|
|
||||||
dependencies {
|
|
||||||
compile "org.apereo.cas:cas-server-some-module:${project.casVersion}"
|
|
||||||
...
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
To collect the list of all project modules and dependencies:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
./gradlew[.bat] allDependencies
|
|
||||||
```
|
|
||||||
|
|
||||||
### Clear Gradle Cache
|
|
||||||
|
|
||||||
If you need to, on Linux/Unix systems, you can delete all the existing artifacts (artifacts and metadata) Gradle has downloaded using:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Only do this when absolutely necessary
|
|
||||||
rm -rf $HOME/.gradle/caches/
|
|
||||||
```
|
|
||||||
|
|
||||||
Same strategy applies to Windows too, provided you switch `$HOME` to its equivalent in the above command.
|
|
||||||
|
|
||||||
# Deployment
|
|
||||||
|
|
||||||
- Create a keystore file `thekeystore` under `/etc/cas`. Use the password `changeit` for both the keystore and the key/certificate entries. This can either be done using the JDK's `keytool` utility or via the following command:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
./gradlew[.bat] createKeystore
|
|
||||||
```
|
|
||||||
|
|
||||||
- Ensure the keystore is loaded up with keys and certificates of the server.
|
|
||||||
|
|
||||||
On a successful deployment via the following methods, CAS will be available at:
|
|
||||||
|
|
||||||
* `https://cas.server.name:8443/cas`
|
|
||||||
|
|
||||||
## Executable WAR
|
|
||||||
|
|
||||||
Run the CAS web application as an executable WAR:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
./gradlew[.bat] run
|
|
||||||
```
|
|
||||||
|
|
||||||
Debug the CAS web application as an executable WAR:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
./gradlew[.bat] debug
|
|
||||||
```
|
|
||||||
|
|
||||||
Run the CAS web application as a *standalone* executable WAR:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
./gradlew[.bat] clean executable
|
|
||||||
```
|
|
||||||
|
|
||||||
## External
|
|
||||||
|
|
||||||
Deploy the binary web application file `cas.war` after a successful build to a servlet container of choice.
|
|
||||||
|
|
||||||
## Docker
|
|
||||||
|
|
||||||
The following strategies outline how to build and deploy CAS Docker images.
|
|
||||||
|
|
||||||
### Jib
|
|
||||||
|
|
||||||
The overlay embraces the [Jib Gradle Plugin](https://github.com/GoogleContainerTools/jib) to provide easy-to-use out-of-the-box tooling for building CAS docker images. Jib is an open-source Java containerizer from Google that lets Java developers build containers using the tools they know. It is a container image builder that handles all the steps of packaging your application into a container image. It does not require you to write a Dockerfile or have Docker installed, and it is directly integrated into the overlay.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
./gradlew build jibDockerBuild
|
|
||||||
```
|
|
||||||
|
|
||||||
### Dockerfile
|
|
||||||
|
|
||||||
You can also use the native Docker tooling and the provided `Dockerfile` to build and run CAS.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
chmod +x *.sh
|
|
||||||
./docker-build.sh
|
|
||||||
./docker-run.sh
|
|
||||||
```
|
|
|
@ -7,3 +7,4 @@ This module contains articles about Java 14.
|
||||||
- [Guide to the @Serial Annotation in Java 14](https://www.baeldung.com/java-14-serial-annotation)
|
- [Guide to the @Serial Annotation in Java 14](https://www.baeldung.com/java-14-serial-annotation)
|
||||||
- [Java Text Blocks](https://www.baeldung.com/java-text-blocks)
|
- [Java Text Blocks](https://www.baeldung.com/java-text-blocks)
|
||||||
- [Pattern Matching for instanceof in Java 14](https://www.baeldung.com/java-pattern-matching-instanceof)
|
- [Pattern Matching for instanceof in Java 14](https://www.baeldung.com/java-pattern-matching-instanceof)
|
||||||
|
- [Helpful NullPointerExceptions in Java 14](https://www.baeldung.com/java-14-nullpointerexception)
|
||||||
|
|
|
@ -4,7 +4,6 @@ This module contains articles about Java 8 core features
|
||||||
|
|
||||||
### Relevant Articles:
|
### Relevant Articles:
|
||||||
|
|
||||||
- [How to Delay Code Execution in Java](https://www.baeldung.com/java-delay-code-execution)
|
|
||||||
- [Run a Java Application from the Command Line](https://www.baeldung.com/java-run-jar-with-arguments)
|
- [Run a Java Application from the Command Line](https://www.baeldung.com/java-run-jar-with-arguments)
|
||||||
- [Java 8 Stream skip() vs limit()](https://www.baeldung.com/java-stream-skip-vs-limit)
|
- [Java 8 Stream skip() vs limit()](https://www.baeldung.com/java-stream-skip-vs-limit)
|
||||||
- [Guide to Java BiFunction Interface](https://www.baeldung.com/java-bifunction-interface)
|
- [Guide to Java BiFunction Interface](https://www.baeldung.com/java-bifunction-interface)
|
||||||
|
|
|
@ -12,4 +12,3 @@
|
||||||
- [Sorting in Java](https://www.baeldung.com/java-sorting)
|
- [Sorting in Java](https://www.baeldung.com/java-sorting)
|
||||||
- [Getting the Size of an Iterable in Java](https://www.baeldung.com/java-iterable-size)
|
- [Getting the Size of an Iterable in Java](https://www.baeldung.com/java-iterable-size)
|
||||||
- [Java Null-Safe Streams from Collections](https://www.baeldung.com/java-null-safe-streams-from-collections)
|
- [Java Null-Safe Streams from Collections](https://www.baeldung.com/java-null-safe-streams-from-collections)
|
||||||
- [Operating on and Removing an Item from Stream](https://www.baeldung.com/java-use-remove-item-stream)
|
|
||||||
|
|
|
@ -4,7 +4,6 @@ This module contains articles about Map data structures in Java.
|
||||||
|
|
||||||
### Relevant Articles:
|
### Relevant Articles:
|
||||||
- [Guide to the Guava BiMap](https://www.baeldung.com/guava-bimap)
|
- [Guide to the Guava BiMap](https://www.baeldung.com/guava-bimap)
|
||||||
- [A Guide to Java HashMap](https://www.baeldung.com/java-hashmap)
|
|
||||||
- [A Guide to LinkedHashMap in Java](https://www.baeldung.com/java-linked-hashmap)
|
- [A Guide to LinkedHashMap in Java](https://www.baeldung.com/java-linked-hashmap)
|
||||||
- [A Guide to TreeMap in Java](https://www.baeldung.com/java-treemap)
|
- [A Guide to TreeMap in Java](https://www.baeldung.com/java-treemap)
|
||||||
- [How to Store Duplicate Keys in a Map in Java?](https://www.baeldung.com/java-map-duplicate-keys)
|
- [How to Store Duplicate Keys in a Map in Java?](https://www.baeldung.com/java-map-duplicate-keys)
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
This module contains articles about Java collections
|
This module contains articles about Java collections
|
||||||
|
|
||||||
### Relevant Articles:
|
### Relevant Articles:
|
||||||
- [Collect a Java Stream to an Immutable Collection](https://www.baeldung.com/java-stream-immutable-collection)
|
|
||||||
- [Introduction to the Java ArrayDeque](https://www.baeldung.com/java-array-deque)
|
- [Introduction to the Java ArrayDeque](https://www.baeldung.com/java-array-deque)
|
||||||
- [An Introduction to Java.util.Hashtable Class](https://www.baeldung.com/java-hash-table)
|
- [An Introduction to Java.util.Hashtable Class](https://www.baeldung.com/java-hash-table)
|
||||||
- [Thread Safe LIFO Data Structure Implementations](https://www.baeldung.com/java-lifo-thread-safe)
|
- [Thread Safe LIFO Data Structure Implementations](https://www.baeldung.com/java-lifo-thread-safe)
|
||||||
|
|
|
@ -10,4 +10,5 @@ This module contains articles about advanced topics about multithreading with co
|
||||||
- [Guide to RejectedExecutionHandler](https://www.baeldung.com/java-rejectedexecutionhandler)
|
- [Guide to RejectedExecutionHandler](https://www.baeldung.com/java-rejectedexecutionhandler)
|
||||||
- [Guide to Work Stealing in Java](https://www.baeldung.com/java-work-stealing)
|
- [Guide to Work Stealing in Java](https://www.baeldung.com/java-work-stealing)
|
||||||
- [Asynchronous Programming in Java](https://www.baeldung.com/java-asynchronous-programming)
|
- [Asynchronous Programming in Java](https://www.baeldung.com/java-asynchronous-programming)
|
||||||
|
- [Java Thread Deadlock and Livelock](https://www.baeldung.com/java-deadlock-livelock)
|
||||||
- [[<-- previous]](/core-java-modules/core-java-concurrency-advanced-2)
|
- [[<-- previous]](/core-java-modules/core-java-concurrency-advanced-2)
|
||||||
|
|
|
@ -8,4 +8,5 @@ This module contains articles about basic Java concurrency
|
||||||
- [Difference Between Wait and Sleep in Java](https://www.baeldung.com/java-wait-and-sleep)
|
- [Difference Between Wait and Sleep in Java](https://www.baeldung.com/java-wait-and-sleep)
|
||||||
- [Guide to the Synchronized Keyword in Java](https://www.baeldung.com/java-synchronized)
|
- [Guide to the Synchronized Keyword in Java](https://www.baeldung.com/java-synchronized)
|
||||||
- [Life Cycle of a Thread in Java](https://www.baeldung.com/java-thread-lifecycle)
|
- [Life Cycle of a Thread in Java](https://www.baeldung.com/java-thread-lifecycle)
|
||||||
|
- [Guide to AtomicMarkableReference](https://www.baeldung.com/java-atomicmarkablereference)
|
||||||
- [[<-- Prev]](/core-java-modules/core-java-concurrency-basic)
|
- [[<-- Prev]](/core-java-modules/core-java-concurrency-basic)
|
|
@ -0,0 +1,3 @@
|
||||||
|
### Relevant Articles:
|
||||||
|
|
||||||
|
- [Introduction to Lock Striping](https://www.baeldung.com/java-lock-stripping)
|
|
@ -7,4 +7,5 @@ This module contains articles about date operations in Java.
|
||||||
- [Checking If Two Java Dates Are on the Same Day](https://www.baeldung.com/java-check-two-dates-on-same-day)
|
- [Checking If Two Java Dates Are on the Same Day](https://www.baeldung.com/java-check-two-dates-on-same-day)
|
||||||
- [Converting Java Date to OffsetDateTime](https://www.baeldung.com/java-convert-date-to-offsetdatetime)
|
- [Converting Java Date to OffsetDateTime](https://www.baeldung.com/java-convert-date-to-offsetdatetime)
|
||||||
- [How to Set the JVM Time Zone](https://www.baeldung.com/java-jvm-time-zone)
|
- [How to Set the JVM Time Zone](https://www.baeldung.com/java-jvm-time-zone)
|
||||||
|
- [How to determine day of week by passing specific date in Java?](https://www.baeldung.com/java-get-day-of-week)
|
||||||
- [[<-- Prev]](/core-java-modules/core-java-date-operations-1)
|
- [[<-- Prev]](/core-java-modules/core-java-date-operations-1)
|
||||||
|
|
|
@ -12,4 +12,5 @@ This module contains articles about core Java input and output (IO)
|
||||||
- [Java – Append Data to a File](https://www.baeldung.com/java-append-to-file)
|
- [Java – Append Data to a File](https://www.baeldung.com/java-append-to-file)
|
||||||
- [How to Copy a File with Java](https://www.baeldung.com/java-copy-file)
|
- [How to Copy a File with Java](https://www.baeldung.com/java-copy-file)
|
||||||
- [Create a Directory in Java](https://www.baeldung.com/java-create-directory)
|
- [Create a Directory in Java](https://www.baeldung.com/java-create-directory)
|
||||||
|
- [Java IO vs NIO](https://www.baeldung.com/java-io-vs-nio)
|
||||||
- [[<-- Prev]](/core-java-modules/core-java-io)
|
- [[<-- Prev]](/core-java-modules/core-java-io)
|
||||||
|
|
|
@ -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)
|
- [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)
|
- [Guide to the Java finally Keyword](https://www.baeldung.com/java-finally-keyword)
|
||||||
- [The Java Headless Mode](https://www.baeldung.com/java-headless-mode)
|
- [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)
|
- [[<-- Prev]](/core-java-modules/core-java-lang)
|
||||||
|
|
|
@ -9,3 +9,4 @@
|
||||||
- [Pre-compile Regex Patterns Into Pattern Objects](https://www.baeldung.com/java-regex-pre-compile)
|
- [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)
|
- [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)
|
- [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)
|
- [MD5 Hashing in Java](http://www.baeldung.com/java-md5)
|
||||||
- [Hashing a Password in Java](https://www.baeldung.com/java-password-hashing)
|
- [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)
|
- [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)
|
- 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)
|
- [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)
|
- [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)
|
- [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)
|
- More articles: [[<-- prev>]](/../core-java-streams-2)
|
||||||
|
|
|
@ -13,4 +13,5 @@ This module contains articles about string operations.
|
||||||
- [Adding a Newline Character to a String in Java](https://www.baeldung.com/java-string-newline)
|
- [Adding a Newline Character to a String in Java](https://www.baeldung.com/java-string-newline)
|
||||||
- [Check If a String Contains a Substring](https://www.baeldung.com/java-string-contains-substring)
|
- [Check If a String Contains a Substring](https://www.baeldung.com/java-string-contains-substring)
|
||||||
- [Java Base64 Encoding and Decoding](https://www.baeldung.com/java-base64-encode-and-decode)
|
- [Java Base64 Encoding and Decoding](https://www.baeldung.com/java-base64-encode-and-decode)
|
||||||
|
- [Java Convert PDF to Base64](https://www.baeldung.com/java-convert-pdf-to-base64)
|
||||||
- More articles: [[next -->]](../core-java-string-operations-2)
|
- More articles: [[next -->]](../core-java-string-operations-2)
|
||||||
|
|
|
@ -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 String Interview Questions and Answers](https://www.baeldung.com/java-string-interview-questions)
|
||||||
- [Java Multi-line String](https://www.baeldung.com/java-multiline-string)
|
- [Java Multi-line String](https://www.baeldung.com/java-multiline-string)
|
||||||
- [Guide to Java String Pool](https://www.baeldung.com/java-string-pool)
|
- [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)
|
- [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)
|
- [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)
|
- [Filtering Kotlin Collections](https://www.baeldung.com/kotlin-filter-collection)
|
||||||
|
- [Collection Transformations in Kotlin](https://www.baeldung.com/kotlin-collection-transformations)
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
This module contains articles about Kotlin core features.
|
This module contains articles about Kotlin core features.
|
||||||
|
|
||||||
### Relevant articles:
|
### Relevant articles:
|
||||||
- [Introduction to the Kotlin Language](https://www.baeldung.com/kotlin-intro)
|
- [Introduction to the Kotlin Language](https://www.baeldung.com/kotlin/tutorial)
|
||||||
- [Kotlin Java Interoperability](https://www.baeldung.com/kotlin-java-interoperability)
|
- [Kotlin Java Interoperability](https://www.baeldung.com/kotlin-java-interoperability)
|
||||||
- [Get a Random Number in Kotlin](https://www.baeldung.com/kotlin-random-number)
|
- [Get a Random Number in Kotlin](https://www.baeldung.com/kotlin-random-number)
|
||||||
- [Create a Java and Kotlin Project with Maven](https://www.baeldung.com/kotlin-maven-java-project)
|
- [Create a Java and Kotlin Project with Maven](https://www.baeldung.com/kotlin-maven-java-project)
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
### Relevant Articles:
|
||||||
|
|
||||||
|
- [Pattern Matching in Scala](https://www.baeldung.com/scala/pattern-matching)
|
|
@ -10,3 +10,4 @@ This module contains articles about map collections in Guava
|
||||||
- [Guide to Guava RangeMap](https://www.baeldung.com/guava-rangemap)
|
- [Guide to Guava RangeMap](https://www.baeldung.com/guava-rangemap)
|
||||||
- [Initialize a HashMap in Java](https://www.baeldung.com/java-initialize-hashmap)
|
- [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)
|
- [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)
|
- [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)
|
- [Quick Guide to the Guava RateLimiter](https://www.baeldung.com/guava-rate-limiter)
|
||||||
|
- [Introduction to Guava Throwables](https://www.baeldung.com/guava-throwables)
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
## Java Collections Cookbooks and Examples
|
||||||
|
|
||||||
|
This module contains articles about Map data structures in Java.
|
||||||
|
|
||||||
|
### Relevant Articles:
|
||||||
|
|
||||||
|
- More articles: [[<-- prev>]](/../java-collections-maps)
|
||||||
|
- More articles: [[<-- prev>]](/../java-collections-maps-2)
|
|
@ -0,0 +1,43 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<parent>
|
||||||
|
<groupId>com.baeldung</groupId>
|
||||||
|
<artifactId>parent-java</artifactId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
<relativePath>../parent-java</relativePath>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<artifactId>java-collections-maps-3</artifactId>
|
||||||
|
<version>0.1.0-SNAPSHOT</version>
|
||||||
|
<name>java-collections-maps-3</name>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework</groupId>
|
||||||
|
<artifactId>spring-core</artifactId>
|
||||||
|
<version>${spring.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.assertj</groupId>
|
||||||
|
<artifactId>assertj-core</artifactId>
|
||||||
|
<version>${assertj.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.commons</groupId>
|
||||||
|
<artifactId>commons-collections4</artifactId>
|
||||||
|
<version>${commons-collections4.version}</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<commons-collections4.version>4.1</commons-collections4.version>
|
||||||
|
<assertj.version>3.6.1</assertj.version>
|
||||||
|
<spring.version>5.2.5.RELEASE</spring.version>
|
||||||
|
</properties>
|
||||||
|
</project>
|
|
@ -0,0 +1,94 @@
|
||||||
|
package com.baeldung.map.caseinsensitivekeys;
|
||||||
|
|
||||||
|
import org.apache.commons.collections4.map.CaseInsensitiveMap;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.springframework.util.LinkedCaseInsensitiveMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.TreeMap;
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
public class CaseInsensitiveMapUnitTest {
|
||||||
|
@Test
|
||||||
|
public void givenCaseInsensitiveTreeMap_whenTwoEntriesAdded_thenSizeIsOne(){
|
||||||
|
Map<String, Integer> treeMap = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
|
||||||
|
treeMap.put("abc", 1);
|
||||||
|
treeMap.put("ABC", 2);
|
||||||
|
|
||||||
|
assertEquals(1, treeMap.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenCommonsCaseInsensitiveMap_whenTwoEntriesAdded_thenSizeIsOne(){
|
||||||
|
Map<String, Integer> commonsHashMap = new CaseInsensitiveMap<>();
|
||||||
|
commonsHashMap.put("abc", 1);
|
||||||
|
commonsHashMap.put("ABC", 2);
|
||||||
|
|
||||||
|
assertEquals(1, commonsHashMap.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenLinkedCaseInsensitiveMap_whenTwoEntriesAdded_thenSizeIsOne(){
|
||||||
|
Map<String, Integer> linkedHashMap = new LinkedCaseInsensitiveMap<>();
|
||||||
|
linkedHashMap.put("abc", 1);
|
||||||
|
linkedHashMap.put("ABC", 2);
|
||||||
|
|
||||||
|
assertEquals(1, linkedHashMap.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenCaseInsensitiveTreeMap_whenSameEntryAdded_thenValueUpdated(){
|
||||||
|
Map<String, Integer> treeMap = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
|
||||||
|
treeMap.put("abc", 1);
|
||||||
|
treeMap.put("ABC", 2);
|
||||||
|
|
||||||
|
assertEquals(2, treeMap.get("aBc").intValue());
|
||||||
|
assertEquals(2, treeMap.get("ABc").intValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenCommonsCaseInsensitiveMap_whenSameEntryAdded_thenValueUpdated(){
|
||||||
|
Map<String, Integer> commonsHashMap = new CaseInsensitiveMap<>();
|
||||||
|
commonsHashMap.put("abc", 1);
|
||||||
|
commonsHashMap.put("ABC", 2);
|
||||||
|
|
||||||
|
assertEquals(2, commonsHashMap.get("aBc").intValue());
|
||||||
|
assertEquals(2, commonsHashMap.get("ABc").intValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenLinkedCaseInsensitiveMap_whenSameEntryAdded_thenValueUpdated(){
|
||||||
|
Map<String, Integer> linkedHashMap = new LinkedCaseInsensitiveMap<>();
|
||||||
|
linkedHashMap.put("abc", 1);
|
||||||
|
linkedHashMap.put("ABC", 2);
|
||||||
|
|
||||||
|
assertEquals(2, linkedHashMap.get("aBc").intValue());
|
||||||
|
assertEquals(2, linkedHashMap.get("ABc").intValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenCaseInsensitiveTreeMap_whenEntryRemoved_thenSizeIsZero(){
|
||||||
|
Map<String, Integer> treeMap = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
|
||||||
|
treeMap.put("abc", 3);
|
||||||
|
treeMap.remove("aBC");
|
||||||
|
|
||||||
|
assertEquals(0, treeMap.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenCommonsCaseInsensitiveMap_whenEntryRemoved_thenSizeIsZero(){
|
||||||
|
Map<String, Integer> commonsHashMap = new CaseInsensitiveMap<>();
|
||||||
|
commonsHashMap.put("abc", 3);
|
||||||
|
commonsHashMap.remove("aBC");
|
||||||
|
|
||||||
|
assertEquals(0, commonsHashMap.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenLinkedCaseInsensitiveMap_whenEntryRemoved_thenSizeIsZero(){
|
||||||
|
Map<String, Integer> linkedHashMap = new LinkedCaseInsensitiveMap<>();
|
||||||
|
linkedHashMap.put("abc", 3);
|
||||||
|
linkedHashMap.remove("aBC");
|
||||||
|
|
||||||
|
assertEquals(0, linkedHashMap.size());
|
||||||
|
}
|
||||||
|
}
|
|
@ -10,4 +10,5 @@ This module contains articles about numbers in Java.
|
||||||
- [Generating Random Numbers in a Range in Java](https://www.baeldung.com/java-generating-random-numbers-in-range)
|
- [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)
|
- [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)
|
- [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)
|
- More articles: [[<-- prev]](/java-numbers-2)
|
||||||
|
|
|
@ -12,4 +12,5 @@ This module contains articles about numbers in Java.
|
||||||
- [Calculating the nth Root in Java](https://www.baeldung.com/java-nth-root)
|
- [Calculating the nth Root in Java](https://www.baeldung.com/java-nth-root)
|
||||||
- [Convert Double to String, Removing Decimal Places](https://www.baeldung.com/java-double-to-string)
|
- [Convert Double to String, Removing Decimal Places](https://www.baeldung.com/java-double-to-string)
|
||||||
- [Changing the Order in a Sum Operation Can Produce Different Results?](https://www.baeldung.com/java-floating-point-sum-order)
|
- [Changing the Order in a Sum Operation Can Produce Different Results?](https://www.baeldung.com/java-floating-point-sum-order)
|
||||||
|
- [Using Math.sin with Degrees](https://www.baeldung.com/java-math-sin-degrees)
|
||||||
- More articles: [[next -->]](/../java-numbers-2)
|
- More articles: [[next -->]](/../java-numbers-2)
|
||||||
|
|
|
@ -26,7 +26,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||||
*/
|
*/
|
||||||
@RunWith(SpringRunner.class)
|
@RunWith(SpringRunner.class)
|
||||||
@SpringBootTest(classes = BookstoreApp.class)
|
@SpringBootTest(classes = BookstoreApp.class)
|
||||||
public class UserMapperUnitTest {
|
public class UserMapperIntegrationTest {
|
||||||
|
|
||||||
private static final String DEFAULT_LOGIN = "johndoe";
|
private static final String DEFAULT_LOGIN = "johndoe";
|
||||||
|
|
|
@ -15,4 +15,5 @@ Remember, for advanced libraries like [Jackson](/jackson) and [JUnit](/testing-m
|
||||||
- [Introduction to the jcabi-aspects AOP Annotations Library](https://www.baeldung.com/java-jcabi-aspects)
|
- [Introduction to the jcabi-aspects AOP Annotations Library](https://www.baeldung.com/java-jcabi-aspects)
|
||||||
- [Introduction to Takes](https://www.baeldung.com/java-takes)
|
- [Introduction to Takes](https://www.baeldung.com/java-takes)
|
||||||
- [Using NullAway to Avoid NullPointerExceptions](https://www.baeldung.com/java-nullaway)
|
- [Using NullAway to Avoid NullPointerExceptions](https://www.baeldung.com/java-nullaway)
|
||||||
|
- [Introduction to Alibaba Arthas](https://www.baeldung.com/java-alibaba-arthas-intro)
|
||||||
|
- [Quick Guide to Spring Cloud Circuit Breaker](https://www.baeldung.com/spring-cloud-circuit-breaker)
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
### Relevant Articles:
|
||||||
|
|
||||||
|
- [Intro to Coroutines with Quasar](https://www.baeldung.com/java-quasar-coroutines)
|
|
@ -0,0 +1,3 @@
|
||||||
|
### Relevant Articles:
|
||||||
|
|
||||||
|
- [How to Use Command Line Arguments in a Bash Script](https://www.baeldung.com/linux/use-command-line-arguments-in-bash-script)
|
|
@ -0,0 +1,3 @@
|
||||||
|
### Relevant Articles
|
||||||
|
|
||||||
|
- [Bash Functions in Linux](https://www.baeldung.com/linux/bash-functions)
|
|
@ -0,0 +1,3 @@
|
||||||
|
### Relevant Articles:
|
||||||
|
|
||||||
|
- [Guide to the Linux read Command](https://www.baeldung.com/linux/read-command)
|
|
@ -1,3 +1,4 @@
|
||||||
### Relevant Articles:
|
### Relevant Articles:
|
||||||
|
|
||||||
- [Linux Commands – Remove All Text After X](https://www.baeldung.com/linux/tr-manipulate-strings)
|
- [Linux Commands – Remove All Text After X](https://www.baeldung.com/linux/tr-manipulate-strings)
|
||||||
|
- [Linux Commands for Appending Multiple Lines to a File](https://www.baeldung.com/linux/appending-multiple-lines-to-file2)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
### Relevant Articles:
|
### Relevant Articles:
|
||||||
- TBD
|
- TBD
|
||||||
- [Improved Java Logging with Mapped Diagnostic Context (MDC)](https://www.baeldung.com/mdc-in-log4j-2-logback)
|
- [Improved Java Logging with Mapped Diagnostic Context (MDC)](https://www.baeldung.com/mdc-in-log4j-2-logback)
|
||||||
- [Java Logging with Nested Diagnostic Context (NDC)](https:www.baeldung.com/java-logging-ndc-log4j)
|
- [Java Logging with Nested Diagnostic Context (NDC)](https://www.baeldung.com/java-logging-ndc-log4j)
|
||||||
- [Drools Using Rules from Excel Files](https://www.baeldung.com/drools-excel)
|
- [Drools Using Rules from Excel Files](https://www.baeldung.com/drools-excel)
|
||||||
|
|
||||||
### References
|
### References
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
### Relevant Articles:
|
||||||
|
|
||||||
|
- [Guide to the Linux wc Command](https://www.baeldung.com/linux/wc-command)
|
|
@ -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)
|
- [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)
|
- [TransactionRequiredException Error](https://www.baeldung.com/jpa-transaction-required-exception)
|
||||||
- [JPA/Hibernate Persistence Context](https://www.baeldung.com/jpa-hibernate-persistence-context)
|
- [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>
|
<artifactId>cassandra-driver-core</artifactId>
|
||||||
<version>${cassandra-driver-core.version}</version>
|
<version>${cassandra-driver-core.version}</version>
|
||||||
<optional>true</optional>
|
<optional>true</optional>
|
||||||
|
<exclusions>
|
||||||
|
<exclusion>
|
||||||
|
<groupId>com.google.guava</groupId>
|
||||||
|
<artifactId>guava</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
</exclusions>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- https://mvnrepository.com/artifact/org.cassandraunit/cassandra-unit -->
|
<!-- 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"
|
|
@ -2,3 +2,4 @@
|
||||||
- [Access the Same In-Memory H2 Database in Multiple Spring Boot Applications](https://www.baeldung.com/spring-boot-access-h2-database-multiple-apps)
|
- [Access the Same In-Memory H2 Database in Multiple Spring Boot Applications](https://www.baeldung.com/spring-boot-access-h2-database-multiple-apps)
|
||||||
- [Spring Boot With H2 Database](https://www.baeldung.com/spring-boot-h2-database)
|
- [Spring Boot With H2 Database](https://www.baeldung.com/spring-boot-h2-database)
|
||||||
- [Hibernate @NotNull vs @Column(nullable = false)](https://www.baeldung.com/hibernate-notnull-vs-nullable)
|
- [Hibernate @NotNull vs @Column(nullable = false)](https://www.baeldung.com/hibernate-notnull-vs-nullable)
|
||||||
|
- [Quick Guide to Hibernate enable_lazy_load_no_trans Property](https://www.baeldung.com/hibernate-lazy-loading-workaround)
|
||||||
|
|
|
@ -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>
|
<artifactId>mysql-connector-java</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.postgresql</groupId>
|
||||||
|
<artifactId>postgresql</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.h2database</groupId>
|
<groupId>com.h2database</groupId>
|
||||||
<artifactId>h2</artifactId>
|
<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
|
|
@ -0,0 +1,9 @@
|
||||||
|
spring.datasource.url=jdbc:h2:mem:spring-strategy
|
||||||
|
spring.datasource.username=sa
|
||||||
|
spring.datasource.password=
|
||||||
|
|
||||||
|
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
|
|
@ -0,0 +1,9 @@
|
||||||
|
spring.datasource.url=jdbc:postgresql://localhost:5432/unquoted-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.UnquotedLowerCaseNamingStrategy
|
||||||
|
#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:unquoted-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.UnquotedLowerCaseNamingStrategy
|
||||||
|
#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/unquoted-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.UnquotedUpperCaseNamingStrategy
|
||||||
|
#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:unquoted-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.UnquotedUpperCaseNamingStrategy
|
||||||
|
#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
|
|
@ -9,7 +9,6 @@ This module contains articles about Spring with Hibernate 4
|
||||||
- [Stored Procedures with Hibernate](https://www.baeldung.com/stored-procedures-with-hibernate-tutorial)
|
- [Stored Procedures with Hibernate](https://www.baeldung.com/stored-procedures-with-hibernate-tutorial)
|
||||||
- [Hibernate: save, persist, update, merge, saveOrUpdate](https://www.baeldung.com/hibernate-save-persist-update-merge-saveorupdate)
|
- [Hibernate: save, persist, update, merge, saveOrUpdate](https://www.baeldung.com/hibernate-save-persist-update-merge-saveorupdate)
|
||||||
- [Eager/Lazy Loading In Hibernate](https://www.baeldung.com/hibernate-lazy-eager-loading)
|
- [Eager/Lazy Loading In Hibernate](https://www.baeldung.com/hibernate-lazy-eager-loading)
|
||||||
- [The DAO with Spring and Hibernate](https://www.baeldung.com/persistence-layer-with-spring-and-hibernate)
|
|
||||||
- [Auditing with JPA, Hibernate, and Spring Data JPA](https://www.baeldung.com/database-auditing-jpa)
|
- [Auditing with JPA, Hibernate, and Spring Data JPA](https://www.baeldung.com/database-auditing-jpa)
|
||||||
|
|
||||||
### Quick Start
|
### Quick Start
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
### Relevant Articles:
|
||||||
|
|
||||||
|
- [Spring JdbcTemplate Unit Testing](https://www.baeldung.com/spring-jdbctemplate-testing)
|
10
pom.xml
10
pom.xml
|
@ -453,6 +453,7 @@
|
||||||
|
|
||||||
<module>java-collections-conversions</module>
|
<module>java-collections-conversions</module>
|
||||||
<module>java-collections-conversions-2</module>
|
<module>java-collections-conversions-2</module>
|
||||||
|
<module>java-collections-maps-3</module>
|
||||||
<!-- <module>java-ee-8-security-api</module> --> <!-- long running -->
|
<!-- <module>java-ee-8-security-api</module> --> <!-- long running -->
|
||||||
|
|
||||||
<module>javafx</module>
|
<module>javafx</module>
|
||||||
|
@ -564,6 +565,8 @@
|
||||||
<module>rxjava-libraries</module>
|
<module>rxjava-libraries</module>
|
||||||
<module>rxjava-observables</module>
|
<module>rxjava-observables</module>
|
||||||
<module>rxjava-operators</module>
|
<module>rxjava-operators</module>
|
||||||
|
|
||||||
|
<module>atomikos</module>
|
||||||
</modules>
|
</modules>
|
||||||
|
|
||||||
</profile>
|
</profile>
|
||||||
|
@ -803,7 +806,7 @@
|
||||||
|
|
||||||
<module>jenkins/plugins</module>
|
<module>jenkins/plugins</module>
|
||||||
<module>jhipster</module>
|
<module>jhipster</module>
|
||||||
<module>jws</module>
|
<!-- <module>jws</module> --> <!-- Failing the build. Fixing in http://jira.baeldung.com/browse/BAEL-3992 -->
|
||||||
|
|
||||||
<module>libraries</module> <!-- very long running -->
|
<module>libraries</module> <!-- very long running -->
|
||||||
|
|
||||||
|
@ -963,6 +966,7 @@
|
||||||
|
|
||||||
<module>java-collections-conversions</module>
|
<module>java-collections-conversions</module>
|
||||||
<module>java-collections-conversions-2</module>
|
<module>java-collections-conversions-2</module>
|
||||||
|
<module>java-collections-maps-3</module>
|
||||||
<!-- <module>java-ee-8-security-api</module> --> <!-- long running -->
|
<!-- <module>java-ee-8-security-api</module> --> <!-- long running -->
|
||||||
|
|
||||||
<module>javafx</module>
|
<module>javafx</module>
|
||||||
|
@ -1073,6 +1077,8 @@
|
||||||
<module>rxjava-libraries</module>
|
<module>rxjava-libraries</module>
|
||||||
<module>rxjava-observables</module>
|
<module>rxjava-observables</module>
|
||||||
<module>rxjava-operators</module>
|
<module>rxjava-operators</module>
|
||||||
|
|
||||||
|
<module>atomikos</module>
|
||||||
</modules>
|
</modules>
|
||||||
|
|
||||||
</profile>
|
</profile>
|
||||||
|
@ -1296,7 +1302,7 @@
|
||||||
|
|
||||||
<module>jenkins/plugins</module>
|
<module>jenkins/plugins</module>
|
||||||
<module>jhipster</module>
|
<module>jhipster</module>
|
||||||
<module>jws</module>
|
<!-- <module>jws</module> --> <!-- Failing the build. Fixing in http://jira.baeldung.com/browse/BAEL-3992 -->
|
||||||
|
|
||||||
<module>libraries</module> <!-- very long running -->
|
<module>libraries</module> <!-- very long running -->
|
||||||
|
|
||||||
|
|
|
@ -6,3 +6,4 @@ This module contains articles about Spring 5 model-view-controller (MVC) pattern
|
||||||
- [Spring Boot and Kotlin](https://www.baeldung.com/spring-boot-kotlin)
|
- [Spring Boot and Kotlin](https://www.baeldung.com/spring-boot-kotlin)
|
||||||
- [Spring MVC Streaming and SSE Request Processing](https://www.baeldung.com/spring-mvc-sse-streams)
|
- [Spring MVC Streaming and SSE Request Processing](https://www.baeldung.com/spring-mvc-sse-streams)
|
||||||
- [Interface Driven Controllers in Spring](https://www.baeldung.com/spring-interface-driven-controllers)
|
- [Interface Driven Controllers in Spring](https://www.baeldung.com/spring-interface-driven-controllers)
|
||||||
|
- [Returning Plain HTML From a Spring MVC Controller](https://www.baeldung.com/spring-mvc-return-html)
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
This module contains articles about Spring Batch
|
This module contains articles about Spring Batch
|
||||||
|
|
||||||
### Relevant Articles:
|
### Relevant Articles:
|
||||||
|
|
||||||
- [Introduction to Spring Batch](https://www.baeldung.com/introduction-to-spring-batch)
|
- [Introduction to Spring Batch](https://www.baeldung.com/introduction-to-spring-batch)
|
||||||
- [Spring Batch using Partitioner](https://www.baeldung.com/spring-batch-partitioner)
|
- [Spring Batch using Partitioner](https://www.baeldung.com/spring-batch-partitioner)
|
||||||
- [Spring Batch – Tasklets vs Chunks](https://www.baeldung.com/spring-batch-tasklet-chunk)
|
- [Spring Batch – Tasklets vs Chunks](https://www.baeldung.com/spring-batch-tasklet-chunk)
|
||||||
|
@ -10,3 +11,4 @@ This module contains articles about Spring Batch
|
||||||
- [Configuring Skip Logic in Spring Batch](https://www.baeldung.com/spring-batch-skip-logic)
|
- [Configuring Skip Logic in Spring Batch](https://www.baeldung.com/spring-batch-skip-logic)
|
||||||
- [Testing a Spring Batch Job](https://www.baeldung.com/spring-batch-testing-job)
|
- [Testing a Spring Batch Job](https://www.baeldung.com/spring-batch-testing-job)
|
||||||
- [Configuring Retry Logic in Spring Batch](https://www.baeldung.com/spring-batch-retry-logic)
|
- [Configuring Retry Logic in Spring Batch](https://www.baeldung.com/spring-batch-retry-logic)
|
||||||
|
- [Conditional Flow in Spring Batch](https://www.baeldung.com/spring-batch-conditional-flow)
|
||||||
|
|
|
@ -28,6 +28,10 @@
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-tomcat</artifactId>
|
<artifactId>spring-boot-starter-tomcat</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-test</artifactId>
|
<artifactId>spring-boot-starter-test</artifactId>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package com.baeldung;
|
package com.baeldung.scheduling.shedlock;
|
||||||
|
|
||||||
import net.javacrumbs.shedlock.spring.annotation.EnableSchedulerLock;
|
import net.javacrumbs.shedlock.spring.annotation.EnableSchedulerLock;
|
||||||
import org.springframework.boot.SpringApplication;
|
import org.springframework.boot.SpringApplication;
|
||||||
|
@ -8,8 +8,8 @@ import org.springframework.scheduling.annotation.EnableScheduling;
|
||||||
@SpringBootApplication
|
@SpringBootApplication
|
||||||
@EnableScheduling
|
@EnableScheduling
|
||||||
@EnableSchedulerLock(defaultLockAtMostFor = "PT30S")
|
@EnableSchedulerLock(defaultLockAtMostFor = "PT30S")
|
||||||
public class Application {
|
public class SpringBootShedlockApplication {
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
SpringApplication.run(Application.class, args);
|
SpringApplication.run(SpringBootShedlockApplication.class, args);
|
||||||
}
|
}
|
||||||
}
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue