Skip to content

Commit b08478d

Browse files
Merge pull request #21 from ydb-platform/spring-data-jpa-v5-example
Spring Data JPA 2.5.7 Example & Hibernate 5
2 parents 1bff0e7 + a05814e commit b08478d

File tree

19 files changed

+818
-0
lines changed

19 files changed

+818
-0
lines changed

jdbc/pom.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
<modules>
2323
<module>basic-example</module>
24+
<module>spring-data-jpa-v5</module>
2425
</modules>
2526

2627
<dependencyManagement>

jdbc/spring-data-jpa-v5/pom.xml

Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
2+
<modelVersion>4.0.0</modelVersion>
3+
<parent>
4+
<groupId>tech.ydb.jdbc.examples</groupId>
5+
<artifactId>ydb-jdbc-examples</artifactId>
6+
<version>1.1.0-SNAPSHOT</version>
7+
</parent>
8+
9+
<artifactId>spring-data-jpa-v5</artifactId>
10+
<name>Spring Data JPA Example Hibernate 5</name>
11+
<description>Basic example for SpringBoot3 and Hibernate 6</description>
12+
<properties>
13+
<kotlin.version>1.9.22</kotlin.version>
14+
<hibernate.ydb.dialect.version>0.9.1</hibernate.ydb.dialect.version>
15+
<spring.boot.version>2.5.7</spring.boot.version>
16+
</properties>
17+
<dependencies>
18+
<dependency>
19+
<groupId>org.springframework.boot</groupId>
20+
<artifactId>spring-boot-starter-data-jpa</artifactId>
21+
<version>${spring.boot.version}</version>
22+
</dependency>
23+
<dependency>
24+
<groupId>org.springframework.data</groupId>
25+
<artifactId>spring-data-commons</artifactId>
26+
<version>${spring.boot.version}</version>
27+
</dependency>
28+
<dependency>
29+
<groupId>org.jetbrains.kotlin</groupId>
30+
<artifactId>kotlin-reflect</artifactId>
31+
<version>${kotlin.version}</version>
32+
</dependency>
33+
<dependency>
34+
<groupId>org.jetbrains.kotlin</groupId>
35+
<artifactId>kotlin-stdlib</artifactId>
36+
<version>${kotlin.version}</version>
37+
</dependency>
38+
<dependency>
39+
<groupId>tech.ydb.dialects</groupId>
40+
<artifactId>hibernate-ydb-dialect-v5</artifactId>
41+
<version>${hibernate.ydb.dialect.version}</version>
42+
</dependency>
43+
<dependency>
44+
<groupId>tech.ydb.jdbc</groupId>
45+
<artifactId>ydb-jdbc-driver-shaded</artifactId>
46+
</dependency>
47+
<dependency>
48+
<groupId>com.github.javafaker</groupId>
49+
<artifactId>javafaker</artifactId>
50+
<version>1.0.2</version>
51+
</dependency>
52+
<dependency>
53+
<groupId>org.jetbrains.kotlinx</groupId>
54+
<artifactId>kotlinx-coroutines-core</artifactId>
55+
<version>1.7.3</version>
56+
</dependency>
57+
<dependency>
58+
<groupId>org.postgresql</groupId>
59+
<artifactId>postgresql</artifactId>
60+
<version>42.7.1</version>
61+
</dependency>
62+
<dependency>
63+
<groupId>org.testcontainers</groupId>
64+
<artifactId>postgresql</artifactId>
65+
<version>1.19.1</version>
66+
<scope>test</scope>
67+
</dependency>
68+
<dependency>
69+
<groupId>tech.ydb.test</groupId>
70+
<artifactId>ydb-junit5-support</artifactId>
71+
<scope>test</scope>
72+
<exclusions>
73+
<exclusion>
74+
<groupId>org.junit.jupiter</groupId>
75+
<artifactId>junit-jupiter-api</artifactId>
76+
</exclusion>
77+
</exclusions>
78+
</dependency>
79+
<dependency>
80+
<groupId>org.springframework.boot</groupId>
81+
<artifactId>spring-boot-starter-test</artifactId>
82+
<version>${spring.boot.version}</version>
83+
<scope>test</scope>
84+
</dependency>
85+
</dependencies>
86+
<build>
87+
<sourceDirectory>${project.basedir}/src/main/kotlin</sourceDirectory>
88+
<testSourceDirectory>${project.basedir}/src/test/kotlin</testSourceDirectory>
89+
<plugins>
90+
<plugin>
91+
<groupId>org.apache.maven.plugins</groupId>
92+
<artifactId>maven-surefire-plugin</artifactId>
93+
<configuration>
94+
<environmentVariables>
95+
<TESTCONTAINERS_REUSE_ENABLE>true</TESTCONTAINERS_REUSE_ENABLE>
96+
</environmentVariables>
97+
</configuration>
98+
</plugin>
99+
<plugin>
100+
<groupId>org.springframework.boot</groupId>
101+
<artifactId>spring-boot-maven-plugin</artifactId>
102+
<version>${spring.boot.version}</version>
103+
</plugin>
104+
<plugin>
105+
<groupId>org.jetbrains.kotlin</groupId>
106+
<artifactId>kotlin-maven-plugin</artifactId>
107+
<version>${kotlin.version}</version>
108+
<executions>
109+
<execution>
110+
<id>compile</id>
111+
<phase>compile</phase>
112+
<goals>
113+
<goal>compile</goal>
114+
</goals>
115+
</execution>
116+
<execution>
117+
<id>test-compile</id>
118+
<goals>
119+
<goal>test-compile</goal>
120+
</goals>
121+
</execution>
122+
</executions>
123+
<configuration>
124+
<args>
125+
<arg>-Xjsr305=strict</arg>
126+
</args>
127+
<compilerPlugins>
128+
<plugin>spring</plugin>
129+
<plugin>jpa</plugin>
130+
</compilerPlugins>
131+
</configuration>
132+
<dependencies>
133+
<dependency>
134+
<groupId>org.jetbrains.kotlin</groupId>
135+
<artifactId>kotlin-maven-allopen</artifactId>
136+
<version>${kotlin.version}</version>
137+
</dependency>
138+
<dependency>
139+
<groupId>org.jetbrains.kotlin</groupId>
140+
<artifactId>kotlin-maven-noarg</artifactId>
141+
<version>${kotlin.version}</version>
142+
</dependency>
143+
</dependencies>
144+
</plugin>
145+
</plugins>
146+
</build>
147+
</project>
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package tech.ydb.jpa.pagination
2+
3+
import javax.persistence.Entity
4+
import javax.persistence.Id
5+
import javax.persistence.Table
6+
7+
@Entity
8+
@Table(name = "authors")
9+
class Author {
10+
11+
@Id
12+
lateinit var id: String
13+
14+
lateinit var firstName: String
15+
16+
lateinit var lastName: String
17+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package tech.ydb.jpa.pagination
2+
3+
import java.util.*
4+
import javax.persistence.*
5+
6+
@Entity
7+
@Table(name = "books")
8+
class Book {
9+
10+
@Id
11+
lateinit var id: String
12+
13+
lateinit var title: String
14+
lateinit var isbn10: String
15+
lateinit var publicationDate: Date
16+
17+
@ManyToOne
18+
lateinit var author: Author
19+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package tech.ydb.jpa.pagination
2+
3+
import org.springframework.data.domain.*
4+
import org.springframework.data.jpa.repository.Query
5+
import org.springframework.data.repository.CrudRepository
6+
import org.springframework.data.repository.query.Param
7+
8+
interface BookRepository : CrudRepository<Book, String> {
9+
10+
/**
11+
* Uses an offset based pagination that first sorts the entries by their [ publication_date][Book.getPublicationDate]
12+
* and then limits the result by dropping the number of rows specified in the
13+
* [offset][Pageable.getOffset] clause. To retrieve [Page.getTotalElements] an additional count query
14+
* is executed.
15+
*
16+
* @param title
17+
* @param pageable
18+
*/
19+
@Query(
20+
"SELECT * FROM books WHERE books.title LIKE %:title% ORDER BY books.publication_date",
21+
countQuery = "SELECT count(*) FROM books WHERE books.title LIKE %:title%",
22+
nativeQuery = true
23+
)
24+
fun findByTitleContainsOrderByPublicationDate(@Param("title") title: String, pageable: Pageable): Page<Book>
25+
26+
/**
27+
* Uses an offset based slicing that first sorts the entries by their [ publication_date][Book.getPublicationDate]
28+
* and then limits the result by dropping the number of rows specified in the
29+
* [offset][Pageable.getOffset] clause.
30+
*
31+
* @param title
32+
* @param pageable
33+
*/
34+
@Query(
35+
"SELECT * FROM books WHERE books.title LIKE %:title% ORDER BY books.publication_date",
36+
nativeQuery = true
37+
)
38+
fun findBooksByTitleContainsOrderByPublicationDate(title: String, pageable: Pageable): Slice<Book>
39+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package tech.ydb.jpa.pagination
2+
3+
import org.springframework.boot.autoconfigure.SpringBootApplication
4+
5+
@SpringBootApplication
6+
class PagingApplication
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
package tech.ydb.jpa.simple;
2+
3+
import org.springframework.data.domain.Pageable
4+
import org.springframework.data.domain.Slice
5+
import org.springframework.data.jpa.repository.Query
6+
import org.springframework.data.repository.CrudRepository
7+
import org.springframework.scheduling.annotation.Async
8+
import java.util.concurrent.CompletableFuture
9+
import java.util.stream.Stream
10+
11+
/**
12+
* Simple repository interface for {@link User} instances. The interface is used to declare the so-called query methods,
13+
* i.e. methods to retrieve single entities or collections of them.
14+
*/
15+
interface SimpleUserRepository : CrudRepository<User, Long> {
16+
17+
/**
18+
* Find the user with the given username. This method will be translated into a query using the
19+
* {@link jakarta.persistence.NamedQuery} annotation at the {@link User} class.
20+
*
21+
* @param username
22+
*/
23+
fun findByTheUsersName(username: String): User
24+
25+
/**
26+
* Uses {@link Optional} as return and parameter type.
27+
*
28+
* @param username
29+
*/
30+
fun findByUsername(username: String?): User?
31+
32+
/**
33+
* Find all users with the given lastname. This method will be translated into a query by constructing it directly
34+
* from the method name as there is no other query declared.
35+
*
36+
* @param lastname
37+
*/
38+
fun findByLastname(lastname: String): List<User>
39+
40+
41+
/**
42+
* Returns all users with the given firstname. This method will be translated into a query using the one declared in
43+
* the {@link Query} annotation declared one.
44+
*
45+
* @param firstname
46+
*/
47+
@Query("select u from User u where u.firstname = :firstname")
48+
fun findByFirstname(firstname: String): List<User>
49+
50+
51+
/**
52+
* Returns all users with the given name as first- or lastname. This makes the query to method relation much more
53+
* refactoring-safe as the order of the method parameters is completely irrelevant.
54+
*
55+
* @param name
56+
*/
57+
@Query("select u from User u where u.firstname = :name or u.lastname = :name")
58+
fun findByFirstnameOrLastname(name: String): List<User>
59+
60+
/**
61+
* Returns the total number of entries deleted as their lastnames match the given one.
62+
*
63+
* @param lastname
64+
* @return
65+
*/
66+
fun removeByLastname(lastname: String): Long
67+
68+
/**
69+
* Returns a {@link Slice} counting a maximum number of {@link Pageable#getPageSize()} users matching given criteria
70+
* starting at {@link Pageable#getOffset()} without prior count of the total number of elements available.
71+
*
72+
* @param lastname
73+
* @param page
74+
*/
75+
@Query(
76+
"SELECT * FROM users WHERE users.lastname = :lastname ORDER BY users.username",
77+
nativeQuery = true
78+
)
79+
fun findByLastnameOrderByUsernameAsc(lastname: String, page: Pageable): Slice<User>
80+
81+
/**
82+
* Return the first 2 users ordered by their lastname asc.
83+
*
84+
* <pre>
85+
* Example for findFirstK / findTopK functionality.
86+
* </pre>
87+
*/
88+
@Query("SELECT * FROM users ORDER BY lastname LIMIT 2", nativeQuery = true)
89+
fun findFirst2ByOrderByLastnameAsc(): List<User>
90+
91+
92+
/**
93+
* Return all the users with the given firstname or lastname. Makes use of SpEL (Spring Expression Language).
94+
*
95+
* @param user
96+
*/
97+
@Query("select u from User u where u.firstname = :#{#user.firstname} or u.lastname = :#{#user.lastname}")
98+
fun findByFirstnameOrLastname(user: User): Iterable<User>
99+
100+
/**
101+
* Sample default method.
102+
*
103+
* @param user
104+
*/
105+
fun findByLastname(user: User): List<User> {
106+
return findByLastname(user.lastname);
107+
}
108+
109+
/**
110+
* Sample method to demonstrate support for {@link Stream} as a return type with a custom query. The query is executed
111+
* in a streaming fashion which means that the method returns as soon as the first results are ready.
112+
*/
113+
@Query("select u from User u")
114+
fun streamAllCustomers(): Stream<User>
115+
116+
/**
117+
* Sample method to demonstrate support for {@link Stream} as a return type with a derived query. The query is
118+
* executed in a streaming fashion which means that the method returns as soon as the first results are ready.
119+
*/
120+
fun findAllByLastnameIsNotNull(): Stream<User>
121+
122+
@Async
123+
fun readAllBy(): CompletableFuture<List<User>>
124+
}

0 commit comments

Comments
 (0)