Merge branch 'eugenp:master' into master

This commit is contained in:
edizor 2023-03-19 02:04:52 +08:00 committed by GitHub
commit b16e7bfc2a
37 changed files with 571 additions and 187 deletions

View File

@ -35,12 +35,12 @@
</dependency>
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-connector-kafka-0.11_2.11</artifactId>
<artifactId>flink-connector-kafka</artifactId>
<version>${flink.version}</version>
</dependency>
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-streaming-java_2.11</artifactId>
<artifactId>flink-streaming-java</artifactId>
<version>${flink.version}</version>
</dependency>
<dependency>
@ -67,7 +67,7 @@
</dependency>
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-test-utils_2.11</artifactId>
<artifactId>flink-test-utils</artifactId>
<version>${flink.version}</version>
<scope>test</scope>
</dependency>
@ -163,11 +163,29 @@
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<argLine>
--add-opens java.base/java.time=ALL-UNNAMED
--add-opens java.base/java.nio=ALL-UNNAMED
--add-opens java.base/java.util=ALL-UNNAMED
</argLine>
</configuration>
</plugin>
</plugins>
</build>
<properties>
<kafka.version>2.8.0</kafka.version>
<kafka.version>3.4.0</kafka.version>
<testcontainers-kafka.version>1.15.3</testcontainers-kafka.version>
<testcontainers-jupiter.version>1.15.3</testcontainers-jupiter.version>
<flink.version>1.5.0</flink.version>
<flink.version>1.16.1</flink.version>
<awaitility.version>3.0.0</awaitility.version>
<org.apache.spark.spark-core.version>2.4.8</org.apache.spark.spark-core.version>
<graphframes.version>0.8.1-spark3.0-s_2.12</graphframes.version>

View File

