Use a repository method like existsByEmail(String email) before attempting a save. While this doesn't solve high-concurrency race conditions, it eliminates the majority of "honest" mistakes.
In some cases, using a "query-then-update" approach or custom native queries with ON CONFLICT DO UPDATE (in PostgreSQL) can ensure the operation succeeds regardless of whether the record already exists. Conclusion causing a primary key collision.
Passing a detached entity to the save() method can sometimes lead JPA to treat it as a new record (attempting an INSERT ) rather than an update, causing a primary key collision. causing a primary key collision.