Как использовать префикс ключа в Spring Data Couchbase с CouchbaseTemplate - PullRequest
1 голос
/ 10 апреля 2019

В приложении 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.

...