Spring Boot kann keine neue Zeile in der Tabelle erstellen
Posted: 19 Jan 2025, 18:39
Ich verwende Spring Boot als einfaches Backend für meine Webseite. Ich nutze Spring Security und OAuth2 zur Authentifizierung (Anmeldung) für Benutzer auf meiner Seite. Wenn sich ein Benutzer auf meiner Seite anmeldet, möchte ich einige grundlegende Informationen über den Benutzer in meinem Backend speichern – nämlich Name, E-Mail-Adresse und eine ID (generiert durch das OAuth-Profil). Mein Problem ist, dass die Methode user.save bei der Implementierung (siehe unten) immer einen Fehler auslöst, der besagt, dass der angegebene Benutzer nicht vorhanden ist.
Der spezifische Fehler:< /p>
Ich habe das Gefühl, dass dies ein Fehler ist, weil ich versuche, mit den bereitgestellten Informationen einen neuen Benutzer in der Datenbank zu erstellen – daher sollte es natürlich nicht danach suchen und der Benutzer sollte es auch nicht bereits tun da sein. Ich möchte, dass es INSERT und nicht UPDATE ist. Ein wichtiger Punkt hierbei ist, dass meine ID NICHT automatisch generiert wird. Ich möchte die OAuth-Anbieter-ID für jeden potenziellen Anbieter nutzen (z. B. Google im Folgenden).
Einige Besonderheiten:
Auf der DB-Seite, falls es darauf ankommt, ist meine Benutzerinitialisierung:
Ich kann und habe jetzt schon eine manuelle Erstellungsmethode im Repository geschrieben, die zu funktionieren scheint. Es fühlt sich jedoch nicht gut an, dass ich eine einfache INSERT-Anweisung nicht zum Laufen bringen kann. Irgendeine Idee, was hier los ist – habe ich etwas falsch konfiguriert?
Der spezifische Fehler:< /p>
Code: Select all
org.springframework.dao.IncorrectUpdateSemanticsDataAccessException: Failed to update entity [User[id=google-1234, externalid=1234, externalidprovider=google, name=John Doe, email=john.doe@gmail]]; Id [google-1234] not found in database
Einige Besonderheiten:
- Ich habe eine Benutzertabelle (Backend Postgres 16), die wie folgt definiert ist:
Code: Select all
@Table(name = "users")
public record User (
@Id
String id,
String externalid,
String externalidprovider,
String name,
@NotNull @Email
String email
) {}
- Der Controller:
Code: Select all
@RestController
@RequestMapping("/users")
public class UserController {
private final UserRepository userRepository;
public UserController(UserRepository userRepository) {
this.userRepository = userRepository;
}
@ResponseStatus(HttpStatus.CREATED)
@PostMapping("/upsert-google")
User upsertGoogleUser(@AuthenticationPrincipal OAuth2User googlePrincipal) {
logger.info("Upserting google user: {}", googlePrincipal);
// Check if the user already exists
if (googlePrincipal == null) {
logger.error("Null OAuth2User principal provided");
throw new IllegalArgumentException("Invalid Google user information");
}
String userId = "google-" + googlePrincipal.getAttribute("sub");
logger.info("Upserting Google user with ID: {}", userId);
// Check if the user already exists
Optional existingUserOpt = userRepository.findById(userId);
if (existingUserOpt.isPresent()) {
User existingUser = existingUserOpt.get();
logger.info("Found existing user: {}", existingUser);
return updatedUser;
} else {
User newUser = new User(
userId,
googlePrincipal.getAttribute("sub"),
"google",
googlePrincipal.getAttribute("name"),
googlePrincipal.getAttribute("email")
);
logger.info("Creating new Google user: {}", newUser);
return userRepository.save(newUser);
}
}
- Das Repository ist nur ein erweitertes CrudRepository:
Code: Select all
public interface UserRepository extends CrudRepository {}
Code: Select all
DROP TABLE IF EXISTS Users CASCADE;
CREATE TABLE IF NOT EXISTS Users (
id TEXT PRIMARY KEY,
externalid TEXT,
externalidprovider TEXT,
name TEXT NOT NULL,
email TEXT NOT NULL,
membersince TIMESTAMP NOT NULL DEFAULT NOW(),
lastlogin TIMESTAMP NOT NULL DEFAULT NOW()
);