The way to resolve this issue currently is to not persist changes to the user in the addUser method, but rather when the transaction is committed. If your store doesn’t support transactions you can achieve this through a transaction wrapper.
If login is via an Identity Provider, another possibility could be to extend that provider, override AbstractIdentityProvider#importNewUser and/or updateBrokeredUser, and call your User Storage Provider something like this:
public void importNewUser(final KeycloakSession session, final RealmModel realm, final UserModel user, final BrokeredIdentityContext context) {
if(context.getEmail() != null) user.setEmail(context.getEmail());
if(context.getFirstName() != null) user.setFirstName(context.getFirstName());
if(context.getLastName() != null) user.setLastName(context.getLastName());
final List<UserUpdateProvider> storageProviders = UserStorageManager.getEnabledStorageProviders(session, realm, UserUpdateProvider.class);
for (final UserUpdateProvider updateProvider : storageProviders) {
updateProvider.updateUser(realm, user);
}
}
UserUpdateProvider is an interface declaring updateUser(realm, user), implemented by your User Storage Provider.
Note however that overriding AbstractIdentityProvider requires using a private SPI which will give the following warning:
WARN [org.jboss.as.dependency.private] (MSC service thread 1-6) WFLYSRV0018: Deployment “deployment.my-keycloak-provider.jar” is using a private module (“org.keycloak.keycloak-server-spi-private”) which may be changed or removed in future versions without notice.