This commit is contained in:
kkaravitis
2020-04-24 14:31:24 +03:00
736 changed files with 11876 additions and 1226 deletions
+3 -3
View File
@@ -9,9 +9,9 @@
<parent>
<groupId>com.baeldung</groupId>
<artifactId>parent-boot-1</artifactId>
<artifactId>parent-boot-2</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../../parent-boot-1</relativePath>
<relativePath>../../parent-boot-2</relativePath>
</parent>
<dependencies>
@@ -63,7 +63,7 @@
</build>
<properties>
<flyway-core.version>5.0.2</flyway-core.version>
<flyway-core.version>5.2.3</flyway-core.version>
<flyway-maven-plugin.version>5.0.2</flyway-maven-plugin.version>
</properties>
@@ -1 +1 @@
#flyway.enabled=false
#spring.flyway.enabled=false
@@ -13,3 +13,4 @@ This module contains articles specific to use of Hibernate as a JPA implementati
- [Enabling Transaction Locks in Spring Data JPA](https://www.baeldung.com/java-jpa-transaction-locks)
- [TransactionRequiredException Error](https://www.baeldung.com/jpa-transaction-required-exception)
- [JPA/Hibernate Persistence Context](https://www.baeldung.com/jpa-hibernate-persistence-context)
- [Quick Guide to EntityManager#getReference()](https://www.baeldung.com/jpa-entity-manager-get-reference)
@@ -18,6 +18,12 @@
<artifactId>cassandra-driver-core</artifactId>
<version>${cassandra-driver-core.version}</version>
<optional>true</optional>
<exclusions>
<exclusion>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- https://mvnrepository.com/artifact/org.cassandraunit/cassandra-unit -->
@@ -0,0 +1,51 @@
cluster_name: 'Test Cluster'
hinted_handoff_enabled: true
max_hint_window_in_ms: 10800000
hinted_handoff_throttle_in_kb: 1024
max_hints_delivery_threads: 2
hints_directory: target/embeddedCassandra/hints
authenticator: AllowAllAuthenticator
authorizer: AllowAllAuthorizer
permissions_validity_in_ms: 2000
partitioner: RandomPartitioner
data_file_directories:
- target/embeddedCassandra/data
commitlog_directory: target/embeddedCassandra/commitlog
cdc_raw_directory: target/embeddedCassandra/cdc
disk_failure_policy: stop
key_cache_size_in_mb:
key_cache_save_period: 14400
row_cache_size_in_mb: 0
row_cache_save_period: 0
saved_caches_directory: target/embeddedCassandra/saved_caches
commitlog_sync: periodic
commitlog_sync_period_in_ms: 10000
commitlog_segment_size_in_mb: 32
concurrent_reads: 32
concurrent_writes: 32
trickle_fsync: false
trickle_fsync_interval_in_kb: 10240
thrift_framed_transport_size_in_mb: 15
thrift_max_message_length_in_mb: 16
incremental_backups: false
snapshot_before_compaction: false
auto_snapshot: false
column_index_size_in_kb: 64
compaction_throughput_mb_per_sec: 16
read_request_timeout_in_ms: 5000
range_request_timeout_in_ms: 10000
write_request_timeout_in_ms: 2000
cas_contention_timeout_in_ms: 1000
truncate_request_timeout_in_ms: 60000
request_timeout_in_ms: 10000
cross_node_timeout: false
endpoint_snitch: SimpleSnitch
dynamic_snitch_update_interval_in_ms: 100
dynamic_snitch_reset_interval_in_ms: 600000
dynamic_snitch_badness_threshold: 0.1
request_scheduler: org.apache.cassandra.scheduler.NoScheduler
index_interval: 128
seed_provider:
- class_name: org.apache.cassandra.locator.SimpleSeedProvider
parameters:
- seeds: "127.0.0.1"
@@ -10,3 +10,4 @@ This module contains articles about MongoDB in Java.
- [Geospatial Support in MongoDB](https://www.baeldung.com/mongodb-geospatial-support)
- [Introduction to Morphia Java ODM for MongoDB](https://www.baeldung.com/mongodb-morphia)
- [MongoDB Aggregations Using Java](https://www.baeldung.com/java-mongodb-aggregations)
- [MongoDB BSON to JSON](https://www.baeldung.com/bson-to-json)
@@ -1,5 +1,7 @@
package com.baeldung.morphia.domain;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.HashSet;
import java.util.Set;
@@ -29,28 +31,13 @@ public class Book {
private double cost;
@Reference
private Set<Book> companionBooks;
@Property
private LocalDateTime publishDate;
public Book() {
}
public String getTitle() {
return title;
}
public String getAuthor() {
return author;
}
public double getCost() {
return cost;
}
public void addCompanionBooks(Book book) {
if (companionBooks != null)
this.companionBooks.add(book);
}
public Book(String isbn, String title, String author, double cost, Publisher publisher) {
this.isbn = isbn;
this.title = title;
@@ -60,6 +47,71 @@ public class Book {
this.companionBooks = new HashSet<>();
}
// Getters and setters ...
public String getIsbn() {
return isbn;
}
public Book setIsbn(String isbn) {
this.isbn = isbn;
return this;
}
public String getTitle() {
return title;
}
public Book setTitle(String title) {
this.title = title;
return this;
}
public String getAuthor() {
return author;
}
public Book setAuthor(String author) {
this.author = author;
return this;
}
public Publisher getPublisher() {
return publisher;
}
public Book setPublisher(Publisher publisher) {
this.publisher = publisher;
return this;
}
public double getCost() {
return cost;
}
public Book setCost(double cost) {
this.cost = cost;
return this;
}
public LocalDateTime getPublishDate() {
return publishDate;
}
public Book setPublishDate(LocalDateTime publishDate) {
this.publishDate = publishDate;
return this;
}
public Set<Book> getCompanionBooks() {
return companionBooks;
}
public Book addCompanionBooks(Book book) {
if (companionBooks != null)
this.companionBooks.add(book);
return this;
}
@Override
public String toString() {
return "Book [isbn=" + isbn + ", title=" + title + ", author=" + author + ", publisher=" + publisher + ", cost=" + cost + "]";
@@ -113,4 +165,4 @@ public class Book {
return true;
}
}
}
@@ -0,0 +1,142 @@
package com.baeldung.bsontojson;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import java.sql.Timestamp;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.TimeZone;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.bson.Document;
import org.bson.json.Converter;
import org.bson.json.JsonMode;
import org.bson.json.JsonWriterSettings;
import org.bson.json.StrictJsonWriter;
import org.bson.types.ObjectId;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.jupiter.api.AfterEach;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.baeldung.morphia.domain.Book;
import com.baeldung.morphia.domain.Publisher;
import com.mongodb.MongoClient;
import com.mongodb.client.MongoDatabase;
import dev.morphia.Datastore;
import dev.morphia.Morphia;
public class BsonToJsonIntegrationTest {
private static final String DB_NAME = "library";
private static Datastore datastore;
@BeforeClass
public static void setUp() {
Morphia morphia = new Morphia();
morphia.mapPackage("com.baeldung.morphia");
datastore = morphia.createDatastore(new MongoClient(), DB_NAME);
datastore.ensureIndexes();
datastore.save(new Book()
.setIsbn("isbn")
.setTitle("title")
.setAuthor("author")
.setCost(3.95)
.setPublisher(new Publisher(new ObjectId("fffffffffffffffffffffffa"),"publisher"))
.setPublishDate(LocalDateTime.parse("2020-01-01T18:13:32Z", DateTimeFormatter.ISO_DATE_TIME))
.addCompanionBooks(new Book().setIsbn("isbn2")));
}
@AfterClass
public static void tearDown() {
datastore.delete(datastore.createQuery(Book.class));
}
@Test
public void givenBsonDocument_whenUsingStandardJsonTransformation_thenJsonDateIsObjectEpochTime() {
String json = null;
try (MongoClient mongoClient = new MongoClient()) {
MongoDatabase mongoDatabase = mongoClient.getDatabase(DB_NAME);
Document bson = mongoDatabase.getCollection("Books").find().first();
json = bson.toJson();
}
String expectedJson = "{\"_id\": \"isbn\", " +
"\"className\": \"com.baeldung.morphia.domain.Book\", " +
"\"title\": \"title\", " +
"\"author\": \"author\", " +
"\"publisher\": {\"_id\": {\"$oid\": \"fffffffffffffffffffffffa\"}, " +
"\"name\": \"publisher\"}, " +
"\"price\": 3.95, " +
"\"publishDate\": {\"$date\": 1577898812000}}";
assertNotNull(json);
assertEquals(expectedJson, json);
}
@Test
public void givenBsonDocument_whenUsingRelaxedJsonTransformation_thenJsonDateIsObjectIsoDate() {
String json = null;
try (MongoClient mongoClient = new MongoClient()) {
MongoDatabase mongoDatabase = mongoClient.getDatabase(DB_NAME);
Document bson = mongoDatabase.getCollection("Books").find().first();
json = bson.toJson(JsonWriterSettings
.builder()
.outputMode(JsonMode.RELAXED)
.build());
}
String expectedJson = "{\"_id\": \"isbn\", " +
"\"className\": \"com.baeldung.morphia.domain.Book\", " +
"\"title\": \"title\", " +
"\"author\": \"author\", " +
"\"publisher\": {\"_id\": {\"$oid\": \"fffffffffffffffffffffffa\"}, " +
"\"name\": \"publisher\"}, " +
"\"price\": 3.95, " +
"\"publishDate\": {\"$date\": \"2020-01-01T17:13:32Z\"}}";
assertNotNull(json);
assertEquals(expectedJson, json);
}
@Test
public void givenBsonDocument_whenUsingCustomJsonTransformation_thenJsonDateIsStringField() {
String json = null;
try (MongoClient mongoClient = new MongoClient()) {
MongoDatabase mongoDatabase = mongoClient.getDatabase(DB_NAME);
Document bson = mongoDatabase.getCollection("Books").find().first();
json = bson.toJson(JsonWriterSettings
.builder()
.dateTimeConverter(new JsonDateTimeConverter())
.build());
}
String expectedJson = "{\"_id\": \"isbn\", " +
"\"className\": \"com.baeldung.morphia.domain.Book\", " +
"\"title\": \"title\", " +
"\"author\": \"author\", " +
"\"publisher\": {\"_id\": {\"$oid\": \"fffffffffffffffffffffffa\"}, " +
"\"name\": \"publisher\"}, " +
"\"price\": 3.95, " +
"\"publishDate\": \"2020-01-01T17:13:32Z\"}";
assertEquals(expectedJson, json);
}
}
@@ -0,0 +1,30 @@
package com.baeldung.bsontojson;
import java.time.Instant;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.TimeZone;
import org.bson.json.Converter;
import org.bson.json.StrictJsonWriter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class JsonDateTimeConverter implements Converter<Long> {
private static final Logger LOGGER = LoggerFactory.getLogger(JsonDateTimeConverter.class);
static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ISO_INSTANT
.withZone(ZoneId.of("UTC"));
@Override
public void convert(Long value, StrictJsonWriter writer) {
try {
Instant instant = new Date(value).toInstant();
String s = DATE_TIME_FORMATTER.format(instant);
writer.writeString(s);
} catch (Exception e) {
LOGGER.error(String.format("Fail to convert offset %d to JSON date", value), e);
}
}
}
+1 -1
View File
@@ -6,7 +6,7 @@
<groupId>com.baeldung.examples.r2dbc</groupId>
<artifactId>r2dbc-example</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>r2dbc-example</name>
<name>r2dbc</name>
<description>Sample R2DBC Project</description>
<parent>
+1 -1
View File
@@ -4,7 +4,7 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>io.sirix</groupId>
<artifactId>core-api-tutorial</artifactId>
<artifactId>sirix</artifactId>
<version>1.0-SNAPSHOT</version>
<name>core-api-tutorial</name>
<packaging>jar</packaging>
@@ -43,7 +43,12 @@
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
@@ -82,6 +87,23 @@
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
<version>${c3p0.version}</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-dbcp2</artifactId>
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-jdbc</artifactId>
</dependency>
</dependencies>
<build>
@@ -90,12 +112,30 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<!-- Please note that ojdbc8.jar, ucp.jar and ons.jar dependencies
are needed for OracleConfiguration.java, OracleUCPConfiguration.java, SpringOraclePoolingApplicationOracleLiveTest.java
and SpringOraclePoolingApplicationOracleUCPLiveTest.java -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<excludes>
<exclude>com/baeldung/spring/oracle/pooling/configuration/OracleConfiguration.java</exclude>
<exclude>com/baeldung/spring/oracle/pooling/configuration/OracleUCPConfiguration.java</exclude>
</excludes>
<testExcludes>
<testExclude>com/baeldung/spring/oracle/pooling/SpringOraclePoolingApplicationOracleLiveTest.java</testExclude>
<testExclude>com/baeldung/spring/oracle/pooling/SpringOraclePoolingApplicationOracleUCPLiveTest.java</testExclude>
</testExcludes>
</configuration>
</plugin>
</plugins>
</build>
<properties>
<jdbi.version>3.9.1</jdbi.version>
<spring.boot.dependencies>2.1.8.RELEASE</spring.boot.dependencies>
<c3p0.version>0.9.5.2</c3p0.version>
</properties>
</project>
@@ -0,0 +1,29 @@
package com.baeldung.spring.oracle.pooling;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import lombok.extern.slf4j.Slf4j;
@SpringBootApplication
@Slf4j
public class SpringOraclePoolingApplication implements CommandLineRunner{
@Autowired
private DataSource dataSource;
public static void main(String[] args) {
SpringApplication.run(SpringOraclePoolingApplication.class, args);
}
@Override
public void run(String... args) throws Exception {
log.info("Connection Polling datasource : "+ dataSource);
}
}
@@ -0,0 +1,27 @@
package com.baeldung.spring.oracle.pooling.configuration;
import java.sql.SQLException;
import javax.sql.DataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import com.mchange.v2.c3p0.ComboPooledDataSource;
@Configuration
@Profile("c3p0")
public class C3P0Configuration {
@Bean
public DataSource dataSource() throws SQLException {
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setUser("books");
dataSource.setPassword("books");
dataSource.setJdbcUrl("jdbc:oracle:thin:@//localhost:11521/ORCLPDB1");
dataSource.setMinPoolSize(5);
dataSource.setMaxPoolSize(10);
return dataSource;
}
}
@@ -0,0 +1,29 @@
package com.baeldung.spring.oracle.pooling.configuration;
import java.sql.SQLException;
import javax.sql.DataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import oracle.jdbc.pool.OracleDataSource;
@Configuration
@Profile("oracle")
public class OracleConfiguration {
@Bean
public DataSource dataSource() throws SQLException {
OracleDataSource dataSource = new OracleDataSource();
dataSource.setUser("books");
dataSource.setPassword("books");
dataSource.setURL("jdbc:oracle:thin:@//localhost:11521/ORCLPDB1");
dataSource.setFastConnectionFailoverEnabled(true);
dataSource.setImplicitCachingEnabled(true);
// Only with clients prior to v11.2
// dataSource.setConnectionCachingEnabled(true);
return dataSource;
}
}
@@ -0,0 +1,32 @@
package com.baeldung.spring.oracle.pooling.configuration;
import java.sql.SQLException;
import javax.sql.DataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import oracle.ucp.jdbc.PoolDataSource;
import oracle.ucp.jdbc.PoolDataSourceFactory;
@Configuration
@Profile("oracle-ucp")
public class OracleUCPConfiguration {
@Bean
public DataSource dataSource() throws SQLException {
PoolDataSource dataSource = PoolDataSourceFactory.getPoolDataSource();
dataSource.setUser("books");
dataSource.setPassword("books");
dataSource.setConnectionFactoryClassName("oracle.jdbc.pool.OracleDataSource");
dataSource.setURL("jdbc:oracle:thin:@//localhost:11521/ORCLPDB1");
dataSource.setFastConnectionFailoverEnabled(true);
dataSource.setInitialPoolSize(5);
dataSource.setMinPoolSize(5);
dataSource.setMaxPoolSize(10);
return dataSource;
}
}
@@ -0,0 +1,45 @@
package com.baeldung.spring.oracle.pooling.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.baeldung.spring.oracle.pooling.entity.Book;
import com.baeldung.spring.oracle.pooling.exception.BookstoreException;
import com.baeldung.spring.oracle.pooling.repository.BookRepository;
@RestController
@RequestMapping("/books")
public class BookstoreController {
@Autowired
private BookRepository repository;
@GetMapping(value = "/hello")
public String sayHello() {
return "Hello";
}
@GetMapping("/all")
public List<Book> findAll() {
return repository.findAll();
}
@PostMapping("/create")
public Book newBook(@RequestBody Book newBook) {
return repository.save(newBook);
}
@GetMapping("/get/{id}")
public Book findOne(@PathVariable Long id) throws BookstoreException {
return repository.findById(id)
.orElseThrow(BookstoreException::new);
}
}
@@ -0,0 +1,45 @@
package com.baeldung.spring.oracle.pooling.entity;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
@Entity
public class Book {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String name;
public Book() {
}
public Book(String name) {
this.name = name;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Book [id=" + id + ", name=" + name + "]";
}
}
@@ -0,0 +1,10 @@
package com.baeldung.spring.oracle.pooling.exception;
public class BookstoreException extends Exception{
/**
*
*/
private static final long serialVersionUID = 1L;
}
@@ -0,0 +1,9 @@
package com.baeldung.spring.oracle.pooling.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import com.baeldung.spring.oracle.pooling.entity.Book;
public interface BookRepository extends JpaRepository<Book, Long>{
}
@@ -0,0 +1,27 @@
logging.level.root=INFO
# OracleDB connection settings
spring.datasource.url=jdbc:oracle:thin:@//localhost:11521/ORCLPDB1
spring.datasource.username=books
spring.datasource.password=books
spring.datasource.driver-class-name=oracle.jdbc.OracleDriver
# Comment this line for standard Spring Boot default choosing algorithm
#spring.datasource.type=org.apache.tomcat.jdbc.pool.DataSource
# HikariCP settings
spring.datasource.hikari.minimumIdle=5
spring.datasource.hikari.maximumPoolSize=20
spring.datasource.hikari.idleTimeout=30000
spring.datasource.hikari.maxLifetime=2000000
spring.datasource.hikari.connectionTimeout=30000
spring.datasource.hikari.poolName=HikariPoolBooks
# Tomcat settings
spring.datasource.tomcat.maxActive=15
spring.datasource.tomcat.minIdle=5
# JPA settings
spring.jpa.database-platform=org.hibernate.dialect.Oracle12cDialect
spring.jpa.hibernate.use-new-id-generator-mappings=false
spring.jpa.hibernate.ddl-auto=create
@@ -1 +1,9 @@
# Available profiles
# - none for no profile
# - oracle-pooling-basic - Oracle database with HikariCP. Loads configuration from application-oracle-pooling-basic.properties
# - oracle - Uses OracleDataSource. This profile also needs "oracle-pooling-basic"
# - oracle-ucp - Uses PoolDataSource. This profile also needs "oracle-pooling-basic"
# - c3p0 - Uses ComboPooledDataSource. This profile also needs "oracle-pooling-basic"
spring:
profiles:
active: none
@@ -5,10 +5,8 @@ import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.jdbi.v3.core.Jdbi;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
@@ -24,7 +22,7 @@ import com.baeldung.boot.jdbi.service.CarMakerService;
import lombok.extern.slf4j.Slf4j;
@RunWith(SpringRunner.class)
@SpringBootTest
@SpringBootTest(classes = {SpringBootJdbiApplication.class, JdbiConfiguration.class})
@Slf4j
public class SpringBootJdbiApplicationUnitTest {
@@ -0,0 +1,27 @@
package com.baeldung.spring.oracle.pooling;
import static org.junit.jupiter.api.Assertions.assertTrue;
import javax.sql.DataSource;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest(classes = {SpringOraclePoolingApplication.class})
@ActiveProfiles({"oracle-pooling-basic", "c3p0"})
public class SpringOraclePoolingApplicationC3P0LiveTest {
@Autowired
private DataSource dataSource;
@Test
public void givenC3p0Configuration_thenBuildsComboPooledDataSource() {
assertTrue(dataSource instanceof com.mchange.v2.c3p0.ComboPooledDataSource);
}
}
@@ -0,0 +1,27 @@
package com.baeldung.spring.oracle.pooling;
import static org.junit.jupiter.api.Assertions.assertTrue;
import javax.sql.DataSource;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest(classes = {SpringOraclePoolingApplication.class})
@ActiveProfiles("oracle-pooling-basic")
public class SpringOraclePoolingApplicationHikariCPLiveTest {
@Autowired
private DataSource dataSource;
@Test
public void givenHikariCPConfiguration_thenBuildsHikariCP() {
assertTrue(dataSource instanceof com.zaxxer.hikari.HikariDataSource);
}
}
@@ -0,0 +1,27 @@
package com.baeldung.spring.oracle.pooling;
import static org.junit.jupiter.api.Assertions.assertTrue;
import javax.sql.DataSource;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest(classes = {SpringOraclePoolingApplication.class})
@ActiveProfiles({"oracle-pooling-basic", "oracle"})
public class SpringOraclePoolingApplicationOracleLiveTest {
@Autowired
private DataSource dataSource;
@Test
public void givenOracleConfiguration_thenBuildsOracleDataSource() {
assertTrue(dataSource instanceof oracle.jdbc.pool.OracleDataSource);
}
}
@@ -0,0 +1,27 @@
package com.baeldung.spring.oracle.pooling;
import static org.junit.jupiter.api.Assertions.assertTrue;
import javax.sql.DataSource;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest(classes = {SpringOraclePoolingApplication.class})
@ActiveProfiles({"oracle-pooling-basic", "oracle-ucp"})
public class SpringOraclePoolingApplicationOracleUCPLiveTest {
@Autowired
private DataSource dataSource;
@Test
public void givenOracleUCPConfiguration_thenBuildsOraclePoolDataSource() {
assertTrue(dataSource instanceof oracle.ucp.jdbc.PoolDataSource);
}
}
@@ -1,4 +1,5 @@
### Relevant Articles:
- [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)
- [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>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
@@ -0,0 +1,35 @@
package com.baeldung.namingstrategy;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
@Entity
public class Person {
@Id
private Long id;
private String firstName;
private String lastName;
public Person() {}
public Person(Long id, String firstName, String lastName) {
this.id = id;
this.firstName = firstName;
this.lastName = lastName;
}
public Long id() {
return id;
}
public String firstName() {
return firstName;
}
public String lastName() {
return lastName;
}
}
@@ -0,0 +1,6 @@
package com.baeldung.namingstrategy;
import org.springframework.data.jpa.repository.JpaRepository;
public interface PersonRepository extends JpaRepository<Person, Long> {
}
@@ -0,0 +1,12 @@
package com.baeldung.namingstrategy;
import org.hibernate.boot.model.naming.Identifier;
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
import org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy;
public class QuotedLowerCaseNamingStrategy extends SpringPhysicalNamingStrategy {
@Override
protected Identifier getIdentifier(String name, boolean quoted, JdbcEnvironment jdbcEnvironment) {
return new Identifier(name.toLowerCase(), true);
}
}
@@ -0,0 +1,12 @@
package com.baeldung.namingstrategy;
import org.hibernate.boot.model.naming.Identifier;
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
import org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy;
public class QuotedUpperCaseNamingStrategy extends SpringPhysicalNamingStrategy {
@Override
protected Identifier getIdentifier(String name, boolean quoted, JdbcEnvironment jdbcEnvironment) {
return new Identifier(name.toUpperCase(), true);
}
}
@@ -0,0 +1,7 @@
package com.baeldung.namingstrategy;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SpringDataJpaNamingConventionApplication {
}
@@ -0,0 +1,12 @@
package com.baeldung.namingstrategy;
import org.hibernate.boot.model.naming.Identifier;
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
import org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy;
public class UnquotedLowerCaseNamingStrategy extends SpringPhysicalNamingStrategy {
@Override
protected Identifier getIdentifier(String name, boolean quoted, JdbcEnvironment jdbcEnvironment) {
return new Identifier(name.toLowerCase(), false);
}
}
@@ -0,0 +1,12 @@
package com.baeldung.namingstrategy;
import org.hibernate.boot.model.naming.Identifier;
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
import org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy;
public class UnquotedUpperCaseNamingStrategy extends SpringPhysicalNamingStrategy {
@Override
protected Identifier getIdentifier(String name, boolean quoted, JdbcEnvironment jdbcEnvironment) {
return new Identifier(name.toUpperCase(), false);
}
}
@@ -0,0 +1,81 @@
package com.baeldung.namingstrategy;
import org.hibernate.exception.SQLGrammarException;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.jdbc.TestDatabaseAutoConfiguration;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.test.context.TestPropertySource;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import java.math.BigInteger;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertThrows;
@DataJpaTest(excludeAutoConfiguration = TestDatabaseAutoConfiguration.class)
@TestPropertySource("quoted-lower-case-naming-strategy.properties")
class QuotedLowerCaseNamingStrategyH2IntegrationTest {
@PersistenceContext
private EntityManager entityManager;
@Autowired
private PersonRepository personRepository;
@BeforeEach
void insertPeople() {
personRepository.saveAll(Arrays.asList(
new Person(1L, "John", "Doe"),
new Person(2L, "Jane", "Doe"),
new Person(3L, "Ted", "Mosby")
));
}
@ParameterizedTest
@ValueSource(strings = {"person", "PERSON", "Person"})
void givenPeopleAndLowerCaseNamingStrategy_whenQueryPersonUnquoted_thenException(String tableName) {
Query query = entityManager.createNativeQuery("select * from " + tableName);
// Unexpected result
assertThrows(SQLGrammarException.class, query::getResultStream);
}
@Test
void givenPeopleAndLowerCaseNamingStrategy_whenQueryPersonQuotedUpperCase_thenException() {
Query query = entityManager.createNativeQuery("select * from \"PERSON\"");
// Expected result
assertThrows(SQLGrammarException.class, query::getResultStream);
}
@Test
void givenPeopleAndLowerCaseNamingStrategy_whenQueryPersonQuotedLowerCase_thenResult() {
Query query = entityManager.createNativeQuery("select * from \"person\"");
// Expected result
List<Person> result = (List<Person>) query.getResultStream()
.map(this::fromDatabase)
.collect(Collectors.toList());
assertThat(result).isNotEmpty();
}
public Person fromDatabase(Object databaseRow) {
Object[] typedDatabaseRow = (Object[]) databaseRow;
return new Person(
((BigInteger) typedDatabaseRow[0]).longValue(),
(String) typedDatabaseRow[1],
(String) typedDatabaseRow[2]
);
}
}
@@ -0,0 +1,85 @@
package com.baeldung.namingstrategy;
import org.hibernate.exception.SQLGrammarException;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.jdbc.TestDatabaseAutoConfiguration;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.test.context.TestPropertySource;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import java.math.BigInteger;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertThrows;
@DataJpaTest(excludeAutoConfiguration = TestDatabaseAutoConfiguration.class)
@TestPropertySource("quoted-lower-case-naming-strategy-on-postgres.properties")
class QuotedLowerCaseNamingStrategyPostgresLiveTest {
@PersistenceContext
private EntityManager entityManager;
@Autowired
private PersonRepository personRepository;
@BeforeEach
void insertPeople() {
personRepository.saveAll(Arrays.asList(
new Person(1L, "John", "Doe"),
new Person(2L, "Jane", "Doe"),
new Person(3L, "Ted", "Mosby")
));
}
@ParameterizedTest
@ValueSource(strings = {"person", "PERSON", "Person"})
void givenPeopleAndLowerCaseNamingStrategy_whenQueryPersonUnquoted_thenResult(String tableName) {
Query query = entityManager.createNativeQuery("select * from " + tableName);
// Expected result
List<Person> result = (List<Person>) query.getResultStream()
.map(this::fromDatabase)
.collect(Collectors.toList());
assertThat(result).isNotEmpty();
}
@Test
void givenPeopleAndLowerCaseNamingStrategy_whenQueryPersonQuotedUpperCase_thenException() {
Query query = entityManager.createNativeQuery("select * from \"PERSON\"");
// Expected result
assertThrows(SQLGrammarException.class, query::getResultStream);
}
@Test
void givenPeopleAndLowerCaseNamingStrategy_whenQueryPersonQuotedLowerCase_thenResult() {
Query query = entityManager.createNativeQuery("select * from \"person\"");
// Expected result
List<Person> result = (List<Person>) query.getResultStream()
.map(this::fromDatabase)
.collect(Collectors.toList());
assertThat(result).isNotEmpty();
}
public Person fromDatabase(Object databaseRow) {
Object[] typedDatabaseRow = (Object[]) databaseRow;
return new Person(
((BigInteger) typedDatabaseRow[0]).longValue(),
(String) typedDatabaseRow[1],
(String) typedDatabaseRow[2]
);
}
}
@@ -0,0 +1,85 @@
package com.baeldung.namingstrategy;
import org.hibernate.exception.SQLGrammarException;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.jdbc.TestDatabaseAutoConfiguration;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.test.context.TestPropertySource;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import java.math.BigInteger;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertThrows;
@DataJpaTest(excludeAutoConfiguration = TestDatabaseAutoConfiguration.class)
@TestPropertySource("quoted-upper-case-naming-strategy.properties")
class QuotedUpperCaseNamingStrategyH2IntegrationTest {
@PersistenceContext
private EntityManager entityManager;
@Autowired
private PersonRepository personRepository;
@BeforeEach
void insertPeople() {
personRepository.saveAll(Arrays.asList(
new Person(1L, "John", "Doe"),
new Person(2L, "Jane", "Doe"),
new Person(3L, "Ted", "Mosby")
));
}
@ParameterizedTest
@ValueSource(strings = {"person", "PERSON", "Person"})
void givenPeopleAndUpperCaseNamingStrategy_whenQueryPersonUnquoted_thenException(String tableName) {
Query query = entityManager.createNativeQuery("select * from " + tableName);
// Expected result
List<Person> result = (List<Person>) query.getResultStream()
.map(this::fromDatabase)
.collect(Collectors.toList());
assertThat(result).isNotEmpty();
}
@Test
void givenPeopleAndUpperCaseNamingStrategy_whenQueryPersonQuotedUpperCase_thenResult() {
Query query = entityManager.createNativeQuery("select * from \"PERSON\"");
// Expected result
List<Person> result = (List<Person>) query.getResultStream()
.map(this::fromDatabase)
.collect(Collectors.toList());
assertThat(result).isNotEmpty();
}
@Test
void givenPeopleAndUpperCaseNamingStrategy_whenQueryPersonQuotedLowerCase_thenException() {
Query query = entityManager.createNativeQuery("select * from \"person\"");
// Expected result
assertThrows(SQLGrammarException.class, query::getResultStream);
}
public Person fromDatabase(Object databaseRow) {
Object[] typedDatabaseRow = (Object[]) databaseRow;
return new Person(
((BigInteger) typedDatabaseRow[0]).longValue(),
(String) typedDatabaseRow[1],
(String) typedDatabaseRow[2]
);
}
}
@@ -0,0 +1,81 @@
package com.baeldung.namingstrategy;
import org.hibernate.exception.SQLGrammarException;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.jdbc.TestDatabaseAutoConfiguration;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.test.context.TestPropertySource;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import java.math.BigInteger;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertThrows;
@DataJpaTest(excludeAutoConfiguration = TestDatabaseAutoConfiguration.class)
@TestPropertySource("quoted-upper-case-naming-strategy-on-postgres.properties")
class QuotedUpperCaseNamingStrategyPostgresLiveTest {
@PersistenceContext
private EntityManager entityManager;
@Autowired
private PersonRepository personRepository;
@BeforeEach
void insertPeople() {
personRepository.saveAll(Arrays.asList(
new Person(1L, "John", "Doe"),
new Person(2L, "Jane", "Doe"),
new Person(3L, "Ted", "Mosby")
));
}
@ParameterizedTest
@ValueSource(strings = {"person", "PERSON", "Person"})
void givenPeopleAndUpperCaseNamingStrategy_whenQueryPersonUnquoted_thenResult(String tableName) {
Query query = entityManager.createNativeQuery("select * from " + tableName);
// Unexpected result
assertThrows(SQLGrammarException.class, query::getResultStream);
}
@Test
void givenPeopleAndUpperCaseNamingStrategy_whenQueryPersonQuotedUpperCase_thenException() {
Query query = entityManager.createNativeQuery("select * from \"PERSON\"");
// Expected result
List<Person> result = (List<Person>) query.getResultStream()
.map(this::fromDatabase)
.collect(Collectors.toList());
assertThat(result).isNotEmpty();
}
@Test
void givenPeopleAndUpperCaseNamingStrategy_whenQueryPersonQuotedLowerCase_thenResult() {
Query query = entityManager.createNativeQuery("select * from \"person\"");
// Expected result
assertThrows(SQLGrammarException.class, query::getResultStream);
}
public Person fromDatabase(Object databaseRow) {
Object[] typedDatabaseRow = (Object[]) databaseRow;
return new Person(
((BigInteger) typedDatabaseRow[0]).longValue(),
(String) typedDatabaseRow[1],
(String) typedDatabaseRow[2]
);
}
}
@@ -0,0 +1,85 @@
package com.baeldung.namingstrategy;
import org.hibernate.exception.SQLGrammarException;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.jdbc.TestDatabaseAutoConfiguration;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.test.context.TestPropertySource;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import java.math.BigInteger;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertThrows;
@DataJpaTest(excludeAutoConfiguration = TestDatabaseAutoConfiguration.class)
@TestPropertySource("spring-physical-naming-strategy.properties")
class SpringPhysicalNamingStrategyH2IntegrationTest {
@PersistenceContext
private EntityManager entityManager;
@Autowired
private PersonRepository personRepository;
@BeforeEach
void insertPeople() {
personRepository.saveAll(Arrays.asList(
new Person(1L, "John", "Doe"),
new Person(2L, "Jane", "Doe"),
new Person(3L, "Ted", "Mosby")
));
}
@ParameterizedTest
@ValueSource(strings = {"person", "PERSON", "Person"})
void givenPeopleAndSpringNamingStrategy_whenQueryPersonUnquoted_thenResult(String tableName) {
Query query = entityManager.createNativeQuery("select * from " + tableName);
// Expected result
List<Person> result = (List<Person>) query.getResultStream()
.map(this::fromDatabase)
.collect(Collectors.toList());
assertThat(result).isNotEmpty();
}
@Test
void givenPeopleAndSpringNamingStrategy_whenQueryPersonQuotedUpperCase_thenResult() {
Query query = entityManager.createNativeQuery("select * from \"PERSON\"");
// Unexpected result
List<Person> result = (List<Person>) query.getResultStream()
.map(this::fromDatabase)
.collect(Collectors.toList());
assertThat(result).isNotEmpty();
}
@Test
void givenPeopleAndSpringNamingStrategy_whenQueryPersonQuotedLowerCase_thenException() {
Query query = entityManager.createNativeQuery("select * from \"person\"");
// Unexpected result
assertThrows(SQLGrammarException.class, query::getResultStream);
}
public Person fromDatabase(Object databaseRow) {
Object[] typedDatabaseRow = (Object[]) databaseRow;
return new Person(
((BigInteger) typedDatabaseRow[0]).longValue(),
(String) typedDatabaseRow[1],
(String) typedDatabaseRow[2]
);
}
}
@@ -0,0 +1,85 @@
package com.baeldung.namingstrategy;
import org.hibernate.exception.SQLGrammarException;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.jdbc.TestDatabaseAutoConfiguration;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.test.context.TestPropertySource;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import java.math.BigInteger;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertThrows;
@DataJpaTest(excludeAutoConfiguration = TestDatabaseAutoConfiguration.class)
@TestPropertySource("spring-physical-naming-strategy-on-postgres.properties")
class SpringPhysicalNamingStrategyPostgresLiveTest {
@PersistenceContext
private EntityManager entityManager;
@Autowired
private PersonRepository personRepository;
@BeforeEach
void insertPeople() {
personRepository.saveAll(Arrays.asList(
new Person(1L, "John", "Doe"),
new Person(2L, "Jane", "Doe"),
new Person(3L, "Ted", "Mosby")
));
}
@ParameterizedTest
@ValueSource(strings = {"person", "PERSON", "Person"})
void givenPeopleAndSpringNamingStrategy_whenQueryPersonUnquoted_thenResult(String tableName) {
Query query = entityManager.createNativeQuery("select * from " + tableName);
// Expected result
List<Person> result = (List<Person>) query.getResultStream()
.map(this::fromDatabase)
.collect(Collectors.toList());
assertThat(result).isNotEmpty();
}
@Test
void givenPeopleAndSpringNamingStrategy_whenQueryPersonQuotedUpperCase_thenException() {
Query query = entityManager.createNativeQuery("select * from \"PERSON\"");
// Expected result
assertThrows(SQLGrammarException.class, query::getResultStream);
}
@Test
void givenPeopleAndSpringNamingStrategy_whenQueryPersonQuotedLowerCase_thenResult() {
Query query = entityManager.createNativeQuery("select * from \"person\"");
// Expected result
List<Person> result = (List<Person>) query.getResultStream()
.map(this::fromDatabase)
.collect(Collectors.toList());
assertThat(result).isNotEmpty();
}
public Person fromDatabase(Object databaseRow) {
Object[] typedDatabaseRow = (Object[]) databaseRow;
return new Person(
((BigInteger) typedDatabaseRow[0]).longValue(),
(String) typedDatabaseRow[1],
(String) typedDatabaseRow[2]
);
}
}
@@ -0,0 +1,86 @@
package com.baeldung.namingstrategy;
import org.hibernate.exception.SQLGrammarException;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.jdbc.TestDatabaseAutoConfiguration;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.test.context.TestPropertySource;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import java.math.BigInteger;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertThrows;
@DataJpaTest(excludeAutoConfiguration = TestDatabaseAutoConfiguration.class)
@TestPropertySource("unquoted-lower-case-naming-strategy.properties")
class UnquotedLowerCaseNamingStrategyH2IntegrationTest {
@PersistenceContext
private EntityManager entityManager;
@Autowired
private PersonRepository personRepository;
@BeforeEach
void insertPeople() {
personRepository.saveAll(Arrays.asList(
new Person(1L, "John", "Doe"),
new Person(2L, "Jane", "Doe"),
new Person(3L, "Ted", "Mosby")
));
}
@ParameterizedTest
@ValueSource(strings = {"person", "PERSON", "Person"})
void givenPeopleAndLowerCaseNamingStrategy_whenQueryPersonUnquoted_thenResult(String tableName) {
Query query = entityManager.createNativeQuery("select * from " + tableName);
// Expected result
List<Person> result = (List<Person>) query.getResultStream()
.map(this::fromDatabase)
.collect(Collectors.toList());
assertThat(result).isNotEmpty();
}
@Test
void givenPeopleAndLowerCaseNamingStrategy_whenQueryPersonQuotedUpperCase_thenResult() {
Query query = entityManager.createNativeQuery("select * from \"PERSON\"");
// Unexpected result
List<Person> result = (List<Person>) query.getResultStream()
.map(this::fromDatabase)
.collect(Collectors.toList());
assertThat(result).isNotEmpty();
}
@Test
void givenPeopleAndLowerCaseNamingStrategy_whenQueryPersonQuotedLowerCase_thenException() {
Query query = entityManager.createNativeQuery("select * from \"person\"");
// Unexpected result
assertThrows(SQLGrammarException.class, query::getResultStream);
}
public Person fromDatabase(Object databaseRow) {
Object[] typedDatabaseRow = (Object[]) databaseRow;
return new Person(
((BigInteger) typedDatabaseRow[0]).longValue(),
(String) typedDatabaseRow[1],
(String) typedDatabaseRow[2]
);
}
}
@@ -0,0 +1,85 @@
package com.baeldung.namingstrategy;
import org.hibernate.exception.SQLGrammarException;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.jdbc.TestDatabaseAutoConfiguration;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.test.context.TestPropertySource;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import java.math.BigInteger;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertThrows;
@DataJpaTest(excludeAutoConfiguration = TestDatabaseAutoConfiguration.class)
@TestPropertySource("unquoted-lower-case-naming-strategy-on-postgres.properties")
class UnquotedLowerCaseNamingStrategyPostgresLiveTest {
@PersistenceContext
private EntityManager entityManager;
@Autowired
private PersonRepository personRepository;
@BeforeEach
void insertPeople() {
personRepository.saveAll(Arrays.asList(
new Person(1L, "John", "Doe"),
new Person(2L, "Jane", "Doe"),
new Person(3L, "Ted", "Mosby")
));
}
@ParameterizedTest
@ValueSource(strings = {"person", "PERSON", "Person"})
void givenPeopleAndLowerCaseNamingStrategy_whenQueryPersonUnquoted_thenResult(String tableName) {
Query query = entityManager.createNativeQuery("select * from " + tableName);
// Expected result
List<Person> result = (List<Person>) query.getResultStream()
.map(this::fromDatabase)
.collect(Collectors.toList());
assertThat(result).isNotEmpty();
}
@Test
void givenPeopleAndLowerCaseNamingStrategy_whenQueryPersonQuotedUpperCase_thenException() {
Query query = entityManager.createNativeQuery("select * from \"PERSON\"");
// Expected result
assertThrows(SQLGrammarException.class, query::getResultStream);
}
@Test
void givenPeopleAndLowerCaseNamingStrategy_whenQueryPersonQuotedLowerCase_thenResult() {
Query query = entityManager.createNativeQuery("select * from \"person\"");
// Expected result
List<Person> result = (List<Person>) query.getResultStream()
.map(this::fromDatabase)
.collect(Collectors.toList());
assertThat(result).isNotEmpty();
}
public Person fromDatabase(Object databaseRow) {
Object[] typedDatabaseRow = (Object[]) databaseRow;
return new Person(
((BigInteger) typedDatabaseRow[0]).longValue(),
(String) typedDatabaseRow[1],
(String) typedDatabaseRow[2]
);
}
}
@@ -0,0 +1,85 @@
package com.baeldung.namingstrategy;
import org.hibernate.exception.SQLGrammarException;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.jdbc.TestDatabaseAutoConfiguration;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.test.context.TestPropertySource;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import java.math.BigInteger;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertThrows;
@DataJpaTest(excludeAutoConfiguration = TestDatabaseAutoConfiguration.class)
@TestPropertySource("unquoted-upper-case-naming-strategy.properties")
class UnquotedUpperCaseNamingStrategyH2IntegrationTest {
@PersistenceContext
private EntityManager entityManager;
@Autowired
private PersonRepository personRepository;
@BeforeEach
void insertPeople() {
personRepository.saveAll(Arrays.asList(
new Person(1L, "John", "Doe"),
new Person(2L, "Jane", "Doe"),
new Person(3L, "Ted", "Mosby")
));
}
@ParameterizedTest
@ValueSource(strings = {"person", "PERSON", "Person"})
void givenPeopleAndUpperCaseNamingStrategy_whenQueryPersonUnquoted_thenResult(String tableName) {
Query query = entityManager.createNativeQuery("select * from " + tableName);
// Expected result
List<Person> result = (List<Person>) query.getResultStream()
.map(this::fromDatabase)
.collect(Collectors.toList());
assertThat(result).isNotEmpty();
}
@Test
void givenPeopleAndUpperCaseNamingStrategy_whenQueryPersonQuotedUpperCase_thenResult() {
Query query = entityManager.createNativeQuery("select * from \"PERSON\"");
// Expected result
List<Person> result = (List<Person>) query.getResultStream()
.map(this::fromDatabase)
.collect(Collectors.toList());
assertThat(result).isNotEmpty();
}
@Test
void givenPeopleAndUpperCaseNamingStrategy_whenQueryPersonQuotedLowerCase_thenException() {
Query query = entityManager.createNativeQuery("select * from \"person\"");
// Expected result
assertThrows(SQLGrammarException.class, query::getResultStream);
}
public Person fromDatabase(Object databaseRow) {
Object[] typedDatabaseRow = (Object[]) databaseRow;
return new Person(
((BigInteger) typedDatabaseRow[0]).longValue(),
(String) typedDatabaseRow[1],
(String) typedDatabaseRow[2]
);
}
}
@@ -0,0 +1,85 @@
package com.baeldung.namingstrategy;
import org.hibernate.exception.SQLGrammarException;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.jdbc.TestDatabaseAutoConfiguration;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.test.context.TestPropertySource;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import java.math.BigInteger;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertThrows;
@DataJpaTest(excludeAutoConfiguration = TestDatabaseAutoConfiguration.class)
@TestPropertySource("unquoted-upper-case-naming-strategy-on-postgres.properties")
class UnquotedUpperCaseNamingStrategyPostgresLiveTest {
@PersistenceContext
private EntityManager entityManager;
@Autowired
private PersonRepository personRepository;
@BeforeEach
void insertPeople() {
personRepository.saveAll(Arrays.asList(
new Person(1L, "John", "Doe"),
new Person(2L, "Jane", "Doe"),
new Person(3L, "Ted", "Mosby")
));
}
@ParameterizedTest
@ValueSource(strings = {"person", "PERSON", "Person"})
void givenPeopleAndUpperCaseNamingStrategy_whenQueryPersonUnquoted_thenResult(String tableName) {
Query query = entityManager.createNativeQuery("select * from " + tableName);
// Expected result
List<Person> result = (List<Person>) query.getResultStream()
.map(this::fromDatabase)
.collect(Collectors.toList());
assertThat(result).isNotEmpty();
}
@Test
void givenPeopleAndUpperCaseNamingStrategy_whenQueryPersonQuotedUpperCase_thenException() {
Query query = entityManager.createNativeQuery("select * from \"PERSON\"");
// Unexpected result
assertThrows(SQLGrammarException.class, query::getResultStream);
}
@Test
void givenPeopleAndUpperCaseNamingStrategy_whenQueryPersonQuotedLowerCase_thenResult() {
Query query = entityManager.createNativeQuery("select * from \"person\"");
// Unexpected result
List<Person> result = (List<Person>) query.getResultStream()
.map(this::fromDatabase)
.collect(Collectors.toList());
assertThat(result).isNotEmpty();
}
public Person fromDatabase(Object databaseRow) {
Object[] typedDatabaseRow = (Object[]) databaseRow;
return new Person(
((BigInteger) typedDatabaseRow[0]).longValue(),
(String) typedDatabaseRow[1],
(String) typedDatabaseRow[2]
);
}
}
@@ -0,0 +1,9 @@
spring.datasource.url=jdbc:postgresql://localhost:5432/quoted-lower-case-strategy
spring.datasource.username=postgres
spring.datasource.password=root
spring.jpa.hibernate.ddl-auto=create-drop
spring.jpa.hibernate.naming.physical-strategy=com.baeldung.namingstrategy.QuotedLowerCaseNamingStrategy
#spring.jpa.properties.javax.persistence.schema-generation.create-source=metadata
#spring.jpa.properties.javax.persistence.schema-generation.scripts.action=create
#spring.jpa.properties.javax.persistence.schema-generation.scripts.create-target=upper-case-naming-strategy-ddl.sql
@@ -0,0 +1,9 @@
spring.datasource.url=jdbc:h2:mem:quoted-lower-case-strategy
spring.datasource.username=sa
spring.datasource.password=
spring.jpa.hibernate.ddl-auto=create-drop
spring.jpa.hibernate.naming.physical-strategy=com.baeldung.namingstrategy.QuotedLowerCaseNamingStrategy
#spring.jpa.properties.javax.persistence.schema-generation.create-source=metadata
#spring.jpa.properties.javax.persistence.schema-generation.scripts.action=create
#spring.jpa.properties.javax.persistence.schema-generation.scripts.create-target=upper-case-naming-strategy-ddl.sql
@@ -0,0 +1,9 @@
spring.datasource.url=jdbc:postgresql://localhost:5432/quoted-upper-case-strategy
spring.datasource.username=postgres
spring.datasource.password=root
spring.jpa.hibernate.ddl-auto=create-drop
spring.jpa.hibernate.naming.physical-strategy=com.baeldung.namingstrategy.QuotedUpperCaseNamingStrategy
#spring.jpa.properties.javax.persistence.schema-generation.create-source=metadata
#spring.jpa.properties.javax.persistence.schema-generation.scripts.action=create
#spring.jpa.properties.javax.persistence.schema-generation.scripts.create-target=upper-case-naming-strategy-ddl.sql
@@ -0,0 +1,9 @@
spring.datasource.url=jdbc:h2:mem:quoted-upper-case-strategy
spring.datasource.username=sa
spring.datasource.password=
spring.jpa.hibernate.ddl-auto=create-drop
spring.jpa.hibernate.naming.physical-strategy=com.baeldung.namingstrategy.QuotedUpperCaseNamingStrategy
#spring.jpa.properties.javax.persistence.schema-generation.create-source=metadata
#spring.jpa.properties.javax.persistence.schema-generation.scripts.action=create
#spring.jpa.properties.javax.persistence.schema-generation.scripts.create-target=upper-case-naming-strategy-ddl.sql
@@ -0,0 +1,9 @@
spring.datasource.url=jdbc:postgresql://localhost:5432/spring-strategy
spring.datasource.username=postgres
spring.datasource.password=root
spring.jpa.hibernate.ddl-auto=create-drop
spring.jpa.hibernate.naming.physical-strategy=org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy
#spring.jpa.properties.javax.persistence.schema-generation.create-source=metadata
#spring.jpa.properties.javax.persistence.schema-generation.scripts.action=create
#spring.jpa.properties.javax.persistence.schema-generation.scripts.create-target=default-naming-strategy-ddl.sql
@@ -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)
- [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)
- [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)
### Quick Start
@@ -0,0 +1,19 @@
package com.baeldung.hibernate.audit;
import java.util.Optional;
import org.springframework.data.domain.AuditorAware;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
public class AuditorAwareImpl implements AuditorAware<String> {
@Override
public String getCurrentAuditor() {
return Optional.ofNullable(SecurityContextHolder.getContext())
.map(e -> e.getAuthentication())
.map(Authentication::getName)
.orElse(null);
}
}
@@ -23,6 +23,7 @@ import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import com.baeldung.hibernate.audit.AuditorAwareImpl;
import com.baeldung.persistence.dao.IBarAuditableDao;
import com.baeldung.persistence.dao.IBarDao;
import com.baeldung.persistence.dao.IFooAuditableDao;
@@ -46,7 +47,7 @@ import com.google.common.base.Preconditions;
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(basePackages = { "com.baeldung.persistence" }, transactionManagerRef = "jpaTransactionManager")
@EnableJpaAuditing
@EnableJpaAuditing(auditorAwareRef = "auditorProvider")
@PropertySource({ "classpath:persistence-h2.properties" })
@ComponentScan({ "com.baeldung.persistence" })
public class PersistenceConfig {
@@ -58,6 +59,11 @@ public class PersistenceConfig {
super();
}
@Bean("auditorProvider")
public AuditorAwareImpl auditorAwareImpl() {
return new AuditorAwareImpl();
}
@Bean
public LocalSessionFactoryBean sessionFactory() {
final LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
+1 -1
View File
@@ -10,7 +10,7 @@
- [Self-Contained Testing Using an In-Memory Database](https://www.baeldung.com/spring-jpa-test-in-memory-database)
- [A Guide to Spring AbstractRoutingDatasource](https://www.baeldung.com/spring-abstract-routing-data-source)
- [Obtaining Auto-generated Keys in Spring JDBC](https://www.baeldung.com/spring-jdbc-autogenerated-keys)
- [Transactions with Spring 4 and JPA](https://www.baeldung.com/transaction-configuration-with-jpa-and-spring)
- [Transactions with Spring and JPA](https://www.baeldung.com/transaction-configuration-with-jpa-and-spring)
- [Use Criteria Queries in a Spring Data Application](https://www.baeldung.com/spring-data-criteria-queries)
- [Many-To-Many Relationship in JPA](https://www.baeldung.com/jpa-many-to-many)
- [Spring Persistence (Hibernate and JPA) with a JNDI datasource](https://www.baeldung.com/spring-persistence-hibernate-and-jpa-with-a-jndi-datasource/)
@@ -0,0 +1,3 @@
### Relevant Articles:
- [Spring JdbcTemplate Unit Testing](https://www.baeldung.com/spring-jdbctemplate-testing)
@@ -7,7 +7,12 @@ public class Employee {
private String lastName;
private String address;
public Employee(int id, String firstName, String lastName) {
this.id = id;
this.firstName = firstName;
this.lastName = lastName;
}
public int getId() {
return id;
@@ -33,12 +38,5 @@ public class Employee {
this.lastName = lastName;
}
public String getAddress() {
return address;
}
public void setAddress(final String address) {
this.address = address;
}
}
@@ -1,21 +1,67 @@
package com.baeldung.jdbc;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.sql.DataSource;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
import org.springframework.stereotype.Repository;
@Repository
public class EmployeeDAO {
private JdbcTemplate jdbcTemplate;
private NamedParameterJdbcTemplate namedJdbcTemplate;
public void setDataSource(DataSource dataSource) {
jdbcTemplate = new JdbcTemplate(dataSource);
namedJdbcTemplate = new NamedParameterJdbcTemplate(dataSource);
}
public int getCountOfEmployees() {
return jdbcTemplate.queryForObject("SELECT COUNT(*) FROM EMPLOYEE", Integer.class);
}
public List<Employee> getEmployeesFromIdListNamed(List<Integer> ids) {
SqlParameterSource parameters = new MapSqlParameterSource("ids", ids);
List<Employee> employees = namedJdbcTemplate.query(
"SELECT * FROM EMPLOYEE WHERE id IN (:ids)",
parameters,
(rs, rowNum) -> new Employee(rs.getInt("id"), rs.getString("first_name"), rs.getString("last_name")));
return employees;
}
public List<Employee> getEmployeesFromIdList(List<Integer> ids) {
String inSql = String.join(",", Collections.nCopies(ids.size(), "?"));
List<Employee> employees = jdbcTemplate.query(
String.format("SELECT * FROM EMPLOYEE WHERE id IN (%s)", inSql),
ids.toArray(),
(rs, rowNum) -> new Employee(rs.getInt("id"), rs.getString("first_name"), rs.getString("last_name")));
return employees;
}
public List<Employee> getEmployeesFromLargeIdList(List<Integer> ids) {
jdbcTemplate.execute("CREATE TEMPORARY TABLE IF NOT EXISTS employee_tmp (id INT NOT NULL)");
List<Object[]> employeeIds = new ArrayList<>();
for (Integer id : ids) {
employeeIds.add(new Object[] { id });
}
jdbcTemplate.batchUpdate("INSERT INTO employee_tmp VALUES(?)", employeeIds);
List<Employee> employees = jdbcTemplate.query(
"SELECT * FROM EMPLOYEE WHERE id IN (SELECT id FROM employee_tmp)",
(rs, rowNum) -> new Employee(rs.getInt("id"), rs.getString("first_name"), rs.getString("last_name")));
jdbcTemplate.update("DELETE FROM employee_tmp");
return employees;
}
}
@@ -2,6 +2,5 @@ CREATE TABLE EMPLOYEE
(
ID int NOT NULL PRIMARY KEY,
FIRST_NAME varchar(255),
LAST_NAME varchar(255),
ADDRESS varchar(255)
LAST_NAME varchar(255)
);
@@ -1,4 +1,4 @@
INSERT INTO EMPLOYEE VALUES (1, 'James', 'Gosling', 'Canada');
INSERT INTO EMPLOYEE VALUES (2, 'Donald', 'Knuth', 'USA');
INSERT INTO EMPLOYEE VALUES (3, 'Linus', 'Torvalds', 'Finland');
INSERT INTO EMPLOYEE VALUES (4, 'Dennis', 'Ritchie', 'USA');
INSERT INTO EMPLOYEE VALUES (1, 'James', 'Gosling');
INSERT INTO EMPLOYEE VALUES (2, 'Donald', 'Knuth');
INSERT INTO EMPLOYEE VALUES (3, 'Linus', 'Torvalds');
INSERT INTO EMPLOYEE VALUES (4, 'Dennis', 'Ritchie');
@@ -2,8 +2,12 @@ package com.baeldung.jdbc;
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.util.ArrayList;
import java.util.List;
import javax.sql.DataSource;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
@@ -14,13 +18,24 @@ import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
import org.springframework.test.util.ReflectionTestUtils;
@RunWith(MockitoJUnitRunner.class)
public class EmployeeDAOUnitTest {
@Mock
JdbcTemplate jdbcTemplate;
DataSource dataSource;
@Before
public void setup() {
dataSource = new EmbeddedDatabaseBuilder().setType(EmbeddedDatabaseType.H2)
.generateUniqueName(true)
.addScript("classpath:jdbc/schema.sql")
.addScript("classpath:jdbc/test-data.sql")
.build();
}
@Test
public void whenMockJdbcTemplate_thenReturnCorrectEmployeeCount() {
EmployeeDAO employeeDAO = new EmployeeDAO();
@@ -38,14 +53,55 @@ public class EmployeeDAOUnitTest {
@Test
public void whenInjectInMemoryDataSource_thenReturnCorrectEmployeeCount() {
DataSource dataSource = new EmbeddedDatabaseBuilder().setType(EmbeddedDatabaseType.H2)
.addScript("classpath:jdbc/schema.sql")
.addScript("classpath:jdbc/test-data.sql")
.build();
EmployeeDAO employeeDAO = new EmployeeDAO();
employeeDAO.setDataSource(dataSource);
assertEquals(4, employeeDAO.getCountOfEmployees());
}
@Test
public void givenSmallIdList_whenGetEmployeesFromIdList_thenReturnCorrectEmployees() {
List<Integer> ids = new ArrayList<>();
ids.add(1);
ids.add(3);
ids.add(4);
EmployeeDAO employeeDAO = new EmployeeDAO();
employeeDAO.setDataSource(dataSource);
List<Employee> employees = employeeDAO.getEmployeesFromIdList(ids);
assertEquals(3, employees.size());
assertEquals(1, employees.get(0).getId());
assertEquals(3, employees.get(1).getId());
assertEquals(4, employees.get(2).getId());
employees = employeeDAO.getEmployeesFromIdListNamed(ids);
assertEquals(3, employees.size());
assertEquals(1, employees.get(0).getId());
assertEquals(3, employees.get(1).getId());
assertEquals(4, employees.get(2).getId());
}
@Test
public void givenLargeIdList_whenGetEmployeesFromIdList_thenReturnCorrectEmployees() {
List<Integer> ids = new ArrayList<>();
ids.add(1);
ids.add(3);
ids.add(4);
EmployeeDAO employeeDAO = new EmployeeDAO();
employeeDAO.setDataSource(dataSource);
List<Employee> employees = employeeDAO.getEmployeesFromLargeIdList(ids);
assertEquals(3, employees.size());
assertEquals(1, employees.get(0).getId());
assertEquals(3, employees.get(1).getId());
assertEquals(4, employees.get(2).getId());
ids.clear();
ids.add(2);
employees = employeeDAO.getEmployeesFromLargeIdList(ids);
assertEquals(1, employees.size());
}
}
@@ -24,7 +24,11 @@
<artifactId>spring-context</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<!-- persistence -->
<dependency>
<groupId>org.hibernate</groupId>
@@ -128,12 +132,13 @@
<properties>
<!-- Spring -->
<org.springframework.version>5.1.6.RELEASE</org.springframework.version>
<org.springframework.version>5.2.5.RELEASE</org.springframework.version>
<!-- persistence -->
<hibernate.version>5.4.2.Final</hibernate.version>
<mysql-connector-java.version>6.0.6</mysql-connector-java.version>
<spring-data-jpa.version>2.1.6.RELEASE</spring-data-jpa.version>
<hibernate.version>5.4.13.Final</hibernate.version>
<mysql-connector-java.version>8.0.19</mysql-connector-java.version>
<h2.version>1.4.200</h2.version>
<spring-data-jpa.version>2.2.6.RELEASE</spring-data-jpa.version>
<tomcat-dbcp.version>9.0.0.M26</tomcat-dbcp.version>
<jta.version>1.1</jta.version>
<querydsl.version>4.2.1</querydsl.version>
@@ -1,9 +1,7 @@
package com.baeldung.config;
import java.util.Properties;
import javax.sql.DataSource;
import com.baeldung.persistence.service.FooService;
import com.google.common.base.Preconditions;
import org.apache.tomcat.dbcp.dbcp2.BasicDataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
@@ -23,16 +21,15 @@ import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import com.baeldung.hibernate.dao.FooDao;
import com.baeldung.jpa.dao.IFooDao;
import com.google.common.base.Preconditions;
import javax.sql.DataSource;
import java.util.Properties;
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(basePackages = { "com.baeldung.hibernate.dao" }, transactionManagerRef = "jpaTransactionManager")
@EnableJpaAuditing
@PropertySource({ "classpath:persistence-mysql.properties" })
@ComponentScan({ "com.baeldung.persistence", "com.baeldung.hibernate.dao" })
@ComponentScan(basePackages = { "com.baeldung.persistence.dao", "com.baeldung.jpa.dao" })
public class PersistenceConfig {
@Autowired
@@ -46,7 +43,7 @@ public class PersistenceConfig {
public LocalSessionFactoryBean sessionFactory() {
final LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
sessionFactory.setDataSource(restDataSource());
sessionFactory.setPackagesToScan(new String[] { "com.baeldung.persistence.model" });
sessionFactory.setPackagesToScan("com.baeldung.persistence.model");
sessionFactory.setHibernateProperties(hibernateProperties());
return sessionFactory;
@@ -56,7 +53,7 @@ public class PersistenceConfig {
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
final LocalContainerEntityManagerFactoryBean emf = new LocalContainerEntityManagerFactoryBean();
emf.setDataSource(restDataSource());
emf.setPackagesToScan(new String[] { "com.baeldung.persistence.model" });
emf.setPackagesToScan("com.baeldung.persistence.model");
final JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
emf.setJpaVendorAdapter(vendorAdapter);
@@ -96,18 +93,15 @@ public class PersistenceConfig {
}
@Bean
public IFooDao fooHibernateDao() {
return new FooDao();
public FooService fooService() {
return new FooService();
}
private final Properties hibernateProperties() {
final Properties hibernateProperties = new Properties();
hibernateProperties.setProperty("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto"));
hibernateProperties.setProperty("hibernate.dialect", env.getProperty("hibernate.dialect"));
hibernateProperties.setProperty("hibernate.show_sql", "true");
// hibernateProperties.setProperty("hibernate.format_sql", "true");
// hibernateProperties.setProperty("hibernate.globally_quoted_identifiers", "true");
// Envers properties
hibernateProperties.setProperty("org.hibernate.envers.audit_table_suffix", env.getProperty("envers.audit_table_suffix"));
@@ -1,10 +1,6 @@
package com.baeldung.config;
import java.util.Properties;
import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;
import com.google.common.base.Preconditions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
@@ -21,7 +17,8 @@ import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import com.google.common.base.Preconditions;
import javax.sql.DataSource;
import java.util.Properties;
@Configuration
@EnableTransactionManagement
@@ -43,7 +40,7 @@ public class PersistenceJPAConfig {
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
final LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(dataSource());
em.setPackagesToScan(new String[] { "com.baeldung.persistence.model" });
em.setPackagesToScan("com.baeldung.persistence.model");
final JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
em.setJpaVendorAdapter(vendorAdapter);
@@ -64,9 +61,9 @@ public class PersistenceJPAConfig {
}
@Bean
public PlatformTransactionManager transactionManager(final EntityManagerFactory emf) {
public PlatformTransactionManager transactionManager() {
final JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(emf);
transactionManager.setEntityManagerFactory(entityManagerFactory().getObject());
return transactionManager;
}
@@ -1,16 +1,15 @@
package com.baeldung.jpa.dao;
import java.io.Serializable;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import java.io.Serializable;
import java.util.List;
public abstract class AbstractJpaDAO<T extends Serializable> {
private Class<T> clazz;
@PersistenceContext
@PersistenceContext(unitName = "entityManagerFactory")
private EntityManager entityManager;
public final void setClazz(final Class<T> clazzToSet) {
@@ -21,7 +21,7 @@
<bean id="dataSource" class="org.apache.tomcat.dbcp.dbcp2.BasicDataSource">
<property name="driverClassName" value="${jdbc.driverClassName}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.eventGeneratedId}"/>
<property name="username" value="${jdbc.user}"/>
<property name="password" value="${jdbc.pass}"/>
</bean>
@@ -3,5 +3,5 @@ CREATE TABLE EMPLOYEE
ID int NOT NULL PRIMARY KEY,
FIRST_NAME varchar(255),
LAST_NAME varchar(255),
ADDRESS varchar(255),
ADDRESS varchar(255)
);
@@ -1,7 +1,7 @@
# jdbc.X
jdbc.driverClassName=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/spring_hibernate5_01?createDatabaseIfNotExist=true
jdbc.eventGeneratedId=tutorialuser
jdbc.url=jdbc:mysql://localhost:3306/spring_hibernate5_01?createDatabaseIfNotExist=true&serverTimezone=UTC
jdbc.user=tutorialuser
jdbc.pass=tutorialmy5ql
# hibernate.X
@@ -1,25 +1,6 @@
package com.baeldung.spring.data.persistence.jpaquery;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.function.Predicate;
import java.util.stream.Stream;
import javax.persistence.EntityManager;
import javax.persistence.Query;
import com.baeldung.spring.data.persistence.config.PersistenceConfig;
import com.baeldung.spring.data.persistence.jpaquery.UserRepository;
import com.baeldung.spring.data.persistence.model.User;
import org.junit.After;
import org.junit.Test;
@@ -36,6 +17,16 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.support.AnnotationConfigContextLoader;
import org.springframework.transaction.annotation.Transactional;
import javax.persistence.EntityManager;
import javax.persistence.Query;
import java.time.LocalDate;
import java.util.*;
import java.util.function.Predicate;
import java.util.stream.Stream;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.*;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = { PersistenceConfig.class }, loader = AnnotationConfigContextLoader.class)
@@ -283,7 +274,7 @@ public class UserRepositoryCommon {
userRepository.save(new User(USER_NAME_PETER, LocalDate.now(), USER_EMAIL2, ACTIVE_STATUS));
userRepository.save(new User("SAMPLE", LocalDate.now(), USER_EMAIL3, INACTIVE_STATUS));
List<User> usersSortByName = userRepository.findAll(new Sort(Sort.Direction.ASC, "name"));
List<User> usersSortByName = userRepository.findAll(Sort.by(Sort.Direction.ASC, "name"));
assertThat(usersSortByName.get(0)
.getName()).isEqualTo(USER_NAME_ADAM);
@@ -295,7 +286,7 @@ public class UserRepositoryCommon {
userRepository.save(new User(USER_NAME_PETER, LocalDate.now(), USER_EMAIL2, ACTIVE_STATUS));
userRepository.save(new User("SAMPLE", LocalDate.now(), USER_EMAIL3, INACTIVE_STATUS));
userRepository.findAll(new Sort(Sort.Direction.ASC, "name"));
userRepository.findAll(Sort.by(Sort.Direction.ASC, "name"));
List<User> usersSortByNameLength = userRepository.findAll(Sort.by("LENGTH(name)"));
@@ -459,6 +450,8 @@ public class UserRepositoryCommon {
userRepository.save(usr01);
userRepository.save(usr02);
System.out.println(TimeZone.getDefault());
List<User> users = userRepository.findUsersWithGmailAddress();
assertEquals(1, users.size());
assertEquals(usr02, users.get(0));