Merge branch 'master' into master
This commit is contained in:
commit
7b84d6ce6f
|
@ -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/
|
||||||
|
|
|
@ -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)
|
||||||
|
|
||||||
|
|
|
@ -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`
|
||||||
|
|
|
@ -2,4 +2,6 @@
|
||||||
|
|
||||||
## Relevant articles:
|
## Relevant articles:
|
||||||
|
|
||||||
|
- [String Matching in Groovy](http://www.baeldung.com/)
|
||||||
- [Groovy def Keyword]
|
- [Groovy def Keyword]
|
||||||
|
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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/
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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)
|
|
@ -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/
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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)
|
||||||
|
|
|
@ -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 8’s 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)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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>
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
package com.baeldung.generics;
|
||||||
|
|
||||||
|
public interface Rankable {
|
||||||
|
public int getRank();
|
||||||
|
}
|
|
@ -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());
|
||||||
|
}
|
||||||
|
}
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
|
@ -0,0 +1,11 @@
|
||||||
|
/bin/
|
||||||
|
|
||||||
|
#ignore gradle
|
||||||
|
.gradle/
|
||||||
|
|
||||||
|
|
||||||
|
#ignore build and generated files
|
||||||
|
build/
|
||||||
|
node/
|
||||||
|
target/
|
||||||
|
out/
|
|
@ -0,0 +1,3 @@
|
||||||
|
## Relevant articles:
|
||||||
|
|
||||||
|
- [InputStream to String in Kotlin](https://www.baeldung.com/kotlin-inputstream-to-string)
|
|
@ -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>
|
|
@ -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()
|
||||||
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
Computer programming can be a hassle
|
||||||
|
It's like trying to take a defended castle
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
## Relevant Articles:
|
||||||
|
- [Map of Primitives in Java](https://www.baeldung.com/java-map-primitives)
|
|
@ -0,0 +1,2 @@
|
||||||
|
## Relevant Articles:
|
||||||
|
- [Converting Between LocalDate and XMLGregorianCalendar](https://www.baeldung.com/java-localdate-to-xmlgregoriancalendar)
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
|
@ -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>
|
||||||
|
|
|
@ -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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
### Relevant Articles:
|
||||||
|
|
||||||
|
- [Get Log Output in JSON](https://www.baeldung.com/java-log-json-output)
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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>
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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> {
|
||||||
|
}
|
|
@ -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 + '\'' +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
|
@ -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
|
|
@ -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());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
|
||||||
|
}
|
|
@ -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> {
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
package com.baeldung.projection.view;
|
||||||
|
|
||||||
|
public interface AddressView {
|
||||||
|
String getZipCode();
|
||||||
|
|
||||||
|
PersonView getPerson();
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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();
|
||||||
|
}
|
|
@ -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();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -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());
|
||||||
|
}
|
||||||
|
}
|
|
@ -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");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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");
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,2 @@
|
||||||
|
DELETE FROM address;
|
||||||
|
DELETE FROM person;
|
|
@ -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');
|
|
@ -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
18
pom.xml
|
@ -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>
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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;
|
|
@ -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;
|
|
@ -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
Loading…
Reference in New Issue