Merge branch 'master' into master

This commit is contained in:
Anshul Bansal 2019-04-17 10:59:36 +03:00 committed by GitHub
commit 7b84d6ce6f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
186 changed files with 2812 additions and 229 deletions

4
.gitignore vendored
View File

@ -19,6 +19,7 @@
.idea/ .idea/
*.iml *.iml
*.iws *.iws
out/
# Mac # Mac
.DS_Store .DS_Store
@ -27,6 +28,9 @@
log/ log/
target/ target/
# Gradle
.gradle/
spring-openid/src/main/resources/application.properties spring-openid/src/main/resources/application.properties
.recommenders/ .recommenders/
/spring-hibernate4/nbproject/ /spring-hibernate4/nbproject/

View File

@ -1,4 +1,4 @@
### Relevant Articles: ### Relevant Articles:
- [Deploy Spring Boot App to Azure](http://www.baeldung.com/spring-boot-azure) - [Deploy a Spring Boot App to Azure](http://www.baeldung.com/spring-boot-azure)

View File

@ -1,5 +1,5 @@
### Relevant Articles: ### Relevant Articles:
- [Blade - A Complete GuideBook](http://www.baeldung.com/blade) - [Blade A Complete Guidebook](http://www.baeldung.com/blade)
Run Integration Tests with `mvn integration-test` Run Integration Tests with `mvn integration-test`

View File

@ -2,4 +2,6 @@
## Relevant articles: ## Relevant articles:
- [String Matching in Groovy](http://www.baeldung.com/)
- [Groovy def Keyword] - [Groovy def Keyword]

View File

@ -96,6 +96,15 @@
</configuration> </configuration>
</execution> </execution>
</executions> </executions>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.20.1</version>
<configuration>
<useFile>false</useFile>
<includes>
<include>**/*Test.java</include>
<include>**/*Spec.java</include>
</includes>
</configuration>
</plugin> </plugin>
</plugins> </plugins>
</build> </build>

View File

@ -0,0 +1,44 @@
package com.baeldung.strings
import spock.lang.Specification
import java.util.regex.Pattern
class StringMatchingSpec extends Specification {
def "pattern operator example"() {
given: "a pattern"
def p = ~'foo'
expect:
p instanceof Pattern
and: "you can use slash strings to avoid escaping of blackslash"
def digitPattern = ~/\d*/
digitPattern.matcher('4711').matches()
}
def "match operator example"() {
expect:
'foobar' ==~ /.*oba.*/
and: "matching is strict"
!('foobar' ==~ /foo/)
}
def "find operator example"() {
when: "using the find operator"
def matcher = 'foo and bar, baz and buz' =~ /(\w+) and (\w+)/
then: "will find groups"
matcher.size() == 2
and: "can access groups using array"
matcher[0][0] == 'foo and bar'
matcher[1][2] == 'buz'
and: "you can use it as a predicate"
'foobarbaz' =~ /bar/
}
}

View File

@ -8,6 +8,8 @@
- [Types of Strings in Groovy](https://www.baeldung.com/groovy-strings) - [Types of Strings in Groovy](https://www.baeldung.com/groovy-strings)
- [A Quick Guide to Iterating a Map in Groovy](https://www.baeldung.com/groovy-map-iterating) - [A Quick Guide to Iterating a Map in Groovy](https://www.baeldung.com/groovy-map-iterating)
- [An Introduction to Traits in Groovy](https://www.baeldung.com/groovy-traits) - [An Introduction to Traits in Groovy](https://www.baeldung.com/groovy-traits)
- [Closures in Groovy](https://www.baeldung.com/groovy-closures)
- [Finding Elements in Collections in Groovy](https://www.baeldung.com/groovy-collections-find-elements)
- [Lists in Groovy](https://www.baeldung.com/groovy-lists) - [Lists in Groovy](https://www.baeldung.com/groovy-lists)
- [Converting a String to a Date in Groovy](https://www.baeldung.com/groovy-string-to-date) - [Converting a String to a Date in Groovy](https://www.baeldung.com/groovy-string-to-date)
- [Guide to I/O in Groovy](https://www.baeldung.com/groovy-io) - [Guide to I/O in Groovy](https://www.baeldung.com/groovy-io)

View File

@ -0,0 +1,44 @@
package com.baeldung.strings
import spock.lang.Specification
import java.util.regex.Pattern
class StringMatchingSpec extends Specification {
def "pattern operator example"() {
given: "a pattern"
def p = ~'foo'
expect:
p instanceof Pattern
and: "you can use slash strings to avoid escaping of blackslash"
def digitPattern = ~/\d*/
digitPattern.matcher('4711').matches()
}
def "match operator example"() {
expect:
'foobar' ==~ /.*oba.*/
and: "matching is strict"
!('foobar' ==~ /foo/)
}
def "find operator example"() {
when: "using the find operator"
def matcher = 'foo and bar, baz and buz' =~ /(\w+) and (\w+)/
then: "will find groups"
matcher.size() == 2
and: "can access groups using array"
matcher[0][0] == 'foo and bar'
matcher[1][2] == 'buz'
and: "you can use it as a predicate"
'foobarbaz' =~ /bar/
}
}

View File

@ -6,3 +6,4 @@
- [Java 11 Nest Based Access Control](https://www.baeldung.com/java-nest-based-access-control) - [Java 11 Nest Based Access Control](https://www.baeldung.com/java-nest-based-access-control)
- [Exploring the New HTTP Client in Java 9 and 11](https://www.baeldung.com/java-9-http-client) - [Exploring the New HTTP Client in Java 9 and 11](https://www.baeldung.com/java-9-http-client)
- [An Introduction to Epsilon GC: A No-Op Experimental Garbage Collector](https://www.baeldung.com/jvm-epsilon-gc-garbage-collector) - [An Introduction to Epsilon GC: A No-Op Experimental Garbage Collector](https://www.baeldung.com/jvm-epsilon-gc-garbage-collector)
- [Guide to jlink](https://www.baeldung.com/jlink)

View File

@ -3,7 +3,7 @@
## Core Java 8 Cookbooks and Examples ## Core Java 8 Cookbooks and Examples
### Relevant Articles: ### Relevant Articles:
- [Java 8 Collectors](http://www.baeldung.com/java-8-collectors) - [Guide to Java 8s Collectors](http://www.baeldung.com/java-8-collectors)
- [Functional Interfaces in Java 8](http://www.baeldung.com/java-8-functional-interfaces) - [Functional Interfaces in Java 8](http://www.baeldung.com/java-8-functional-interfaces)
- [Java 8 Powerful Comparison with Lambdas](http://www.baeldung.com/java-8-sort-lambda) - [Java 8 Powerful Comparison with Lambdas](http://www.baeldung.com/java-8-sort-lambda)
- [New Features in Java 8](http://www.baeldung.com/java-8-new-features) - [New Features in Java 8](http://www.baeldung.com/java-8-new-features)

View File

@ -5,26 +5,21 @@
[Java 9 New Features](http://www.baeldung.com/new-java-9) [Java 9 New Features](http://www.baeldung.com/new-java-9)
### Relevant Articles: ### Relevant Articles:
- [Java 9 Stream API Improvements](http://www.baeldung.com/java-9-stream-api)
- [Java 9 Convenience Factory Methods for Collections](http://www.baeldung.com/java-9-collections-factory-methods) - [Java 9 New Features](https://www.baeldung.com/new-java-9)
- [New Stream Collectors in Java 9](http://www.baeldung.com/java9-stream-collectors) - [New Stream Collectors in Java 9](http://www.baeldung.com/java9-stream-collectors)
- [Java 9 CompletableFuture API Improvements](http://www.baeldung.com/java-9-completablefuture)
- [Introduction to Java 9 StackWalking API](http://www.baeldung.com/java-9-stackwalking-api)
- [Introduction to Project Jigsaw](http://www.baeldung.com/project-jigsaw-java-modularity) - [Introduction to Project Jigsaw](http://www.baeldung.com/project-jigsaw-java-modularity)
- [Java 9 Optional API Additions](http://www.baeldung.com/java-9-optional) - [Java 9 Variable Handles Demystified](http://www.baeldung.com/java-variable-handles)
- [Java 9 Reactive Streams](http://www.baeldung.com/java-9-reactive-streams)
- [Java 9 java.util.Objects Additions](http://www.baeldung.com/java-9-objects-new)
- [Java 9 Variable Handles Demistyfied](http://www.baeldung.com/java-variable-handles)
- [Exploring the New HTTP Client in Java 9 and 11](http://www.baeldung.com/java-9-http-client) - [Exploring the New HTTP Client in Java 9 and 11](http://www.baeldung.com/java-9-http-client)
- [Method Handles in Java](http://www.baeldung.com/java-method-handles) - [Method Handles in Java](http://www.baeldung.com/java-method-handles)
- [Introduction to Chronicle Queue](http://www.baeldung.com/java-chronicle-queue) - [Introduction to Chronicle Queue](http://www.baeldung.com/java-chronicle-queue)
- [A Guide to Java 9 Modularity](http://www.baeldung.com/java-9-modularity)
- [Optional orElse Optional](http://www.baeldung.com/java-optional-or-else-optional) - [Optional orElse Optional](http://www.baeldung.com/java-optional-or-else-optional)
- [Java 9 java.lang.Module API](http://www.baeldung.com/java-9-module-api)
- [Iterate Through a Range of Dates in Java](https://www.baeldung.com/java-iterate-date-range) - [Iterate Through a Range of Dates in Java](https://www.baeldung.com/java-iterate-date-range)
- [Initialize a HashMap in Java](https://www.baeldung.com/java-initialize-hashmap) - [Initialize a HashMap in Java](https://www.baeldung.com/java-initialize-hashmap)
- [Java 9 Platform Logging API](https://www.baeldung.com/java-9-logging-api)
- [Immutable Set in Java](https://www.baeldung.com/java-immutable-set) - [Immutable Set in Java](https://www.baeldung.com/java-immutable-set)
- [Multi-Release Jar Files](https://www.baeldung.com/java-multi-release-jar) - [Multi-Release Jar Files](https://www.baeldung.com/java-multi-release-jar)
- [Ahead of Time Compilation (AoT)](https://www.baeldung.com/ahead-of-time-compilation) - [Ahead of Time Compilation (AoT)](https://www.baeldung.com/ahead-of-time-compilation)
- [Java 9 Process API Improvements](https://www.baeldung.com/java-9-process-api)
- [Guide to java.lang.Process API](https://www.baeldung.com/java-process-api)

View File

@ -3,7 +3,7 @@
## Core Java Collections Cookbooks and Examples ## Core Java Collections Cookbooks and Examples
### Relevant Articles: ### Relevant Articles:
- [Java - Combine Multiple Collections](http://www.baeldung.com/java-combine-multiple-collections) - [Java Combine Multiple Collections](http://www.baeldung.com/java-combine-multiple-collections)
- [HashSet and TreeSet Comparison](http://www.baeldung.com/java-hashset-vs-treeset) - [HashSet and TreeSet Comparison](http://www.baeldung.com/java-hashset-vs-treeset)
- [Collect a Java Stream to an Immutable Collection](http://www.baeldung.com/java-stream-immutable-collection) - [Collect a Java Stream to an Immutable Collection](http://www.baeldung.com/java-stream-immutable-collection)
- [Introduction to the Java ArrayDeque](http://www.baeldung.com/java-array-deque) - [Introduction to the Java ArrayDeque](http://www.baeldung.com/java-array-deque)

View File

@ -12,7 +12,7 @@
- [Guide to the Java Phaser](http://www.baeldung.com/java-phaser) - [Guide to the Java Phaser](http://www.baeldung.com/java-phaser)
- [An Introduction to Atomic Variables in Java](http://www.baeldung.com/java-atomic-variables) - [An Introduction to Atomic Variables in Java](http://www.baeldung.com/java-atomic-variables)
- [CyclicBarrier in Java](http://www.baeldung.com/java-cyclic-barrier) - [CyclicBarrier in Java](http://www.baeldung.com/java-cyclic-barrier)
- [Guide to Volatile Keyword in Java](http://www.baeldung.com/java-volatile) - [Guide to the Volatile Keyword in Java](http://www.baeldung.com/java-volatile)
- [Semaphores in Java](http://www.baeldung.com/java-semaphore) - [Semaphores in Java](http://www.baeldung.com/java-semaphore)
- [Daemon Threads in Java](http://www.baeldung.com/java-daemon-thread) - [Daemon Threads in Java](http://www.baeldung.com/java-daemon-thread)
- [Priority-based Job Scheduling in Java](http://www.baeldung.com/java-priority-job-schedule) - [Priority-based Job Scheduling in Java](http://www.baeldung.com/java-priority-job-schedule)
@ -20,6 +20,6 @@
- [Print Even and Odd Numbers Using 2 Threads](https://www.baeldung.com/java-even-odd-numbers-with-2-threads) - [Print Even and Odd Numbers Using 2 Threads](https://www.baeldung.com/java-even-odd-numbers-with-2-threads)
- [Java CyclicBarrier vs CountDownLatch](https://www.baeldung.com/java-cyclicbarrier-countdownlatch) - [Java CyclicBarrier vs CountDownLatch](https://www.baeldung.com/java-cyclicbarrier-countdownlatch)
- [Guide to the Fork/Join Framework in Java](http://www.baeldung.com/java-fork-join) - [Guide to the Fork/Join Framework in Java](http://www.baeldung.com/java-fork-join)
- [A Guide to ThreadLocalRandom in Java](http://www.baeldung.com/java-thread-local-random) - [Guide to ThreadLocalRandom in Java](http://www.baeldung.com/java-thread-local-random)
- [The Thread.join() Method in Java](http://www.baeldung.com/java-thread-join) - [The Thread.join() Method in Java](http://www.baeldung.com/java-thread-join)
- [Passing Parameters to Java Threads](https://www.baeldung.com/java-thread-parameters) - [Passing Parameters to Java Threads](https://www.baeldung.com/java-thread-parameters)

View File

@ -7,13 +7,13 @@
- [A Guide to the Java ExecutorService](http://www.baeldung.com/java-executor-service-tutorial) - [A Guide to the Java ExecutorService](http://www.baeldung.com/java-executor-service-tutorial)
- [Guide to java.util.concurrent.Future](http://www.baeldung.com/java-future) - [Guide to java.util.concurrent.Future](http://www.baeldung.com/java-future)
- [Difference Between Wait and Sleep in Java](http://www.baeldung.com/java-wait-and-sleep) - [Difference Between Wait and Sleep in Java](http://www.baeldung.com/java-wait-and-sleep)
- [Guide to Synchronized Keyword in Java](http://www.baeldung.com/java-synchronized) - [Guide to the Synchronized Keyword in Java](http://www.baeldung.com/java-synchronized)
- [Overview of the java.util.concurrent](http://www.baeldung.com/java-util-concurrent) - [Overview of the java.util.concurrent](http://www.baeldung.com/java-util-concurrent)
- [Implementing a Runnable vs Extending a Thread](http://www.baeldung.com/java-runnable-vs-extending-thread) - [Implementing a Runnable vs Extending a Thread](http://www.baeldung.com/java-runnable-vs-extending-thread)
- [How to Kill a Java Thread](http://www.baeldung.com/java-thread-stop) - [How to Kill a Java Thread](http://www.baeldung.com/java-thread-stop)
- [ExecutorService - Waiting for Threads to Finish](http://www.baeldung.com/java-executor-wait-for-threads) - [ExecutorService Waiting for Threads to Finish](http://www.baeldung.com/java-executor-wait-for-threads)
- [wait and notify() Methods in Java](http://www.baeldung.com/java-wait-notify) - [wait and notify() Methods in Java](http://www.baeldung.com/java-wait-notify)
- [Life Cycle of a Thread in Java](http://www.baeldung.com/java-thread-lifecycle) - [Life Cycle of a Thread in Java](http://www.baeldung.com/java-thread-lifecycle)
- [Runnable vs. Callable in Java](http://www.baeldung.com/java-runnable-callable) - [Runnable vs. Callable in Java](http://www.baeldung.com/java-runnable-callable)
- [What is Thread-Safety and How to Achieve it](https://www.baeldung.com/java-thread-safety) - [What is Thread-Safety and How to Achieve it?](https://www.baeldung.com/java-thread-safety)
- [How to Start a Thread in Java](https://www.baeldung.com/java-start-thread) - [How to Start a Thread in Java](https://www.baeldung.com/java-start-thread)

View File

@ -6,7 +6,7 @@
- [How to Read a Large File Efficiently with Java](http://www.baeldung.com/java-read-lines-large-file) - [How to Read a Large File Efficiently with Java](http://www.baeldung.com/java-read-lines-large-file)
- [Java InputStream to String](http://www.baeldung.com/convert-input-stream-to-string) - [Java InputStream to String](http://www.baeldung.com/convert-input-stream-to-string)
- [Java Write to File](http://www.baeldung.com/java-write-to-file) - [Java Write to File](http://www.baeldung.com/java-write-to-file)
- [Java - Convert File to InputStream](http://www.baeldung.com/convert-file-to-input-stream) - [Java Convert File to InputStream](http://www.baeldung.com/convert-file-to-input-stream)
- [Java Scanner](http://www.baeldung.com/java-scanner) - [Java Scanner](http://www.baeldung.com/java-scanner)
- [Java Byte Array to Writer](http://www.baeldung.com/java-convert-byte-array-to-writer) - [Java Byte Array to Writer](http://www.baeldung.com/java-convert-byte-array-to-writer)
- [Java Directory Size](http://www.baeldung.com/java-folder-size) - [Java Directory Size](http://www.baeldung.com/java-folder-size)
@ -14,7 +14,7 @@
- [File Size in Java](http://www.baeldung.com/java-file-size) - [File Size in Java](http://www.baeldung.com/java-file-size)
- [Comparing getPath(), getAbsolutePath(), and getCanonicalPath() in Java](http://www.baeldung.com/java-path) - [Comparing getPath(), getAbsolutePath(), and getCanonicalPath() in Java](http://www.baeldung.com/java-path)
- [Using Java MappedByteBuffer](http://www.baeldung.com/java-mapped-byte-buffer) - [Using Java MappedByteBuffer](http://www.baeldung.com/java-mapped-byte-buffer)
- [Copy a File with Java](http://www.baeldung.com/java-copy-file) - [How to Copy a File with Java](http://www.baeldung.com/java-copy-file)
- [Java Append Data to a File](http://www.baeldung.com/java-append-to-file) - [Java Append Data to a File](http://www.baeldung.com/java-append-to-file)
- [FileNotFoundException in Java](http://www.baeldung.com/java-filenotfound-exception) - [FileNotFoundException in Java](http://www.baeldung.com/java-filenotfound-exception)
- [How to Read a File in Java](http://www.baeldung.com/reading-file-in-java) - [How to Read a File in Java](http://www.baeldung.com/reading-file-in-java)

View File

@ -3,4 +3,4 @@
## Core Java JVM Cookbooks and Examples ## Core Java JVM Cookbooks and Examples
### Relevant Articles: ### Relevant Articles:
- [Method Inlining in the JVM](http://www.baeldung.com/method-inlining-in-the-jvm/) - [Method Inlining in the JVM](https://www.baeldung.com/jvm-method-inlining)

19
core-java-lambdas/pom.xml Normal file
View File

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>core-java-lambdas</artifactId>
<version>0.1.0-SNAPSHOT</version>
<name>core-java</name>
<packaging>jar</packaging>
<parent>
<groupId>com.baeldung</groupId>
<artifactId>parent-java</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../parent-java</relativePath>
</parent>
</project>

View File

@ -0,0 +1,88 @@
package com.baeldung.lambdas;
import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.function.Supplier;
import java.util.stream.IntStream;
/**
* Class with examples about working with capturing lambdas.
*/
public class LambdaVariables {
private volatile boolean run = true;
private int start = 0;
private ExecutorService executor = Executors.newFixedThreadPool(3);
public static void main(String[] args) {
new LambdaVariables().localVariableMultithreading();
}
Supplier<Integer> incrementer(int start) {
return () -> start; // can't modify start parameter inside the lambda
}
Supplier<Integer> incrementer() {
return () -> start++;
}
public void localVariableMultithreading() {
boolean run = true;
executor.execute(() -> {
while (run) {
// do operation
}
});
// commented because it doesn't compile, it's just an example of non-final local variables in lambdas
// run = false;
}
public void instanceVariableMultithreading() {
executor.execute(() -> {
while (run) {
// do operation
}
});
run = false;
}
/**
* WARNING: always avoid this workaround!!
*/
public void workaroundSingleThread() {
int[] holder = new int[] { 2 };
IntStream sums = IntStream
.of(1, 2, 3)
.map(val -> val + holder[0]);
holder[0] = 0;
System.out.println(sums.sum());
}
/**
* WARNING: always avoid this workaround!!
*/
public void workaroundMultithreading() {
int[] holder = new int[] { 2 };
Runnable runnable = () -> System.out.println(IntStream
.of(1, 2, 3)
.map(val -> val + holder[0])
.sum());
new Thread(runnable).start();
// simulating some processing
try {
Thread.sleep(new Random().nextInt(3) * 1000L);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
holder[0] = 0;
}
}

View File

@ -0,0 +1,38 @@
package com.baeldung.generics;
import java.io.Serializable;
public class Entry {
private String data;
private int rank;
// non-generic constructor
public Entry(String data, int rank) {
this.data = data;
this.rank = rank;
}
// generic constructor
public <E extends Rankable & Serializable> Entry(E element) {
this.data = element.toString();
this.rank = element.getRank();
}
// getters and setters
public String getData() {
return data;
}
public void setData(String data) {
this.data = data;
}
public int getRank() {
return rank;
}
public void setRank(int rank) {
this.rank = rank;
}
}

View File

@ -0,0 +1,53 @@
package com.baeldung.generics;
import java.io.Serializable;
import java.util.Optional;
public class GenericEntry<T> {
private T data;
private int rank;
// non-generic constructor
public GenericEntry(int rank) {
this.rank = rank;
}
// generic constructor
public GenericEntry(T data, int rank) {
this.data = data;
this.rank = rank;
}
// generic constructor with different type
public <E extends Rankable & Serializable> GenericEntry(E element) {
this.data = (T) element;
this.rank = element.getRank();
}
// generic constructor with different type and wild card
public GenericEntry(Optional<? extends Rankable> optional) {
if (optional.isPresent()) {
this.data = (T) optional.get();
this.rank = optional.get()
.getRank();
}
}
// getters and setters
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
public int getRank() {
return rank;
}
public void setRank(int rank) {
this.rank = rank;
}
}

View File

@ -0,0 +1,34 @@
package com.baeldung.generics;
public class MapEntry<K, V> {
private K key;
private V value;
public MapEntry() {
super();
}
// generic constructor with two parameters
public MapEntry(K key, V value) {
this.key = key;
this.value = value;
}
// getters and setters
public K getKey() {
return key;
}
public void setKey(K key) {
this.key = key;
}
public V getValue() {
return value;
}
public void setValue(V value) {
this.value = value;
}
}

View File

@ -0,0 +1,50 @@
package com.baeldung.generics;
import java.io.Serializable;
public class Product implements Rankable, Serializable {
private String name;
private double price;
private int sales;
public Product(String name, double price) {
this.name = name;
this.price = price;
}
@Override
public int getRank() {
return sales;
}
@Override
public String toString() {
return "Product [name=" + name + ", price=" + price + ", sales=" + sales + "]";
}
// getters and setters
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public int getSales() {
return sales;
}
public void setSales(int sales) {
this.sales = sales;
}
}

View File

@ -0,0 +1,5 @@
package com.baeldung.generics;
public interface Rankable {
public int getRank();
}

View File

@ -0,0 +1,76 @@
package com.baeldung.generics;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import java.io.Serializable;
import java.util.Optional;
import org.junit.Test;
public class GenericConstructorUnitTest {
@Test
public void givenNonGenericConstructor_whenCreateNonGenericEntry_thenOK() {
Entry entry = new Entry("sample", 1);
assertEquals("sample", entry.getData());
assertEquals(1, entry.getRank());
}
@Test
public void givenGenericConstructor_whenCreateNonGenericEntry_thenOK() {
Product product = new Product("milk", 2.5);
product.setSales(30);
Entry entry = new Entry(product);
assertEquals(product.toString(), entry.getData());
assertEquals(30, entry.getRank());
}
@Test
public void givenNonGenericConstructor_whenCreateGenericEntry_thenOK() {
GenericEntry<String> entry = new GenericEntry<String>(1);
assertNull(entry.getData());
assertEquals(1, entry.getRank());
}
@Test
public void givenGenericConstructor_whenCreateGenericEntry_thenOK() {
GenericEntry<String> entry = new GenericEntry<String>("sample", 1);
assertEquals("sample", entry.getData());
assertEquals(1, entry.getRank());
}
@Test
public void givenGenericConstructorWithDifferentType_whenCreateGenericEntry_thenOK() {
Product product = new Product("milk", 2.5);
product.setSales(30);
GenericEntry<Serializable> entry = new GenericEntry<Serializable>(product);
assertEquals(product, entry.getData());
assertEquals(30, entry.getRank());
}
@Test
public void givenGenericConstructorWithWildCard_whenCreateGenericEntry_thenOK() {
Product product = new Product("milk", 2.5);
product.setSales(30);
Optional<Product> optional = Optional.of(product);
GenericEntry<Serializable> entry = new GenericEntry<Serializable>(optional);
assertEquals(product, entry.getData());
assertEquals(30, entry.getRank());
}
@Test
public void givenGenericConstructor_whenCreateGenericEntryWithTwoTypes_thenOK() {
MapEntry<String, Integer> entry = new MapEntry<String, Integer>("sample", 1);
assertEquals("sample", entry.getKey());
assertEquals(1, entry.getValue()
.intValue());
}
}

View File

@ -10,7 +10,7 @@
- [How to Make a Deep Copy of an Object in Java](http://www.baeldung.com/java-deep-copy) - [How to Make a Deep Copy of an Object in Java](http://www.baeldung.com/java-deep-copy)
- [Guide to Inheritance in Java](http://www.baeldung.com/java-inheritance) - [Guide to Inheritance in Java](http://www.baeldung.com/java-inheritance)
- [Object Type Casting in Java](http://www.baeldung.com/java-type-casting) - [Object Type Casting in Java](http://www.baeldung.com/java-type-casting)
- [The "final" Keyword in Java](http://www.baeldung.com/java-final) - [The “final” Keyword in Java](http://www.baeldung.com/java-final)
- [Type Erasure in Java Explained](http://www.baeldung.com/java-type-erasure) - [Type Erasure in Java Explained](http://www.baeldung.com/java-type-erasure)
- [Pass-By-Value as a Parameter Passing Mechanism in Java](http://www.baeldung.com/java-pass-by-value-or-pass-by-reference) - [Pass-By-Value as a Parameter Passing Mechanism in Java](http://www.baeldung.com/java-pass-by-value-or-pass-by-reference)
- [Variable and Method Hiding in Java](http://www.baeldung.com/java-variable-method-hiding) - [Variable and Method Hiding in Java](http://www.baeldung.com/java-variable-method-hiding)

View File

@ -12,7 +12,7 @@
- [Dynamic Proxies in Java](http://www.baeldung.com/java-dynamic-proxies) - [Dynamic Proxies in Java](http://www.baeldung.com/java-dynamic-proxies)
- [Java Double Brace Initialization](http://www.baeldung.com/java-double-brace-initialization) - [Java Double Brace Initialization](http://www.baeldung.com/java-double-brace-initialization)
- [Guide to the Diamond Operator in Java](http://www.baeldung.com/java-diamond-operator) - [Guide to the Diamond Operator in Java](http://www.baeldung.com/java-diamond-operator)
- [Quick Example - Comparator vs Comparable in Java](http://www.baeldung.com/java-comparator-comparable) - [Comparator and Comparable in Java](http://www.baeldung.com/java-comparator-comparable)
- [The Java continue and break Keywords](http://www.baeldung.com/java-continue-and-break) - [The Java continue and break Keywords](http://www.baeldung.com/java-continue-and-break)
- [Nested Classes in Java](http://www.baeldung.com/java-nested-classes) - [Nested Classes in Java](http://www.baeldung.com/java-nested-classes)
- [A Guide to Inner Interfaces in Java](http://www.baeldung.com/java-inner-interfaces) - [A Guide to Inner Interfaces in Java](http://www.baeldung.com/java-inner-interfaces)

View File

@ -14,4 +14,5 @@
- [A Guide to Java Sockets](http://www.baeldung.com/a-guide-to-java-sockets) - [A Guide to Java Sockets](http://www.baeldung.com/a-guide-to-java-sockets)
- [Guide to Java URL Encoding/Decoding](http://www.baeldung.com/java-url-encoding-decoding) - [Guide to Java URL Encoding/Decoding](http://www.baeldung.com/java-url-encoding-decoding)
- [Do a Simple HTTP Request in Java](http://www.baeldung.com/java-http-request) - [Do a Simple HTTP Request in Java](http://www.baeldung.com/java-http-request)
- [Difference between URL and URI](http://www.baeldung.com/java-url-vs-uri) - [Difference between URL and URI](http://www.baeldung.com/java-url-vs-uri)
- [Read an InputStream using the Java Server Socket](https://www.baeldung.com/java-inputstream-server-socket)

View File

@ -29,7 +29,7 @@
- [What is the serialVersionUID?](http://www.baeldung.com/java-serial-version-uid) - [What is the serialVersionUID?](http://www.baeldung.com/java-serial-version-uid)
- [A Guide to the ResourceBundle](http://www.baeldung.com/java-resourcebundle) - [A Guide to the ResourceBundle](http://www.baeldung.com/java-resourcebundle)
- [Class Loaders in Java](http://www.baeldung.com/java-classloaders) - [Class Loaders in Java](http://www.baeldung.com/java-classloaders)
- [Guide to Java Clock Class](http://www.baeldung.com/java-clock) - [Guide to the Java Clock Class](http://www.baeldung.com/java-clock)
- [Importance of Main Manifest Attribute in a Self-Executing JAR](http://www.baeldung.com/java-jar-executable-manifest-main-class) - [Importance of Main Manifest Attribute in a Self-Executing JAR](http://www.baeldung.com/java-jar-executable-manifest-main-class)
- [Java Global Exception Handler](http://www.baeldung.com/java-global-exception-handler) - [Java Global Exception Handler](http://www.baeldung.com/java-global-exception-handler)
- [How to Get the Size of an Object in Java](http://www.baeldung.com/java-size-of-object) - [How to Get the Size of an Object in Java](http://www.baeldung.com/java-size-of-object)

View File

@ -2,5 +2,8 @@
- [Void Type in Kotlin](https://www.baeldung.com/kotlin-void-type) - [Void Type in Kotlin](https://www.baeldung.com/kotlin-void-type)
- [How to use Kotlin Range Expressions](https://www.baeldung.com/kotlin-ranges) - [How to use Kotlin Range Expressions](https://www.baeldung.com/kotlin-ranges)
- [Creating a Kotlin Range Iterator on a Custom Object](https://www.baeldung.com/kotlin-custom-range-iterator)
- [Kotlin Scope Functions](https://www.baeldung.com/kotlin-scope-functions)
- [Kotlin Annotations](https://www.baeldung.com/kotlin-annotations)
- [Split a List into Parts in Kotlin](https://www.baeldung.com/kotlin-split-list-into-parts) - [Split a List into Parts in Kotlin](https://www.baeldung.com/kotlin-split-list-into-parts)
- [String Comparison in Kotlin](https://www.baeldung.com/kotlin-string-comparison) - [String Comparison in Kotlin](https://www.baeldung.com/kotlin-string-comparison)

11
core-kotlin-io/.gitignore vendored Normal file
View File

@ -0,0 +1,11 @@
/bin/
#ignore gradle
.gradle/
#ignore build and generated files
build/
node/
target/
out/

3
core-kotlin-io/README.md Normal file
View File

@ -0,0 +1,3 @@
## Relevant articles:
- [InputStream to String in Kotlin](https://www.baeldung.com/kotlin-inputstream-to-string)

78
core-kotlin-io/pom.xml Normal file
View File

@ -0,0 +1,78 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>core-kotlin-io</artifactId>
<name>core-kotlin-io</name>
<packaging>jar</packaging>
<parent>
<groupId>com.baeldung</groupId>
<artifactId>parent-kotlin</artifactId>
<version>1.0.0-SNAPSHOT</version>
<relativePath>../parent-kotlin</relativePath>
</parent>
<dependencies>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib-jdk8</artifactId>
<version>${kotlin.version}</version>
</dependency>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-runner</artifactId>
<version>${junit.platform.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.jetbrains.kotlin</groupId>
<artifactId>kotlin-test</artifactId>
<version>${kotlin.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-plugin</artifactId>
<version>${kotlin.version}</version>
<executions>
<execution>
<id>compile</id>
<phase>compile</phase>
<goals>
<goal>compile</goal>
</goals>
</execution>
<execution>
<id>test-compile</id>
<phase>test-compile</phase>
<goals>
<goal>test-compile</goal>
</goals>
</execution>
</executions>
<configuration>
<jvmTarget>1.8</jvmTarget>
</configuration>
</plugin>
</plugins>
</build>
<properties>
<kotlin.version>1.2.71</kotlin.version>
<junit.platform.version>1.1.1</junit.platform.version>
<junit.vintage.version>5.2.0</junit.vintage.version>
<assertj.version>3.10.0</assertj.version>
</properties>
</project>

View File

@ -0,0 +1,18 @@
package com.baeldung.inputstream
import java.io.InputStream
fun InputStream.readUpToChar(stopChar: Char): String {
val stringBuilder = StringBuilder()
var currentChar = this.read().toChar()
while (currentChar != stopChar) {
stringBuilder.append(currentChar)
currentChar = this.read().toChar()
if (this.available() <= 0) {
stringBuilder.append(currentChar)
break
}
}
return stringBuilder.toString()
}

View File

@ -0,0 +1,71 @@
package com.baeldung.inputstream
import kotlinx.io.core.use
import org.junit.Test
import java.io.BufferedReader
import java.io.File
import kotlin.test.assertEquals
class InputStreamToStringTest {
private val fileName = "src/test/resources/inputstream2string.txt"
private val fileFullContent = "Computer programming can be a hassle\r\n" +
"It's like trying to take a defended castle"
@Test
fun whenReadFileWithBufferedReader_thenFullFileContentIsReadAsString() {
val file = File(fileName)
val inputStream = file.inputStream()
val content = inputStream.bufferedReader().use(BufferedReader::readText)
assertEquals(fileFullContent, content)
}
@Test
fun whenReadFileWithBufferedReaderReadText_thenFullFileContentIsReadAsString() {
val file = File(fileName)
val inputStream = file.inputStream()
val reader = BufferedReader(inputStream.reader())
var content: String
try {
content = reader.readText()
} finally {
reader.close()
}
assertEquals(fileFullContent, content)
}
@Test
fun whenReadFileWithBufferedReaderManually_thenFullFileContentIsReadAsString() {
val file = File(fileName)
val inputStream = file.inputStream()
val reader = BufferedReader(inputStream.reader())
val content = StringBuilder()
try {
var line = reader.readLine()
while (line != null) {
content.append(line)
line = reader.readLine()
}
} finally {
reader.close()
}
assertEquals(fileFullContent.replace("\r\n", ""), content.toString())
}
@Test
fun whenReadFileUpToStopChar_thenPartBeforeStopCharIsReadAsString() {
val file = File(fileName)
val inputStream = file.inputStream()
val content = inputStream.use { it.readUpToChar(' ') }
assertEquals("Computer", content)
}
@Test
fun whenReadFileWithoutContainingStopChar_thenFullFileContentIsReadAsString() {
val file = File(fileName)
val inputStream = file.inputStream()
val content = inputStream.use { it.readUpToChar('-') }
assertEquals(fileFullContent, content)
}
}

View File

@ -0,0 +1,2 @@
Computer programming can be a hassle
It's like trying to take a defended castle

View File

@ -1,7 +1,7 @@
## Relevant articles: ## Relevant articles:
- [Introduction to the Kotlin Language](http://www.baeldung.com/kotlin) - [Introduction to the Kotlin Language](http://www.baeldung.com/kotlin)
- [A guide to the “when{}” block in Kotlin](http://www.baeldung.com/kotlin-when) - [Guide to the “when{}” Block in Kotlin](http://www.baeldung.com/kotlin-when)
- [Comprehensive Guide to Null Safety in Kotlin](http://www.baeldung.com/kotlin-null-safety) - [Comprehensive Guide to Null Safety in Kotlin](http://www.baeldung.com/kotlin-null-safety)
- [Kotlin Java Interoperability](http://www.baeldung.com/kotlin-java-interoperability) - [Kotlin Java Interoperability](http://www.baeldung.com/kotlin-java-interoperability)
- [Difference Between “==” and “===” operators in Kotlin](http://www.baeldung.com/kotlin-equality-operators) - [Difference Between “==” and “===” operators in Kotlin](http://www.baeldung.com/kotlin-equality-operators)

View File

@ -3,7 +3,7 @@
### Relevant Articles: ### Relevant Articles:
- [Introduction to Couchbase SDK for Java](http://www.baeldung.com/java-couchbase-sdk) - [Introduction to Couchbase SDK for Java](http://www.baeldung.com/java-couchbase-sdk)
- [Using Couchbase in a Spring Application](http://www.baeldung.com/couchbase-sdk-spring) - [Using Couchbase in a Spring Application](http://www.baeldung.com/couchbase-sdk-spring)
- [Asynchronous Batch Opereations in Couchbase](http://www.baeldung.com/async-batch-operations-in-couchbase) - [Asynchronous Batch Operations in Couchbase](http://www.baeldung.com/async-batch-operations-in-couchbase)
- [Querying Couchbase with MapReduce Views](http://www.baeldung.com/couchbase-query-mapreduce-view) - [Querying Couchbase with MapReduce Views](http://www.baeldung.com/couchbase-query-mapreduce-view)
- [Querying Couchbase with N1QL](http://www.baeldung.com/n1ql-couchbase) - [Querying Couchbase with N1QL](http://www.baeldung.com/n1ql-couchbase)

View File

@ -11,6 +11,6 @@
- [Convert JSON to a Map Using Gson](https://www.baeldung.com/gson-json-to-map) - [Convert JSON to a Map Using Gson](https://www.baeldung.com/gson-json-to-map)
- [Working with Primitive Values in Gson](https://www.baeldung.com/java-gson-primitives) - [Working with Primitive Values in Gson](https://www.baeldung.com/java-gson-primitives)
- [Convert String to JsonObject with Gson](https://www.baeldung.com/gson-string-to-jsonobject) - [Convert String to JsonObject with Gson](https://www.baeldung.com/gson-string-to-jsonobject)
- [Mapping Multiple JSON Fields to One Java Field](https://www.baeldung.com/json-multiple-fields-single-java-field) - [Mapping Multiple JSON Fields to a Single Java Field](https://www.baeldung.com/json-multiple-fields-single-java-field)
- [Serializing and Deserializing a List with Gson](https://www.baeldung.com/gson-list) - [Serializing and Deserializing a List with Gson](https://www.baeldung.com/gson-list)

View File

@ -1,4 +1,4 @@
### Relevant articles: ### Relevant articles:
- [New Stream, Comparator and Collector Functionality in Guava 21](http://www.baeldung.com/guava-21-new) - [New Stream, Comparator and Collector in Guava 21](http://www.baeldung.com/guava-21-new)
- [New in Guava 21 common.util.concurrent](http://www.baeldung.com/guava-21-util-concurrent) - [New in Guava 21 common.util.concurrent](http://www.baeldung.com/guava-21-util-concurrent)
- [Zipping Collections in Java](http://www.baeldung.com/java-collections-zip) - [Zipping Collections in Java](http://www.baeldung.com/java-collections-zip)

View File

@ -9,7 +9,7 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring
- [HttpClient 4 Send Custom Cookie](http://www.baeldung.com/httpclient-4-cookies) - [HttpClient 4 Send Custom Cookie](http://www.baeldung.com/httpclient-4-cookies)
- [HttpClient 4 Get the Status Code](http://www.baeldung.com/httpclient-status-code) - [HttpClient 4 Get the Status Code](http://www.baeldung.com/httpclient-status-code)
- [HttpClient 4 Cancel / Abort Request](http://www.baeldung.com/httpclient-cancel-request) - [HttpClient 4 Cancel Request](http://www.baeldung.com/httpclient-cancel-request)
- [HttpClient 4 Cookbook](http://www.baeldung.com/httpclient4) - [HttpClient 4 Cookbook](http://www.baeldung.com/httpclient4)
- [Unshorten URLs with HttpClient](http://www.baeldung.com/unshorten-url-httpclient) - [Unshorten URLs with HttpClient](http://www.baeldung.com/unshorten-url-httpclient)
- [HttpClient 4 Follow Redirects for POST](http://www.baeldung.com/httpclient-redirect-on-http-post) - [HttpClient 4 Follow Redirects for POST](http://www.baeldung.com/httpclient-redirect-on-http-post)

View File

@ -16,7 +16,7 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring
- [Jackson Bidirectional Relationships](http://www.baeldung.com/jackson-bidirectional-relationships-and-infinite-recursion) - [Jackson Bidirectional Relationships](http://www.baeldung.com/jackson-bidirectional-relationships-and-infinite-recursion)
- [Jackson JSON Tutorial](http://www.baeldung.com/jackson) - [Jackson JSON Tutorial](http://www.baeldung.com/jackson)
- [Jackson Working with Maps and nulls](http://www.baeldung.com/jackson-map-null-values-or-null-key) - [Jackson Working with Maps and nulls](http://www.baeldung.com/jackson-map-null-values-or-null-key)
- [Jackson Decide What Fields Get Serialized/Deserializaed](http://www.baeldung.com/jackson-field-serializable-deserializable-or-not) - [Jackson Decide What Fields Get Serialized/Deserialized](http://www.baeldung.com/jackson-field-serializable-deserializable-or-not)
- [Jackson Annotation Examples](http://www.baeldung.com/jackson-annotations) - [Jackson Annotation Examples](http://www.baeldung.com/jackson-annotations)
- [Working with Tree Model Nodes in Jackson](http://www.baeldung.com/jackson-json-node-tree-model) - [Working with Tree Model Nodes in Jackson](http://www.baeldung.com/jackson-json-node-tree-model)
- [Jackson vs Gson](http://www.baeldung.com/jackson-vs-gson) - [Jackson vs Gson](http://www.baeldung.com/jackson-vs-gson)

View File

@ -0,0 +1,2 @@
## Relevant Articles:
- [Map of Primitives in Java](https://www.baeldung.com/java-map-primitives)

2
java-dates-2/README.md Normal file
View File

@ -0,0 +1,2 @@
## Relevant Articles:
- [Converting Between LocalDate and XMLGregorianCalendar](https://www.baeldung.com/java-localdate-to-xmlgregoriancalendar)

View File

@ -8,7 +8,7 @@
- [Java 8 and Infinite Streams](http://www.baeldung.com/java-inifinite-streams) - [Java 8 and Infinite Streams](http://www.baeldung.com/java-inifinite-streams)
- [Java 8 Stream findFirst() vs. findAny()](http://www.baeldung.com/java-stream-findfirst-vs-findany) - [Java 8 Stream findFirst() vs. findAny()](http://www.baeldung.com/java-stream-findfirst-vs-findany)
- [How to Get the Last Element of a Stream in Java?](http://www.baeldung.com/java-stream-last-element) - [How to Get the Last Element of a Stream in Java?](http://www.baeldung.com/java-stream-last-element)
- [Stream has already been operated upon or closed” Exception in Java](http://www.baeldung.com/java-stream-operated-upon-or-closed-exception) - [Stream has already been operated upon or closed” Exception in Java](http://www.baeldung.com/java-stream-operated-upon-or-closed-exception)
- [Iterable to Stream in Java](http://www.baeldung.com/java-iterable-to-stream) - [Iterable to Stream in Java](http://www.baeldung.com/java-iterable-to-stream)
- [How to Iterate Over a Stream With Indices](http://www.baeldung.com/java-stream-indices) - [How to Iterate Over a Stream With Indices](http://www.baeldung.com/java-stream-indices)
- [Primitive Type Streams in Java 8](http://www.baeldung.com/java-8-primitive-streams) - [Primitive Type Streams in Java 8](http://www.baeldung.com/java-8-primitive-streams)

View File

@ -10,3 +10,5 @@
- [Introduction to Arrow in Kotlin](https://www.baeldung.com/kotlin-arrow) - [Introduction to Arrow in Kotlin](https://www.baeldung.com/kotlin-arrow)
- [Kotlin with Ktor](https://www.baeldung.com/kotlin-ktor) - [Kotlin with Ktor](https://www.baeldung.com/kotlin-ktor)
- [REST API With Kotlin and Kovert](https://www.baeldung.com/kotlin-kovert) - [REST API With Kotlin and Kovert](https://www.baeldung.com/kotlin-kovert)
- [MockK: A Mocking Library for Kotlin](https://www.baeldung.com/kotlin-mockk)
- [Kotlin Immutable Collections](https://www.baeldung.com/kotlin-immutable-collections)

View File

@ -32,6 +32,12 @@
<version>${scribejava.version}</version> <version>${scribejava.version}</version>
</dependency> </dependency>
<dependency>
<groupId>com.google.crypto.tink</groupId>
<artifactId>tink</artifactId>
<version>${tink.version}</version>
</dependency>
<dependency> <dependency>
<groupId>junit</groupId> <groupId>junit</groupId>
<artifactId>junit</artifactId> <artifactId>junit</artifactId>
@ -55,6 +61,7 @@
<scribejava.version>5.6.0</scribejava.version> <scribejava.version>5.6.0</scribejava.version>
<spring-security-oauth2.version>2.3.3.RELEASE</spring-security-oauth2.version> <spring-security-oauth2.version>2.3.3.RELEASE</spring-security-oauth2.version>
<passay.version>1.3.1</passay.version> <passay.version>1.3.1</passay.version>
<tink.version>1.2.2</tink.version>
<cryptacular.version>1.2.2</cryptacular.version> <cryptacular.version>1.2.2</cryptacular.version>
</properties> </properties>
</project> </project>

View File

@ -0,0 +1,101 @@
package com.baeldung.tink;
import com.google.crypto.tink.*;
import com.google.crypto.tink.aead.AeadConfig;
import com.google.crypto.tink.aead.AeadFactory;
import com.google.crypto.tink.aead.AeadKeyTemplates;
import com.google.crypto.tink.config.TinkConfig;
import com.google.crypto.tink.hybrid.HybridDecryptFactory;
import com.google.crypto.tink.hybrid.HybridEncryptFactory;
import com.google.crypto.tink.hybrid.HybridKeyTemplates;
import com.google.crypto.tink.mac.MacFactory;
import com.google.crypto.tink.mac.MacKeyTemplates;
import com.google.crypto.tink.signature.PublicKeySignFactory;
import com.google.crypto.tink.signature.PublicKeyVerifyFactory;
import com.google.crypto.tink.signature.SignatureKeyTemplates;
import org.junit.Assert;
import org.junit.Test;
import java.security.GeneralSecurityException;
public class TinkUnitTest {
private static final String PLAINTEXT = "BAELDUNG";
private static final String DATA = "TINK";
@Test
public void givenPlaintext_whenEncryptWithAead_thenPlaintextIsEncrypted() throws GeneralSecurityException {
AeadConfig.register();
KeysetHandle keysetHandle = KeysetHandle.generateNew(
AeadKeyTemplates.AES256_GCM);
Aead aead = AeadFactory.getPrimitive(keysetHandle);
byte[] ciphertext = aead.encrypt(PLAINTEXT.getBytes(),
DATA.getBytes());
Assert.assertNotEquals(PLAINTEXT, new String(ciphertext));
}
@Test
public void givenData_whenComputeMAC_thenVerifyMAC() throws GeneralSecurityException {
TinkConfig.register();
KeysetHandle keysetHandle = KeysetHandle.generateNew(
MacKeyTemplates.HMAC_SHA256_128BITTAG);
Mac mac = MacFactory.getPrimitive(keysetHandle);
byte[] tag = mac.computeMac(DATA.getBytes());
mac.verifyMac(tag, DATA.getBytes());
}
@Test
public void givenData_whenSignData_thenVerifySignature() throws GeneralSecurityException {
TinkConfig.register();
KeysetHandle privateKeysetHandle = KeysetHandle.generateNew(
SignatureKeyTemplates.ECDSA_P256);
PublicKeySign signer = PublicKeySignFactory.getPrimitive(privateKeysetHandle);
byte[] signature = signer.sign(DATA.getBytes());
KeysetHandle publicKeysetHandle =
privateKeysetHandle.getPublicKeysetHandle();
PublicKeyVerify verifier = PublicKeyVerifyFactory.getPrimitive(publicKeysetHandle);
verifier.verify(signature, DATA.getBytes());
}
@Test
public void givenPlaintext_whenEncryptWithHybridEncryption_thenVerifyDecryptedIsEqual() throws GeneralSecurityException {
TinkConfig.register();
KeysetHandle privateKeysetHandle = KeysetHandle.generateNew(
HybridKeyTemplates.ECIES_P256_HKDF_HMAC_SHA256_AES128_CTR_HMAC_SHA256);
KeysetHandle publicKeysetHandle = privateKeysetHandle.getPublicKeysetHandle();
HybridEncrypt hybridEncrypt = HybridEncryptFactory.getPrimitive(publicKeysetHandle);
HybridDecrypt hybridDecrypt = HybridDecryptFactory.getPrimitive(privateKeysetHandle);
String contextInfo = "Tink";
byte[] ciphertext = hybridEncrypt.encrypt(PLAINTEXT.getBytes(), contextInfo.getBytes());
byte[] plaintextDecrypted = hybridDecrypt.decrypt(ciphertext, contextInfo.getBytes());
Assert.assertEquals(PLAINTEXT,new String(plaintextDecrypted));
}
}

View File

@ -3,7 +3,7 @@
- [Embedded Jetty Server in Java](http://www.baeldung.com/jetty-embedded) - [Embedded Jetty Server in Java](http://www.baeldung.com/jetty-embedded)
- [Introduction to Netty](http://www.baeldung.com/netty) - [Introduction to Netty](http://www.baeldung.com/netty)
- [Exceptions in Netty](http://www.baeldung.com/netty-exception-handling) - [Exceptions in Netty](http://www.baeldung.com/netty-exception-handling)
- [Programatically Create, Configure, and Run a Tomcat Server](http://www.baeldung.com/tomcat-programmatic-setup) - [Programmatically Create, Configure and Run a Tomcat Server](http://www.baeldung.com/tomcat-programmatic-setup)
- [Creating and Configuring Jetty 9 Server in Java](http://www.baeldung.com/jetty-java-programmatic) - [Creating and Configuring Jetty 9 Server in Java](http://www.baeldung.com/jetty-java-programmatic)
- [Testing Netty with EmbeddedChannel](http://www.baeldung.com/testing-netty-embedded-channel) - [Testing Netty with EmbeddedChannel](http://www.baeldung.com/testing-netty-embedded-channel)
- [MQTT Client in Java](https://www.baeldung.com/java-mqtt-client) - [MQTT Client in Java](https://www.baeldung.com/java-mqtt-client)

View File

@ -6,7 +6,7 @@
- [Introduction to Apache Flink with Java](http://www.baeldung.com/apache-flink) - [Introduction to Apache Flink with Java](http://www.baeldung.com/apache-flink)
- [Introduction to JSONassert](http://www.baeldung.com/jsonassert) - [Introduction to JSONassert](http://www.baeldung.com/jsonassert)
- [Intro to JaVers](http://www.baeldung.com/javers) - [Intro to JaVers](http://www.baeldung.com/javers)
- [Intro to Serenity BDD](http://www.baeldung.com/serenity-bdd) - [Introduction to Serenity BDD](http://www.baeldung.com/serenity-bdd)
- [Merging Streams in Java](http://www.baeldung.com/java-merge-streams) - [Merging Streams in Java](http://www.baeldung.com/java-merge-streams)
- [Serenity BDD and Screenplay](http://www.baeldung.com/serenity-screenplay) - [Serenity BDD and Screenplay](http://www.baeldung.com/serenity-screenplay)
- [Introduction to Quartz](http://www.baeldung.com/quartz) - [Introduction to Quartz](http://www.baeldung.com/quartz)
@ -14,14 +14,14 @@
- [Software Transactional Memory in Java Using Multiverse](http://www.baeldung.com/java-multiverse-stm) - [Software Transactional Memory in Java Using Multiverse](http://www.baeldung.com/java-multiverse-stm)
- [Serenity BDD with Spring and JBehave](http://www.baeldung.com/serenity-spring-jbehave) - [Serenity BDD with Spring and JBehave](http://www.baeldung.com/serenity-spring-jbehave)
- [Locality-Sensitive Hashing in Java Using Java-LSH](http://www.baeldung.com/locality-sensitive-hashing) - [Locality-Sensitive Hashing in Java Using Java-LSH](http://www.baeldung.com/locality-sensitive-hashing)
- [Introduction to Awaitility](http://www.baeldung.com/awaitlity-testing) - [Introduction to Awaitlity](http://www.baeldung.com/awaitlity-testing)
- [Guide to the HyperLogLog Algorithm](http://www.baeldung.com/java-hyperloglog) - [Guide to the HyperLogLog Algorithm](http://www.baeldung.com/java-hyperloglog)
- [Introduction to Neuroph](http://www.baeldung.com/neuroph) - [Introduction to Neuroph](http://www.baeldung.com/neuroph)
- [Quick Guide to RSS with Rome](http://www.baeldung.com/rome-rss) - [Quick Guide to RSS with Rome](http://www.baeldung.com/rome-rss)
- [Introduction to PCollections](http://www.baeldung.com/java-pcollections) - [Introduction to PCollections](http://www.baeldung.com/java-pcollections)
- [Introduction to Hoverfly in Java](http://www.baeldung.com/hoverfly) - [Introduction to Hoverfly in Java](http://www.baeldung.com/hoverfly)
- [Introduction to Eclipse Collections](http://www.baeldung.com/eclipse-collections) - [Introduction to Eclipse Collections](http://www.baeldung.com/eclipse-collections)
- [DistinctBy in Java Stream API](http://www.baeldung.com/java-streams-distinct-by) - [DistinctBy in the Java Stream API](http://www.baeldung.com/java-streams-distinct-by)
- [Introduction to NoException](http://www.baeldung.com/no-exception) - [Introduction to NoException](http://www.baeldung.com/no-exception)
- [Introduction to Conflict-Free Replicated Data Types](http://www.baeldung.com/java-conflict-free-replicated-data-types) - [Introduction to Conflict-Free Replicated Data Types](http://www.baeldung.com/java-conflict-free-replicated-data-types)
- [Introduction to javax.measure](http://www.baeldung.com/javax-measure) - [Introduction to javax.measure](http://www.baeldung.com/javax-measure)
@ -36,7 +36,7 @@
- [Introduction To Docx4J](http://www.baeldung.com/docx4j) - [Introduction To Docx4J](http://www.baeldung.com/docx4j)
- [Introduction to StreamEx](http://www.baeldung.com/streamex) - [Introduction to StreamEx](http://www.baeldung.com/streamex)
- [Introduction to BouncyCastle with Java](http://www.baeldung.com/java-bouncy-castle) - [Introduction to BouncyCastle with Java](http://www.baeldung.com/java-bouncy-castle)
- [Guide to google-http-client](http://www.baeldung.com/google-http-client) - [A Guide to Google-Http-Client](http://www.baeldung.com/google-http-client)
- [Interact with Google Sheets from Java](http://www.baeldung.com/google-sheets-java-client) - [Interact with Google Sheets from Java](http://www.baeldung.com/google-sheets-java-client)
- [A Docker Guide for Java](http://www.baeldung.com/docker-java-api) - [A Docker Guide for Java](http://www.baeldung.com/docker-java-api)
- [Introduction To OpenCSV](http://www.baeldung.com/opencsv) - [Introduction To OpenCSV](http://www.baeldung.com/opencsv)

View File

@ -4,5 +4,4 @@
### Relevant Articles: ### Relevant Articles:
- [Creating a Custom Logback Appender](http://www.baeldung.com/custom-logback-appender) - [Creating a Custom Logback Appender](http://www.baeldung.com/custom-logback-appender)
- [Get Log Output in JSON Format](http://www.baeldung.com/java-log-json-output)
- [A Guide To Logback](http://www.baeldung.com/logback) - [A Guide To Logback](http://www.baeldung.com/logback)

View File

@ -4,3 +4,4 @@
- [Log4j 2 and Lambda Expressions](http://www.baeldung.com/log4j-2-lazy-logging) - [Log4j 2 and Lambda Expressions](http://www.baeldung.com/log4j-2-lazy-logging)
- [Programmatic Configuration with Log4j 2](http://www.baeldung.com/log4j2-programmatic-config) - [Programmatic Configuration with Log4j 2](http://www.baeldung.com/log4j2-programmatic-config)
- [Creating a Custom Log4j2 Appender](https://www.baeldung.com/log4j2-custom-appender) - [Creating a Custom Log4j2 Appender](https://www.baeldung.com/log4j2-custom-appender)
- [Get Log Output in JSON](http://www.baeldung.com/java-log-json-output)

View File

@ -0,0 +1,3 @@
### Relevant Articles:
- [Get Log Output in JSON](https://www.baeldung.com/java-log-json-output)

View File

@ -3,3 +3,4 @@
- [Introduction to Intercepting Filter Pattern in Java](http://www.baeldung.com/intercepting-filter-pattern-in-java) - [Introduction to Intercepting Filter Pattern in Java](http://www.baeldung.com/intercepting-filter-pattern-in-java)
- [Introduction to the Null Object Pattern](https://www.baeldung.com/java-null-object-pattern) - [Introduction to the Null Object Pattern](https://www.baeldung.com/java-null-object-pattern)
- [The Dependency Inversion Principle in Java](https://www.baeldung.com/java-dependency-inversion-principle) - [The Dependency Inversion Principle in Java](https://www.baeldung.com/java-dependency-inversion-principle)
- [Avoid Check for Null Statement in Java](https://www.baeldung.com/java-avoid-null-check)

View File

@ -19,4 +19,4 @@
- [The Command Pattern in Java](http://www.baeldung.com/java-command-pattern) - [The Command Pattern in Java](http://www.baeldung.com/java-command-pattern)
- [Java Constructors vs Static Factory Methods](https://www.baeldung.com/java-constructors-vs-static-factory-methods) - [Java Constructors vs Static Factory Methods](https://www.baeldung.com/java-constructors-vs-static-factory-methods)
- [The Adapter Pattern in Java](https://www.baeldung.com/java-adapter-pattern) - [The Adapter Pattern in Java](https://www.baeldung.com/java-adapter-pattern)
- [Currying in Java](https://baeldung.com/currying-in-java) - [Currying in Java](https://www.baeldung.com/java-currying)

View File

@ -1,5 +1,5 @@
### Relevant Articles: ### Relevant Articles:
- [A Guide to Solid Principles](https://www.baeldung.com/solid-principles) - [A Solid Guide to Solid Principles](https://www.baeldung.com/solid-principles)

View File

@ -11,3 +11,5 @@
- [Pessimistic Locking in JPA](http://www.baeldung.com/jpa-pessimistic-locking) - [Pessimistic Locking in JPA](http://www.baeldung.com/jpa-pessimistic-locking)
- [Get All Data from a Table with Hibernate](https://www.baeldung.com/hibernate-select-all) - [Get All Data from a Table with Hibernate](https://www.baeldung.com/hibernate-select-all)
- [Spring Data with Reactive Cassandra](https://www.baeldung.com/spring-data-cassandra-reactive) - [Spring Data with Reactive Cassandra](https://www.baeldung.com/spring-data-cassandra-reactive)
- [Spring Data JPA Derived Delete Methods](https://www.baeldung.com/spring-data-jpa-deleteby)
- [Difference Between save() and saveAndFlush() in Spring Data JPA](https://www.baeldung.com/spring-data-jpa-save-saveandflush)

View File

@ -6,15 +6,21 @@
<version>0.1.0-SNAPSHOT</version> <version>0.1.0-SNAPSHOT</version>
<name>core-java-persistence</name> <name>core-java-persistence</name>
<packaging>jar</packaging> <packaging>jar</packaging>
<parent> <parent>
<groupId>com.baeldung</groupId> <groupId>com.baeldung</groupId>
<artifactId>parent-java</artifactId> <artifactId>parent-java</artifactId>
<version>0.0.1-SNAPSHOT</version> <version>0.0.1-SNAPSHOT</version>
<relativePath>../../parent-java</relativePath> <relativePath>../../parent-java</relativePath>
</parent> </parent>
<dependencies> <dependencies>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>${postgresql.version}</version>
<scope>test</scope>
</dependency>
<dependency> <dependency>
<groupId>org.assertj</groupId> <groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId> <artifactId>assertj-core</artifactId>
@ -52,7 +58,7 @@
<version>${springframework.boot.spring-boot-starter.version}</version> <version>${springframework.boot.spring-boot-starter.version}</version>
</dependency> </dependency>
</dependencies> </dependencies>
<build> <build>
<finalName>core-java-persistence</finalName> <finalName>core-java-persistence</finalName>
<resources> <resources>
@ -62,8 +68,10 @@
</resource> </resource>
</resources> </resources>
</build> </build>
<properties> <properties>
<postgresql.version>42.2.5.jre7</postgresql.version>
<mysql-connector.version>8.0.15</mysql-connector.version>
<assertj-core.version>3.10.0</assertj-core.version> <assertj-core.version>3.10.0</assertj-core.version>
<h2database.version>1.4.197</h2database.version> <h2database.version>1.4.197</h2database.version>
<commons-dbcp2.version>2.4.0</commons-dbcp2.version> <commons-dbcp2.version>2.4.0</commons-dbcp2.version>
@ -72,5 +80,5 @@
<springframework.boot.spring-boot-starter.version>1.5.8.RELEASE</springframework.boot.spring-boot-starter.version> <springframework.boot.spring-boot-starter.version>1.5.8.RELEASE</springframework.boot.spring-boot-starter.version>
<springframework.spring-web.version>4.3.4.RELEASE</springframework.spring-web.version> <springframework.spring-web.version>4.3.4.RELEASE</springframework.spring-web.version>
</properties> </properties>
</project> </project>

View File

@ -0,0 +1,41 @@
package com.baeldung.jdbc.joins;
class ArticleWithAuthor {
private String title;
private String authorFirstName;
private String authorLastName;
public ArticleWithAuthor(String title, String authorFirstName, String authorLastName) {
this.title = title;
this.authorFirstName = authorFirstName;
this.authorLastName = authorLastName;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getAuthorFirstName() {
return authorFirstName;
}
public void setAuthorFirstName(String authorFirstName) {
this.authorFirstName = authorFirstName;
}
public String getAuthorLastName() {
return authorLastName;
}
public void setAuthorLastName(String authorLastName) {
this.authorLastName = authorLastName;
}
}

View File

@ -0,0 +1,61 @@
package com.baeldung.jdbc.joins;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
class ArticleWithAuthorDAO {
private static final String QUERY_TEMPLATE = "SELECT ARTICLE.TITLE, AUTHOR.LAST_NAME, AUTHOR.FIRST_NAME FROM ARTICLE %s AUTHOR ON AUTHOR.id=ARTICLE.AUTHOR_ID";
private final Connection connection;
ArticleWithAuthorDAO(Connection connection) {
this.connection = connection;
}
List<ArticleWithAuthor> articleInnerJoinAuthor() {
String query = String.format(QUERY_TEMPLATE, "INNER JOIN");
return executeQuery(query);
}
List<ArticleWithAuthor> articleLeftJoinAuthor() {
String query = String.format(QUERY_TEMPLATE, "LEFT JOIN");
return executeQuery(query);
}
List<ArticleWithAuthor> articleRightJoinAuthor() {
String query = String.format(QUERY_TEMPLATE, "RIGHT JOIN");
return executeQuery(query);
}
List<ArticleWithAuthor> articleFullJoinAuthor() {
String query = String.format(QUERY_TEMPLATE, "FULL JOIN");
return executeQuery(query);
}
private List<ArticleWithAuthor> executeQuery(String query) {
try (Statement statement = connection.createStatement()) {
ResultSet resultSet = statement.executeQuery(query);
return mapToList(resultSet);
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
private List<ArticleWithAuthor> mapToList(ResultSet resultSet) throws SQLException {
List<ArticleWithAuthor> list = new ArrayList<>();
while (resultSet.next()) {
ArticleWithAuthor articleWithAuthor = new ArticleWithAuthor(
resultSet.getString("TITLE"),
resultSet.getString("FIRST_NAME"),
resultSet.getString("LAST_NAME")
);
list.add(articleWithAuthor);
}
return list;
}
}

View File

@ -0,0 +1,89 @@
package com.baeldung.jdbc.joins;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
public class ArticleWithAuthorDAOIntegrationTest {
private Connection connection;
private ArticleWithAuthorDAO articleWithAuthorDAO;
@Before
public void setup() throws ClassNotFoundException, SQLException {
Class.forName("org.postgresql.Driver");
connection = DriverManager.getConnection("jdbc:postgresql://localhost:5432/myDb", "user", "pass");
articleWithAuthorDAO = new ArticleWithAuthorDAO(connection);
Statement statement = connection.createStatement();
String createAuthorSql = "CREATE TABLE IF NOT EXISTS AUTHOR (ID int NOT NULL PRIMARY KEY, FIRST_NAME varchar(255), LAST_NAME varchar(255));";
String createArticleSql = "CREATE TABLE IF NOT EXISTS ARTICLE (ID int NOT NULL PRIMARY KEY, TITLE varchar(255) NOT NULL, AUTHOR_ID int, FOREIGN KEY(AUTHOR_ID) REFERENCES AUTHOR(ID));";
statement.execute(createAuthorSql);
statement.execute(createArticleSql);
insertTestData(statement);
}
@Test
public void whenQueryWithInnerJoin_thenShouldReturnProperRows() {
List<ArticleWithAuthor> articleWithAuthorList = articleWithAuthorDAO.articleInnerJoinAuthor();
assertThat(articleWithAuthorList).hasSize(4);
assertThat(articleWithAuthorList).noneMatch(row -> row.getAuthorFirstName() == null || row.getTitle() == null);
}
@Test
public void whenQueryWithLeftJoin_thenShouldReturnProperRows() {
List<ArticleWithAuthor> articleWithAuthorList = articleWithAuthorDAO.articleLeftJoinAuthor();
assertThat(articleWithAuthorList).hasSize(5);
assertThat(articleWithAuthorList).anyMatch(row -> row.getAuthorFirstName() == null);
}
@Test
public void whenQueryWithRightJoin_thenShouldReturnProperRows() {
List<ArticleWithAuthor> articleWithAuthorList = articleWithAuthorDAO.articleRightJoinAuthor();
assertThat(articleWithAuthorList).hasSize(5);
assertThat(articleWithAuthorList).anyMatch(row -> row.getTitle() == null);
}
@Test
public void whenQueryWithFullJoin_thenShouldReturnProperRows() {
List<ArticleWithAuthor> articleWithAuthorList = articleWithAuthorDAO.articleFullJoinAuthor();
assertThat(articleWithAuthorList).hasSize(6);
assertThat(articleWithAuthorList).anyMatch(row -> row.getTitle() == null);
assertThat(articleWithAuthorList).anyMatch(row -> row.getAuthorFirstName() == null);
}
@After
public void cleanup() throws SQLException {
connection.createStatement().execute("DROP TABLE ARTICLE");
connection.createStatement().execute("DROP TABLE AUTHOR");
connection.close();
}
public void insertTestData(Statement statement) throws SQLException {
String insertAuthors = "INSERT INTO AUTHOR VALUES "
+ "(1, 'Siena', 'Kerr'),"
+ "(2, 'Daniele', 'Ferguson'),"
+ "(3, 'Luciano', 'Wise'),"
+ "(4, 'Jonas', 'Lugo');";
String insertArticles = "INSERT INTO ARTICLE VALUES "
+ "(1, 'First steps in Java', 1),"
+ "(2, 'SpringBoot tutorial', 1),"
+ "(3, 'Java 12 insights', null),"
+ "(4, 'SQL JOINS', 2),"
+ "(5, 'Introduction to Spring Security', 3);";
statement.execute(insertAuthors);
statement.execute(insertArticles);
}
}

View File

@ -32,3 +32,4 @@
- [Common Hibernate Exceptions](https://www.baeldung.com/hibernate-exceptions) - [Common Hibernate Exceptions](https://www.baeldung.com/hibernate-exceptions)
- [Hibernate Aggregate Functions](https://www.baeldung.com/hibernate-aggregate-functions) - [Hibernate Aggregate Functions](https://www.baeldung.com/hibernate-aggregate-functions)
- [Hibernate Query Plan Cache](https://www.baeldung.com/hibernate-query-plan-cache) - [Hibernate Query Plan Cache](https://www.baeldung.com/hibernate-query-plan-cache)
- [TransactionRequiredException Error](https://www.baeldung.com/jpa-transaction-required-exception)

View File

@ -2,7 +2,7 @@
- [A Guide to SqlResultSetMapping](http://www.baeldung.com/jpa-sql-resultset-mapping) - [A Guide to SqlResultSetMapping](http://www.baeldung.com/jpa-sql-resultset-mapping)
- [A Guide to Stored Procedures with JPA](http://www.baeldung.com/jpa-stored-procedures) - [A Guide to Stored Procedures with JPA](http://www.baeldung.com/jpa-stored-procedures)
- [Fixing the JPA error “java.lang.String cannot be cast to Ljava.lang.String;”](https://www.baeldung.com/jpa-error-java-lang-string-cannot-be-cast) - [Fixing the JPA error “java.lang.String cannot be cast to [Ljava.lang.String;”]](https://www.baeldung.com/jpa-error-java-lang-string-cannot-be-cast)
- [JPA Entity Graph](https://www.baeldung.com/jpa-entity-graph) - [JPA Entity Graph](https://www.baeldung.com/jpa-entity-graph)
- [JPA 2.2 Support for Java 8 Date/Time Types](https://www.baeldung.com/jpa-java-time) - [JPA 2.2 Support for Java 8 Date/Time Types](https://www.baeldung.com/jpa-java-time)
- [Converting Between LocalDate and SQL Date](https://www.baeldung.com/java-convert-localdate-sql-date) - [Converting Between LocalDate and SQL Date](https://www.baeldung.com/java-convert-localdate-sql-date)

View File

@ -0,0 +1,12 @@
package com.baeldung.h2db.springboot;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SpringBootH2Application {
public static void main(String... args) {
SpringApplication.run(SpringBootH2Application.class, args);
}
}

View File

@ -0,0 +1,10 @@
package com.baeldung.h2db.springboot.daos;
import com.baeldung.h2db.springboot.models.User;
import org.springframework.data.repository.CrudRepository;
public interface UserRepository extends CrudRepository<User, Integer> {
}

View File

@ -0,0 +1,54 @@
package com.baeldung.h2db.springboot.models;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
@Table(name = "users")
@Entity
public class User {
@Id
@GeneratedValue
private int id;
private String firstName;
private String lastName;
public User() { }
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", firstName='" + firstName + '\'' +
", lastName='" + lastName + '\'' +
'}';
}
}

View File

@ -2,7 +2,7 @@ spring.datasource.url=jdbc:h2:mem:mydb
spring.datasource.driverClassName=org.h2.Driver spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa spring.datasource.username=sa
spring.datasource.password= spring.datasource.password=
spring.jpa.hibernate.ddl-auto=create spring.jpa.hibernate.ddl-auto=create-drop
spring.h2.console.enabled=true spring.h2.console.enabled=true
spring.h2.console.path=/h2-console spring.h2.console.path=/h2-console
debug=true debug=true

View File

@ -0,0 +1,50 @@
package com.baeldung;
import com.baeldung.h2db.springboot.SpringBootH2Application;
import com.baeldung.h2db.springboot.daos.UserRepository;
import com.baeldung.h2db.springboot.models.User;
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.junit4.SpringRunner;
import java.util.List;
import static org.junit.Assert.*;
@RunWith(SpringRunner.class)
@SpringBootTest(classes = SpringBootH2Application.class)
public class SpringBootH2IntegrationTest {
@Autowired
private UserRepository userRepository;
@Test
public void contextLoads() { }
@Test
public void givenUserProfile_whenAddUser_thenCreateNewUser() {
User user = new User();
user.setFirstName("John");
user.setLastName("Doe");
userRepository.save(user);
List<User> users = (List<User>) userRepository.findAll();
assertFalse(users.isEmpty());
String firstName = "Aliko";
String lastName = "Dangote";
User user1 = userRepository.findById(users.get(0).getId()).get();
user1.setLastName(lastName);
user1.setFirstName(firstName);
userRepository.save(user1);
user = userRepository.findById(user.getId()).get();
assertEquals(user.getFirstName(), firstName);
assertEquals(user.getLastName(), lastName);
userRepository.deleteById(user.getId());
assertTrue( ((List<User>) userRepository.findAll()).isEmpty());
}
}

View File

@ -8,3 +8,4 @@
- [Integrating Spring Boot with HSQLDB](https://www.baeldung.com/spring-boot-hsqldb) - [Integrating Spring Boot with HSQLDB](https://www.baeldung.com/spring-boot-hsqldb)
- [Configuring a DataSource Programmatically in Spring Boot](https://www.baeldung.com/spring-boot-configure-data-source-programmatic) - [Configuring a DataSource Programmatically in Spring Boot](https://www.baeldung.com/spring-boot-configure-data-source-programmatic)
- [Resolving “Failed to Configure a DataSource” Error](https://www.baeldung.com/spring-boot-failed-to-configure-data-source) - [Resolving “Failed to Configure a DataSource” Error](https://www.baeldung.com/spring-boot-failed-to-configure-data-source)
- [Spring Boot with Hibernate](https://www.baeldung.com/spring-boot-hibernate)

View File

@ -1,13 +1,9 @@
package com.baeldung.boot.config; package com.baeldung.boot.config;
import java.util.Properties;
import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.context.annotation.PropertySource; import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment; import org.springframework.core.env.Environment;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories; import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
@ -17,10 +13,17 @@ import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter; import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.annotation.EnableTransactionManagement; import org.springframework.transaction.annotation.EnableTransactionManagement;
import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;
import java.util.Properties;
@Configuration @Configuration
@EnableJpaRepositories(basePackages = { "com.baeldung.boot.repository", "com.baeldung.repository" }) @EnableJpaRepositories(basePackages = { "com.baeldung.boot.repository", "com.baeldung.repository" })
@PropertySource("classpath:persistence-generic-entity.properties") @PropertySource("classpath:persistence-generic-entity.properties")
@EnableTransactionManagement @EnableTransactionManagement
@Profile("default") //only required to allow H2JpaConfig and H2TestProfileJPAConfig to coexist in same project
//this demo project is showcasing several ways to achieve the same end, and class-level
//Profile annotations are only necessary because the different techniques are sharing a project
public class H2JpaConfig { public class H2JpaConfig {
@Autowired @Autowired

View File

@ -1,8 +1,9 @@
package com.baeldung; package com.baeldung;
import static org.junit.Assert.assertEquals; import com.baeldung.boot.Application;
import static org.junit.Assert.assertNotNull; import com.baeldung.boot.domain.GenericEntity;
import com.baeldung.boot.repository.GenericEntityRepository;
import com.baeldung.config.H2TestProfileJPAConfig;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@ -10,13 +11,11 @@ import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ActiveProfiles; import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.context.junit4.SpringRunner;
import com.baeldung.boot.Application; import static org.junit.Assert.assertEquals;
import com.baeldung.boot.config.H2JpaConfig; import static org.junit.Assert.assertNotNull;
import com.baeldung.boot.domain.GenericEntity;
import com.baeldung.boot.repository.GenericEntityRepository;
@RunWith(SpringRunner.class) @RunWith(SpringRunner.class)
@SpringBootTest(classes = { Application.class, H2JpaConfig.class }) @SpringBootTest(classes = { Application.class, H2TestProfileJPAConfig.class })
@ActiveProfiles("test") @ActiveProfiles("test")
public class SpringBootProfileIntegrationTest { public class SpringBootProfileIntegrationTest {
@Autowired @Autowired

View File

@ -1,10 +1,5 @@
package com.baeldung.config; package com.baeldung.config;
import java.util.Properties;
import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
@ -17,9 +12,16 @@ import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter; import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.annotation.EnableTransactionManagement; import org.springframework.transaction.annotation.EnableTransactionManagement;
import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;
import java.util.Properties;
@Configuration @Configuration
@EnableJpaRepositories(basePackages = { "com.baeldung.repository", "com.baeldung.boot.repository" }) @EnableJpaRepositories(basePackages = { "com.baeldung.repository", "com.baeldung.boot.repository" })
@EnableTransactionManagement @EnableTransactionManagement
@Profile("test") //only required to allow H2JpaConfig and H2TestProfileJPAConfig to coexist in same project
//this demo project is showcasing several ways to achieve the same end, and class-level
//Profile annotations are only necessary because the different techniques are sharing a project
public class H2TestProfileJPAConfig { public class H2TestProfileJPAConfig {
@Autowired @Autowired

View File

@ -2,7 +2,7 @@
### Relevant Articles: ### Relevant Articles:
- [Intro to Spring Data Couchbase](http://www.baeldung.com/spring-data-couchbase) - [Intro to Spring Data Couchbase](http://www.baeldung.com/spring-data-couchbase)
- [Entity Validation, Query Consistency, and Optimistic Locking in Spring Data Couchbase](http://www.baeldung.com/entity-validation-locking-and-query-consistency-in-spring-data-couchbase) - [Entity Validation, Optimistic Locking, and Query Consistency in Spring Data Couchbase](http://www.baeldung.com/entity-validation-locking-and-query-consistency-in-spring-data-couchbase)
- [Multiple Buckets and Spatial View Queries in Spring Data Couchbase](http://www.baeldung.com/spring-data-couchbase-buckets-and-spatial-view-queries) - [Multiple Buckets and Spatial View Queries in Spring Data Couchbase](http://www.baeldung.com/spring-data-couchbase-buckets-and-spatial-view-queries)
### Overview ### Overview

View File

@ -3,3 +3,4 @@
## Spring Data JPA Example Project ## Spring Data JPA Example Project
### Relevant Articles: ### Relevant Articles:
- [Spring Data JPA Derived Delete Methods](https://www.baeldung.com/spring-data-jpa-deleteby)

View File

@ -0,0 +1,51 @@
package com.baeldung.datajpadelete.entity;
import javax.persistence.*;
@Entity
public class Book {
@Id
@GeneratedValue
private Long id;
private String title;
@ManyToOne
private Category category;
public Book() {
}
public Book(String title) {
this.title = title;
}
public Book(String title, Category category) {
this.title = title;
this.category = category;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public Category getCategory() {
return category;
}
public void setCategory(Category category) {
this.category = category;
}
}

View File

@ -0,0 +1,60 @@
package com.baeldung.datajpadelete.entity;
import javax.persistence.*;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@Entity
public class Category {
@Id
@GeneratedValue
private Long id;
private String name;
@OneToMany(mappedBy = "category", cascade = CascadeType.ALL, orphanRemoval = true)
private List<Book> books;
public Category() {
}
public Category(String name) {
this.name = name;
}
public Category(String name, Book... books) {
this.name = name;
this.books = Stream.of(books).collect(Collectors.toList());
this.books.forEach(x -> x.setCategory(this));
}
public Category(String name, List<Book> books) {
this.name = name;
this.books = books;
}
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;
}
public List<Book> getBooks() {
return books;
}
public void setBooks(List<Book> books) {
this.books = books;
}
}

View File

@ -0,0 +1,19 @@
package com.baeldung.datajpadelete.repository;
import com.baeldung.datajpadelete.entity.Book;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
@Repository
public interface BookRepository extends CrudRepository<Book, Long> {
long deleteByTitle(String title);
@Modifying
@Query("delete from Book b where b.title=:title")
void deleteBooks(@Param("title") String title);
}

View File

@ -0,0 +1,9 @@
package com.baeldung.datajpadelete.repository;
import com.baeldung.datajpadelete.entity.Category;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface CategoryRepository extends CrudRepository<Category, Long> {
}

View File

@ -0,0 +1,71 @@
package com.baeldung.embeddable.model;
import javax.persistence.AttributeOverride;
import javax.persistence.AttributeOverrides;
import javax.persistence.Column;
import javax.persistence.Embedded;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
@Entity
public class Company {
@Id
@GeneratedValue
private Integer id;
private String name;
private String address;
private String phone;
@Embedded
@AttributeOverrides(value = {
@AttributeOverride( name = "firstName", column = @Column(name = "contact_first_name")),
@AttributeOverride( name = "lastName", column = @Column(name = "contact_last_name")),
@AttributeOverride( name = "phone", column = @Column(name = "contact_phone"))
})
private ContactPerson contactPerson;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public ContactPerson getContactPerson() {
return contactPerson;
}
public void setContactPerson(ContactPerson contactPerson) {
this.contactPerson = contactPerson;
}
}

View File

@ -0,0 +1,38 @@
package com.baeldung.embeddable.model;
import javax.persistence.Embeddable;
@Embeddable
public class ContactPerson {
private String firstName;
private String lastName;
private String phone;
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
}

View File

@ -0,0 +1,18 @@
package com.baeldung.embeddable.repositories;
import com.baeldung.embeddable.model.Company;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import java.util.List;
public interface CompanyRepository extends JpaRepository<Company, Integer> {
List<Company> findByContactPersonFirstName(String firstName);
@Query("SELECT C FROM Company C WHERE C.contactPerson.firstName = ?1")
List<Company> findByContactPersonFirstNameWithJPQL(String firstName);
@Query(value = "SELECT * FROM company WHERE contact_first_name = ?1", nativeQuery = true)
List<Company> findByContactPersonFirstNameWithNativeQuery(String firstName);
}

View File

@ -0,0 +1,57 @@
package com.baeldung.projection.model;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.OneToOne;
@Entity
public class Address {
@Id
private Long id;
@OneToOne
private Person person;
private String state;
private String city;
private String street;
private String zipCode;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getStreet() {
return street;
}
public void setStreet(String street) {
this.street = street;
}
public String getZipCode() {
return zipCode;
}
public void setZipCode(String zipCode) {
this.zipCode = zipCode;
}
}

View File

@ -0,0 +1,47 @@
package com.baeldung.projection.model;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.OneToOne;
@Entity
public class Person {
@Id
private Long id;
private String firstName;
private String lastName;
@OneToOne(mappedBy = "person")
private Address address;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
}

View File

@ -0,0 +1,11 @@
package com.baeldung.projection.repository;
import com.baeldung.projection.view.AddressView;
import com.baeldung.projection.model.Address;
import org.springframework.data.repository.Repository;
import java.util.List;
public interface AddressRepository extends Repository<Address, Long> {
List<AddressView> getAddressByState(String state);
}

View File

@ -0,0 +1,14 @@
package com.baeldung.projection.repository;
import com.baeldung.projection.model.Person;
import com.baeldung.projection.view.PersonDto;
import com.baeldung.projection.view.PersonView;
import org.springframework.data.repository.Repository;
public interface PersonRepository extends Repository<Person, Long> {
PersonView findByLastName(String lastName);
PersonDto findByFirstName(String firstName);
<T> T findByLastName(String lastName, Class<T> type);
}

View File

@ -0,0 +1,7 @@
package com.baeldung.projection.view;
public interface AddressView {
String getZipCode();
PersonView getPerson();
}

View File

@ -0,0 +1,34 @@
package com.baeldung.projection.view;
import java.util.Objects;
public class PersonDto {
private final String firstName;
private final String lastName;
public PersonDto(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
public String getFirstName() {
return firstName;
}
public String getLastName() {
return lastName;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
PersonDto personDto = (PersonDto) o;
return Objects.equals(firstName, personDto.firstName) && Objects.equals(lastName, personDto.lastName);
}
@Override
public int hashCode() {
return Objects.hash(firstName, lastName);
}
}

View File

@ -0,0 +1,12 @@
package com.baeldung.projection.view;
import org.springframework.beans.factory.annotation.Value;
public interface PersonView {
String getFirstName();
String getLastName();
@Value("#{target.firstName + ' ' + target.lastName}")
String getFullName();
}

View File

@ -0,0 +1,72 @@
package com.baeldung.datajpadelete;
import com.baeldung.Application;
import com.baeldung.datajpadelete.entity.Book;
import com.baeldung.datajpadelete.repository.BookRepository;
import org.junit.After;
import org.junit.Before;
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.junit4.SpringRunner;
import org.springframework.transaction.annotation.Transactional;
import java.util.Arrays;
import static org.assertj.core.api.Assertions.assertThat;
@RunWith(SpringRunner.class)
@SpringBootTest(classes = {Application.class})
public class DeleteFromRepositoryUnitTest {
@Autowired
private BookRepository repository;
Book book1;
Book book2;
@Before
public void setup() {
book1 = new Book("The Hobbit");
book2 = new Book("All Quiet on the Western Front");
repository.saveAll(Arrays.asList(book1, book2));
}
@After
public void teardown() {
repository.deleteAll();
}
@Test
public void whenDeleteByIdFromRepository_thenDeletingShouldBeSuccessful() {
repository.deleteById(book1.getId());
assertThat(repository.count() == 1).isTrue();
}
@Test
public void whenDeleteAllFromRepository_thenRepositoryShouldBeEmpty() {
repository.deleteAll();
assertThat(repository.count() == 0).isTrue();
}
@Test
@Transactional
public void whenDeleteFromDerivedQuery_thenDeletingShouldBeSuccessful() {
repository.deleteByTitle("The Hobbit");
assertThat(repository.count() == 1).isTrue();
}
@Test
@Transactional
public void whenDeleteFromCustomQuery_thenDeletingShouldBeSuccessful() {
repository.deleteBooks("The Hobbit");
assertThat(repository.count() == 1).isTrue();
}
}

View File

@ -0,0 +1,60 @@
package com.baeldung.datajpadelete;
import com.baeldung.Application;
import com.baeldung.datajpadelete.entity.Book;
import com.baeldung.datajpadelete.entity.Category;
import com.baeldung.datajpadelete.repository.BookRepository;
import com.baeldung.datajpadelete.repository.CategoryRepository;
import org.junit.After;
import org.junit.Before;
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.junit4.SpringRunner;
import static org.assertj.core.api.Assertions.assertThat;
@RunWith(SpringRunner.class)
@SpringBootTest(classes = {Application.class})
public class DeleteInRelationshipsUnitTest {
@Autowired
private BookRepository bookRepository;
@Autowired
private CategoryRepository categoryRepository;
@Before
public void setup() {
Book book1 = new Book("The Hobbit");
Category category1 = new Category("Cat1", book1);
categoryRepository.save(category1);
Book book2 = new Book("All Quiet on the Western Front");
Category category2 = new Category("Cat2", book2);
categoryRepository.save(category2);
}
@After
public void teardown() {
bookRepository.deleteAll();
categoryRepository.deleteAll();
}
@Test
public void whenDeletingCategories_thenBooksShouldAlsoBeDeleted() {
categoryRepository.deleteAll();
assertThat(bookRepository.count() == 0).isTrue();
assertThat(categoryRepository.count() == 0).isTrue();
}
@Test
public void whenDeletingBooks_thenCategoriesShouldAlsoBeDeleted() {
bookRepository.deleteAll();
assertThat(bookRepository.count() == 0).isTrue();
assertThat(categoryRepository.count() == 2).isTrue();
}
}

View File

@ -0,0 +1,125 @@
package com.baeldung.embeddable;
import com.baeldung.Application;
import com.baeldung.embeddable.model.Company;
import com.baeldung.embeddable.model.ContactPerson;
import com.baeldung.embeddable.repositories.CompanyRepository;
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.junit4.SpringRunner;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import static org.junit.Assert.assertEquals;
@RunWith(SpringRunner.class)
@SpringBootTest(classes = {Application.class})
public class EmbeddableIntegrationTest {
@Autowired
private CompanyRepository companyRepository;
@Test
@Transactional
public void whenInsertingCompany_thenEmbeddedContactPersonDetailsAreMapped() {
ContactPerson contactPerson = new ContactPerson();
contactPerson.setFirstName("First");
contactPerson.setLastName("Last");
contactPerson.setPhone("123-456-789");
Company company = new Company();
company.setName("Company");
company.setAddress("1st street");
company.setPhone("987-654-321");
company.setContactPerson(contactPerson);
companyRepository.save(company);
Company result = companyRepository.getOne(company.getId());
assertEquals("Company", result.getName());
assertEquals("1st street", result.getAddress());
assertEquals("987-654-321", result.getPhone());
assertEquals("First", result.getContactPerson().getFirstName());
assertEquals("Last", result.getContactPerson().getLastName());
assertEquals("123-456-789", result.getContactPerson().getPhone());
}
@Test
@Transactional
public void whenFindingCompanyByContactPersonAttribute_thenCompanyIsReturnedProperly() {
ContactPerson contactPerson = new ContactPerson();
contactPerson.setFirstName("Name");
contactPerson.setLastName("Last");
contactPerson.setPhone("123-456-789");
Company company = new Company();
company.setName("Company");
company.setAddress("1st street");
company.setPhone("987-654-321");
company.setContactPerson(contactPerson);
companyRepository.save(company);
List<Company> result = companyRepository.findByContactPersonFirstName("Name");
assertEquals(1, result.size());
result = companyRepository.findByContactPersonFirstName("FirstName");
assertEquals(0, result.size());
}
@Test
@Transactional
public void whenFindingCompanyByContactPersonAttributeWithJPQL_thenCompanyIsReturnedProperly() {
ContactPerson contactPerson = new ContactPerson();
contactPerson.setFirstName("@QueryName");
contactPerson.setLastName("Last");
contactPerson.setPhone("123-456-789");
Company company = new Company();
company.setName("Company");
company.setAddress("1st street");
company.setPhone("987-654-321");
company.setContactPerson(contactPerson);
companyRepository.save(company);
List<Company> result = companyRepository.findByContactPersonFirstNameWithJPQL("@QueryName");
assertEquals(1, result.size());
result = companyRepository.findByContactPersonFirstNameWithJPQL("FirstName");
assertEquals(0, result.size());
}
@Test
@Transactional
public void whenFindingCompanyByContactPersonAttributeWithNativeQuery_thenCompanyIsReturnedProperly() {
ContactPerson contactPerson = new ContactPerson();
contactPerson.setFirstName("NativeQueryName");
contactPerson.setLastName("Last");
contactPerson.setPhone("123-456-789");
Company company = new Company();
company.setName("Company");
company.setAddress("1st street");
company.setPhone("987-654-321");
company.setContactPerson(contactPerson);
companyRepository.save(company);
List<Company> result = companyRepository.findByContactPersonFirstNameWithNativeQuery("NativeQueryName");
assertEquals(1, result.size());
result = companyRepository.findByContactPersonFirstNameWithNativeQuery("FirstName");
assertEquals(0, result.size());
}
}

View File

@ -4,6 +4,7 @@ import static org.assertj.core.api.Assertions.assertThat;
import com.baeldung.joins.model.Department; import com.baeldung.joins.model.Department;
import com.baeldung.joins.model.Phone; import com.baeldung.joins.model.Phone;
import java.util.Collection;
import java.util.List; import java.util.List;
import javax.persistence.EntityManager; import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext; import javax.persistence.PersistenceContext;
@ -79,11 +80,11 @@ public class JpaJoinsIntegrationTest {
@Test @Test
public void whenCollectionValuedAssociationIsJoined_ThenCanSelect() { public void whenCollectionValuedAssociationIsJoined_ThenCanSelect() {
TypedQuery<Phone> query = entityManager.createQuery("SELECT ph FROM Employee e JOIN e.phones ph ", Phone.class); TypedQuery<Phone> query = entityManager.createQuery("SELECT ph FROM Employee e JOIN e.phones ph WHERE ph LIKE '1%'", Phone.class);
List<Phone> resultList = query.getResultList(); List<Phone> resultList = query.getResultList();
assertThat(resultList).hasSize(3); assertThat(resultList).hasSize(1);
} }
@Test @Test
@ -122,9 +123,20 @@ public class JpaJoinsIntegrationTest {
@Test @Test
public void whenLeftAndFetchKeywordsAreSpecified_ThenCreatesOuterFetchJoin() { public void whenLeftAndFetchKeywordsAreSpecified_ThenCreatesOuterFetchJoin() {
TypedQuery<Department> query = entityManager.createQuery("SELECT d FROM Department d LEFT JOIN FETCH d.employees", Department.class); TypedQuery<Department> query = entityManager.createQuery("SELECT d FROM Department d LEFT JOIN FETCH d.employees", Department.class);
List<Department> resultList = query.getResultList(); List<Department> resultList = query.getResultList();
assertThat(resultList).hasSize(4); assertThat(resultList).hasSize(4);
assertThat(resultList).extracting("name") assertThat(resultList).extracting("name")
.containsOnly("Infra", "Accounting", "Accounting", "Management"); .containsOnly("Infra", "Accounting", "Accounting", "Management");
} }
@Test
public void whenCollectionValuedAssociationIsSpecifiedInSelect_ThenReturnsCollections() {
TypedQuery<Collection> query = entityManager.createQuery("SELECT e.phones FROM Employee e", Collection.class);
List<Collection> resultList = query.getResultList();
assertThat(resultList).extracting("number").containsOnly("111", "222", "333");
}
} }

View File

@ -0,0 +1,63 @@
package com.baeldung.projection;
import com.baeldung.projection.model.Person;
import com.baeldung.projection.repository.AddressRepository;
import com.baeldung.projection.repository.PersonRepository;
import com.baeldung.projection.view.AddressView;
import com.baeldung.projection.view.PersonDto;
import com.baeldung.projection.view.PersonView;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.test.context.jdbc.Sql;
import org.springframework.test.context.junit4.SpringRunner;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.test.context.jdbc.Sql.ExecutionPhase.AFTER_TEST_METHOD;
@DataJpaTest
@RunWith(SpringRunner.class)
@Sql(scripts = "/projection-insert-data.sql")
@Sql(scripts = "/projection-clean-up-data.sql", executionPhase = AFTER_TEST_METHOD)
public class JpaProjectionIntegrationTest {
@Autowired
private AddressRepository addressRepository;
@Autowired
private PersonRepository personRepository;
@Test
public void whenUsingClosedProjections_thenViewWithRequiredPropertiesIsReturned() {
AddressView addressView = addressRepository.getAddressByState("CA").get(0);
assertThat(addressView.getZipCode()).isEqualTo("90001");
PersonView personView = addressView.getPerson();
assertThat(personView.getFirstName()).isEqualTo("John");
assertThat(personView.getLastName()).isEqualTo("Doe");
}
@Test
public void whenUsingOpenProjections_thenViewWithRequiredPropertiesIsReturned() {
PersonView personView = personRepository.findByLastName("Doe");
assertThat(personView.getFullName()).isEqualTo("John Doe");
}
@Test
public void whenUsingClassBasedProjections_thenDtoWithRequiredPropertiesIsReturned() {
PersonDto personDto = personRepository.findByFirstName("John");
assertThat(personDto.getFirstName()).isEqualTo("John");
assertThat(personDto.getLastName()).isEqualTo("Doe");
}
@Test
public void whenUsingDynamicProjections_thenObjectWithRequiredPropertiesIsReturned() {
Person person = personRepository.findByLastName("Doe", Person.class);
PersonView personView = personRepository.findByLastName("Doe", PersonView.class);
PersonDto personDto = personRepository.findByLastName("Doe", PersonDto.class);
assertThat(person.getFirstName()).isEqualTo("John");
assertThat(personView.getFirstName()).isEqualTo("John");
assertThat(personDto.getFirstName()).isEqualTo("John");
}
}

View File

@ -0,0 +1,2 @@
DELETE FROM address;
DELETE FROM person;

View File

@ -0,0 +1,2 @@
INSERT INTO person(id,first_name,last_name) VALUES (1,'John','Doe');
INSERT INTO address(id,person_id,state,city,street,zip_code) VALUES (1,1,'CA', 'Los Angeles', 'Standford Ave', '90001');

View File

@ -5,7 +5,7 @@
### Relevant Articles: ### Relevant Articles:
- [Spring JPA Multiple Databases](http://www.baeldung.com/spring-data-jpa-multiple-databases) - [Spring JPA Multiple Databases](http://www.baeldung.com/spring-data-jpa-multiple-databases)
- [Spring Data JPA Adding a Method in All Repositories](http://www.baeldung.com/spring-data-jpa-method-in-all-repositories) - [Spring Data JPA Adding a Method in All Repositories](http://www.baeldung.com/spring-data-jpa-method-in-all-repositories)
- [Advanced Tagging Implementation with JPA](http://www.baeldung.com/jpa-tagging-advanced) - [An Advanced Tagging Implementation with JPA](http://www.baeldung.com/jpa-tagging-advanced)
- [Spring Data JPA @Query](http://www.baeldung.com/spring-data-jpa-query) - [Spring Data JPA @Query](http://www.baeldung.com/spring-data-jpa-query)
- [Spring Data Annotations](http://www.baeldung.com/spring-data-annotations) - [Spring Data Annotations](http://www.baeldung.com/spring-data-annotations)
- [Spring Data Java 8 Support](http://www.baeldung.com/spring-data-java-8) - [Spring Data Java 8 Support](http://www.baeldung.com/spring-data-java-8)

18
pom.xml
View File

@ -382,6 +382,7 @@
<!-- <module>core-java-12</module> --> <!-- We haven't upgraded to java 12. Fixing in BAEL-10841 --> <!-- <module>core-java-12</module> --> <!-- We haven't upgraded to java 12. Fixing in BAEL-10841 -->
<module>core-java-8</module> <module>core-java-8</module>
<module>core-java-8-2</module> <module>core-java-8-2</module>
<module>core-java-lambdas</module>
<!--<module>core-java-9</module> --> <!-- We haven't upgraded to java 9. Fixing in BAEL-10841 --> <!--<module>core-java-9</module> --> <!-- We haven't upgraded to java 9. Fixing in BAEL-10841 -->
<!--<module>core-java-os</module> --> <!-- We haven't upgraded to java 9.--> <!--<module>core-java-os</module> --> <!-- We haven't upgraded to java 9.-->
<module>core-java-arrays</module> <module>core-java-arrays</module>
@ -540,7 +541,8 @@
<module>software-security/sql-injection-samples</module> <module>software-security/sql-injection-samples</module>
<module>tensorflow-java</module> <module>tensorflow-java</module>
<module>spring-boot-flowable</module>
</modules> </modules>
</profile> </profile>
@ -586,6 +588,7 @@
<module>spring-5</module> <module>spring-5</module>
<module>spring-5-webflux</module> <module>spring-5-webflux</module>
<module>spring-5-data-reactive</module>
<module>spring-5-mvc</module> <module>spring-5-mvc</module>
<module>spring-5-reactive</module> <module>spring-5-reactive</module>
<module>spring-5-reactive-client</module> <module>spring-5-reactive-client</module>
@ -598,6 +601,7 @@
<module>spring-akka</module> <module>spring-akka</module>
<module>spring-all</module> <module>spring-all</module>
<module>spring-amqp</module> <module>spring-amqp</module>
<module>spring-amqp-simple</module>
<module>spring-aop</module> <module>spring-aop</module>
<module>spring-apache-camel</module> <module>spring-apache-camel</module>
<module>spring-batch</module> <module>spring-batch</module>
@ -764,6 +768,7 @@
<module>xstream</module> <module>xstream</module>
<module>tensorflow-java</module> <module>tensorflow-java</module>
<module>spring-boot-flowable</module>
</modules> </modules>
@ -906,6 +911,8 @@
<module>persistence-modules/spring-data-eclipselink</module> <module>persistence-modules/spring-data-eclipselink</module>
<module>persistence-modules/spring-data-solr</module> <module>persistence-modules/spring-data-solr</module>
<module>persistence-modules/spring-hibernate-5</module> <module>persistence-modules/spring-hibernate-5</module>
<module>spring-boot-flowable</module>
</modules> </modules>
</profile> </profile>
@ -947,6 +954,7 @@
<module>core-java-concurrency-advanced</module> <!-- very long running? --> <module>core-java-concurrency-advanced</module> <!-- very long running? -->
<module>core-kotlin</module> <!-- long running? --> <module>core-kotlin</module> <!-- long running? -->
<module>core-kotlin-2</module> <module>core-kotlin-2</module>
<module>core-kotlin-io</module>
<module>jenkins/hello-world</module> <module>jenkins/hello-world</module>
<module>jws</module> <module>jws</module>
@ -958,9 +966,6 @@
<module>persistence-modules/java-mongodb</module> <module>persistence-modules/java-mongodb</module>
<module>persistence-modules/jnosql</module> <module>persistence-modules/jnosql</module>
<module>spring-5-data-reactive</module> <!-- very long running. Fixing in BAEL-10891 -->
<module>spring-amqp-simple</module> <!-- very long running. Fixing in BAEL-10891 -->
<module>vaadin</module> <module>vaadin</module>
</modules> </modules>
</profile> </profile>
@ -1232,6 +1237,7 @@
<module>spring-4</module> <module>spring-4</module>
<module>spring-5</module> <module>spring-5</module>
<module>spring-5-data-reactive</module>
<module>spring-5-mvc</module> <module>spring-5-mvc</module>
<module>spring-5-reactive</module> <module>spring-5-reactive</module>
<module>spring-5-reactive-client</module> <module>spring-5-reactive-client</module>
@ -1244,6 +1250,7 @@
<module>spring-akka</module> <module>spring-akka</module>
<module>spring-all</module> <module>spring-all</module>
<module>spring-amqp</module> <module>spring-amqp</module>
<module>spring-amqp-simple</module>
<module>spring-aop</module> <module>spring-aop</module>
<module>spring-apache-camel</module> <module>spring-apache-camel</module>
<module>spring-batch</module> <module>spring-batch</module>
@ -1456,9 +1463,6 @@
<module>persistence-modules/java-mongodb</module> <module>persistence-modules/java-mongodb</module>
<module>persistence-modules/jnosql</module> <module>persistence-modules/jnosql</module>
<module>spring-5-data-reactive</module> <!-- very long running. Fixing in BAEL-10891 -->
<module>spring-amqp-simple</module> <!-- very long running. Fixing in BAEL-10891 -->
<module>vaadin</module> <module>vaadin</module>
</modules> </modules>

View File

@ -2,8 +2,8 @@
- [RxJava and Error Handling](http://www.baeldung.com/rxjava-error-handling) - [RxJava and Error Handling](http://www.baeldung.com/rxjava-error-handling)
- [RxJava 2 Flowable](http://www.baeldung.com/rxjava-2-flowable) - [RxJava 2 Flowable](http://www.baeldung.com/rxjava-2-flowable)
- [RxJava 2 - Completable](http://www.baeldung.com/rxjava-completable)
- [RxJava Maybe](http://www.baeldung.com/rxjava-maybe) - [RxJava Maybe](http://www.baeldung.com/rxjava-maybe)
- [Introduction to RxRelay for RxJava](http://www.baeldung.com/rx-relay) - [Introduction to RxRelay for RxJava](http://www.baeldung.com/rx-relay)
- [Combining RxJava Completables](https://www.baeldung.com/rxjava-completable) - [Combining RxJava Completables](https://www.baeldung.com/rxjava-completable)
- [Converting Synchronous and Asynchronous APIs to Observables using RxJava2](https://www.baeldung.com/rxjava-apis-to-observables) - [Converting Synchronous and Asynchronous APIs to Observables using RxJava2](https://www.baeldung.com/rxjava-apis-to-observables)
- [RxJava Hooks](https://www.baeldung.com/rxjava-hooks)

View File

@ -17,7 +17,7 @@ import static org.junit.Assert.assertNotNull;
@RunWith(SpringRunner.class) @RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = Spring5ReactiveApplication.class) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = Spring5ReactiveApplication.class)
public class AccountCrudRepositoryIntegrationTest { public class AccountCrudRepositoryManualTest {
@Autowired @Autowired
AccountCrudRepository repository; AccountCrudRepository repository;

View File

@ -19,7 +19,7 @@ import static org.springframework.data.domain.ExampleMatcher.GenericPropertyMatc
@RunWith(SpringRunner.class) @RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = Spring5ReactiveApplication.class) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = Spring5ReactiveApplication.class)
public class AccountMongoRepositoryIntegrationTest { public class AccountMongoRepositoryManualTest {
@Autowired @Autowired
AccountMongoRepository repository; AccountMongoRepository repository;

View File

@ -15,7 +15,7 @@ import static org.junit.Assert.assertNotNull;
@RunWith(SpringRunner.class) @RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = Spring5ReactiveApplication.class) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = Spring5ReactiveApplication.class)
public class AccountRxJavaRepositoryIntegrationTest { public class AccountRxJavaRepositoryManualTest {
@Autowired @Autowired
AccountRxJavaRepository repository; AccountRxJavaRepository repository;

Some files were not shown because too many files have changed in this diff Show More