From 0854a1d26e5a3ca3ecbf546d75cdb147f0abc5b6 Mon Sep 17 00:00:00 2001 From: Dimitris Kaitantzidis <44621809+DimK10@users.noreply.github.com> Date: Fri, 23 Aug 2024 23:37:45 +0300 Subject: [PATCH] Fixes LazyInitializationException in User entity (#1749) Temp integration of playground dist files of pdfme as-is to investigate the result --- .../SPDF/config/security/UserService.java | 19 +++++----- .../controller/web/AccountWebController.java | 36 +++++++------------ .../stirling/software/SPDF/model/User.java | 19 ++-------- .../SPDF/repository/UserRepository.java | 9 +++-- 4 files changed, 30 insertions(+), 53 deletions(-) diff --git a/src/main/java/stirling/software/SPDF/config/security/UserService.java b/src/main/java/stirling/software/SPDF/config/security/UserService.java index b1b51596..78f17822 100644 --- a/src/main/java/stirling/software/SPDF/config/security/UserService.java +++ b/src/main/java/stirling/software/SPDF/config/security/UserService.java @@ -1,13 +1,5 @@ package stirling.software.SPDF.config.security; -import java.io.IOException; -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; -import java.util.Optional; -import java.util.UUID; -import java.util.stream.Collectors; - import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.MessageSource; import org.springframework.context.i18n.LocaleContextHolder; @@ -21,7 +13,6 @@ import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.oauth2.core.user.OAuth2User; import org.springframework.stereotype.Service; - import stirling.software.SPDF.config.DatabaseBackupInterface; import stirling.software.SPDF.config.security.session.SessionPersistentRegistry; import stirling.software.SPDF.controller.api.pipeline.UserServiceInterface; @@ -32,6 +23,10 @@ import stirling.software.SPDF.model.User; import stirling.software.SPDF.repository.AuthorityRepository; import stirling.software.SPDF.repository.UserRepository; +import java.io.IOException; +import java.util.*; +import java.util.stream.Collectors; + @Service public class UserService implements UserServiceInterface { @@ -221,7 +216,7 @@ public class UserService implements UserServiceInterface { public void updateUserSettings(String username, Map updates) throws IOException { - Optional userOpt = findByUsernameIgnoreCase(username); + Optional userOpt = findByUsernameIgnoreCaseWithSettings(username); if (userOpt.isPresent()) { User user = userOpt.get(); Map settingsMap = user.getSettings(); @@ -246,6 +241,10 @@ public class UserService implements UserServiceInterface { return userRepository.findByUsernameIgnoreCase(username); } + public Optional findByUsernameIgnoreCaseWithSettings(String username) { + return userRepository.findByUsernameIgnoreCaseWithSettings(username); + } + public Authority findRole(User user) { return authorityRepository.findByUserId(user.getId()); } diff --git a/src/main/java/stirling/software/SPDF/controller/web/AccountWebController.java b/src/main/java/stirling/software/SPDF/controller/web/AccountWebController.java index 57c97e75..739f2600 100644 --- a/src/main/java/stirling/software/SPDF/controller/web/AccountWebController.java +++ b/src/main/java/stirling/software/SPDF/controller/web/AccountWebController.java @@ -1,15 +1,10 @@ package stirling.software.SPDF.controller.web; -import java.time.Instant; -import java.time.temporal.ChronoUnit; -import java.util.Date; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.stream.Collectors; - +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.servlet.http.HttpServletRequest; +import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.core.Authentication; @@ -18,27 +13,20 @@ import org.springframework.security.oauth2.core.user.OAuth2User; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; - -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; - -import io.swagger.v3.oas.annotations.tags.Tag; - -import jakarta.servlet.http.HttpServletRequest; -import lombok.extern.slf4j.Slf4j; import stirling.software.SPDF.config.security.session.SessionPersistentRegistry; -import stirling.software.SPDF.model.ApplicationProperties; +import stirling.software.SPDF.model.*; import stirling.software.SPDF.model.ApplicationProperties.Security.OAUTH2; import stirling.software.SPDF.model.ApplicationProperties.Security.OAUTH2.Client; -import stirling.software.SPDF.model.Authority; -import stirling.software.SPDF.model.Role; -import stirling.software.SPDF.model.SessionEntity; -import stirling.software.SPDF.model.User; import stirling.software.SPDF.model.provider.GithubProvider; import stirling.software.SPDF.model.provider.GoogleProvider; import stirling.software.SPDF.model.provider.KeycloakProvider; import stirling.software.SPDF.repository.UserRepository; +import java.time.Instant; +import java.time.temporal.ChronoUnit; +import java.util.*; +import java.util.stream.Collectors; + @Controller @Slf4j @Tag(name = "Account Security", description = "Account Security APIs") @@ -361,7 +349,7 @@ public class AccountWebController { if (username != null) { // Fetch user details from the database Optional user = - userRepository.findByUsernameIgnoreCase( + userRepository.findByUsernameIgnoreCaseWithSettings( username); // Assuming findByUsername method exists if (!user.isPresent()) { return "redirect:/error"; diff --git a/src/main/java/stirling/software/SPDF/model/User.java b/src/main/java/stirling/software/SPDF/model/User.java index bcccbd08..7006712b 100644 --- a/src/main/java/stirling/software/SPDF/model/User.java +++ b/src/main/java/stirling/software/SPDF/model/User.java @@ -1,5 +1,7 @@ package stirling.software.SPDF.model; +import jakarta.persistence.*; + import java.io.Serializable; import java.util.HashMap; import java.util.HashSet; @@ -7,21 +9,6 @@ import java.util.Map; import java.util.Set; import java.util.stream.Collectors; -import jakarta.persistence.CascadeType; -import jakarta.persistence.CollectionTable; -import jakarta.persistence.Column; -import jakarta.persistence.ElementCollection; -import jakarta.persistence.Entity; -import jakarta.persistence.FetchType; -import jakarta.persistence.GeneratedValue; -import jakarta.persistence.GenerationType; -import jakarta.persistence.Id; -import jakarta.persistence.JoinColumn; -import jakarta.persistence.Lob; -import jakarta.persistence.MapKeyColumn; -import jakarta.persistence.OneToMany; -import jakarta.persistence.Table; - @Entity @Table(name = "users") public class User implements Serializable { @@ -57,7 +44,7 @@ public class User implements Serializable { @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, mappedBy = "user") private Set authorities = new HashSet<>(); - @ElementCollection(fetch = FetchType.EAGER) + @ElementCollection @MapKeyColumn(name = "setting_key") @Lob @Column(name = "setting_value", columnDefinition = "CLOB") diff --git a/src/main/java/stirling/software/SPDF/repository/UserRepository.java b/src/main/java/stirling/software/SPDF/repository/UserRepository.java index 7a5ccffb..a80b58cb 100644 --- a/src/main/java/stirling/software/SPDF/repository/UserRepository.java +++ b/src/main/java/stirling/software/SPDF/repository/UserRepository.java @@ -1,16 +1,19 @@ package stirling.software.SPDF.repository; -import java.util.Optional; - import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; import org.springframework.stereotype.Repository; - import stirling.software.SPDF.model.User; +import java.util.Optional; + @Repository public interface UserRepository extends JpaRepository { Optional findByUsernameIgnoreCase(String username); + @Query("FROM User u LEFT JOIN FETCH u.settings where upper(u.username) = upper(:username)") + Optional findByUsernameIgnoreCaseWithSettings(String username); + Optional findByUsername(String username); Optional findByApiKey(String apiKey);