大家好,提前感谢大家看了这个问题。我正在JavaSpringBoot(JavaJDK1.8版)上使用couchbase服务器社区6.6.0。
问题描述:为了与couchbase交互,我使用了pagingandsortingrepository。每次我调用.save()时,都会在couchbase中创建一个新文档,表示我正在使用的对象的新示例。另外,当我从couchbase检索一个对象时,更改某个字段的值,例如,.setpassword(),然后调用.save()使更改持久化,然后在couchbase中创建该对象的新文档(具有新id)。在我看来,当我调用.save()时,数据库中似乎存在该对象的许多不同版本,我想确保我一直在处理对象/实体示例的最新版本。
我真的很困惑!我要做的应该是简单明了的,每次我更新一个java实体时,我都希望对couchbase中的文档(使用该文档id)进行持久化的更改。也许我错过了什么。请给我建议。
pom的局部视图如下所示:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.0</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
...
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-couchbase</artifactId>
</dependency>
实体如下:
@Data
@Document
@CompositeQueryIndex(fields = {"id", "userName"})
public class User implements Serializable {
private static final long serialVersionUID = 1L;
@IdPrefix
private String prefix;
@Id @NotNull @GeneratedValue( delimiter = "::", strategy = GenerationStrategy.UNIQUE)
private String id;
@Field
@NotNull
@Size(min=2, max=40)
private String firstname;
@Field
@NotNull
@QueryIndexed
private String username;
//Other attributes here ...
}
//ConfirmationToken Entity
@Data
@NoArgsConstructor
@CompositeQueryIndex(fields = {"id", "confirmationToken"})
public class ConfirmationToken {
@IdPrefix
private String prefix = "token";
@Id @NotNull @GeneratedValue(delimiter = "::", strategy = GenerationStrategy.UNIQUE)
private String id;
@Field
@Reference
private User user;
@Field
@QueryIndexed
private String confirmationToken;
//Other attributes here ...
}
userrepository看起来像:
@Repository
public interface UserRepository extends PagingAndSortingRepository<User, Long> {
@ScanConsistency(query = QueryScanConsistency.REQUEST_PLUS)
List<User> findByUsername(String username);
}
@Service
@AllArgsConstructor
public class ConfirmationTokenServiceImpl implements ConfirmationTokenService {
@Autowired
private final ConfirmationTokenRepository confirmationTokenRepository;
@Override
public void saveConfirmationToken(ConfirmationToken confirmToken) {
confirmationTokenRepository.save(confirmToken);
}
}//end class
当我想从couchbase检索用户对象时,我会执行以下操作:
//How do I ensure this Object is the latest version of that document?
List<User> users = userRepository.findByUsername(username);
//The following does not ensure that I get the latest version of that User document with that username
User testUser = users.get(users.size()-1);
在某些方法中,我更改java对象(即user)的字段值,然后在调用.save(user对象)时在数据库中创建该用户文档的新修订版。如何更新该用户对象的字段并使该文档在数据库中持久化,而不创建该文档的新修订版?另外,我如何确保我总是获得并处理该用户文档的最新版本?
public void someMethod(UserDTO regForm, final String contextPath) {
User testUser = new User();
testUser.setFirstname(regForm.getFname());
testUser.setLastname(regForm.getSname());
//Make User persistent
userRepository.save(testUser);
//Create the confirmation token for that User instance
final ConfirmationToken confirmToken = new ConfirmationToken(testUser);
confirmationTokenService.saveConfirmationToken(confirmToken);
}
在这个方法中,我有另一个名为confirmationtoken的类,它引用了一个用户对象。这是将每个confirmationtoken示例与特定的用户示例相关联。当我调用以下方法来更改用户密码时,将为数据库中的用户创建一个具有新id的新文档。我无法理解如何更新当前示例。请帮忙。
public void changeUserPassword(ConfirmationToken confirmToken, ResetPassDTO resetPassForm) {
//Retrieve the User instance that is associated with that Token
final User testUser = confirmToken.getUser();
if (testUser.getEmail().equals(resetPassForm.getEmail())) {
//Get the Hash of the User's password
final String encryptedPassword = bCryptPasswordEncoder.encode(resetPassForm.getNewPassword());
testUser.setPassword(encryptedPassword);
//Enable the user account - since email ownership is also verified
testUser.setIsEnabled(true);
userRepository.save(testUser);
}
//Delete the Confirmation Token entity
confirmationTokenService.deleteConfirmationToken(confirmToken);
}
更新:
似乎我不得不回去为实体建立领域模型。更具体地说,考虑couchbase如何进行文档嵌入以及何时进行引用。在我的示例中,confirmationtoken示例持有对用户示例的引用。实际上,confirmationtoken将用户示例嵌入到同一个json文档中。但我无法访问所需的实际用户对象。换句话说,我似乎无法从confirmationtoken示例中通过跟随user对象的id来取消引用并获取用户示例。我的解决方法:我引入了一个 uuid
字段,然后从confirmationtoken获取用户示例的引用,然后调用 userRepository.findByUuid(userFromToken.getUuid());
只有那时我才能得到我想要的实际用户对象。我的问题是为什么couchbase-spring-sdk不能自动取消引用?而且,似乎当我更改某个属性的值时,更改不会发生在实际对象上,而是发生在嵌入对象上,因此每次我都需要手动执行此取消引用以获取实际对象。这类似于mongodb@dbrefs??不确定是否有使用n1ql和嵌套查询的解决方案?我能用n1ql实现这一点吗?
暂无答案!
目前还没有任何答案,快来回答吧!