Skip to content

Commit a009397

Browse files
Add files via upload
1 parent a1b909a commit a009397

File tree

9 files changed

+347
-0
lines changed

9 files changed

+347
-0
lines changed
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
4+
<modelVersion>4.0.0</modelVersion>
5+
6+
<groupId>com.jpa</groupId>
7+
<artifactId>jpa</artifactId>
8+
<version>1.0</version>
9+
<packaging>jar</packaging>
10+
11+
<name>jpa</name>
12+
<description>JPA project for Spring Boot</description>
13+
14+
<parent>
15+
<groupId>org.springframework.boot</groupId>
16+
<artifactId>spring-boot-starter-parent</artifactId>
17+
<version>2.0.5.RELEASE</version>
18+
<relativePath/> <!-- lookup parent from repository -->
19+
</parent>
20+
21+
<properties>
22+
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
23+
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
24+
<java.version>1.8</java.version>
25+
</properties>
26+
27+
<dependencies>
28+
<dependency>
29+
<groupId>org.springframework.boot</groupId>
30+
<artifactId>spring-boot-starter-data-jpa</artifactId>
31+
</dependency>
32+
<dependency>
33+
<groupId>org.springframework.boot</groupId>
34+
<artifactId>spring-boot-starter-jdbc</artifactId>
35+
</dependency>
36+
<dependency>
37+
<groupId>org.springframework.boot</groupId>
38+
<artifactId>spring-boot-starter-web</artifactId>
39+
</dependency>
40+
<dependency>
41+
<groupId>mysql</groupId>
42+
<artifactId>mysql-connector-java</artifactId>
43+
<scope>runtime</scope>
44+
</dependency>
45+
<dependency>
46+
<groupId>org.springframework.boot</groupId>
47+
<artifactId>spring-boot-starter-test</artifactId>
48+
<scope>test</scope>
49+
</dependency>
50+
</dependencies>
51+
52+
<build>
53+
<plugins>
54+
<plugin>
55+
<groupId>org.springframework.boot</groupId>
56+
<artifactId>spring-boot-maven-plugin</artifactId>
57+
</plugin>
58+
</plugins>
59+
</build>
60+
61+
62+
</project>
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package com.jpa;
2+
3+
import java.util.List;
4+
import org.springframework.beans.factory.annotation.Autowired;
5+
import org.springframework.boot.ApplicationRunner;
6+
import org.springframework.boot.SpringApplication;
7+
import org.springframework.boot.autoconfigure.SpringBootApplication;
8+
import org.springframework.context.annotation.Bean;
9+
10+
@SpringBootApplication
11+
public class MergeCollectionsApplication {
12+
13+
@Autowired
14+
private TennisService tennisService;
15+
16+
public static void main(String[] args) {
17+
SpringApplication.run(MergeCollectionsApplication.class, args);
18+
}
19+
20+
@Bean
21+
public ApplicationRunner init() {
22+
return args -> {
23+
24+
System.out.println("------------------- Players from US Open --------------------");
25+
List<TennisPlayer> players = tennisService.fetchPlayersOfTournament("US Open");
26+
27+
players.forEach((t) -> System.out.println("Us Open: " + t.getName() + " | id:(" + t.getId() + ")"));
28+
29+
System.out.println("---------- Players from US Open Updated Detached ------------");
30+
31+
// ,update first player name
32+
players.get(0).setName("Fernando Verdasco");
33+
34+
// remove second player
35+
players.remove(1);
36+
37+
// add a new player
38+
TennisPlayer player = new TennisPlayer();
39+
player.setName("Alexander Zverev");
40+
players.add(player);
41+
42+
players.forEach((t) -> System.out.println("Us Open: " + t.getName() + " | id:(" + t.getId() + ")"));
43+
44+
System.out.println("----------------- Players from US Open Merged ----------------");
45+
tennisService.updatePlayersOfTorunament("Us Open", players);
46+
47+
players.forEach((t) -> System.out.println("Us Open: " + t.getName() + " | id:(" + t.getId() + ")"));
48+
};
49+
}
50+
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
package com.jpa;
2+
3+
import java.io.Serializable;
4+
import javax.persistence.Entity;
5+
import javax.persistence.FetchType;
6+
import javax.persistence.GeneratedValue;
7+
import javax.persistence.GenerationType;
8+
import javax.persistence.Id;
9+
import javax.persistence.JoinColumn;
10+
import javax.persistence.ManyToOne;
11+
12+
@Entity
13+
public class TennisPlayer implements Serializable {
14+
15+
private static final long serialVersionUID = 1L;
16+
17+
@Id
18+
@GeneratedValue(strategy = GenerationType.IDENTITY)
19+
private Long id;
20+
21+
private String name;
22+
23+
@ManyToOne(fetch = FetchType.LAZY)
24+
@JoinColumn(name = "tournament_id")
25+
private Tournament tournament;
26+
27+
public Long getId() {
28+
return id;
29+
}
30+
31+
public void setId(Long id) {
32+
this.id = id;
33+
}
34+
35+
public String getName() {
36+
return name;
37+
}
38+
39+
public void setName(String name) {
40+
this.name = name;
41+
}
42+
43+
public Tournament getTournament() {
44+
return tournament;
45+
}
46+
47+
public void setTournament(Tournament tournament) {
48+
this.tournament = tournament;
49+
}
50+
51+
@Override
52+
public boolean equals(Object obj) {
53+
if (this == obj) {
54+
return true;
55+
}
56+
if (!(obj instanceof TennisPlayer)) {
57+
return false;
58+
}
59+
return id != null && id.equals(((TennisPlayer) obj).id);
60+
}
61+
62+
@Override
63+
public int hashCode() {
64+
return 2018;
65+
}
66+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package com.jpa;
2+
3+
import java.util.List;
4+
import org.springframework.data.jpa.repository.JpaRepository;
5+
import org.springframework.data.jpa.repository.Query;
6+
import org.springframework.stereotype.Repository;
7+
import org.springframework.transaction.annotation.Transactional;
8+
9+
@Repository
10+
@Transactional(readOnly = true)
11+
public interface TennisPlayerRepository extends JpaRepository<TennisPlayer, Long> {
12+
13+
@Query(value = "SELECT p FROM TennisPlayer p JOIN p.tournament t WHERE t.name = ?1")
14+
List<TennisPlayer> playersOfTournament(String name);
15+
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
package com.jpa;
2+
3+
import java.util.List;
4+
import java.util.stream.Collectors;
5+
import org.springframework.stereotype.Service;
6+
import org.springframework.transaction.annotation.Transactional;
7+
8+
@Service
9+
public class TennisService {
10+
11+
private final TournamentRepository tournamentRepository;
12+
private final TennisPlayerRepository tennisPlayerRepository;
13+
14+
public TennisService(TournamentRepository tournamentRepository,
15+
TennisPlayerRepository tennisPlayerRepository) {
16+
17+
this.tournamentRepository = tournamentRepository;
18+
this.tennisPlayerRepository = tennisPlayerRepository;
19+
}
20+
21+
public List<TennisPlayer> fetchPlayersOfTournament(String name) {
22+
23+
return tennisPlayerRepository.playersOfTournament(name);
24+
}
25+
26+
@Transactional
27+
public void updatePlayersOfTorunament(String name, List<TennisPlayer> players) {
28+
29+
Tournament tournament = tournamentRepository.tournamentAndPlayers(name);
30+
System.out.println("-------------------------------------------------");
31+
32+
// Remove the existing database rows that are no
33+
// longer found in the incoming collection (players)
34+
tournament.getTennisPlayers().removeIf((t) -> !players.contains(t));
35+
36+
// Update the existing database rows which can be found
37+
// in the incoming collection (players)
38+
List<TennisPlayer> newPlayers = players.stream()
39+
.filter((t) -> !tournament.getTennisPlayers().contains(t))
40+
.collect(Collectors.toList());
41+
42+
players.stream()
43+
.filter((t) -> !newPlayers.contains(t))
44+
.forEach((t) -> {
45+
t.setTournament(tournament);
46+
TennisPlayer mergedPlayer = tennisPlayerRepository.save(t);
47+
tournament.getTennisPlayers().set(
48+
tournament.getTennisPlayers().indexOf(mergedPlayer),
49+
mergedPlayer);
50+
});
51+
52+
// Add the rows found in the incoming collection,
53+
// which cannot be found in the current database snapshot
54+
newPlayers.forEach((t) -> tournament.addTennisPlayer(t));
55+
}
56+
57+
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
package com.jpa;
2+
3+
import java.io.Serializable;
4+
import java.util.ArrayList;
5+
import java.util.List;
6+
import javax.persistence.CascadeType;
7+
import javax.persistence.Entity;
8+
import javax.persistence.GeneratedValue;
9+
import javax.persistence.GenerationType;
10+
import javax.persistence.Id;
11+
import javax.persistence.OneToMany;
12+
13+
@Entity
14+
public class Tournament implements Serializable {
15+
16+
private static final long serialVersionUID = 1L;
17+
18+
@Id
19+
@GeneratedValue(strategy = GenerationType.IDENTITY)
20+
private Long id;
21+
22+
private String name;
23+
24+
@OneToMany(cascade = CascadeType.ALL,
25+
mappedBy = "tournament", orphanRemoval = true)
26+
private List<TennisPlayer> tennisPlayers = new ArrayList<>();
27+
28+
public void addTennisPlayer(TennisPlayer tennisPlayer) {
29+
this.tennisPlayers.add(tennisPlayer);
30+
tennisPlayer.setTournament(this);
31+
}
32+
33+
public void removeTennisPlayer(TennisPlayer tennisPlayer) {
34+
tennisPlayer.setTournament(null);
35+
this.tennisPlayers.remove(tennisPlayer);
36+
}
37+
38+
public Long getId() {
39+
return id;
40+
}
41+
42+
public void setId(Long id) {
43+
this.id = id;
44+
}
45+
46+
public String getName() {
47+
return name;
48+
}
49+
50+
public void setName(String name) {
51+
this.name = name;
52+
}
53+
54+
public List<TennisPlayer> getTennisPlayers() {
55+
return tennisPlayers;
56+
}
57+
58+
public void setTennisPlayers(List<TennisPlayer> tennisPlayers) {
59+
this.tennisPlayers = tennisPlayers;
60+
}
61+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package com.jpa;
2+
3+
import org.springframework.data.jpa.repository.JpaRepository;
4+
import org.springframework.data.jpa.repository.Query;
5+
import org.springframework.stereotype.Repository;
6+
import org.springframework.transaction.annotation.Transactional;
7+
8+
@Repository
9+
@Transactional(readOnly = true)
10+
public interface TournamentRepository extends JpaRepository<Tournament, Long> {
11+
12+
@Query(value="SELECT t FROM Tournament t JOIN FETCH t.tennisPlayers WHERE t.name = ?1")
13+
Tournament tournamentAndPlayers(String name);
14+
}
15+
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
spring.datasource.url=jdbc:mysql://localhost:3306/db_tennis
2+
spring.datasource.username=root
3+
spring.datasource.password=root
4+
5+
spring.jpa.hibernate.ddl-auto=create
6+
spring.jpa.show-sql=true
7+
8+
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
9+
10+
spring.datasource.initialization-mode=always
11+
spring.datasource.platform=mysql
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
INSERT INTO tournament (id, name) VALUES (1, 'Roland Garros');
2+
INSERT INTO tournament (id, name) VALUES (2, 'US Open');
3+
INSERT INTO tennis_player (id, name, tournament_id) VALUES (1, 'Rafael Nadal', 1);
4+
INSERT INTO tennis_player (id, name, tournament_id) VALUES (2, 'Roger Federer', 1);
5+
INSERT INTO tennis_player (id, name, tournament_id) VALUES (3, 'David Ferer', 2);
6+
INSERT INTO tennis_player (id, name, tournament_id) VALUES (4, 'Andy Murray', 2);
7+
INSERT INTO tennis_player (id, name, tournament_id) VALUES (5, 'Del Potro', 2);
8+
INSERT INTO tennis_player (id, name, tournament_id) VALUES (6, 'Novak D', 2);
9+
INSERT INTO tennis_player (id, name, tournament_id) VALUES (7, 'John Isner', 2);
10+

0 commit comments

Comments
 (0)