如何提供CassandraEntityInformation对于 SimpleReactiveCassandraRepository?

发布于 2025-01-19 14:04:12 字数 3639 浏览 7 评论 0原文

我正在对 spring-data-cassandra-reactive 进行一些研究,看起来我无法弄清楚或找到关于此的正确文档。

根据文档,您可以创建一个用 @Repository 注释的接口,然后使用注释创建自定义查询来检索您想要的数据。代码看起来像这样:


@Repository
public interface UserRepository
        extends ReactiveCassandraRepository<UserEntity, UUID>
{

    @Query("SELECT u FROM UserEntity u WHERE username = :user ALLOW FILTERING")
    Mono<UserEntity> findUserEntityByUsername(@Param("user") String user);

    /**
     * This is just to illustrate/simulate some custom/advanced logic that cannot be
     * done via @Query()
     */
    default Mono<UserEntity> saveWithBase64EncodedPassword(UserEntity entity)
    {
        String encodedPassword = Base64.getEncoder().encodeToString(entity.getPassword().getBytes());
        entity.updatePassword(encodedPassword);
        return this.save(entity);
    }

}


@Table(UserEntity.TABLE_NAME)
public class UserEntity
{

    public final static String TABLE_NAME = "users";

    @PrimaryKeyColumn(name = "uuid", ordinal = 0, type = PrimaryKeyType.PARTITIONED)
    @CassandraType(type = CassandraType.Name.UUID)
    @Column
    private UUID id;

    @Column
    @CassandraType(type = CassandraType.Name.VARCHAR)
    private String username;

    @Column
    @CassandraType(type = CassandraType.Name.VARCHAR)
    private String password;

    public UserEntity()
    {
        this.id = UUID.randomUUID();
    }

    public UserEntity(String username, String password)
    {
        this.id = UUID.randomUUID();
        this.username = username;
        this.password = password;
    }

    public UUID getId()
    {
        return id;
    }

    public void setId(UUID id)
    {
        this.id = id;
    }

    public String getUsername()
    {
        return username;
    }

    public void setUsername(String username)
    {
        this.username = username;
    }

    public String getPassword()
    {
        return password;
    }

    public void setPassword(String password)
    {
        this.password = password;
    }

    public void updatePassword(String newPassword)
    {
        this.password = newPassword;
    }

}

依赖关系:

plugins {
    id("org.springframework.boot") version "2.6.6"
    id("io.spring.dependency-management") version "1.0.11.RELEASE"
}

dependencies {

    // Embedded Cassandra Server - used for testing.
    implementation("com.github.nosan:embedded-cassandra-spring-boot-starter:4.1.0")

    // Spring Data Cassandra Dependencies
    annotationProcessor("org.springframework.boot:spring-boot-configuration-processor")
    implementation("org.springframework.boot:spring-boot-starter-actuator")
    implementation("org.springframework.boot:spring-boot-starter-data-cassandra-reactive")

    testImplementation("org.springframework.boot:spring-boot-starter-test") {
        exclude("org.junit.vintage:junit-vintage-engine")
        exclude("com.vaadin.external.google:android-json")
    }
    testImplementation("io.projectreactor:reactor-test")
    // /Spring Data Cassandra Dependencies
}

到目前为止,这工作得很好。但是,我试图弄清楚如何切换到实现接口以便能够使用 @Autowire (即在此示例代码中自动装配
org.springframework.security.crypto.password.PasswordEncoder)

浏览 spring-data-cassandra jar 中的代码我注意到有一个名为 org.springframework 的类.data.cassandra.repository.support.SimpleReactiveCassandraRepository 您可以从中进行扩展。它已经具备了您需要实现的大多数常见功能,这就是为什么它看起来是扩展的完美候选者。

问题来了 - 它需要 CassandraEntityInformation元数据。 我似乎无法找到这是从哪里获取的,或者它应该如何自动连接,我觉得我可能缺少一些东西或者可能是依赖项。

有什么想法吗?

I'm doing some research bout spring-data-cassandra-reactive and it looks like I can't figure out or find the right documentation about this.

According to the documentation you can create an interface which is annotated with @Repository and then use annotations to create custom queries that will retrieve the data you want. The code would look something like this:


@Repository
public interface UserRepository
        extends ReactiveCassandraRepository<UserEntity, UUID>
{

    @Query("SELECT u FROM UserEntity u WHERE username = :user ALLOW FILTERING")
    Mono<UserEntity> findUserEntityByUsername(@Param("user") String user);

    /**
     * This is just to illustrate/simulate some custom/advanced logic that cannot be
     * done via @Query()
     */
    default Mono<UserEntity> saveWithBase64EncodedPassword(UserEntity entity)
    {
        String encodedPassword = Base64.getEncoder().encodeToString(entity.getPassword().getBytes());
        entity.updatePassword(encodedPassword);
        return this.save(entity);
    }

}


@Table(UserEntity.TABLE_NAME)
public class UserEntity
{

    public final static String TABLE_NAME = "users";

    @PrimaryKeyColumn(name = "uuid", ordinal = 0, type = PrimaryKeyType.PARTITIONED)
    @CassandraType(type = CassandraType.Name.UUID)
    @Column
    private UUID id;

    @Column
    @CassandraType(type = CassandraType.Name.VARCHAR)
    private String username;

    @Column
    @CassandraType(type = CassandraType.Name.VARCHAR)
    private String password;

    public UserEntity()
    {
        this.id = UUID.randomUUID();
    }

    public UserEntity(String username, String password)
    {
        this.id = UUID.randomUUID();
        this.username = username;
        this.password = password;
    }

    public UUID getId()
    {
        return id;
    }

