Skip to content
This repository was archived by the owner on Jan 13, 2023. It is now read-only.

Commit 14be720

Browse files
committed
Create new exercise "Hello JPA Repository"
1 parent c4bebf9 commit 14be720

File tree

7 files changed

+248
-0
lines changed

7 files changed

+248
-0
lines changed

hello-jpa-repository/README.MD

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# <img src="https://raw.githubusercontent.com/bobocode-projects/resources/master/image/logo_transparent_background.png" height=50/>Hello JpaRepository exercise :muscle:
2+
Improve your *Spring Data JPA* Java configuration skills
3+
### Task
4+
The task is to **configure Spring Data JPA repository** for `User`. In order to do that you need to **configure
5+
`EntityManagerFactory`**, **enable transaction management** and **create a JPA repository**. Please follow
6+
the instruction in the *todo* sections.
7+
8+
To verify your configuration, run `SpringDataJpaConfigTest.java`
9+
10+
11+
### Pre-conditions :heavy_exclamation_mark:
12+
You're supposed to be familiar with *Spring IoC* and *Dependency injection*
13+
14+
### How to start :question:
15+
* Just clone the repository and start implementing the **todo** section, verify your changes by running tests
16+
* If you don't have enough knowledge about this domain, check out the [links below](#related-materials-information_source)
17+
* Don't worry if you got stuck, checkout the **exercise/completed** branch and see the final implementation
18+
19+
### Related materials :information_source:
20+
* [Spring Data JPA basics tutorial](https://github.com/bobocode-projects/spring-data-jpa-tutorial/tree/master/jpa-repository-basics)<img src="https://raw.githubusercontent.com/bobocode-projects/resources/master/image/logo_transparent_background.png" height=20/>
21+

hello-jpa-repository/pom.xml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5+
<parent>
6+
<artifactId>spring-data-jpa-exercises</artifactId>
7+
<groupId>com.bobocode</groupId>
8+
<version>1.0-SNAPSHOT</version>
9+
</parent>
10+
<modelVersion>4.0.0</modelVersion>
11+
12+
<artifactId>hello-jpa-repository</artifactId>
13+
14+
<dependencies>
15+
<dependency>
16+
<groupId>com.bobocode</groupId>
17+
<artifactId>spring-data-jpa-exercises-util</artifactId>
18+
<version>1.0-SNAPSHOT</version>
19+
</dependency>
20+
</dependencies>
21+
22+
</project>
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package com.bobocode.config;
2+
3+
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
4+
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
5+
import org.springframework.orm.jpa.JpaVendorAdapter;
6+
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
7+
8+
import javax.sql.DataSource;
9+
10+
/**
11+
* This class provides spring configuration for {@link javax.persistence.EntityManagerFactory} bean.
12+
* <p>
13+
* todo: 1. PLEASE NOTE, THAT SOME REQUIRED STEPS ARE OMITTED IN THE TODO LIST AND YOU HAVE TO DO IT ON YOUR OWN
14+
* <p>
15+
* todo: 2. Configure {@link DataSource} bean
16+
* todo: 3. Configure {@link JpaVendorAdapter} bean
17+
* todo: 3. Configure {@link javax.persistence.EntityManagerFactory} bean with name "entityManagerFactory"
18+
* todo: 4. Enable JPA repository, set appropriate package using annotation property "basePackages"
19+
*/
20+
public class JpaConfig {
21+
22+
public DataSource dataSource() {
23+
return new EmbeddedDatabaseBuilder()
24+
.setType(EmbeddedDatabaseType.H2)
25+
.build();
26+
}
27+
28+
public JpaVendorAdapter jpaVendorAdapter() {
29+
// todo: create HibernateJpaVendorAdapter
30+
// todo: set H2 database
31+
// todo: enable DDL generation
32+
throw new UnsupportedOperationException("Application won't start until you provide configs");
33+
}
34+
35+
public LocalContainerEntityManagerFactoryBean localContainerEMF() {
36+
// todo: create and configure required bean
37+
// todo: set package "com.bobocode.model" to scan for JPA entities
38+
throw new UnsupportedOperationException("Application won't start until you provide configs");
39+
}
40+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package com.bobocode.config;
2+
3+
import org.springframework.transaction.PlatformTransactionManager;
4+
5+
/**
6+
* This class is provides root Java config for Spring application.
7+
* <p>
8+
* todo: 1. PLEASE NOTE, THAT SOME REQUIRED STEPS ARE OMITTED IN THE TODO LIST AND YOU HAVE TO DO IT ON YOUR OWN
9+
* <p>
10+
* todo: 2. Configure {@link PlatformTransactionManager} bean with name "transactionManager"
11+
* todo: 3. Enable transaction management
12+
*/
13+
public class RootConfig {
14+
}
15+
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package com.bobocode.dao;
2+
3+
import com.bobocode.model.User;
4+
import org.springframework.data.jpa.repository.JpaRepository;
5+
6+
/**
7+
* This interface represents a data access object (DAO) for {@link User}.
8+
* <p>
9+
* todo: 1. Configure {@link UserRepository} as {@link JpaRepository} for class User
10+
*/
11+
public interface UserRepository extends JpaRepository {
12+
13+
}
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
package com.bobocode;
2+
3+
import com.bobocode.config.JpaConfig;
4+
import com.bobocode.config.RootConfig;
5+
import com.bobocode.dao.UserRepository;
6+
import com.bobocode.model.User;
7+
import com.bobocode.util.TestDataGenerator;
8+
import org.junit.jupiter.api.Test;
9+
import org.springframework.beans.factory.annotation.Autowired;
10+
import org.springframework.context.ApplicationContext;
11+
import org.springframework.context.annotation.Bean;
12+
import org.springframework.context.annotation.ComponentScan;
13+
import org.springframework.context.annotation.Configuration;
14+
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
15+
import org.springframework.stereotype.Repository;
16+
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
17+
import org.springframework.transaction.PlatformTransactionManager;
18+
import org.springframework.transaction.annotation.Transactional;
19+
20+
import javax.persistence.EntityManagerFactory;
21+
22+
import java.util.List;
23+
import java.util.stream.Stream;
24+
25+
import static org.hamcrest.MatcherAssert.assertThat;
26+
import static org.hamcrest.Matchers.*;
27+
import static org.hamcrest.core.IsNull.notNullValue;
28+
29+
@SpringJUnitConfig(RootConfig.class)
30+
@Transactional
31+
public class SpringDataJpaConfigTest {
32+
@Configuration
33+
static class TestConfig {
34+
@Bean
35+
TestDataGenerator dataGenerator() {
36+
return new TestDataGenerator();
37+
}
38+
}
39+
40+
@Autowired
41+
private ApplicationContext applicationContext;
42+
43+
@Autowired
44+
private UserRepository userRepository;
45+
46+
@Autowired
47+
private TestDataGenerator dataGenerator;
48+
49+
@Test
50+
public void testTxManagerBeanName() {
51+
PlatformTransactionManager transactionManager = applicationContext.getBean(PlatformTransactionManager.class, "transactionManager");
52+
53+
assertThat(transactionManager, notNullValue());
54+
}
55+
56+
@Test
57+
public void testUserRepositoryBeanName() {
58+
UserRepository userRepository = applicationContext.getBean(UserRepository.class, "userRepository");
59+
60+
assertThat(userRepository, notNullValue());
61+
}
62+
63+
@Test
64+
public void testEntityManagerFactoryBeanName() {
65+
EntityManagerFactory entityManagerFactory = applicationContext.getBean(EntityManagerFactory.class, "entityManagerFactory");
66+
67+
assertThat(entityManagerFactory, notNullValue());
68+
}
69+
70+
@Test
71+
public void testUserRepositoryIsNotMarkedAsRepository() {
72+
Repository repository = UserRepository.class.getAnnotation(Repository.class);
73+
74+
assertThat(repository, nullValue());
75+
}
76+
77+
@Test
78+
public void testRootConfigComponentScan() {
79+
ComponentScan componentScan = RootConfig.class.getAnnotation(ComponentScan.class);
80+
81+
String[] basePackages = componentScan.basePackages();
82+
if (basePackages.length == 0) {
83+
basePackages = componentScan.value();
84+
}
85+
86+
assertThat(basePackages, array(equalTo("com.bobocode")));
87+
}
88+
89+
@Test
90+
public void testJpaConfigRepositoriesPackage() {
91+
EnableJpaRepositories enableJpaRepositories = JpaConfig.class.getAnnotation(EnableJpaRepositories.class);
92+
93+
assertThat(enableJpaRepositories.basePackages(), array(equalTo("com.bobocode.dao")));
94+
}
95+
96+
@Test
97+
public void testSaveUser() {
98+
User user = dataGenerator.generateUser();
99+
100+
userRepository.save(user);
101+
102+
assertThat(user.getId(), notNullValue());
103+
}
104+
105+
@Test
106+
public void testFindAll() {
107+
Stream.generate(dataGenerator::generateUser).limit(10).forEach(userRepository::save);
108+
109+
List<User> users = userRepository.findAll();
110+
111+
assertThat(users.size(), is(10));
112+
}
113+
}

pom.xml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
<modules>
1111
<module>spring-data-jpa-exercises-model</module>
1212
<module>spring-data-jpa-exercises-util</module>
13+
<module>hello-jpa-repository</module>
1314
</modules>
1415

1516
<packaging>pom</packaging>
@@ -25,6 +26,11 @@
2526
<artifactId>spring-data-jpa</artifactId>
2627
<version>2.1.0.RELEASE</version>
2728
</dependency>
29+
<dependency>
30+
<groupId>org.springframework</groupId>
31+
<artifactId>spring-test</artifactId>
32+
<version>5.0.7.RELEASE</version>
33+
</dependency>
2834
<dependency>
2935
<groupId>com.h2database</groupId>
3036
<artifactId>h2</artifactId>
@@ -45,6 +51,24 @@
4551
<artifactId>hibernate-core</artifactId>
4652
<version>5.3.2.Final</version>
4753
</dependency>
54+
<dependency>
55+
<groupId>org.junit.jupiter</groupId>
56+
<artifactId>junit-jupiter-engine</artifactId>
57+
<version>5.2.0</version>
58+
<scope>test</scope>
59+
</dependency>
60+
<dependency>
61+
<groupId>org.junit.platform</groupId>
62+
<artifactId>junit-platform-launcher</artifactId>
63+
<version>1.3.1</version>
64+
<scope>test</scope>
65+
</dependency>
66+
<dependency>
67+
<groupId>org.hamcrest</groupId>
68+
<artifactId>hamcrest-all</artifactId>
69+
<version>1.3</version>
70+
<scope>test</scope>
71+
</dependency>
4872
<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
4973
<dependency>
5074
<groupId>org.projectlombok</groupId>

0 commit comments

Comments
 (0)