В приложении Spring Data Couchbase я настроил bean-компонент CouchbaseTemplate для использования префикса ключа и разделителя:
public class CouchbaseConfig extends AbstractCouchbaseConfiguration {
...
@Override
@Bean(name = BeanNames.COUCHBASE_TEMPLATE)
public CouchbaseTemplate couchbaseTemplate() throws Exception {
CouchbaseTemplate couchbaseTemplate = super.couchbaseTemplate();
couchbaseTemplate.keySettings(KeySettings.build()
.prefix("USER")
.delimiter("::"));
return couchbaseTemplate;
}
...
}
У меня есть документ с идентификатором, созданный из атрибута в документе, какниже:
@Data
@Document
public class User {
@Id @GeneratedValue(strategy = GenerationStrategy.USE_ATTRIBUTES)
private String id;
@Field
@IdAttribute
private String userName;
@Field
private String firstName;
}
Затем CouchbaseRepository:
@ViewIndexed(designDoc = "user", viewName = "all")
public interface CouchbaseUserRepository extends CouchbaseRepository<User, String> {
}
Это упаковано реализацией UserRepository:
@Repository
public class UserRepositoryImpl implements UserRepository {
private CouchbaseUserRepository couchbaseUserRepository;
private CouchbaseTemplate couchbaseTemplate;
public UserRepositoryImpl(CouchbaseUserRepository couchbaseUserRepository,
CouchbaseTemplate couchbaseTemplate) {
this.couchbaseUserRepository = couchbaseUserRepository;
this.couchbaseTemplate = couchbaseTemplate;
}
@Override
public User save(User user) {
return couchbaseUserRepository.save(user);
}
@Override
public User findByUserName(String userName) {
User user = new User();
user.setUserName(userName);
String idToFind = couchbaseTemplate.getGeneratedId(user);
return couchbaseUserRepository.findOne(idToFind);
}
@Override
public void deleteAll() {
couchbaseUserRepository.deleteAll();
}
}
И следующим тестом:
@RunWith(SpringRunner.class)
@SpringBootTest
public class UserRepositoryIntegrationTest {
private static final String USERNAME = "username";
@Autowired
private UserRepository userRepository;
@Before
public void setup() {
userRepository.deleteAll();
User user = new User();
user.setUserName(USERNAME);
userRepository.save(user);
}
@Test
public void testSave() {
User user = userRepository.findByUserName(USERNAME);
user.setFirstName("Fred");
userRepository.save(user);
}
}
Когда я запускаю тест, в моем корзине появляются два документа:
USER::USER::username{"firstName":"Fred","_class":"com.example.couchbase.resiliency.User","userName":"username"}
USER::username{"userName":"username","_class":"com.example.couchbase.resiliency.User"}
Кажется, что когда тест загружает объект, объект, очевидно, имеет идентификатор.Однако при повторном сохранении префикс ключа добавляется перед сохранением, что означает сохранение второго документа, поскольку этот новый идентификатор не существует.
- Как я могу остановить добавление префикса ключа дважды?
- Есть ли более элегантный способ реализации метода findByUserName?При чтении документов Spring Data Couchbase кажется, что вы должны попросить CouchbaseTemplate сгенерировать для вас идентификатор, прежде чем передавать его в COOBBASE Repository метод findOne.
Для информации, я используюSpring Data Couchbase v 2.2.18 в приложении Spring Boot 1.5.19.