    public void setId(UUID id)
    {
        this.id = id;
    }

    public String getUsername()
    {
        return username;
    }

    public void setUsername(String username)
    {
        this.username = username;
    }

    public String getPassword()
    {
        return password;
    }

    public void setPassword(String password)
    {
        this.password = password;
    }

    public void updatePassword(String newPassword)
    {
        this.password = newPassword;
    }

}

Dependencies:

plugins {
    id("org.springframework.boot") version "2.6.6"
    id("io.spring.dependency-management") version "1.0.11.RELEASE"
}

dependencies {

    // Embedded Cassandra Server - used for testing.
    implementation("com.github.nosan:embedded-cassandra-spring-boot-starter:4.1.0")

    // Spring Data Cassandra Dependencies
    annotationProcessor("org.springframework.boot:spring-boot-configuration-processor")
    implementation("org.springframework.boot:spring-boot-starter-actuator")
    implementation("org.springframework.boot:spring-boot-starter-data-cassandra-reactive")

    testImplementation("org.springframework.boot:spring-boot-starter-test") {
        exclude("org.junit.vintage:junit-vintage-engine")
        exclude("com.vaadin.external.google:android-json")
    }
    testImplementation("io.projectreactor:reactor-test")
    // /Spring Data Cassandra Dependencies
}

This, so far, works fine. However, I'm trying to figure out how to switch to implementing the interface in order to be able to use @Autowire (i.e. in this example code to autowire
org.springframework.security.crypto.password.PasswordEncoder)

Surfing through the code in the spring-data-cassandra jar I noticed there's a class named org.springframework.data.cassandra.repository.support.SimpleReactiveCassandraRepository which you can extend from. It already has most of the common things you would need implemented for you which is why it looks like the perfect candidate to extend from.

And here comes the problem - it requires CassandraEntityInformation<T, ID> metadata.
I cannot seem to find where this is taken from or how it's supposed to be auto-wired and I feel like I might be missing something or maybe a dependency.

Any ideas?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

和我恋爱吧 2025-01-26 14:04:13

SimpleReactiveCassandraRepository 是一个很棒的类,因为它使您可以访问 ReactiveCassandraOperations 以及 CqlSession。这是进行细粒度操作的好方法。 (LWT,Bacthes)

您是正确的,不同的类将被自动装配。这是示例代码:

@Repository
public class OwnerReactiveCassandraRepository extends SimpleReactiveCassandraRepository<OwnerEntitySpring, UUID> {

protected final CqlSession cqlSession;
protected final ReactiveCassandraOperations reactiveCassandraTemplate;

@SuppressWarnings("unchecked")
public OwnerReactiveCassandraRepository(CqlSession cqlSession, ReactiveCassandraOperations ops) {
    super(new MappingCassandraEntityInformation<OwnerEntitySpring, UUID>(
            (CassandraPersistentEntity<OwnerEntitySpring>) ops.getConverter().getMappingContext()
            .getRequiredPersistentEntity(OwnerEntitySpring.class), ops.getConverter()), ops);
    this.cqlSession = cqlSession;
    this.reactiveCassandraTemplate = ops;
}

public Flux<OwnerEntitySpring> searchByOwnerName(String ownerLastName) {
    return reactiveCassandraTemplate.getReactiveCqlOperations()
                                    .query(SimpleStatement
                                        .builder("SELECT * FROM " + TABLE_NAME + " WHERE " + COLUMN_LASTNAME  + "=?")
                                        .addPositionalValues(ownerLastName)
                                        .build(), (row, rownum) -> new OwnerEntitySpring(row));
}

TLDR;我使用 Spring data Reactive 实现了 Spring PetClinic,您可以在此处 这是一个包含代码的分步研讨会。您可能需要特别查看 此文件夹

在项目中,您会发现仅与驱动程序反应,与CassandraRepositories反应以及与SimpleCassandraRepositories。 (检查TEST文件夹)

SimpleReactiveCassandraRepository is a great class as it gives you access to ReactiveCassandraOperations and as such to CqlSession. It is a great way to have fine grained operations. (LWT, Bacthes)

You are correct the different classes would be autowired. Here is a sample code:

@Repository
public class OwnerReactiveCassandraRepository extends SimpleReactiveCassandraRepository<OwnerEntitySpring, UUID> {

protected final CqlSession cqlSession;
protected final ReactiveCassandraOperations reactiveCassandraTemplate;

@SuppressWarnings("unchecked")
public OwnerReactiveCassandraRepository(CqlSession cqlSession, ReactiveCassandraOperations ops) {
    super(new MappingCassandraEntityInformation<OwnerEntitySpring, UUID>(
            (CassandraPersistentEntity<OwnerEntitySpring>) ops.getConverter().getMappingContext()
            .getRequiredPersistentEntity(OwnerEntitySpring.class), ops.getConverter()), ops);
    this.cqlSession = cqlSession;
    this.reactiveCassandraTemplate = ops;
}

public Flux<OwnerEntitySpring> searchByOwnerName(String ownerLastName) {
    return reactiveCassandraTemplate.getReactiveCqlOperations()
                                    .query(SimpleStatement
                                        .builder("SELECT * FROM " + TABLE_NAME + " WHERE " + COLUMN_LASTNAME  + "=?")
                                        .addPositionalValues(ownerLastName)
                                        .build(), (row, rownum) -> new OwnerEntitySpring(row));
}

TLDR; I implemented the Spring PetClinic with Spring data Reactive and you can have access to the full code here It is a step by step workshop with the code. You may want to look specially at this folder

In the project you will find reactive with the drivers only, reactive with CassandraRepositories and reactive with SimpleCassandraRepositories. (Check the TEST folder)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文