Bael 7420 (#16242)
* BAEL-7490 read write file in separate thread * Change the to try resources * Update the code to sync with article * Jsonb query * Added new module to parent pom
This commit is contained in:
parent
7cb3519bd2
commit
bb544b9168
|
@ -88,6 +88,7 @@
|
|||
<module>spring-data-jpa-query</module>
|
||||
<module>spring-data-jpa-query-2</module>
|
||||
<module>spring-data-jpa-query-3</module>
|
||||
<module>spring-data-jpa-query-4</module>
|
||||
<module>spring-data-jpa-repo</module>
|
||||
<module>spring-data-jpa-repo-2</module>
|
||||
<module>spring-data-jpa-repo-4</module>
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
<?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>spring-data-jpa-query-4</artifactId>
|
||||
<name>spring-data-jpa-query-4</name>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>parent-boot-2</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<relativePath>../../parent-boot-2</relativePath>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.h2database</groupId>
|
||||
<artifactId>h2</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.postgresql</groupId>
|
||||
<artifactId>postgresql</artifactId>
|
||||
<version>${postgresql.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<properties>
|
||||
<postgresql.version>42.7.1</postgresql.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,52 @@
|
|||
package com.baeldung.spring.data.jpa.queryjsonb;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
|
||||
@Entity
|
||||
public class Product {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Long id;
|
||||
|
||||
private String name;
|
||||
@Column(columnDefinition = "jsonb")
|
||||
private String attributes;
|
||||
|
||||
public Product() {
|
||||
}
|
||||
|
||||
public Product(String name, String attributes) {
|
||||
this.name = name;
|
||||
this.attributes = attributes;
|
||||
}
|
||||
|
||||
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 String getAttributes() {
|
||||
return attributes;
|
||||
}
|
||||
|
||||
public void setAttributes(String attributes) {
|
||||
this.attributes = attributes;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
package com.baeldung.spring.data.jpa.queryjsonb;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
public class ProductApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(ProductApplication.class);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
package com.baeldung.spring.data.jpa.queryjsonb;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.data.repository.query.Param;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface ProductRepository extends JpaRepository<Product, Long>, JpaSpecificationExecutor<Product> {
|
||||
@Query(value = "SELECT * FROM product WHERE attributes ->> ?1 = ?2", nativeQuery = true)
|
||||
List<Product> findByAttribute(String key, String value);
|
||||
|
||||
@Query(value = "SELECT * FROM product WHERE attributes -> ?1 ->> ?2 = ?3", nativeQuery = true)
|
||||
List<Product> findByNestedAttribute(String key1, String key2, String value);
|
||||
|
||||
@Query(value = "SELECT * FROM product WHERE jsonb_extract_path_text(attributes, ?1) = ?2", nativeQuery = true)
|
||||
List<Product> findByJsonPath(String path, String value);
|
||||
|
||||
@Query(value = "SELECT * FROM product WHERE jsonb_extract_path_text(attributes, ?1, ?2) = ?3", nativeQuery = true)
|
||||
List<Product> findByNestedJsonPath(String key1, String key2, String value);
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
package com.baeldung.spring.data.jpa.queryjsonb;
|
||||
|
||||
import javax.persistence.criteria.CriteriaBuilder;
|
||||
import javax.persistence.criteria.CriteriaQuery;
|
||||
import javax.persistence.criteria.Predicate;
|
||||
import javax.persistence.criteria.Root;
|
||||
|
||||
import org.springframework.data.jpa.domain.Specification;
|
||||
public class ProductSpecification implements Specification<Product> {
|
||||
|
||||
private final String key;
|
||||
private final String value;
|
||||
|
||||
public ProductSpecification(String key, String value) {
|
||||
this.key = key; this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Predicate toPredicate(Root<Product> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
|
||||
return cb.equal(cb.function("jsonb_extract_path_text", String.class, root.get("attributes"), cb.literal(key)), value);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
spring.datasource.url=jdbc:postgresql://localhost:5432/postgres
|
||||
spring.datasource.username=postgres
|
||||
spring.datasource.password=
|
||||
spring.jpa.database-platform=org.hibernate.dialect.PostgreSQLDialect
|
||||
spring.jpa.hibernate.ddl-auto=create
|
||||
spring.jpa.show-sql=true
|
||||
|
||||
logging.level.org.hibernate.SQL=DEBUG
|
||||
logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE
|
||||
spring.jpa.properties.hibernate.format_sql=true
|
|
@ -0,0 +1,77 @@
|
|||
package com.baeldung.spring.data.jpa.queryjsonb;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import javax.transaction.Transactional;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||
import org.springframework.data.domain.PageImpl;
|
||||
import org.springframework.test.annotation.Commit;
|
||||
import org.springframework.test.context.ActiveProfiles;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.test.context.jdbc.Sql;
|
||||
import org.springframework.transaction.annotation.Propagation;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
||||
@SpringBootTest
|
||||
@ActiveProfiles("test")
|
||||
@Sql(scripts = "/testdata.sql", executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD)
|
||||
public class ProductRepositoryIntegrationTest {
|
||||
|
||||
@Autowired
|
||||
private ProductRepository productRepository;
|
||||
|
||||
@Test
|
||||
void whenFindByAttribute_thenReturnTheObject() {
|
||||
List<Product> redProducts = productRepository.findByAttribute("color", "red");
|
||||
|
||||
assertEquals(1, redProducts.size());
|
||||
assertEquals("Laptop", redProducts.get(0).getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenFindByNestedAttribute_thenReturnTheObject() {
|
||||
List<Product> electronicProducts = productRepository.findByNestedAttribute("details", "category", "electronics");
|
||||
|
||||
assertEquals(1, electronicProducts.size());
|
||||
assertEquals("Headphones", electronicProducts.get(0)
|
||||
.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenFindByJsonPath_thenReturnTheObject() {
|
||||
List<Product> redProducts = productRepository.findByJsonPath("color", "red");
|
||||
assertEquals(1, redProducts.size());
|
||||
assertEquals("Laptop", redProducts.get(0)
|
||||
.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenNestedJsonAttribute_whenFindByJsonPath_thenReturnTheObject() {
|
||||
List<Product> electronicProducts = productRepository.findByNestedJsonPath("details", "category", "electronics");
|
||||
assertEquals(1, electronicProducts.size());
|
||||
assertEquals("Headphones", electronicProducts.get(0)
|
||||
.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenUsingJPASpecification_thenReturnTheObject() {
|
||||
ProductSpecification spec = new ProductSpecification("color", "red");
|
||||
Page<Product> redProducts = productRepository.findAll(spec, Pageable.unpaged());
|
||||
|
||||
assertEquals(1, redProducts.getContent()
|
||||
.size());
|
||||
assertEquals("Laptop", redProducts.getContent()
|
||||
.get(0)
|
||||
.getName());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
spring.datasource.url=jdbc:postgresql://localhost:5432/postgres
|
||||
spring.datasource.username=postgres
|
||||
spring.datasource.password=
|
||||
spring.jpa.database-platform=org.hibernate.dialect.PostgreSQLDialect
|
||||
spring.jpa.hibernate.ddl-auto=create
|
||||
spring.jpa.show-sql=true
|
||||
spring.jpa.properties.hibernate.format_sql=true
|
||||
|
||||
logging.level.org.hibernate.SQL=DEBUG
|
||||
logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE
|
|
@ -0,0 +1,13 @@
|
|||
DELETE FROM product;
|
||||
|
||||
INSERT INTO product (name, attributes)
|
||||
VALUES ('Laptop', '{"color": "red", "size": "15 inch"}');
|
||||
|
||||
INSERT INTO product (name, attributes)
|
||||
VALUES ('Phone', '{"color": "blue", "size": "6 inch"}');
|
||||
|
||||
INSERT INTO product (name, attributes)
|
||||
VALUES ('Headphones', '{"brand": "Sony", "details": {"category": "electronics", "model": "WH-1000XM4"}}');
|
||||
|
||||
INSERT INTO product (name, attributes)
|
||||
VALUES ('Laptop', '{"brand": "Dell", "details": {"category": "computers", "model": "XPS 13"}}');
|
Loading…
Reference in New Issue