I use two-step registration. In the first step, I only require a username, password, and email. In the second step, I require a full name, bio, gender, etc. I have a registerDetails
method for that. Inside registerDetails
, there is updateAppUser
method that updates the user with given information(full name, bio, gender, etc. ). The registerDetails
method is transactional because in the first step, I call for updateAppUser
and in the second step I call for the setDetailsRegistered
method. The setDetailsRegistered
method only sets isDetailsRegistered
boolean to true. I do that because I require the user to fill remaining information(full name, bio, gender, etc. ). Anyway, my problem is that when I return AppUserResponse
after those two processes, I still get isDetailsRegistered
as false
, however, I used setDetailsRegistered
method to set it as true
. I understand that, because my method is transactional, it is still false when I call for the AppUser
object because the transaction is not completed, yet. I want to close the transaction and after that retrieve the AppUser object from the database. I think I will get isDetailsRegistered
as true
. How can I achieve that? Those are my methods.
registerDetails
@Transactional
public AppUserResponse registerDetails(RegisterRequest registerRequest, UUID appUserId) {
//fixme:first registerDetails returned false
AppUser appUser = userDetailsService.findAppUserById(appUserId);
if (appUser.isDetailsRegistered()) {
throw new InvalidRequestException("Bu kullanıcının bilgileri zaten kayıtlı.");
}
AppUser mapped = appUserMapper.registerDetailsToAppUser(appUser,registerRequest);
updateAppUser(mapped);
setDetailsRegistered(appUserId);
appUserRepository.flush(); //after updating and setting isdetailsRegistered flag as true, then flush changes.
AppUser newAppUser = userDetailsService.findAppUserById(appUserId);
return appUserMapper.appUserToResponse(newAppUser);
}
updateAppUser
public AppUser updateAppUser(AppUser appUser) {
return appUserRepository.save(appUser);
}
setDetailsRegistered
public void setDetailsRegistered(UUID userId) {
appUserRepository.setDetailsRegistered(userId);
appUserRepository.flush();
}
jpa query for setDetailsRegistered
@Modifying
@Transactional
@Query("UPDATE AppUser a " +
"SET a.isDetailsRegistered = TRUE WHERE a.appUserId = ?1")
void setDetailsRegistered(UUID userId);
Try next code:
@Transactional
public AppUserResponse registerDetails(RegisterRequest registerRequest, UUID appUserId) {
AppUser appUser = userDetailsService.findAppUserById(appUserId);
if (appUser.isDetailsRegistered()) {
throw new InvalidRequestException("Bu kullanıcının bilgileri zaten kayıtlı.");
}
appUser = appUserMapper.registerDetailsToAppUser(appUser,registerRequest);
appUser = appUserRepository.save(appUser);
//setDetailsRegistered(appUserId);
appUser.setDetailsRegistered(true);//if you don't have this setter you can create it in the class AppUser
appUser = appUserRepository.save(appUser);
return appUserMapper.appUserToResponse(appUser);
}