@ -9,8 +9,8 @@ import org.apache.flink.streaming.api.TimeCharacteristic;
import org.apache.flink.streaming.api.datastream.DataStream;
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
import org.apache.flink.streaming.api.windowing.time.Time;
import org.apache.flink.streaming.connectors.kafka.FlinkKafkaConsumer011;
import org.apache.flink.streaming.connectors.kafka.FlinkKafkaProducer011;
import org.apache.flink.streaming.connectors.kafka.FlinkKafkaConsumer;
import org.apache.flink.streaming.connectors.kafka.FlinkKafkaProducer;
import static com.baeldung.flink.connector.Consumers.*;
import static com.baeldung.flink.connector.Producers.*;
@ -25,12 +25,12 @@ public class FlinkDataPipeline {
StreamExecutionEnvironment environment = StreamExecutionEnvironment.getExecutionEnvironment();
FlinkKafkaConsumer011<String> flinkKafkaConsumer = createStringConsumerForTopic(inputTopic, address, consumerGroup);
FlinkKafkaConsumer<String> flinkKafkaConsumer = createStringConsumerForTopic(inputTopic, address, consumerGroup);
flinkKafkaConsumer.setStartFromEarliest();
DataStream<String> stringInputStream = environment.addSource(flinkKafkaConsumer);
FlinkKafkaProducer011<String> flinkKafkaProducer = createStringProducer(outputTopic, address);
FlinkKafkaProducer<String> flinkKafkaProducer = createStringProducer(outputTopic, address);
stringInputStream.map(new WordsCapitalizer())
.addSink(flinkKafkaProducer);
@ -48,11 +48,11 @@ public class FlinkDataPipeline {
environment.setStreamTimeCharacteristic(TimeCharacteristic.EventTime);
FlinkKafkaConsumer011<InputMessage> flinkKafkaConsumer = createInputMessageConsumer(inputTopic, kafkaAddress, consumerGroup);
FlinkKafkaConsumer<InputMessage> flinkKafkaConsumer = createInputMessageConsumer(inputTopic, kafkaAddress, consumerGroup);
flinkKafkaConsumer.setStartFromEarliest();
flinkKafkaConsumer.assignTimestampsAndWatermarks(new InputMessageTimestampAssigner());
FlinkKafkaProducer011<Backup> flinkKafkaProducer = createBackupProducer(outputTopic, kafkaAddress);
FlinkKafkaProducer<Backup> flinkKafkaProducer = createBackupProducer(outputTopic, kafkaAddress);
DataStream<InputMessage> inputMessagesStream = environment.addSource(flinkKafkaConsumer);

View File

@ -3,26 +3,26 @@ package com.baeldung.flink.connector;
import com.baeldung.flink.model.InputMessage;
import com.baeldung.flink.schema.InputMessageDeserializationSchema;
import org.apache.flink.api.common.serialization.SimpleStringSchema;
import org.apache.flink.streaming.connectors.kafka.FlinkKafkaConsumer011;
import org.apache.flink.streaming.connectors.kafka.FlinkKafkaConsumer;
import java.util.Properties;
public class Consumers {
public static FlinkKafkaConsumer011<String> createStringConsumerForTopic(String topic, String kafkaAddress, String kafkaGroup) {
public static FlinkKafkaConsumer<String> createStringConsumerForTopic(String topic, String kafkaAddress, String kafkaGroup) {
Properties props = new Properties();
props.setProperty("bootstrap.servers", kafkaAddress);
props.setProperty("group.id", kafkaGroup);
FlinkKafkaConsumer011<String> consumer = new FlinkKafkaConsumer011<>(topic, new SimpleStringSchema(), props);
FlinkKafkaConsumer<String> consumer = new FlinkKafkaConsumer<>(topic, new SimpleStringSchema(), props);
return consumer;
}
public static FlinkKafkaConsumer011<InputMessage> createInputMessageConsumer(String topic, String kafkaAddress, String kafkaGroup) {
public static FlinkKafkaConsumer<InputMessage> createInputMessageConsumer(String topic, String kafkaAddress, String kafkaGroup) {
Properties properties = new Properties();
properties.setProperty("bootstrap.servers", kafkaAddress);
properties.setProperty("group.id", kafkaGroup);
FlinkKafkaConsumer011<InputMessage> consumer = new FlinkKafkaConsumer011<InputMessage>(topic, new InputMessageDeserializationSchema(), properties);
FlinkKafkaConsumer<InputMessage> consumer = new FlinkKafkaConsumer<InputMessage>(topic, new InputMessageDeserializationSchema(), properties);
return consumer;
}

View File

@ -3,15 +3,15 @@ package com.baeldung.flink.connector;
import com.baeldung.flink.model.Backup;
import com.baeldung.flink.schema.BackupSerializationSchema;
import org.apache.flink.api.common.serialization.SimpleStringSchema;
import org.apache.flink.streaming.connectors.kafka.FlinkKafkaProducer011;
import org.apache.flink.streaming.connectors.kafka.FlinkKafkaProducer;
public class Producers {
public static FlinkKafkaProducer011<String> createStringProducer(String topic, String kafkaAddress) {
return new FlinkKafkaProducer011<>(kafkaAddress, topic, new SimpleStringSchema());
public static FlinkKafkaProducer<String> createStringProducer(String topic, String kafkaAddress) {
return new FlinkKafkaProducer<>(kafkaAddress, topic, new SimpleStringSchema());
}
public static FlinkKafkaProducer011<Backup> createBackupProducer(String topic, String kafkaAddress) {
return new FlinkKafkaProducer011<Backup>(kafkaAddress, topic, new BackupSerializationSchema());
public static FlinkKafkaProducer<Backup> createBackupProducer(String topic, String kafkaAddress) {
return new FlinkKafkaProducer<Backup>(kafkaAddress, topic, new BackupSerializationSchema());
}
}

View File

@ -103,7 +103,7 @@
<configuration>
<packageName>com.baeldung.feign.soap</packageName>
<sources>
<source>src/main/resources/users.xsd</source>
<source>${project.basedir}/src/main/resources/users.xsd</source>
</sources>
</configuration>
</plugin>

5
jetbrains/README.md Normal file
View File

@ -0,0 +1,5 @@
## Jetbrains
This module contains articles about Jetbrains' libraries.
### Relevant articles:

37
jetbrains/pom.xml Normal file
View File

@ -0,0 +1,37 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>jetbrains</artifactId>
<version>1.0-SNAPSHOT</version>
<name>jetbrains</name>
<packaging>jar</packaging>
<url>http://maven.apache.org</url>
<parent>
<groupId>com.baeldung</groupId>
<artifactId>parent-java</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../parent-java</relativePath>
</parent>
<dependencies>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>${apache.commons.version}</version>
</dependency>
<dependency>
<groupId>org.jetbrains</groupId>
<artifactId>annotations</artifactId>
<version>${jetbrains.annotations.version}</version>
</dependency>
</dependencies>
<properties>
<apache.commons.version>3.12.0</apache.commons.version>
<jetbrains.annotations.version>24.0.1</jetbrains.annotations.version>
</properties>
</project>

View File

@ -0,0 +1,112 @@
package com.baeldung.annotations;
import java.util.List;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.Contract;
public class Demo {
@Contract("_ -> new")
Person fromName(String name) {
return new Person().withName(name);
}
@Contract(" -> fail")
void alwaysFail() {
throw new RuntimeException();
}
@Contract(" -> fail")
void doNothingWithWrongContract() {
}
@Contract("_, null -> null; null, _ -> param2; _, !null -> !null")
String concatenateOnlyIfSecondArgumentIsNotNull(String head, String tail) {
if (tail == null) {
return null;
}
if (head == null) {
return tail;
}
return head + tail;
}
void uselessNullCheck() {
String head = "1234";
String tail = "5678";
String concatenation = concatenateOnlyIfSecondArgumentIsNotNull(head, tail);
if (concatenation != null) {
System.out.println(concatenation);
}
}
void uselessNullCheckOnInferredAnnotation() {
if (StringUtils.isEmpty(null)) {
System.out.println("baeldung");
}
}
@Contract(pure = true)
String replace(String string, char oldChar, char newChar) {
return string.replace(oldChar, newChar);
}
@Contract(value = "true -> false; false -> true", pure = true)
boolean not(boolean input) {
return !input;
}
@Contract("true -> new")
void contractExpectsWrongParameterType(List<Integer> integers) {
}
@Contract("_, _ -> new")
void contractExpectsMoreParametersThanMethodHas(String s) {
}
@Contract("_ -> _; null -> !null")
String secondContractClauseNotReachable(String s) {
return "";
}
@Contract("_ -> true")
void contractExpectsWrongReturnType(String s) {
}
// NB: the following examples demonstrate how to use the mutates attribute of the annotation
// This attribute is currently experimental and could be changed or removed in the future
@Contract(mutates = "param")
void incrementArrayFirstElement(Integer[] integers) {
if (integers.length > 0) {
integers[0] = integers[0] + 1;
}
}
@Contract(pure = true, mutates = "param")
void impossibleToMutateParamInPureFunction(List<String> strings) {
if (strings != null) {
strings.forEach(System.out::println);
}
}
@Contract(mutates = "param3")
void impossibleToMutateThirdParamWhenMethodHasOnlyTwoParams(int a, int b) {
}
@Contract(mutates = "param")
void impossibleToMutableImmutableType(String s) {
}
@Contract(mutates = "this")
static void impossibleToMutateThisInStaticMethod() {
}
}

View File

@ -0,0 +1,15 @@
package com.baeldung.annotations;
import org.jetbrains.annotations.Contract;
public class Person {
String name;
@Contract("_ -> this")
Person withName(String name) {
this.name = name;
return this;
}
}

View File

@ -48,8 +48,15 @@
<plugin>
<groupId>com.lazerycode.jmeter</groupId>
<artifactId>jmeter-maven-plugin</artifactId>
<version>${jmeter.version}</version>
<version>3.7.0</version>
<executions>
<!-- Generate JMeter configuration -->
<execution>
<id>configuration</id>
<goals>
<goal>configure</goal>
</goals>
</execution>
<execution>
<id>jmeter-tests</id>
<goals>
@ -66,7 +73,6 @@
</build>
<properties>
<jmeter.version>2.6.0</jmeter.version>
</properties>
<profiles>

View File

@ -57,7 +57,7 @@
<stringProp name="filename"></stringProp>
<stringProp name="parameters"></stringProp>
<boolProp name="resetInterpreter">false</boolProp>
<stringProp name="script">FileWriter fWriter = new FileWriter(&quot;<path>/result.txt&quot;, true);
<stringProp name="script">FileWriter fWriter = new FileWriter(&quot;&lt;path&gt;/result.txt&quot;, true);
BufferedWriter buff = new BufferedWriter(fWriter);
buff.write(&quot;Response Code : &quot; + ctx.getPreviousResult().getResponseCode());

View File

@ -98,7 +98,8 @@
<module>spring-data-mongodb-reactive</module>
<module>spring-data-neo4j</module>
<module>spring-data-redis</module>
<module>spring-data-rest</module>
<!-- Moved to JDK9+ profiles-->
<!-- <module>spring-data-rest</module>-->
<module>spring-data-rest-2</module>
<module>spring-data-rest-querydsl</module>
<module>spring-data-solr</module>

View File

@ -11,9 +11,9 @@
<parent>
<groupId>com.baeldung</groupId>
<artifactId>parent-boot-2</artifactId>
<artifactId>parent-boot-3</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../../parent-boot-2</relativePath>
<relativePath>../../parent-boot-3</relativePath>
</parent>
<dependencies>
@ -42,6 +42,17 @@
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hibernate.orm</groupId>
<artifactId>hibernate-community-dialects</artifactId>
<version>${hibernate-community-dialects.version}</version>
</dependency>
<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>rest-assured</artifactId>
<version>3.3.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
@ -64,23 +75,6 @@
<build>
<finalName>${project.artifactId}</finalName>
<plugins>
<plugin>
<groupId>com.mysema.maven</groupId>
<artifactId>maven-apt-plugin</artifactId>
<version>${maven.version}</version>
<executions>
<execution>
<phase>generate-sources</phase>
<goals>
<goal>process</goal>
</goals>
<configuration>
<outputDirectory>target/generated-sources</outputDirectory>
<processor>com.querydsl.apt.jpa.JPAAnnotationProcessor</processor>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
@ -91,6 +85,7 @@
<properties>
<start-class>com.baeldung.books.SpringDataRestApplication</start-class>
<maven.version>1.0</maven.version>
<hibernate-community-dialects.version>6.1.7.Final</hibernate-community-dialects.version>
</properties>
</project>

View File

@ -1,78 +0,0 @@
package com.baeldung.books.dialect;
import org.hibernate.dialect.Dialect;
import org.hibernate.dialect.identity.IdentityColumnSupport;
import java.sql.Types;
public class SQLiteDialect extends Dialect {
public SQLiteDialect() {
registerColumnType(Types.BIT, "integer");
registerColumnType(Types.TINYINT, "tinyint");
registerColumnType(Types.SMALLINT, "smallint");
registerColumnType(Types.INTEGER, "integer");
registerColumnType(Types.BIGINT, "bigint");
registerColumnType(Types.FLOAT, "float");
registerColumnType(Types.REAL, "real");
registerColumnType(Types.DOUBLE, "double");
registerColumnType(Types.NUMERIC, "numeric");
registerColumnType(Types.DECIMAL, "decimal");
registerColumnType(Types.CHAR, "char");
registerColumnType(Types.VARCHAR, "varchar");
registerColumnType(Types.LONGVARCHAR, "longvarchar");
registerColumnType(Types.DATE, "date");
registerColumnType(Types.TIME, "time");
registerColumnType(Types.TIMESTAMP, "timestamp");
registerColumnType(Types.BINARY, "blob");
registerColumnType(Types.VARBINARY, "blob");
registerColumnType(Types.LONGVARBINARY, "blob");
registerColumnType(Types.BLOB, "blob");
registerColumnType(Types.CLOB, "clob");
registerColumnType(Types.BOOLEAN, "integer");
}
public IdentityColumnSupport getIdentityColumnSupport() {
return new SQLiteIdentityColumnSupport();
}
public boolean hasAlterTable() {
return false;
}
public boolean dropConstraints() {
return false;
}
public String getDropForeignKeyString() {
return "";
}
public String getAddForeignKeyConstraintString(String constraintName, String[] foreignKey, String referencedTable, String[] primaryKey, boolean referencesPrimaryKey) {
return "";
}
public String getAddPrimaryKeyConstraintString(String constraintName) {
return "";
}
public String getForUpdateString() {
return "";
}
public String getAddColumnString() {
return "add column";
}
public boolean supportsOuterJoinForUpdate() {
return false;
}
public boolean supportsIfExistsBeforeTableName() {
return true;
}
public boolean supportsCascadeDelete() {
return false;
}
}

View File

@ -1,22 +0,0 @@
package com.baeldung.books.dialect;
import org.hibernate.MappingException;
import org.hibernate.dialect.identity.IdentityColumnSupportImpl;
public class SQLiteIdentityColumnSupport extends IdentityColumnSupportImpl {
@Override
public boolean supportsIdentityColumns() {
return true;
}
@Override
public String getIdentitySelectString(String table, String column, int type) throws MappingException {
return "select last_insert_rowid()";
}
@Override
public String getIdentityColumnString(int type) throws MappingException {
return "integer";
}
}

View File

@ -1,11 +1,11 @@
package com.baeldung.books.models;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToOne;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.OneToOne;
@Entity
public class Address {

View File

@ -2,15 +2,15 @@ package com.baeldung.books.models;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import jakarta.persistence.CascadeType;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.JoinTable;
import jakarta.persistence.ManyToMany;
@Entity
public class Author {

View File

@ -2,15 +2,15 @@ package com.baeldung.books.models;
import java.util.List;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToMany;
import jakarta.persistence.ManyToOne;
@Entity
public class Book {

View File

@ -2,14 +2,14 @@ package com.baeldung.books.models;
import java.util.List;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.OneToMany;
import jakarta.persistence.OneToOne;
import org.springframework.data.rest.core.annotation.RestResource;

View File

@ -1,10 +1,10 @@
package com.baeldung.books.models;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
@Entity
public class Subject {

View File

@ -2,6 +2,6 @@ driverClassName=org.sqlite.JDBC
url=jdbc:sqlite:memory:myDb?cache=shared
username=sa
password=sa
hibernate.dialect=com.baeldung.dialect.SQLiteDialect
spring.jpa.database-platform=org.hibernate.community.dialect.SQLiteDialect
hibernate.hbm2ddl.auto=create-drop
hibernate.show_sql=true

View File

@ -352,6 +352,7 @@
<module>java-jdi</module>
<module>java-websocket</module>
<module>jetbrains</module>
<module>jhipster-5</module>
<module>jmh</module>
@ -730,7 +731,7 @@
<module>spring-boot-modules/spring-boot-react</module>
<module>spring-ejb-modules/ejb-beans</module>
<module>vaadin</module>
<module>vavr-modules</module>
<module>vavr-modules</module>
</modules>
</profile>
@ -904,6 +905,7 @@
<module>spring-swagger-codegen/custom-validations-opeanpi-codegen</module>
<module>testing-modules/testing-assertions</module>
<module>persistence-modules/fauna</module>
<module>persistence-modules/spring-data-rest</module>
<module>rule-engines-modules</module>
@ -933,7 +935,6 @@
<module>asm</module>
<module>atomikos</module>
<module>atomix</module>
<!-- <module>axon</module>--><!-- JAVA-18408 -->
<module>bazel</module>
<module>code-generation</module>
@ -1162,6 +1163,7 @@
<module>spring-swagger-codegen/custom-validations-opeanpi-codegen</module>
<module>testing-modules/testing-assertions</module>
<module>persistence-modules/fauna</module>
<module>persistence-modules/spring-data-rest</module>
<module>rule-engines-modules</module>

View File

@ -28,13 +28,13 @@
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>${jaxb.version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
<version>${jaxb.version}</version>
<scope>runtime</scope>
</dependency>
<!-- SQLite database driver -->
<dependency>

View File

@ -124,6 +124,8 @@
<mapstruct.version>1.5.2.Final</mapstruct.version>
<springdoc.version>2.0.0</springdoc.version>
<maven-surefire-plugin.version>3.0.0-M7</maven-surefire-plugin.version>
<start-class>com.baeldung.sample.TodoApplication</start-class>
</properties>
</project>

View File

@ -0,0 +1,42 @@
package com.baeldung.recordswithjpa;
import com.baeldung.recordswithjpa.entity.Book;
import com.baeldung.recordswithjpa.records.BookRecord;
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import jakarta.persistence.Query;
import jakarta.persistence.TypedQuery;
import jakarta.persistence.criteria.CriteriaBuilder;
import jakarta.persistence.criteria.CriteriaQuery;
import jakarta.persistence.criteria.Root;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class QueryService {
@PersistenceContext
private EntityManager entityManager;
public List<BookRecord> findAllBooks() {
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<BookRecord> query = cb.createQuery(BookRecord.class);
Root<Book> root = query.from(Book.class);
query.select(cb
.construct(BookRecord.class, root.get("id"), root.get("title"), root.get("author"), root.get("isbn")));
return entityManager.createQuery(query).getResultList();
}
public BookRecord findBookById(Long id) {
TypedQuery<BookRecord> query = entityManager
.createQuery("SELECT new com.baeldung.recordswithjpa.records.BookRecord(b.id, b.title, b.author, b.isbn) " +
"FROM Book b WHERE b.id = :id", BookRecord.class);
query.setParameter("id", id);
return query.getSingleResult();
}
public List<BookRecord> findAllBooksUsingMapping() {
Query query = entityManager.createNativeQuery("SELECT * FROM book", "BookRecordMapping");
return query.getResultList();
}
}

View File

@ -0,0 +1,13 @@
package com.baeldung.recordswithjpa;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class RecordsAsJpaApplication {
public static void main(String[] args) {
SpringApplication.run(RecordsAsJpaApplication.class, args);
}
}

View File

@ -0,0 +1,70 @@
package com.baeldung.recordswithjpa.entity;
import com.baeldung.recordswithjpa.records.BookRecord;
import jakarta.persistence.*;
@SqlResultSetMapping(
name = "BookRecordMapping",
classes = @ConstructorResult(
targetClass = BookRecord.class,
columns = {
@ColumnResult(name = "id", type = Long.class),
@ColumnResult(name = "title", type = String.class),
@ColumnResult(name = "author", type = String.class),
@ColumnResult(name = "isbn", type = String.class)
}
)
)
@Entity
@Table(name = "book")
public class Book {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String title;
private String author;
private String isbn;
public Book() {
}
public Book(Long id, String title, String author, String isbn) {
this.id = id;
this.title = title;
this.author = author;
this.isbn = isbn;
}
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 String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public String getIsbn() {
return isbn;
}
public void setIsbn(String isbn) {
this.isbn = isbn;
}
}

View File

@ -0,0 +1,4 @@
package com.baeldung.recordswithjpa.records;
public record BookRecord(Long id, String title, String author, String isbn) {
}

View File

@ -0,0 +1,4 @@
package com.baeldung.recordswithjpa.records;
public record CustomBookRecord(Long id, String title) {
}

View File

@ -0,0 +1,17 @@
package com.baeldung.recordswithjpa.repository;
import com.baeldung.recordswithjpa.entity.Book;
import com.baeldung.recordswithjpa.records.BookRecord;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.query.Param;
import java.util.List;
public interface BookRepository extends CrudRepository<Book, Long> {
List<BookRecord> findBookByAuthor(String author);
@Query("SELECT new com.baeldung.recordswithjpa.records.BookRecord(b.id, b.title, b.author, b.isbn) " +
"FROM Book b WHERE b.id = :id")
BookRecord findBookById(@Param("id") Long id);
}

View File

@ -0,0 +1,9 @@
package com.baeldung.recordswithjpa.repository;
import com.baeldung.recordswithjpa.records.CustomBookRecord;
import java.util.List;
public interface CustomBookRepository {
List<CustomBookRecord> findAllBooks();
}

View File

@ -0,0 +1,20 @@
package com.baeldung.recordswithjpa.repository;
import com.baeldung.recordswithjpa.records.CustomBookRecord;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public class CustomBookRepositoryImpl implements CustomBookRepository {
private final JdbcTemplate jdbcTemplate;
public CustomBookRepositoryImpl(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
public List<CustomBookRecord> findAllBooks() {
return jdbcTemplate.query("SELECT id, title FROM book", (rs, rowNum) -> new CustomBookRecord(rs.getLong("id"), rs.getString("title")));
}
}

View File

@ -0,0 +1,39 @@
package com.baeldung.recordswithjpa;
import com.baeldung.recordswithjpa.entity.Book;
import com.baeldung.recordswithjpa.records.BookRecord;
import com.baeldung.recordswithjpa.repository.BookRepository;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.List;
import static org.junit.jupiter.api.Assertions.*;
public class QueryServiceIntegrationTest extends RecordsAsJpaIntegrationTest {
@Autowired
private QueryService queryService;
@Test
void findAllBooks() {
List<BookRecord> allBooks = queryService.findAllBooks();
assertEquals(3, allBooks.size());
}
@Test
void findBookById() {
BookRecord bookById = queryService.findBookById(1L);
assertEquals("The Lord of the Rings", bookById.title());
}
@Test
void findAllBooksUsingMapping() {
List<BookRecord> allBooksUsingMapping = queryService.findAllBooksUsingMapping();
assertEquals(3, allBooksUsingMapping.size());
}
}

View File

@ -0,0 +1,30 @@
package com.baeldung.recordswithjpa;
import com.baeldung.recordswithjpa.entity.Book;
import com.baeldung.recordswithjpa.repository.BookRepository;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
public class RecordsAsJpaIntegrationTest {
@Autowired
protected BookRepository bookRepository;
@BeforeEach
void setUp() {
Book book = new Book(1L,"The Lord of the Rings", "J.R.R. Tolkien", "978-0544003415");
Book book2 = new Book(2L,"The Hobbit", "J.R.R. Tolkien", "978-0547928227");
Book book3 = new Book(3L,"Harry Potter and the Philosopher's Stone", "J.K. Rowling", "978-0747532699");
bookRepository.save(book);
bookRepository.save(book2);
bookRepository.save(book3);
}
@AfterEach
void tearDown() {
bookRepository.deleteAll();
}
}

View File

@ -0,0 +1,19 @@
package com.baeldung.recordswithjpa.repository;
import com.baeldung.recordswithjpa.RecordsAsJpaIntegrationTest;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
class BookRepositoryIntegrationTest extends RecordsAsJpaIntegrationTest {
@Test
void findBookByAuthor() {
assertEquals(2, bookRepository.findBookByAuthor("J.R.R. Tolkien").size());
}
@Test
void findBookById() {
assertEquals("The Lord of the Rings", bookRepository.findBookById(1L).title());
}
}

View File

@ -0,0 +1,23 @@
package com.baeldung.recordswithjpa.repository;
import com.baeldung.recordswithjpa.RecordsAsJpaIntegrationTest;
import com.baeldung.recordswithjpa.records.CustomBookRecord;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.List;
import static org.junit.jupiter.api.Assertions.*;
class CustomBookRepositoryIntegrationTest extends RecordsAsJpaIntegrationTest {
@Autowired
private CustomBookRepository customBookRepository;
@Test
void findAllBooks() {
List<CustomBookRecord> allBooks = customBookRepository.findAllBooks();
assertEquals(3, allBooks.size());
}
}

View File

@ -42,6 +42,7 @@
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.22</version>
</dependency>
<dependency>
<groupId>io.projectreactor</groupId>