Spring Data MongoRepository更新实体时save触发重复键错误问题
I’ve run into this exact issue before—here’s what’s going on and how to fix it:
Why the Error Happens
Your ApplicationUser entity doesn’t have an @Id field mapped to MongoDB’s primary _id key. When you fetch the user via findByEmail(), the returned object doesn’t include the document’s unique identifier. When you call save() afterward, Spring Data MongoDB treats this as a new entity to insert instead of updating the existing one. Since the email is marked as unique, inserting a duplicate email triggers the constraint violation error.
Solution 1: Add the @Id Field (Recommended)
The simplest fix is to add an @Id field to your entity class. This allows Spring Data to track the existing document and perform an update instead of an insert:
@Document @Data public class ApplicationUser { @Id private String id; // You can also use ObjectId instead of String private String name; @Indexed(unique = true) private String email; private String organization = null; // 其他字段 }
Once you add this, when you fetch the user via findByEmail(), the id field will be populated from the database. Calling save() will now update the existing document instead of creating a new one.
Solution 2: Use an Update Query Instead of Fetching and Saving
If you don’t want to modify your entity class, you can define an update query directly in your repository interface. This skips fetching the entity entirely and updates the document in-place:
In your ApplicationUserRepository:
public interface ApplicationUserRepository extends MongoRepository<ApplicationUser, String> { ApplicationUser findByEmail(String email); @Query("{ 'email' : ?0 }") @Update("{ '$set' : { 'name' : ?1 } }") void updateNameByEmail(String email, String newName); }
Then, instead of fetching and saving, call this method directly:
applicationUserRepository.updateNameByEmail("abc@gmail.com", "John Doe 2");
This approach is more efficient for simple updates since it avoids round-tripping the entity to/from the database.
Additional Checks
- Double-check that
findByEmail()is actually returning the existing user (not null). If it returns null, you’d be creating a new user with the same email, which would also trigger the error. - Verify that the unique index on
emailis correctly created in MongoDB. You can check this using the MongoDB shell command:db.applicationUser.getIndexes()(replaceapplicationUserwith your actual collection name).
内容的提问来源于stack exchange,提问作者conquester

