JAVA-66: New module spring-data-jpa-query
This commit is contained in:
parent
7a86d7de49
commit
52da4c8ee8
|
@ -0,0 +1,22 @@
|
|||
## Spring Data JPA - Query
|
||||
|
||||
This module contains articles about querying data using Spring Data JPA
|
||||
|
||||
### Relevant Articles:
|
||||
- [Query Entities by Dates and Times with Spring Data JPA](https://www.baeldung.com/spring-data-jpa-query-by-date)
|
||||
- [The Exists Query in Spring Data](https://www.baeldung.com/spring-data-exists-query)
|
||||
- [Customizing the Result of JPA Queries with Aggregation Functions](https://www.baeldung.com/jpa-queries-custom-result-with-aggregation-functions)
|
||||
- [Limiting Query Results with JPA and Spring Data JPA](https://www.baeldung.com/jpa-limit-query-results)
|
||||
- [Sorting Query Results with Spring Data](https://www.baeldung.com/spring-data-sorting)
|
||||
- [Spring Data JPA Query by Example](https://www.baeldung.com/spring-data-query-by-example)
|
||||
- [JPA Join Types](https://www.baeldung.com/jpa-join-types)
|
||||
- [Spring Data JPA and Named Entity Graphs](https://www.baeldung.com/spring-data-jpa-named-entity-graphs)
|
||||
|
||||
### Eclipse Config
|
||||
After importing the project into Eclipse, you may see the following error:
|
||||
"No persistence xml file found in project"
|
||||
|
||||
This can be ignored:
|
||||
- Project -> Properties -> Java Persistance -> JPA -> Error/Warnings -> Select Ignore on "No persistence xml file found in project"
|
||||
Or:
|
||||
- Eclipse -> Preferences - Validation - disable the "Build" execution of the JPA Validator
|
|
@ -0,0 +1,48 @@
|
|||
<?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</artifactId>
|
||||
<name>spring-data-jpa-query</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-data-jpa</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.h2database</groupId>
|
||||
<artifactId>h2</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>net.ttddyy</groupId>
|
||||
<artifactId>datasource-proxy</artifactId>
|
||||
<version>${datasource-proxy.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-oxm</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<properties>
|
||||
<datasource-proxy.version>1.4.1</datasource-proxy.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,13 @@
|
|||
package com.baeldung;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
public class Application {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(Application.class, args);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,85 @@
|
|||
package com.baeldung.aggregation.model;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.ManyToOne;
|
||||
import java.util.Objects;
|
||||
|
||||
@Entity
|
||||
public class Comment {
|
||||
@Id
|
||||
private Integer id;
|
||||
private Integer year;
|
||||
private boolean approved;
|
||||
private String content;
|
||||
@ManyToOne
|
||||
private Post post;
|
||||
|
||||
public Comment() {
|
||||
}
|
||||
|
||||
public Comment(int id, int year, boolean approved, String content, Post post) {
|
||||
this.id = id;
|
||||
this.year = year;
|
||||
this.approved = approved;
|
||||
this.content = content;
|
||||
this.post = post;
|
||||
}
|
||||
|
||||
public Integer getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Integer id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public Integer getYear() {
|
||||
return year;
|
||||
}
|
||||
|
||||
public void setYear(Integer year) {
|
||||
this.year = year;
|
||||
}
|
||||
|
||||
public boolean isApproved() {
|
||||
return approved;
|
||||
}
|
||||
|
||||
public void setApproved(boolean approved) {
|
||||
this.approved = approved;
|
||||
}
|
||||
|
||||
public String getContent() {
|
||||
return content;
|
||||
}
|
||||
|
||||
public void setContent(String content) {
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
public Post getPost() {
|
||||
return post;
|
||||
}
|
||||
|
||||
public void setPost(Post post) {
|
||||
this.post = post;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (!(o instanceof Comment)) {
|
||||
return false;
|
||||
}
|
||||
Comment comment = (Comment) o;
|
||||
return getId().equals(comment.getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(getId());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
package com.baeldung.aggregation.model;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.OneToMany;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
@Entity
|
||||
public class Post {
|
||||
@Id
|
||||
private Integer id;
|
||||
private String title;
|
||||
private String content;
|
||||
@OneToMany(mappedBy = "post")
|
||||
private List<Comment> comments;
|
||||
|
||||
public Post() {
|
||||
}
|
||||
|
||||
public Post(Integer id, String title, String content) {
|
||||
this.id = id;
|
||||
this.title = title;
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
public Integer getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Integer id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public void setTitle(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public String getContent() {
|
||||
return content;
|
||||
}
|
||||
|
||||
public void setContent(String content) {
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
public List<Comment> getComments() {
|
||||
return comments;
|
||||
}
|
||||
|
||||
public void setComments(List<Comment> comments) {
|
||||
this.comments = comments;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (!(o instanceof Post)) {
|
||||
return false;
|
||||
}
|
||||
Post post = (Post) o;
|
||||
return getId().equals(post.getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(getId());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
package com.baeldung.aggregation.model.custom;
|
||||
|
||||
public class CommentCount {
|
||||
private Integer year;
|
||||
private Long total;
|
||||
|
||||
public CommentCount(Integer year, Long total) {
|
||||
this.year = year;
|
||||
this.total = total;
|
||||
}
|
||||
|
||||
public Integer getYear() {
|
||||
return year;
|
||||
}
|
||||
|
||||
public void setYear(Integer year) {
|
||||
this.year = year;
|
||||
}
|
||||
|
||||
public Long getTotal() {
|
||||
return total;
|
||||
}
|
||||
|
||||
public void setTotal(Long total) {
|
||||
this.total = total;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
package com.baeldung.aggregation.model.custom;
|
||||
|
||||
public interface ICommentCount {
|
||||
|
||||
Integer getYearComment();
|
||||
|
||||
Long getTotalComment();
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
package com.baeldung.aggregation.repository;
|
||||
|
||||
import com.baeldung.aggregation.model.Comment;
|
||||
import com.baeldung.aggregation.model.custom.CommentCount;
|
||||
import com.baeldung.aggregation.model.custom.ICommentCount;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Repository
|
||||
public interface CommentRepository extends JpaRepository<Comment, Integer> {
|
||||
|
||||
@Query("SELECT c.year, COUNT(c.year) FROM Comment AS c GROUP BY c.year ORDER BY c.year DESC")
|
||||
List<Object[]> countTotalCommentsByYear();
|
||||
|
||||
@Query("SELECT new com.baeldung.aggregation.model.custom.CommentCount(c.year, COUNT(c.year)) FROM Comment AS c GROUP BY c.year ORDER BY c.year DESC")
|
||||
List<CommentCount> countTotalCommentsByYearClass();
|
||||
|
||||
@Query("SELECT c.year AS yearComment, COUNT(c.year) AS totalComment FROM Comment AS c GROUP BY c.year ORDER BY c.year DESC")
|
||||
List<ICommentCount> countTotalCommentsByYearInterface();
|
||||
|
||||
@Query(value = "SELECT c.year AS yearComment, COUNT(c.*) AS totalComment FROM comment AS c GROUP BY c.year ORDER BY c.year DESC", nativeQuery = true)
|
||||
List<ICommentCount> countTotalCommentsByYearNative();
|
||||
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
package com.baeldung.boot.daos;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.data.repository.query.Param;
|
||||
|
||||
import com.baeldung.boot.domain.Article;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
public interface ArticleRepository extends JpaRepository<Article, Integer> {
|
||||
|
||||
List<Article> findAllByPublicationDate(Date publicationDate);
|
||||
|
||||
List<Article> findAllByPublicationTimeBetween(Date publicationTimeStart,
|
||||
Date publicationTimeEnd);
|
||||
|
||||
@Query("select a from Article a where a.creationDateTime <= :creationDateTime")
|
||||
List<Article> findAllWithCreationDateTimeBefore(
|
||||
@Param("creationDateTime") Date creationDateTime);
|
||||
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
package com.baeldung.boot.domain;
|
||||
|
||||
import javax.persistence.*;
|
||||
import java.util.Date;
|
||||
|
||||
@Entity
|
||||
public class Article {
|
||||
|
||||
@Id
|
||||
@GeneratedValue
|
||||
private Integer id;
|
||||
@Temporal(TemporalType.DATE)
|
||||
private Date publicationDate;
|
||||
@Temporal(TemporalType.TIME)
|
||||
private Date publicationTime;
|
||||
@Temporal(TemporalType.TIMESTAMP)
|
||||
private Date creationDateTime;
|
||||
|
||||
public Integer getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
package com.baeldung.boot.passenger;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
interface CustomPassengerRepository {
|
||||
|
||||
List<Passenger> findOrderedBySeatNumberLimitedTo(int limit);
|
||||
}
|
|
@ -0,0 +1,82 @@
|
|||
package com.baeldung.boot.passenger;
|
||||
|
||||
import javax.persistence.Basic;
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.Id;
|
||||
import java.util.Objects;
|
||||
|
||||
@Entity
|
||||
class Passenger {
|
||||
|
||||
@Id
|
||||
@GeneratedValue
|
||||
@Column(nullable = false)
|
||||
private Long id;
|
||||
|
||||
@Basic(optional = false)
|
||||
@Column(nullable = false)
|
||||
private String firstName;
|
||||
|
||||
@Basic(optional = false)
|
||||
@Column(nullable = false)
|
||||
private String lastName;
|
||||
|
||||
@Basic(optional = false)
|
||||
@Column(nullable = false)
|
||||
private Integer seatNumber;
|
||||
|
||||
private Passenger(String firstName, String lastName, Integer seatNumber) {
|
||||
this.firstName = firstName;
|
||||
this.lastName = lastName;
|
||||
this.seatNumber = seatNumber;
|
||||
}
|
||||
|
||||
static Passenger from(String firstName, String lastName, Integer seatNumber) {
|
||||
return new Passenger(firstName, lastName, seatNumber);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object object) {
|
||||
if (this == object)
|
||||
return true;
|
||||
if (object == null || getClass() != object.getClass())
|
||||
return false;
|
||||
Passenger passenger = (Passenger) object;
|
||||
return getSeatNumber() == passenger.getSeatNumber() && Objects.equals(getFirstName(), passenger.getFirstName())
|
||||
&& Objects.equals(getLastName(), passenger.getLastName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(getFirstName(), getLastName(), getSeatNumber());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
final StringBuilder toStringBuilder = new StringBuilder(getClass().getSimpleName());
|
||||
toStringBuilder.append("{ id=").append(id);
|
||||
toStringBuilder.append(", firstName='").append(firstName).append('\'');
|
||||
toStringBuilder.append(", lastName='").append(lastName).append('\'');
|
||||
toStringBuilder.append(", seatNumber=").append(seatNumber);
|
||||
toStringBuilder.append('}');
|
||||
return toStringBuilder.toString();
|
||||
}
|
||||
|
||||
Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
String getFirstName() {
|
||||
return firstName;
|
||||
}
|
||||
|
||||
String getLastName() {
|
||||
return lastName;
|
||||
}
|
||||
|
||||
Integer getSeatNumber() {
|
||||
return seatNumber;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
package com.baeldung.boot.passenger;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
|
||||
interface PassengerRepository extends JpaRepository<Passenger, Long>, CustomPassengerRepository {
|
||||
|
||||
Passenger findFirstByOrderBySeatNumberAsc();
|
||||
|
||||
Passenger findTopByOrderBySeatNumberAsc();
|
||||
|
||||
List<Passenger> findByOrderBySeatNumberAsc();
|
||||
|
||||
List<Passenger> findByFirstNameIgnoreCase(String firstName);
|
||||
|
||||
List<Passenger> findByLastNameOrderBySeatNumberAsc(String lastName);
|
||||
|
||||
List<Passenger> findByLastName(String lastName, Sort sort);
|
||||
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
package com.baeldung.boot.passenger;
|
||||
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.PersistenceContext;
|
||||
import java.util.List;
|
||||
|
||||
@Repository
|
||||
class PassengerRepositoryImpl implements CustomPassengerRepository {
|
||||
|
||||
@PersistenceContext
|
||||
private EntityManager entityManager;
|
||||
|
||||
@Override
|
||||
public List<Passenger> findOrderedBySeatNumberLimitedTo(int limit) {
|
||||
return entityManager.createQuery("SELECT p FROM Passenger p ORDER BY p.seatNumber",
|
||||
Passenger.class).setMaxResults(limit).getResultList();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
package com.baeldung.entitygraph.model;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.FetchType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.JoinColumn;
|
||||
import javax.persistence.ManyToOne;
|
||||
|
||||
@Entity
|
||||
public class Characteristic {
|
||||
|
||||
@Id
|
||||
private Long id;
|
||||
private String type;
|
||||
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
@JoinColumn
|
||||
private Item item;
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public Item getItem() {
|
||||
return item;
|
||||
}
|
||||
|
||||
public void setItem(Item item) {
|
||||
this.item = item;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
package com.baeldung.entitygraph.model;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.NamedAttributeNode;
|
||||
import javax.persistence.NamedEntityGraph;
|
||||
import javax.persistence.OneToMany;
|
||||
|
||||
@Entity
|
||||
@NamedEntityGraph(name = "Item.characteristics",
|
||||
attributeNodes = @NamedAttributeNode("characteristics")
|
||||
)
|
||||
public class Item {
|
||||
|
||||
@Id
|
||||
private Long id;
|
||||
private String name;
|
||||
|
||||
@OneToMany(mappedBy = "item")
|
||||
private List<Characteristic> characteristics = new ArrayList<>();
|
||||
|
||||
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<Characteristic> getCharacteristics() {
|
||||
return characteristics;
|
||||
}
|
||||
|
||||
public void setCharacteristics(List<Characteristic> characteristics) {
|
||||
this.characteristics = characteristics;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
package com.baeldung.entitygraph.repository;
|
||||
|
||||
import org.springframework.data.jpa.repository.EntityGraph;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
|
||||
import com.baeldung.entitygraph.model.Characteristic;
|
||||
|
||||
public interface CharacteristicsRepository extends JpaRepository<Characteristic, Long> {
|
||||
|
||||
@EntityGraph(attributePaths = {"item"})
|
||||
Characteristic findByType(String type);
|
||||
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
package com.baeldung.entitygraph.repository;
|
||||
|
||||
import org.springframework.data.jpa.repository.EntityGraph;
|
||||
import org.springframework.data.jpa.repository.EntityGraph.EntityGraphType;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
|
||||
import com.baeldung.entitygraph.model.Item;
|
||||
|
||||
public interface ItemRepository extends JpaRepository<Item, Long> {
|
||||
|
||||
@EntityGraph(value = "Item.characteristics", type = EntityGraphType.FETCH)
|
||||
Item findByName(String name);
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
package com.baeldung.exists;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.Id;
|
||||
|
||||
/**
|
||||
* @author paullatzelsperger
|
||||
* @since 2019-03-20
|
||||
*/
|
||||
@Entity
|
||||
public class Car {
|
||||
|
||||
@Id
|
||||
@GeneratedValue
|
||||
private int id;
|
||||
private Integer power;
|
||||
private String model;
|
||||
|
||||
Car() {
|
||||
|
||||
}
|
||||
|
||||
public Car(int power, String model) {
|
||||
this.power = power;
|
||||
this.model = model;
|
||||
}
|
||||
|
||||
public Integer getPower() {
|
||||
return power;
|
||||
}
|
||||
|
||||
public void setPower(Integer power) {
|
||||
this.power = power;
|
||||
}
|
||||
|
||||
public String getModel() {
|
||||
return model;
|
||||
}
|
||||
|
||||
public void setModel(String model) {
|
||||
this.model = model;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
package com.baeldung.exists;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.data.repository.query.Param;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
/**
|
||||
* @author paullatzelsperger
|
||||
* @since 2019-03-20
|
||||
*/
|
||||
@Repository
|
||||
public interface CarRepository extends JpaRepository<Car, Integer> {
|
||||
|
||||
boolean existsCarByPower(int power);
|
||||
|
||||
boolean existsCarByModel(String model);
|
||||
|
||||
@Query("select case when count(c)> 0 then true else false end from Car c where c.model = :model")
|
||||
boolean existsCarExactCustomQuery(@Param("model") String model);
|
||||
|
||||
@Query("select case when count(c)> 0 then true else false end from Car c where lower(c.model) like lower(:model)")
|
||||
boolean existsCarLikeCustomQuery(@Param("model") String model);
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
package com.baeldung.joins.model;
|
||||
|
||||
import java.util.List;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.OneToMany;
|
||||
|
||||
@Entity
|
||||
public class Department {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||
private long id;
|
||||
|
||||
private String name;
|
||||
|
||||
@OneToMany(mappedBy = "department")
|
||||
private List<Employee> employees;
|
||||
|
||||
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<Employee> getEmployees() {
|
||||
return employees;
|
||||
}
|
||||
|
||||
public void setEmployees(List<Employee> employees) {
|
||||
this.employees = employees;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
package com.baeldung.joins.model;
|
||||
|
||||
import java.util.List;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.ManyToOne;
|
||||
import javax.persistence.OneToMany;
|
||||
import javax.persistence.Table;
|
||||
|
||||
@Entity
|
||||
@Table(name = "joins_employee")
|
||||
public class Employee {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private long id;
|
||||
|
||||
private String name;
|
||||
|
||||
private int age;
|
||||
|
||||
@ManyToOne
|
||||
private Department department;
|
||||
|
||||
@OneToMany(mappedBy = "employee")
|
||||
private List<Phone> phones;
|
||||
|
||||
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 int getAge() {
|
||||
return age;
|
||||
}
|
||||
|
||||
public void setAge(int age) {
|
||||
this.age = age;
|
||||
}
|
||||
|
||||
public Department getDepartment() {
|
||||
return department;
|
||||
}
|
||||
|
||||
public void setDepartment(Department department) {
|
||||
this.department = department;
|
||||
}
|
||||
|
||||
public List<Phone> getPhones() {
|
||||
return phones;
|
||||
}
|
||||
|
||||
public void setPhones(List<Phone> phones) {
|
||||
this.phones = phones;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
package com.baeldung.joins.model;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.ManyToOne;
|
||||
|
||||
@Entity
|
||||
public class Phone {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private long id;
|
||||
|
||||
private String number;
|
||||
|
||||
@ManyToOne
|
||||
private Employee employee;
|
||||
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getNumber() {
|
||||
return number;
|
||||
}
|
||||
|
||||
public void setNumber(String number) {
|
||||
this.number = number;
|
||||
}
|
||||
|
||||
public Employee getEmployee() {
|
||||
return employee;
|
||||
}
|
||||
|
||||
public void setEmployee(Employee employee) {
|
||||
this.employee = employee;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<fruit>
|
||||
<id>1</id>
|
||||
<name>apple</name>
|
||||
<color>red</color>
|
||||
</fruit>
|
|
@ -0,0 +1 @@
|
|||
spring.datasource.data=classpath:db/import_joins.sql
|
|
@ -0,0 +1 @@
|
|||
spring.jpa.show-sql=true
|
|
@ -0,0 +1,13 @@
|
|||
INSERT INTO department (id, name) VALUES (1, 'Infra');
|
||||
INSERT INTO department (id, name) VALUES (2, 'Accounting');
|
||||
INSERT INTO department (id, name) VALUES (3, 'Management');
|
||||
|
||||
INSERT INTO joins_employee (id, name, age, department_id) VALUES (1, 'Baeldung', '35', 1);
|
||||
INSERT INTO joins_employee (id, name, age, department_id) VALUES (2, 'John', '35', 2);
|
||||
INSERT INTO joins_employee (id, name, age, department_id) VALUES (3, 'Jane', '35', 2);
|
||||
|
||||
INSERT INTO phone (id, number, employee_id) VALUES (1, '111', 1);
|
||||
INSERT INTO phone (id, number, employee_id) VALUES (2, '222', 1);
|
||||
INSERT INTO phone (id, number, employee_id) VALUES (3, '333', 1);
|
||||
|
||||
COMMIT;
|
|
@ -0,0 +1,14 @@
|
|||
[
|
||||
{
|
||||
"_class": "com.baeldung.entity.Fruit",
|
||||
"name": "apple",
|
||||
"color": "red",
|
||||
"id": 1
|
||||
},
|
||||
{
|
||||
"_class": "com.baeldung.entity.Fruit",
|
||||
"name": "guava",
|
||||
"color": "green",
|
||||
"id": 2
|
||||
}
|
||||
]
|
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<fruit>
|
||||
<id>2</id>
|
||||
<name>guava</name>
|
||||
<color>green</color>
|
||||
</fruit>
|
|
@ -0,0 +1,3 @@
|
|||
insert into Article(id, publication_date, publication_time, creation_date_time) values(1, TO_DATE('01/01/2018', 'DD/MM/YYYY'), TO_DATE('15:00', 'HH24:MI'), TO_DATE('31/12/2017 07:30', 'DD/MM/YYYY HH24:MI'));
|
||||
insert into Article(id, publication_date, publication_time, creation_date_time) values(2, TO_DATE('01/01/2018', 'DD/MM/YYYY'), TO_DATE('15:30', 'HH24:MI'), TO_DATE('15/12/2017 08:00', 'DD/MM/YYYY HH24:MI'));
|
||||
insert into Article(id, publication_date, publication_time, creation_date_time) values(3, TO_DATE('15/12/2017', 'DD/MM/YYYY'), TO_DATE('16:00', 'HH24:MI'), TO_DATE('01/12/2017 13:45', 'DD/MM/YYYY HH24:MI'));
|
|
@ -0,0 +1,107 @@
|
|||
package com.baeldung.aggregation;
|
||||
|
||||
import com.baeldung.aggregation.model.custom.CommentCount;
|
||||
import com.baeldung.aggregation.model.custom.ICommentCount;
|
||||
import com.baeldung.aggregation.repository.CommentRepository;
|
||||
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 java.util.List;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
@RunWith(SpringRunner.class)
|
||||
@DataJpaTest
|
||||
|
||||
@Sql(scripts = "/test-aggregation-data.sql")
|
||||
public class SpringDataAggregateIntegrationTest {
|
||||
|
||||
@Autowired
|
||||
private CommentRepository commentRepository;
|
||||
|
||||
@Test
|
||||
public void whenQueryWithAggregation_thenReturnResult() {
|
||||
List<Object[]> commentCountsByYear = commentRepository.countTotalCommentsByYear();
|
||||
|
||||
Object[] countYear2019 = commentCountsByYear.get(0);
|
||||
|
||||
assertThat(countYear2019[0], is(Integer.valueOf(2019)));
|
||||
assertThat(countYear2019[1], is(1l));
|
||||
|
||||
Object[] countYear2018 = commentCountsByYear.get(1);
|
||||
|
||||
assertThat(countYear2018[0], is(Integer.valueOf(2018)));
|
||||
assertThat(countYear2018[1], is(2l));
|
||||
|
||||
Object[] countYear2017 = commentCountsByYear.get(2);
|
||||
|
||||
assertThat(countYear2017[0], is(Integer.valueOf(2017)));
|
||||
assertThat(countYear2017[1], is(1l));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenQueryWithAggregation_thenReturnCustomResult() {
|
||||
List<CommentCount> commentCountsByYear = commentRepository.countTotalCommentsByYearClass();
|
||||
|
||||
CommentCount countYear2019 = commentCountsByYear.get(0);
|
||||
|
||||
assertThat(countYear2019.getYear(), is(Integer.valueOf(2019)));
|
||||
assertThat(countYear2019.getTotal(), is(1l));
|
||||
|
||||
CommentCount countYear2018 = commentCountsByYear.get(1);
|
||||
|
||||
assertThat(countYear2018.getYear(), is(Integer.valueOf(2018)));
|
||||
assertThat(countYear2018.getTotal(), is(2l));
|
||||
|
||||
CommentCount countYear2017 = commentCountsByYear.get(2);
|
||||
|
||||
assertThat(countYear2017.getYear(), is(Integer.valueOf(2017)));
|
||||
assertThat(countYear2017.getTotal(), is(1l));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenQueryWithAggregation_thenReturnInterfaceResult() {
|
||||
List<ICommentCount> commentCountsByYear = commentRepository.countTotalCommentsByYearInterface();
|
||||
|
||||
ICommentCount countYear2019 = commentCountsByYear.get(0);
|
||||
|
||||
assertThat(countYear2019.getYearComment(), is(Integer.valueOf(2019)));
|
||||
assertThat(countYear2019.getTotalComment(), is(1l));
|
||||
|
||||
ICommentCount countYear2018 = commentCountsByYear.get(1);
|
||||
|
||||
assertThat(countYear2018.getYearComment(), is(Integer.valueOf(2018)));
|
||||
assertThat(countYear2018.getTotalComment(), is(2l));
|
||||
|
||||
ICommentCount countYear2017 = commentCountsByYear.get(2);
|
||||
|
||||
assertThat(countYear2017.getYearComment(), is(Integer.valueOf(2017)));
|
||||
assertThat(countYear2017.getTotalComment(), is(1l));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenNativeQueryWithAggregation_thenReturnInterfaceResult() {
|
||||
List<ICommentCount> commentCountsByYear = commentRepository.countTotalCommentsByYearNative();
|
||||
|
||||
ICommentCount countYear2019 = commentCountsByYear.get(0);
|
||||
|
||||
assertThat(countYear2019.getYearComment(), is(Integer.valueOf(2019)));
|
||||
assertThat(countYear2019.getTotalComment(), is(1l));
|
||||
|
||||
ICommentCount countYear2018 = commentCountsByYear.get(1);
|
||||
|
||||
assertThat(countYear2018.getYearComment(), is(Integer.valueOf(2018)));
|
||||
assertThat(countYear2018.getTotalComment(), is(2l));
|
||||
|
||||
ICommentCount countYear2017 = commentCountsByYear.get(2);
|
||||
|
||||
assertThat(countYear2017.getYearComment(), is(Integer.valueOf(2017)));
|
||||
assertThat(countYear2017.getTotalComment(), is(1l));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
package com.baeldung.boot.daos;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
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.junit4.SpringRunner;
|
||||
|
||||
import com.baeldung.boot.domain.Article;
|
||||
|
||||
@RunWith(SpringRunner.class)
|
||||
@DataJpaTest(properties="spring.datasource.data=classpath:import_entities.sql")
|
||||
public class ArticleRepositoryIntegrationTest {
|
||||
|
||||
@Autowired
|
||||
private ArticleRepository repository;
|
||||
|
||||
@Test
|
||||
public void givenImportedArticlesWhenFindAllByPublicationDateThenArticles1And2Returned()
|
||||
throws Exception {
|
||||
List<Article> result = repository.findAllByPublicationDate(
|
||||
new SimpleDateFormat("yyyy-MM-dd").parse("2018-01-01")
|
||||
);
|
||||
|
||||
assertEquals(2, result.size());
|
||||
assertTrue(result.stream()
|
||||
.map(Article::getId)
|
||||
.allMatch(id -> Arrays.asList(1, 2).contains(id))
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenImportedArticlesWhenFindAllByPublicationTimeBetweenThenArticles2And3Returned()
|
||||
throws Exception {
|
||||
List<Article> result = repository.findAllByPublicationTimeBetween(
|
||||
new SimpleDateFormat("HH:mm").parse("15:15"),
|
||||
new SimpleDateFormat("HH:mm").parse("16:30")
|
||||
);
|
||||
|
||||
assertEquals(2, result.size());
|
||||
assertTrue(result.stream()
|
||||
.map(Article::getId)
|
||||
.allMatch(id -> Arrays.asList(2, 3).contains(id))
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenImportedArticlesWhenFindAllWithCreationDateTimeBeforeThenArticles2And3Returned() throws Exception {
|
||||
List<Article> result = repository.findAllWithCreationDateTimeBefore(
|
||||
new SimpleDateFormat("yyyy-MM-dd HH:mm").parse("2017-12-15 10:00")
|
||||
);
|
||||
|
||||
assertEquals(2, result.size());
|
||||
assertTrue(result.stream()
|
||||
.map(Article::getId)
|
||||
.allMatch(id -> Arrays.asList(2, 3).contains(id))
|
||||
);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,190 @@
|
|||
package com.baeldung.boot.passenger;
|
||||
|
||||
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.autoconfigure.orm.jpa.DataJpaTest;
|
||||
import org.springframework.data.domain.Example;
|
||||
import org.springframework.data.domain.ExampleMatcher;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
import com.baeldung.boot.passenger.Passenger;
|
||||
import com.baeldung.boot.passenger.PassengerRepository;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.PersistenceContext;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.contains;
|
||||
import static org.hamcrest.core.IsNot.not;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
|
||||
@DataJpaTest
|
||||
@RunWith(SpringRunner.class)
|
||||
public class PassengerRepositoryIntegrationTest {
|
||||
|
||||
@PersistenceContext
|
||||
private EntityManager entityManager;
|
||||
@Autowired
|
||||
private PassengerRepository repository;
|
||||
|
||||
@Before
|
||||
public void before() {
|
||||
entityManager.persist(Passenger.from("Jill", "Smith", 50));
|
||||
entityManager.persist(Passenger.from("Eve", "Jackson", 95));
|
||||
entityManager.persist(Passenger.from("Fred", "Bloggs", 22));
|
||||
entityManager.persist(Passenger.from("Ricki", "Bobbie", 36));
|
||||
entityManager.persist(Passenger.from("Siya", "Kolisi", 85));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenSeveralPassengersWhenOrderedBySeatNumberLimitedToThenThePassengerInTheFirstFilledSeatIsReturned() {
|
||||
Passenger expected = Passenger.from("Fred", "Bloggs", 22);
|
||||
|
||||
List<Passenger> passengers = repository.findOrderedBySeatNumberLimitedTo(1);
|
||||
|
||||
assertEquals(1, passengers.size());
|
||||
|
||||
Passenger actual = passengers.get(0);
|
||||
assertEquals(expected, actual);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenSeveralPassengersWhenFindFirstByOrderBySeatNumberAscThenThePassengerInTheFirstFilledSeatIsReturned() {
|
||||
Passenger expected = Passenger.from("Fred", "Bloggs", 22);
|
||||
|
||||
Passenger actual = repository.findFirstByOrderBySeatNumberAsc();
|
||||
|
||||
assertEquals(expected, actual);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenSeveralPassengersWhenFindPageSortedByThenThePassengerInTheFirstFilledSeatIsReturned() {
|
||||
Passenger expected = Passenger.from("Fred", "Bloggs", 22);
|
||||
|
||||
Page<Passenger> page = repository.findAll(PageRequest.of(0, 1,
|
||||
Sort.by(Sort.Direction.ASC, "seatNumber")));
|
||||
|
||||
assertEquals(1, page.getContent().size());
|
||||
|
||||
Passenger actual = page.getContent().get(0);
|
||||
assertEquals(expected, actual);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenPassengers_whenOrderedBySeatNumberAsc_thenCorrectOrder() {
|
||||
Passenger fred = Passenger.from("Fred", "Bloggs", 22);
|
||||
Passenger ricki = Passenger.from("Ricki", "Bobbie", 36);
|
||||
Passenger jill = Passenger.from("Jill", "Smith", 50);
|
||||
Passenger siya = Passenger.from("Siya", "Kolisi", 85);
|
||||
Passenger eve = Passenger.from("Eve", "Jackson", 95);
|
||||
|
||||
List<Passenger> passengers = repository.findByOrderBySeatNumberAsc();
|
||||
|
||||
assertThat(passengers, contains(fred, ricki, jill, siya, eve));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenPassengers_whenFindAllWithSortBySeatNumberAsc_thenCorrectOrder() {
|
||||
Passenger fred = Passenger.from("Fred", "Bloggs", 22);
|
||||
Passenger ricki = Passenger.from("Ricki", "Bobbie", 36);
|
||||
Passenger jill = Passenger.from("Jill", "Smith", 50);
|
||||
Passenger siya = Passenger.from("Siya", "Kolisi", 85);
|
||||
Passenger eve = Passenger.from("Eve", "Jackson", 95);
|
||||
|
||||
List<Passenger> passengers = repository.findAll(Sort.by(Sort.Direction.ASC, "seatNumber"));
|
||||
|
||||
assertThat(passengers, contains(fred, ricki, jill, siya, eve));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenPassengers_whenFindByExampleDefaultMatcher_thenExpectedReturned() {
|
||||
Example<Passenger> example = Example.of(Passenger.from("Fred", "Bloggs", null));
|
||||
|
||||
Optional<Passenger> actual = repository.findOne(example);
|
||||
|
||||
assertTrue(actual.isPresent());
|
||||
assertEquals(Passenger.from("Fred", "Bloggs", 22), actual.get());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenPassengers_whenFindByExampleCaseInsensitiveMatcher_thenExpectedReturned() {
|
||||
ExampleMatcher caseInsensitiveExampleMatcher = ExampleMatcher.matchingAll().withIgnoreCase();
|
||||
Example<Passenger> example = Example.of(Passenger.from("fred", "bloggs", null),
|
||||
caseInsensitiveExampleMatcher);
|
||||
|
||||
Optional<Passenger> actual = repository.findOne(example);
|
||||
|
||||
assertTrue(actual.isPresent());
|
||||
assertEquals(Passenger.from("Fred", "Bloggs", 22), actual.get());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenPassengers_whenFindByExampleCustomMatcher_thenExpectedReturned() {
|
||||
Passenger jill = Passenger.from("Jill", "Smith", 50);
|
||||
Passenger eve = Passenger.from("Eve", "Jackson", 95);
|
||||
Passenger fred = Passenger.from("Fred", "Bloggs", 22);
|
||||
Passenger siya = Passenger.from("Siya", "Kolisi", 85);
|
||||
Passenger ricki = Passenger.from("Ricki", "Bobbie", 36);
|
||||
|
||||
ExampleMatcher customExampleMatcher = ExampleMatcher.matchingAny().withMatcher("firstName",
|
||||
ExampleMatcher.GenericPropertyMatchers.contains().ignoreCase()).withMatcher("lastName",
|
||||
ExampleMatcher.GenericPropertyMatchers.contains().ignoreCase());
|
||||
|
||||
Example<Passenger> example = Example.of(Passenger.from("e", "s", null),
|
||||
customExampleMatcher);
|
||||
|
||||
List<Passenger> passengers = repository.findAll(example);
|
||||
|
||||
assertThat(passengers, contains(jill, eve, fred, siya));
|
||||
assertThat(passengers, not(contains(ricki)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenPassengers_whenFindByIgnoringMatcher_thenExpectedReturned() {
|
||||
Passenger jill = Passenger.from("Jill", "Smith", 50);
|
||||
Passenger eve = Passenger.from("Eve", "Jackson", 95);
|
||||
Passenger fred = Passenger.from("Fred", "Bloggs", 22);
|
||||
Passenger siya = Passenger.from("Siya", "Kolisi", 85);
|
||||
Passenger ricki = Passenger.from("Ricki", "Bobbie", 36);
|
||||
|
||||
ExampleMatcher ignoringExampleMatcher = ExampleMatcher.matchingAny().withMatcher("lastName",
|
||||
ExampleMatcher.GenericPropertyMatchers.startsWith().ignoreCase()).withIgnorePaths("firstName", "seatNumber");
|
||||
|
||||
Example<Passenger> example = Example.of(Passenger.from(null, "b", null),
|
||||
ignoringExampleMatcher);
|
||||
|
||||
List<Passenger> passengers = repository.findAll(example);
|
||||
|
||||
assertThat(passengers, contains(fred, ricki));
|
||||
assertThat(passengers, not(contains(jill)));
|
||||
assertThat(passengers, not(contains(eve)));
|
||||
assertThat(passengers, not(contains(siya)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenPassengers_whenMatchingIgnoreCase_thenExpectedReturned() {
|
||||
Passenger jill = Passenger.from("Jill", "Smith", 50);
|
||||
Passenger eve = Passenger.from("Eve", "Jackson", 95);
|
||||
Passenger fred = Passenger.from("Fred", "Bloggs", 22);
|
||||
Passenger siya = Passenger.from("Siya", "Kolisi", 85);
|
||||
Passenger ricki = Passenger.from("Ricki", "Bobbie", 36);
|
||||
|
||||
List<Passenger> passengers = repository.findByFirstNameIgnoreCase("FRED");
|
||||
|
||||
assertThat(passengers, contains(fred));
|
||||
assertThat(passengers, not(contains(eve)));
|
||||
assertThat(passengers, not(contains(siya)));
|
||||
assertThat(passengers, not(contains(jill)));
|
||||
assertThat(passengers, not(contains(ricki)));
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
package com.baeldung.entitygraph;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
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 com.baeldung.entitygraph.model.Characteristic;
|
||||
import com.baeldung.entitygraph.model.Item;
|
||||
import com.baeldung.entitygraph.repository.CharacteristicsRepository;
|
||||
import com.baeldung.entitygraph.repository.ItemRepository;
|
||||
|
||||
@DataJpaTest
|
||||
@RunWith(SpringRunner.class)
|
||||
@Sql(scripts = "/entitygraph-data.sql")
|
||||
public class EntityGraphIntegrationTest {
|
||||
|
||||
@Autowired
|
||||
private ItemRepository itemRepo;
|
||||
|
||||
@Autowired
|
||||
private CharacteristicsRepository characteristicsRepo;
|
||||
|
||||
@Test
|
||||
public void givenEntityGraph_whenCalled_shouldRetrunDefinedFields() {
|
||||
Item item = itemRepo.findByName("Table");
|
||||
assertThat(item.getId()).isEqualTo(1L);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenAdhocEntityGraph_whenCalled_shouldRetrunDefinedFields() {
|
||||
Characteristic characteristic = characteristicsRepo.findByType("Rigid");
|
||||
assertThat(characteristic.getId()).isEqualTo(1L);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,87 @@
|
|||
package com.baeldung.exists;
|
||||
|
||||
import com.baeldung.Application;
|
||||
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.data.domain.Example;
|
||||
import org.springframework.data.domain.ExampleMatcher;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.springframework.data.domain.ExampleMatcher.GenericPropertyMatchers.ignoreCase;
|
||||
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(classes = {Application.class})
|
||||
public class CarRepositoryIntegrationTest {
|
||||
|
||||
@Autowired
|
||||
private CarRepository repository;
|
||||
private int searchId;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
List<Car> cars = repository.saveAll(Arrays.asList(new Car(200, "BMW"), new Car(300, "Audi")));
|
||||
searchId = cars.get(0).getId();
|
||||
}
|
||||
|
||||
@After
|
||||
public void teardown() {
|
||||
repository.deleteAll();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenIdIsCorrect_thenExistsShouldReturnTrue() {
|
||||
assertThat(repository.existsById(searchId)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenExample_whenExists_thenIsTrue() {
|
||||
ExampleMatcher modelMatcher = ExampleMatcher.matching()
|
||||
.withIgnorePaths("id") // must explicitly ignore -> PK
|
||||
.withMatcher("model", ignoreCase());
|
||||
Car probe = new Car();
|
||||
probe.setModel("bmw");
|
||||
|
||||
Example<Car> example = Example.of(probe, modelMatcher);
|
||||
|
||||
assertThat(repository.exists(example)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenPower_whenExists_thenIsFalse() {
|
||||
assertThat(repository.existsCarByPower(200)).isTrue();
|
||||
assertThat(repository.existsCarByPower(800)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void existsByDerivedQuery_byModel() {
|
||||
assertThat(repository.existsCarByModel("Audi")).isTrue();
|
||||
assertThat(repository.existsCarByModel("audi")).isFalse();
|
||||
assertThat(repository.existsCarByModel("AUDI")).isFalse();
|
||||
assertThat(repository.existsCarByModel("")).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenModelName_whenExistsExact_thenIsTrue() {
|
||||
assertThat(repository.existsCarExactCustomQuery("BMW")).isTrue();
|
||||
assertThat(repository.existsCarExactCustomQuery("Bmw")).isFalse();
|
||||
assertThat(repository.existsCarExactCustomQuery("bmw")).isFalse();
|
||||
assertThat(repository.existsCarExactCustomQuery("")).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenModelName_whenExistsLike_thenIsTrue() {
|
||||
assertThat(repository.existsCarLikeCustomQuery("BMW")).isTrue();
|
||||
assertThat(repository.existsCarLikeCustomQuery("Bmw")).isTrue();
|
||||
assertThat(repository.existsCarLikeCustomQuery("bmw")).isTrue();
|
||||
assertThat(repository.existsCarLikeCustomQuery("")).isFalse();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,142 @@
|
|||
package com.baeldung.joins;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import com.baeldung.joins.model.Department;
|
||||
import com.baeldung.joins.model.Phone;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.PersistenceContext;
|
||||
import javax.persistence.TypedQuery;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
|
||||
import org.springframework.test.context.ActiveProfiles;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
@RunWith(SpringRunner.class)
|
||||
@DataJpaTest
|
||||
@ActiveProfiles("joins")
|
||||
public class JpaJoinsIntegrationTest {
|
||||
|
||||
@PersistenceContext
|
||||
private EntityManager entityManager;
|
||||
|
||||
@Test
|
||||
public void whenPathExpressionIsUsedForSingleValuedAssociation_thenCreatesImplicitInnerJoin() {
|
||||
TypedQuery<Department> query = entityManager.createQuery("SELECT e.department FROM Employee e", Department.class);
|
||||
|
||||
List<Department> resultList = query.getResultList();
|
||||
|
||||
assertThat(resultList).hasSize(3);
|
||||
assertThat(resultList).extracting("name")
|
||||
.containsOnly("Infra", "Accounting", "Accounting");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenJoinKeywordIsUsed_thenCreatesExplicitInnerJoin() {
|
||||
TypedQuery<Department> query = entityManager.createQuery("SELECT d FROM Employee e JOIN e.department d", Department.class);
|
||||
|
||||
List<Department> resultList = query.getResultList();
|
||||
|
||||
assertThat(resultList).hasSize(3);
|
||||
assertThat(resultList).extracting("name")
|
||||
.containsOnly("Infra", "Accounting", "Accounting");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenInnerJoinKeywordIsUsed_thenCreatesExplicitInnerJoin() {
|
||||
TypedQuery<Department> query = entityManager.createQuery("SELECT d FROM Employee e INNER JOIN e.department d", Department.class);
|
||||
|
||||
List<Department> resultList = query.getResultList();
|
||||
|
||||
assertThat(resultList).hasSize(3);
|
||||
assertThat(resultList).extracting("name")
|
||||
.containsOnly("Infra", "Accounting", "Accounting");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenEntitiesAreListedInFromAndMatchedInWhere_ThenCreatesJoin() {
|
||||
TypedQuery<Department> query = entityManager.createQuery("SELECT d FROM Employee e, Department d WHERE e.department = d", Department.class);
|
||||
|
||||
List<Department> resultList = query.getResultList();
|
||||
|
||||
assertThat(resultList).hasSize(3);
|
||||
assertThat(resultList).extracting("name")
|
||||
.containsOnly("Infra", "Accounting", "Accounting");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenEntitiesAreListedInFrom_ThenCreatesCartesianProduct() {
|
||||
TypedQuery<Department> query = entityManager.createQuery("SELECT d FROM Employee e, Department d", Department.class);
|
||||
|
||||
List<Department> resultList = query.getResultList();
|
||||
|
||||
assertThat(resultList).hasSize(9);
|
||||
assertThat(resultList).extracting("name")
|
||||
.containsOnly("Infra", "Accounting", "Management", "Infra", "Accounting", "Management", "Infra", "Accounting", "Management");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenCollectionValuedAssociationIsJoined_ThenCanSelect() {
|
||||
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();
|
||||
|
||||
assertThat(resultList).hasSize(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenMultipleEntitiesAreListedWithJoin_ThenCreatesMultipleJoins() {
|
||||
TypedQuery<Phone> query = entityManager.createQuery("SELECT ph FROM Employee e JOIN e.department d JOIN e.phones ph WHERE d.name IS NOT NULL", Phone.class);
|
||||
|
||||
List<Phone> resultList = query.getResultList();
|
||||
|
||||
assertThat(resultList).hasSize(3);
|
||||
assertThat(resultList).extracting("number")
|
||||
.containsOnly("111", "222", "333");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenLeftKeywordIsSpecified_thenCreatesOuterJoinAndIncludesNonMatched() {
|
||||
TypedQuery<Department> query = entityManager.createQuery("SELECT DISTINCT d FROM Department d LEFT JOIN d.employees e", Department.class);
|
||||
|
||||
List<Department> resultList = query.getResultList();
|
||||
|
||||
assertThat(resultList).hasSize(3);
|
||||
assertThat(resultList).extracting("name")
|
||||
.containsOnly("Infra", "Accounting", "Management");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenFetchKeywordIsSpecified_ThenCreatesFetchJoin() {
|
||||
TypedQuery<Department> query = entityManager.createQuery("SELECT d FROM Department d JOIN FETCH d.employees", Department.class);
|
||||
|
||||
List<Department> resultList = query.getResultList();
|
||||
|
||||
assertThat(resultList).hasSize(3);
|
||||
assertThat(resultList).extracting("name")
|
||||
.containsOnly("Infra", "Accounting", "Accounting");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenLeftAndFetchKeywordsAreSpecified_ThenCreatesOuterFetchJoin() {
|
||||
TypedQuery<Department> query = entityManager.createQuery("SELECT d FROM Department d LEFT JOIN FETCH d.employees", Department.class);
|
||||
|
||||
List<Department> resultList = query.getResultList();
|
||||
|
||||
assertThat(resultList).hasSize(4);
|
||||
assertThat(resultList).extracting("name")
|
||||
.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,7 @@
|
|||
INSERT INTO Item(id,name) VALUES (1,'Table');
|
||||
INSERT INTO Item(id,name) VALUES (2,'Bottle');
|
||||
|
||||
INSERT INTO Characteristic(id,item_id, type) VALUES (1,1,'Rigid');
|
||||
INSERT INTO Characteristic(id,item_id,type) VALUES (2,1,'Big');
|
||||
INSERT INTO Characteristic(id,item_id,type) VALUES (3,2,'Fragile');
|
||||
INSERT INTO Characteristic(id,item_id,type) VALUES (4,2,'Small');
|
|
@ -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');
|
|
@ -0,0 +1,7 @@
|
|||
INSERT INTO post (id, title, content) VALUES (1, 'Comment 1', 'Content 1');
|
||||
INSERT INTO post (id, title, content) VALUES (2, 'Comment 2', 'Content 2');
|
||||
INSERT INTO post (id, title, content) VALUES (3, 'Comment 3', 'Content 3');
|
||||
INSERT INTO comment (id, year, approved, content, post_id) VALUES (1, 2019, false, 'Comment 1', 1);
|
||||
INSERT INTO comment (id, year, approved, content, post_id) VALUES (2, 2018, true, 'Comment 2', 1);
|
||||
INSERT INTO comment (id, year, approved, content, post_id) VALUES (3, 2018, true, 'Comment 3', 2);
|
||||
INSERT INTO comment (id, year, approved, content, post_id) VALUES (4, 2017, false, 'Comment 4', 3);
|
|
@ -0,0 +1,6 @@
|
|||
truncate table fruit;
|
||||
|
||||
insert into fruit(id,name,color) values (1,'apple','red');
|
||||
insert into fruit(id,name,color) values (2,'custard apple','green');
|
||||
insert into fruit(id,name,color) values (3,'mango','yellow');
|
||||
insert into fruit(id,name,color) values (4,'guava','green');
|
Loading…
Reference in New Issue