diff --git a/hello-jpa-repository/src/main/java/com/bobocode/config/JpaConfig.java b/hello-jpa-repository/src/main/java/com/bobocode/config/JpaConfig.java
index ec3d6a4..717d3fe 100644
--- a/hello-jpa-repository/src/main/java/com/bobocode/config/JpaConfig.java
+++ b/hello-jpa-repository/src/main/java/com/bobocode/config/JpaConfig.java
@@ -1,9 +1,14 @@
package com.bobocode.config;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
import org.springframework.orm.jpa.JpaVendorAdapter;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
+import org.springframework.orm.jpa.vendor.Database;
+import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import javax.sql.DataSource;
@@ -17,24 +22,36 @@
* todo: 3. Configure {@link javax.persistence.EntityManagerFactory} bean with name "entityManagerFactory"
* todo: 4. Enable JPA repository, set appropriate package using annotation property "basePackages"
*/
+@Configuration
+@EnableJpaRepositories(basePackages = "com.bobocode.dao")
public class JpaConfig {
+ @Bean
public DataSource dataSource() {
return new EmbeddedDatabaseBuilder()
.setType(EmbeddedDatabaseType.H2)
.build();
}
+ @Bean
public JpaVendorAdapter jpaVendorAdapter() {
// todo: create HibernateJpaVendorAdapter
+ HibernateJpaVendorAdapter adapter = new HibernateJpaVendorAdapter();
// todo: set H2 database
+ adapter.setDatabase(Database.H2);
// todo: enable DDL generation
- throw new UnsupportedOperationException("Application won't start until you provide configs");
+ adapter.setGenerateDdl(true);
+ return adapter;
}
- public LocalContainerEntityManagerFactoryBean localContainerEMF() {
+ @Bean("entityManagerFactory")
+ public LocalContainerEntityManagerFactoryBean localContainerEMF(DataSource dataSource, JpaVendorAdapter jpaVendorAdapter) {
// todo: create and configure required bean
+ LocalContainerEntityManagerFactoryBean emf = new LocalContainerEntityManagerFactoryBean();
+ emf.setDataSource(dataSource);
+ emf.setJpaVendorAdapter(jpaVendorAdapter);
// todo: set package "com.bobocode.model" to scan for JPA entities
- throw new UnsupportedOperationException("Application won't start until you provide configs");
+ emf.setPackagesToScan("com.bobocode.model");// JPA entity classes will be loaded from this package
+ return emf;
}
}
diff --git a/hello-jpa-repository/src/main/java/com/bobocode/config/RootConfig.java b/hello-jpa-repository/src/main/java/com/bobocode/config/RootConfig.java
index 58293dd..1e57517 100644
--- a/hello-jpa-repository/src/main/java/com/bobocode/config/RootConfig.java
+++ b/hello-jpa-repository/src/main/java/com/bobocode/config/RootConfig.java
@@ -1,6 +1,13 @@
package com.bobocode.config;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
+import org.springframework.transaction.annotation.EnableTransactionManagement;
+
+import javax.persistence.EntityManagerFactory;
/**
* This class is provides root Java config for Spring application.
@@ -10,6 +17,14 @@
* todo: 2. Configure {@link PlatformTransactionManager} bean with name "transactionManager"
* todo: 3. Enable transaction management
*/
+@Configuration
+@ComponentScan("com.bobocode")
+@EnableTransactionManagement
public class RootConfig {
+
+ @Bean
+ public PlatformTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) {
+ return new JpaTransactionManager(entityManagerFactory);
+ }
}
diff --git a/hello-jpa-repository/src/main/java/com/bobocode/dao/UserRepository.java b/hello-jpa-repository/src/main/java/com/bobocode/dao/UserRepository.java
index 69fd52d..a875fdd 100644
--- a/hello-jpa-repository/src/main/java/com/bobocode/dao/UserRepository.java
+++ b/hello-jpa-repository/src/main/java/com/bobocode/dao/UserRepository.java
@@ -8,6 +8,6 @@
*
* todo: 1. Configure {@link UserRepository} as {@link JpaRepository} for class User
*/
-public interface UserRepository extends JpaRepository {
+public interface UserRepository extends JpaRepository {
}
diff --git a/user-service/src/main/java/com/bobocode/config/JpaConfig.java b/user-service/src/main/java/com/bobocode/config/JpaConfig.java
index c9c133e..440899f 100644
--- a/user-service/src/main/java/com/bobocode/config/JpaConfig.java
+++ b/user-service/src/main/java/com/bobocode/config/JpaConfig.java
@@ -1,8 +1,14 @@
package com.bobocode.config;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
import org.springframework.orm.jpa.JpaVendorAdapter;
+import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
+import org.springframework.orm.jpa.vendor.Database;
+import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import javax.sql.DataSource;
@@ -16,11 +22,32 @@
* todo: 3. Configure {@link javax.persistence.EntityManagerFactory} bean with name "entityManagerFactory"
* todo: 4. Enable JPA repository
*/
+@Configuration
+@EnableJpaRepositories(basePackages = "com.bobocode.dao")
public class JpaConfig {
+ @Bean
public DataSource dataSource() {
return new EmbeddedDatabaseBuilder()
.setType(EmbeddedDatabaseType.H2)
.build();
}
-}
+
+ @Bean
+ public JpaVendorAdapter jpaVendorAdapter() {
+ HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
+ vendorAdapter.setDatabase(Database.H2);
+ vendorAdapter.setGenerateDdl(true);
+ vendorAdapter.setShowSql(true);
+ return vendorAdapter;
+ }
+
+ @Bean("entityManagerFactory")
+ public LocalContainerEntityManagerFactoryBean localContainerEMF() {
+ LocalContainerEntityManagerFactoryBean emf = new LocalContainerEntityManagerFactoryBean();
+ emf.setDataSource(dataSource());
+ emf.setJpaVendorAdapter(jpaVendorAdapter());
+ emf.setPackagesToScan("com.bobocode.model");
+ return emf;
+ }
+}
\ No newline at end of file
diff --git a/user-service/src/main/java/com/bobocode/config/RootConfig.java b/user-service/src/main/java/com/bobocode/config/RootConfig.java
index 52a639e..8ae7399 100644
--- a/user-service/src/main/java/com/bobocode/config/RootConfig.java
+++ b/user-service/src/main/java/com/bobocode/config/RootConfig.java
@@ -1,6 +1,13 @@
package com.bobocode.config;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
+import org.springframework.transaction.annotation.EnableTransactionManagement;
+
+import javax.persistence.EntityManagerFactory;
/**
* This class is provides root Java config for Spring application.
@@ -10,6 +17,13 @@
* todo: 1. Configure {@link PlatformTransactionManager} bean with name "transactionManager"
* todo: 2. Enable transaction management
*/
+@Configuration
+@ComponentScan("com.bobocode")
+@EnableTransactionManagement
public class RootConfig {
-}
+ @Bean
+ public PlatformTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) {
+ return new JpaTransactionManager(entityManagerFactory);
+ }
+}
\ No newline at end of file
diff --git a/user-service/src/main/java/com/bobocode/dao/UserRepository.java b/user-service/src/main/java/com/bobocode/dao/UserRepository.java
index 1dd20ad..0a821af 100644
--- a/user-service/src/main/java/com/bobocode/dao/UserRepository.java
+++ b/user-service/src/main/java/com/bobocode/dao/UserRepository.java
@@ -2,6 +2,11 @@
import com.bobocode.model.User;
import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.data.repository.query.Param;
+
+import java.util.List;
+import java.util.Optional;
/**
* This interface represents a data access object (DAO) for {@link User}.
@@ -13,6 +18,9 @@
* todo: 3. Create method that finds optional user by email fetching its address and roles using {@link org.springframework.data.jpa.repository.Query}
* todo: 4. Add custom User repository interface
*/
-public interface UserRepository extends JpaRepository{
+public interface UserRepository extends JpaRepository, CustomUserRepository {
+ List findAllByAddressCity(String city);
+ @Query("select u from User u left join fetch u.address left join fetch u.roles where u.email = :email")
+ Optional findByEmailFetchRoles(@Param("email") String email);
}
diff --git a/user-service/src/main/java/com/bobocode/dao/impl/CustomUserRepositoryImpl.java b/user-service/src/main/java/com/bobocode/dao/impl/CustomUserRepositoryImpl.java
new file mode 100644
index 0000000..34d4875
--- /dev/null
+++ b/user-service/src/main/java/com/bobocode/dao/impl/CustomUserRepositoryImpl.java
@@ -0,0 +1,38 @@
+package com.bobocode.dao.impl;
+
+import com.bobocode.dao.CustomUserRepository;
+import com.bobocode.model.Role;
+import com.bobocode.model.RoleType;
+import com.bobocode.model.User;
+import org.springframework.stereotype.Repository;
+import org.springframework.transaction.annotation.Transactional;
+
+import javax.persistence.EntityManager;
+import javax.persistence.PersistenceContext;
+import java.util.List;
+
+@Repository
+@Transactional
+public class CustomUserRepositoryImpl implements CustomUserRepository {
+
+ @PersistenceContext
+ private EntityManager entityManager;
+
+
+ @Override
+ public void addRoleToAllUsers(RoleType roleType) {
+ List users = entityManager.createQuery("select u from User u left join fetch u.roles", User.class)
+ .getResultList();
+ users.stream()
+ .filter(user -> hasNoRole(user, roleType))
+ .forEach(user -> user.addRole(Role.valueOf(roleType)));
+ }
+
+ private boolean hasNoRole(User user, RoleType roleType) {
+ return user.getRoles()
+ .stream()
+ .map(Role::getRoleType)
+ .noneMatch(type -> type.equals(roleType));
+ }
+}
+
diff --git a/user-service/src/main/java/com/bobocode/service/UserService.java b/user-service/src/main/java/com/bobocode/service/UserService.java
index bd4b874..b15caf3 100644
--- a/user-service/src/main/java/com/bobocode/service/UserService.java
+++ b/user-service/src/main/java/com/bobocode/service/UserService.java
@@ -4,6 +4,8 @@
import com.bobocode.exception.EntityNotFoundException;
import com.bobocode.model.RoleType;
import com.bobocode.model.User;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
import java.util.List;
@@ -17,16 +19,27 @@
* todo: 3. In case user is not found by email, throw {@link EntityNotFoundException} with message "Cannot find user by email ${email}"
* todo: 4. Implement {@link UserService#addRoleToAllUsers(RoleType)} using {@link UserRepository}
*/
+@Transactional
+@Service
public class UserService {
+ private final UserRepository userRepository;
+
+ public UserService(UserRepository userRepository) {
+ this.userRepository = userRepository;
+ }
+
+ @Transactional(readOnly = true)
public List findByCity(String city) {
- throw new UnsupportedOperationException("Do your best and implement this method!");
+ return userRepository.findAllByAddressCity(city);
}
+ @Transactional(readOnly = true)
public User getByEmail(String email) {
- throw new UnsupportedOperationException("Do your best and implement this method!");
+ return userRepository.findByEmailFetchRoles(email)
+ .orElseThrow(() -> new EntityNotFoundException(String.format("Cannot find user by email %s", email)));
}
public void addRoleToAllUsers(RoleType roleType) {
- throw new UnsupportedOperationException("Do your best and implement this method!");
+ userRepository.addRoleToAllUsers(roleType);
}
}