Skip to content

Adopt to AOT changes in Commons #1574

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: 5.0.x
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

<groupId>org.springframework.data</groupId>
<artifactId>spring-data-cassandra-parent</artifactId>
<version>5.0.0-SNAPSHOT</version>
<version>5.0.0-GH-1566-SNAPSHOT</version>
<packaging>pom</packaging>

<name>Spring Data for Apache Cassandra</name>
Expand Down
2 changes: 1 addition & 1 deletion spring-data-cassandra-distribution/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<parent>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-cassandra-parent</artifactId>
<version>5.0.0-SNAPSHOT</version>
<version>5.0.0-GH-1566-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

Expand Down
2 changes: 1 addition & 1 deletion spring-data-cassandra/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<parent>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-cassandra-parent</artifactId>
<version>5.0.0-SNAPSHOT</version>
<version>5.0.0-GH-1566-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import org.springframework.data.cassandra.core.mapping.Table;
import org.springframework.data.cassandra.repository.CassandraRepository;
import org.springframework.data.cassandra.repository.support.CassandraRepositoryFactoryBean;
import org.springframework.data.cassandra.repository.support.SimpleCassandraRepository;
import org.springframework.data.repository.config.AnnotationRepositoryConfigurationSource;
import org.springframework.data.repository.config.RepositoryConfigurationExtension;
import org.springframework.data.repository.config.RepositoryConfigurationExtensionSupport;
Expand All @@ -40,6 +41,7 @@
* @author Mark Paluch
* @author Christoph Strobl
* @author Mateusz Szymczak
* @author Chris Bono
*/
public class CassandraRepositoryConfigurationExtension extends RepositoryConfigurationExtensionSupport {

Expand All @@ -55,6 +57,11 @@ protected String getModulePrefix() {
return "cassandra";
}

@Override
public String getRepositoryBaseClassName() {
return SimpleCassandraRepository.class.getName();
}

@Override
public String getRepositoryFactoryBeanClassName() {
return CassandraRepositoryFactoryBean.class.getName();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.data.cassandra.repository.ReactiveCassandraRepository;
import org.springframework.data.cassandra.repository.support.ReactiveCassandraRepositoryFactoryBean;
import org.springframework.data.cassandra.repository.support.SimpleReactiveCassandraRepository;
import org.springframework.data.repository.config.AnnotationRepositoryConfigurationSource;
import org.springframework.data.repository.config.RepositoryConfigurationExtension;
import org.springframework.data.repository.core.RepositoryMetadata;
Expand All @@ -30,6 +31,7 @@
* {@link RepositoryConfigurationExtension} for Cassandra.
*
* @author Mark Paluch
* @author Chris Bono
* @since 2.0
*/
public class ReactiveCassandraRepositoryConfigurationExtension extends CassandraRepositoryConfigurationExtension {
Expand All @@ -39,6 +41,11 @@ public String getModuleName() {
return "Reactive Cassandra";
}

@Override
public String getRepositoryBaseClassName() {
return SimpleReactiveCassandraRepository.class.getName();
}

@Override
public String getRepositoryFactoryBeanClassName() {
return ReactiveCassandraRepositoryFactoryBean.class.getName();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import org.springframework.data.repository.core.NamedQueries;
import org.springframework.data.repository.core.RepositoryInformation;
import org.springframework.data.repository.core.RepositoryMetadata;
import org.springframework.data.repository.core.support.RepositoryComposition.RepositoryFragments;
import org.springframework.data.repository.core.support.RepositoryFactorySupport;
import org.springframework.data.repository.query.CachingValueExpressionDelegate;
import org.springframework.data.repository.query.QueryLookupStrategy;
Expand All @@ -50,13 +51,16 @@
* @author Thomas Darimont
* @author Mark Paluch
* @author John Blum
* @author Chris Bono
*/
public class CassandraRepositoryFactory extends RepositoryFactorySupport {

private final MappingContext<? extends CassandraPersistentEntity<?>, CassandraPersistentProperty> mappingContext;

private final CassandraOperations operations;

private CassandraRepositoryFragmentsContributor fragmentsContributor = CassandraRepositoryFragmentsContributor.DEFAULT;

/**
* Create a new {@link CassandraRepositoryFactory} with the given {@link CassandraOperations}.
*
Expand All @@ -70,6 +74,17 @@ public CassandraRepositoryFactory(CassandraOperations operations) {
this.mappingContext = operations.getConverter().getMappingContext();
}

/**
* Configures the {@link CassandraRepositoryFragmentsContributor} to be used. Defaults to
* {@link CassandraRepositoryFragmentsContributor#DEFAULT}.
*
* @param fragmentsContributor
* @since 5.0
*/
public void setFragmentsContributor(CassandraRepositoryFragmentsContributor fragmentsContributor) {
this.fragmentsContributor = fragmentsContributor;
}

@Override
protected ProjectionFactory getProjectionFactory(@Nullable ClassLoader classLoader,
@Nullable BeanFactory beanFactory) {
Expand Down Expand Up @@ -105,6 +120,23 @@ protected Optional<QueryLookupStrategy> getQueryLookupStrategy(@Nullable Key key
new CachingValueExpressionDelegate(valueExpressionDelegate), mappingContext));
}

@Override
protected RepositoryFragments getRepositoryFragments(RepositoryMetadata metadata) {
return getRepositoryFragments(metadata, operations);
}

/**
* Creates {@link RepositoryFragments} based on {@link RepositoryMetadata} to add Cassandra-specific extensions.
* Built-in fragment contribution can be customized by configuring {@link CassandraRepositoryFragmentsContributor}.
*
* @param metadata repository metadata.
* @param operations the Cassandra operations manager.
* @return {@link RepositoryFragments} to be added to the repository.
* @since 5.0
*/
protected RepositoryFragments getRepositoryFragments(RepositoryMetadata metadata, CassandraOperations operations) {
return fragmentsContributor.contribute(metadata, getEntityInformation(metadata.getDomainType()), operations);
}

private record CassandraQueryLookupStrategy(CassandraOperations operations,
ValueExpressionDelegate valueExpressionDelegate,
Expand Down Expand Up @@ -132,4 +164,3 @@ public RepositoryQuery resolveQuery(Method method, RepositoryMetadata metadata,
}

}

Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import org.springframework.data.cassandra.core.CassandraOperations;
import org.springframework.data.cassandra.core.CassandraTemplate;
import org.springframework.data.cassandra.repository.CassandraRepository;
import org.springframework.data.mapping.context.MappingContext;
import org.springframework.data.repository.Repository;
import org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport;
import org.springframework.data.repository.core.support.RepositoryFactorySupport;
Expand All @@ -31,12 +32,17 @@
* @author John Blum
* @author Oliver Gierke
* @author Mark Paluch
* @author Chris Bono
*/
public class CassandraRepositoryFactoryBean<T extends Repository<S, ID>, S, ID>
extends RepositoryFactoryBeanSupport<T, S, ID> {

private boolean mappingContextConfigured = false;

private @Nullable CassandraOperations cassandraOperations;

private CassandraRepositoryFragmentsContributor repositoryFragmentsContributor = CassandraRepositoryFragmentsContributor.DEFAULT;

/**
* Create a new {@link CassandraRepositoryFactoryBean} for the given repository interface.
*
Expand All @@ -51,7 +57,35 @@ protected RepositoryFactorySupport createRepositoryFactory() {

Assert.state(cassandraOperations != null, "CassandraOperations must not be null");

return new CassandraRepositoryFactory(cassandraOperations);
CassandraRepositoryFactory factory = getFactoryInstance(cassandraOperations);
factory.setFragmentsContributor(repositoryFragmentsContributor);
return factory;
}

/**
* Creates and initializes a {@link CassandraRepositoryFactory} instance.
*
* @param operations the Cassandra operations
* @return new {@link CassandraRepositoryFactory} instance
*/
protected CassandraRepositoryFactory getFactoryInstance(CassandraOperations operations) {
return new CassandraRepositoryFactory(operations);
}

@Override
public CassandraRepositoryFragmentsContributor getRepositoryFragmentsContributor() {
return this.repositoryFragmentsContributor;
}

/**
* Configures the {@link CassandraRepositoryFragmentsContributor} to contribute built-in fragment functionality to the
* repository.
*
* @param repositoryFragmentsContributor must not be {@literal null}.
* @since 5.0
*/
public void setRepositoryFragmentsContributor(CassandraRepositoryFragmentsContributor repositoryFragmentsContributor) {
this.repositoryFragmentsContributor = repositoryFragmentsContributor;
}

/**
Expand All @@ -61,9 +95,15 @@ protected RepositoryFactorySupport createRepositoryFactory() {
* on Apache Cassandra.
*/
public void setCassandraTemplate(CassandraTemplate cassandraTemplate) {

this.cassandraOperations = cassandraTemplate;
setMappingContext(cassandraTemplate.getConverter().getMappingContext());
}

@Override
protected void setMappingContext(MappingContext<?, ?> mappingContext) {

super.setMappingContext(mappingContext);

this.mappingContextConfigured = true;
}

@Override
Expand All @@ -72,5 +112,9 @@ public void afterPropertiesSet() {
super.afterPropertiesSet();

Assert.notNull(cassandraOperations, "CassandraOperations must not be null");

if (!mappingContextConfigured) {
setMappingContext(cassandraOperations.getConverter().getMappingContext());
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
/*
* Copyright 2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.cassandra.repository.support;

import org.springframework.data.cassandra.core.CassandraOperations;
import org.springframework.data.cassandra.repository.query.CassandraEntityInformation;
import org.springframework.data.repository.core.RepositoryMetadata;
import org.springframework.data.repository.core.support.RepositoryComposition.RepositoryFragments;
import org.springframework.data.repository.core.support.RepositoryFragmentsContributor;
import org.springframework.util.Assert;

/**
* Cassandra-specific {@link RepositoryFragmentsContributor} contributing fragments based on the repository.
* <p>
* Implementations must define a no-args constructor.
*
* @author Chris Bono
* @since 5.0
*/
public interface CassandraRepositoryFragmentsContributor extends RepositoryFragmentsContributor {

CassandraRepositoryFragmentsContributor DEFAULT = DefaultCassandraRepositoryFragmentsContributor.INSTANCE;

/**
* Returns a composed {@code CassandraRepositoryFragmentsContributor} that first applies this contributor to its inputs,
* and then applies the {@code after} contributor concatenating effectively both results. If evaluation of either
* contributors throws an exception, it is relayed to the caller of the composed contributor.
*
* @param after the contributor to apply after this contributor is applied.
* @return a composed contributor that first applies this contributor and then applies the {@code after} contributor.
*/
default CassandraRepositoryFragmentsContributor andThen(CassandraRepositoryFragmentsContributor after) {

Assert.notNull(after, "CassandraRepositoryFragmentsContributor must not be null");

return new CassandraRepositoryFragmentsContributor() {

@Override
public RepositoryFragments contribute(RepositoryMetadata metadata,
CassandraEntityInformation<?, ?> entityInformation, CassandraOperations operations) {
return CassandraRepositoryFragmentsContributor.this.contribute(metadata, entityInformation, operations)
.append(after.contribute(metadata, entityInformation, operations));
}

@Override
public RepositoryFragments describe(RepositoryMetadata metadata) {
return CassandraRepositoryFragmentsContributor.this.describe(metadata).append(after.describe(metadata));
}
};
}

/**
* Creates {@link RepositoryFragments} based on {@link RepositoryMetadata} to add
* Cassandra-specific extensions.
*
* @param metadata repository metadata.
* @param entityInformation must not be {@literal null}.
* @param operations must not be {@literal null}.
* @return {@link RepositoryFragments} to be added to the repository.
*/
RepositoryFragments contribute(RepositoryMetadata metadata,
CassandraEntityInformation<?, ?> entityInformation, CassandraOperations operations);

/**
* Implementation of {@link CassandraRepositoryFragmentsContributor} that contributes empty fragments by default.
*
* @author Chris Bono
* @since 5.0
*/
enum DefaultCassandraRepositoryFragmentsContributor implements CassandraRepositoryFragmentsContributor {

INSTANCE;

@Override
public RepositoryFragments contribute(RepositoryMetadata metadata,
CassandraEntityInformation<?, ?> entityInformation, CassandraOperations operations) {
return RepositoryFragments.empty();
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Eventhough the fragment are empty by default for Cassandra, I chose to create a default impl that simple returned empty() to serve as a non-null fragmentsContributor default in the factory/factoryBeans as well as a placeholder in case we add default fragments (e.g. the MongoDB queryDsl fragments).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense to have the same extension points across our Spring Data modules. Having the enum inside the interface makes it public. I suggest having a package-protected visibility for the default implementation.

}

@Override
public RepositoryFragments describe(RepositoryMetadata metadata) {
return RepositoryFragments.empty();
}
}
}
Loading