I have a Spring WebFlux App with mongo dB integration. It has Entities with @DBRef annotation. In order to @DBRef resolution, I have added both reactive and non-reactive dependencies for spring-data-mongodb as below.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb-reactive</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
with above configs, @DBRef functionality works as expected even in my webflux application (spring-boot-starter-parent 2.4.4)
However, I have recently migrated my app to AWS and started to use AWS document db, for that, I had to create below seperate db configurations to establish reactive and none-reactive connectivities
@Slf4j
@Configuration
public class MongoConfiguration {
private static final String SSL_CERTIFICATE = "sslCertificate";
private static final String KEY_STORE_FILE_PREFIX = "sys-connect-via-ssl-test-cacerts";
private static final String KEY_STORE_FILE_SUFFIX = ".jks";
private static final String DEFAULT_KEY_STORE_KEYPW = "abcd";
@Value("${mongodb.uri}")
private String mongoURI;
@Value("${default.dbname}")
private String dbName;
@Value("${default.certificateName}")
private String defaultCertificatePath;
/**
* Reactive mongo database factory reactive mongo database factory.
*
* @return the reactive mongo database factory
* @throws NoSuchAlgorithmException the no such algorithm exception
* @throws CertificateException the certificate exception
* @throws IOException the io exception
* @throws KeyStoreException the key store exception
* @throws KeyManagementException the key management exception
*/
@Bean
public ReactiveMongoDatabaseFactory reactiveMongoDatabaseFactory()
throws NoSuchAlgorithmException, CertificateException, IOException, KeyStoreException, KeyManagementException {
MongoClientSettings.Builder builder = MongoClientSettings.builder();
SslSettings.Builder sslBuilder = SslSettings.builder();
X509Certificate caCert = createCertificate();
File keyStoreFile = File.createTempFile(KEY_STORE_FILE_PREFIX, KEY_STORE_FILE_SUFFIX);
FileOutputStream fos = new FileOutputStream(keyStoreFile.getPath());
TrustManagerFactory trustManagerFactory = TrustManagerFactory
.getInstance(TrustManagerFactory.getDefaultAlgorithm());
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
keyStore.load(null);
keyStore.setCertificateEntry("caCert", caCert);
keyStore.store(fos, DEFAULT_KEY_STORE_KEYPW.toCharArray());
trustManagerFactory.init(keyStore);
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, trustManagerFactory.getTrustManagers(), null);
sslBuilder.invalidHostNameAllowed(true);
sslBuilder.enabled(true);
sslBuilder.context(sslContext);
SslSettings sslsettings = sslBuilder.build();
builder.applyConnectionString(new ConnectionString(
mongoURI));
MongoClientSettings settings = builder
.applyToSslSettings(builder1 -> builder1.applySettings(sslsettings)).build();
return new SimpleReactiveMongoDatabaseFactory(MongoClients.create(settings), dbName);
}
@Bean
public MongoDatabaseFactory mongoDatabaseFactory()
throws NoSuchAlgorithmException, CertificateException, IOException, KeyStoreException, KeyManagementException {
MongoClientSettings.Builder builder = MongoClientSettings.builder();
SslSettings.Builder sslBuilder = SslSettings.builder();
X509Certificate caCert = createCertificate();
File keyStoreFile = File.createTempFile(KEY_STORE_FILE_PREFIX, KEY_STORE_FILE_SUFFIX);
FileOutputStream fos = new FileOutputStream(keyStoreFile.getPath());
TrustManagerFactory trustManagerFactory = TrustManagerFactory
.getInstance(TrustManagerFactory.getDefaultAlgorithm());
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
keyStore.load(null);
keyStore.setCertificateEntry("caCert", caCert);
keyStore.store(fos, DEFAULT_KEY_STORE_KEYPW.toCharArray());
trustManagerFactory.init(keyStore);
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, trustManagerFactory.getTrustManagers(), null);
sslBuilder.invalidHostNameAllowed(true);
sslBuilder.enabled(true);
sslBuilder.context(sslContext);
SslSettings sslsettings = sslBuilder.build();
builder.applyConnectionString(new ConnectionString(
mongoURI));
MongoClientSettings settings = builder
.applyToSslSettings(builder1 -> builder1.applySettings(sslsettings)).build();
return new SimpleMongoClientDatabaseFactory(com.mongodb.client.MongoClients.create(settings), dbName);
}
/**
* Reactive mongo template reactive mongo template.
*
* @return the reactive mongo template
* @throws CertificateException the certificate exception
* @throws NoSuchAlgorithmException the no such algorithm exception
* @throws IOException the io exception
* @throws KeyStoreException the key store exception
* @throws KeyManagementException the key management exception
*/
@Bean
public ReactiveMongoTemplate reactiveMongoTemplate()
throws CertificateException, NoSuchAlgorithmException, IOException, KeyStoreException, KeyManagementException {
return new ReactiveMongoTemplate(reactiveMongoDatabaseFactory());
}
@Primary
@Bean
public MongoTemplate mongoTemplate()
throws CertificateException, NoSuchAlgorithmException, IOException, KeyStoreException, KeyManagementException {
return new MongoTemplate(mongoDatabaseFactory());
}
private X509Certificate createCertificate()
throws CertificateException, MalformedURLException {
String sslCertificate = System.getProperty(SSL_CERTIFICATE);
if (StringUtils.isEmpty(sslCertificate)) {
sslCertificate = defaultCertificatePath;
}
CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
URL url = new File(sslCertificate).toURI().toURL();
try (InputStream certInputStream = url.openStream()) {
return (X509Certificate) certFactory.generateCertificate(certInputStream);
} catch (IOException e) {
log.error(e.getMessage());
return null;
}
}
}
with above settings, my application return UnsupportedOperationException
DBRef resolution is not supported!
error when involving entities with @DBRef annotation.
Please note that before AWS migration, no DB configuration beans were manually implemented. Just added two dependencies which mentioned earlier along with value for spring.data.mongodb.uri
property.
DBRef is a feature that is not currently supported with Amazon DocumentDB.