spring-data-mongodb icon indicating copy to clipboard operation
spring-data-mongodb copied to clipboard

Attempts to update a lazy object result in the creation of a new object rather than modifying the existing one.

Open salman-khandu opened this issue 2 years ago • 5 comments

I have a user document that has a reference to subgroups as lazy. I am trying to get a subgroup from the user and then try to modify it but instead of updating it tries to insert a new one. This is only the case when I add the auditing field @Version version. If I removed the version field, everything work fine and it update the document.

       // PostConstruct
	public void test() {
		setup(); // setting update test data
		executeOperation(); 
	}

private void executeOperation() {
	final User user = userRepository.findById("1").get();
	user.getSubTree().getChildren().add(subRepository.findById("p1").get());
	nodeService.save(user.getSubTree());
}

private void setup() {
	final MongoUser user = new MongoUser("1");
	user.setName("test");
	final MongoUser savedUser = userRepository.save(user);
	final MongoSubGroup group = new MongoSubGroup();
	group.setId("BASE");
	group.setOwner(savedUser);
	group.setName("BASE");
	subGroupRepository.save(group);
	
	final Dept mongoDepartment = new MongoDept("dept1");
	final Dept savedDepartment = deptRepository.save(mongoDepartment);
	
	final MongoSub profile = new MongoSub();
	profile.setId("p1");
	profile.setOwner(savedDepartment);
	subRepository.save(profile);
}`

From executeOperation() there is a lazy load operation for subgroups and then there is a call to nodeservice

public void save(SubGroup subgrup) {
		for (SubTreeNode node : subgrup.getChildren()) {
			// skipping Some business logic
			final Link link = new Link();
			link.setId("1");
			((MongoSubGroup) (subgrup)).getLinks().add(link);
		}

		groupRepository.save(subgrup);
	}

So here as soon groupRepository.save(subgrup) tries to create a new one and as id as the index it gives duplicate error

Caused by: com.mongodb.MongoWriteException: Write operation error on server localhost:27017. Write error: WriteError{code=11000, message='E11000 duplicate key error collection: demo.subGroup index: _id_ dup key: { _id: "BASE" }', details={}}.

Attached sample project demo.zip

salman-khandu avatar Apr 12 '23 10:04 salman-khandu

Thanks for reporting and the reproducer project - we'll have a look!

christophstrobl avatar Apr 12 '23 11:04 christophstrobl

While saving lazy loading references back as such is supported, storing them back as entities is currently not. The entire szenario is related to #2306 which had been declined some years ago. Nevertheless we think it's worth revisting the past decission and investigate potential solutions like unwrapping proxies before save operations.

christophstrobl avatar Apr 12 '23 13:04 christophstrobl

@christophstrob By removing the version property, mongo modifies the document. So not sure even though object is lazy without versioning it's working

salman-khandu avatar Apr 12 '23 16:04 salman-khandu

it's a matter of accessing properties to determine if an entity is new or not that then leads to different routes within the template as versioned ones need more treatment.

christophstrobl avatar Apr 13 '23 05:04 christophstrobl

it's a matter of accessing properties to determine if an entity is new or not that then leads to different routes within the template as versioned ones need more treatment.

Any updates on the fix?

salman-khandu avatar Apr 23 '23 04:04 salman-khandu