Reputation: 13616
I use Java Spring Framework and MongoDB in my project.
I create a PasswordRecovery object and save it in MongoDB document using the MongoRepository.
When I try to fetch back from MongoDB the stored object I get an error.
Here is the class that I save in MongoDB:
@Document("password_recovery_data")
@Data
public class PasswordRecovery {
@Id
private String id;
@Indexed
private String token;
@Email
private String email;
private LocalDateTime created;
private LocalDateTime expired;
private boolean isUsed;
}
Here is repository defenition:
package com.priceandbuild.operationaldashboardapi.shared.repository;
import com.priceandbuild.operationaldashboardapi.shared.model.PasswordRecovery;
import org.springframework.data.mongodb.repository.MongoRepository;
import java.util.Optional;
public interface PasswordRecoveryRepository extends MongoRepository<PasswordRecovery, String> {
Optional<PasswordRecovery> findPasswordRecoveryByToken(String token);
}
Here is how I save the new PasswordRecovery:
private final PasswordRecoveryRepository passwordRecoveryRepository;
PasswordRecovery passwordRecovery = new PasswordRecovery() {};
passwordRecovery.setToken(UUID.randomUUID().toString());
passwordRecovery.setEmail(email);
passwordRecovery.setCreated(LocalDateTime.now());
passwordRecovery.setExpired(LocalDateTime.now().plusDays(1));
passwordRecovery.setUsed(false);
passwordRecoveryRepository.save(passwordRecovery);
After the save function is executed the password recovery object is saved in MongoDB:
{
"_id": {
"$oid": "3456345635g56756h65"
},
"token": "dasdasd34235-ded6-4442-234dsfdsf-334terffe4",
"email": "[email protected]",
"created": {
"$date": "2022-03-13T23:32:19.702Z"
},
"expired": {
"$date": "2022-03-14T23:32:19.885Z"
},
"isUsed": false,
"_class": "com.website.opdash.shared.service.auth.AuthServiceImpl$1"
}
I am trying to get the value from the MongoDB document saved like that:
Optional<PasswordRecovery> passwordRecoveryOptional =
passwordRecoveryRepository.findPasswordRecoveryByToken(token);
But I get an error when I try to fetch saved earlier document:
No property this$0 found on entity class com.website.opdash.shared.service.auth.AuthServiceImpl$1 to bind constructor parameter to!
It looks like the issue was caused by the value of the property _class saved password recovery document in MongoDB.
I spent a couple of hours on this issue, but I don't understand why exactly I get this error, please help me to solve this issue.
Upvotes: 1
Views: 433
Reputation: 53381
I think you are totally right and the issue was caused by the value of the property _class
saved password recovery document in MongoDB: in a nutshell, MongoDB is unable to create a new instance of the class stored in the _class
field when you try to read it later.
If your question is accurate, my guess is that the following code fragment is defined in the AuthServiceImpl
class:
PasswordRecovery passwordRecovery = new PasswordRecovery() {};
passwordRecovery.setToken(UUID.randomUUID().toString());
passwordRecovery.setEmail(email);
passwordRecovery.setCreated(LocalDateTime.now());
passwordRecovery.setExpired(LocalDateTime.now().plusDays(1));
passwordRecovery.setUsed(false);
passwordRecoveryRepository.save(passwordRecovery);
Please, note the following line, especially the curly braces at the end of the statement:
PasswordRecovery passwordRecovery = new PasswordRecovery() {};
When using these curly braces after the PasswordRecovery
constructor invocation you are creating an instance of an an anonymous class, not just instantiating a new PasswordRecovery
object.
To make the point clear, please, consider the following test case.
Given:
package com.website.opdash.shared.service.auth;
public class AuthServiceImpl {
public void setPasswordRecoveryData() {
PasswordRecovery passwordRecovery = new PasswordRecovery() {};
System.out.println(passwordRecovery.getClass());
}
public static void main(String[] args){
AuthServiceImpl impl = new AuthServiceImpl();
impl.setPasswordRecoveryData();
}
}
Then, the System.println
statement will output:
com.website.opdash.shared.service.auth.AuthServiceImpl$1
As you can see, this value is the one MongoDB is actually storing when saving your data in the _class
field.
To solve the problem, just get rid of these curly braces when creating your PasswordRecovery
object:
// Just instantiate the object
PasswordRecovery passwordRecovery = new PasswordRecovery();
passwordRecovery.setToken(UUID.randomUUID().toString());
passwordRecovery.setEmail(email);
passwordRecovery.setCreated(LocalDateTime.now());
passwordRecovery.setExpired(LocalDateTime.now().plusDays(1));
passwordRecovery.setUsed(false);
passwordRecoveryRepository.save(passwordRecovery);
It will allow you to successfully recover the information later.
Upvotes: 4