Add nullability annotations to module/spring-boot-jpa

See gh-46587
This commit is contained in:
Moritz Halbritter
2025-08-01 09:16:11 +02:00
parent 78ec5ce3f9
commit ac8db5d4e5
6 changed files with 49 additions and 28 deletions
@@ -91,4 +91,5 @@
<suppress files="Bindable\.java" checks="NoWhitespaceBefore" message="'...' is preceded with whitespace"/>
<suppress files="LambdaSafe\.java" checks="NoWhitespaceBefore" message="'...' is preceded with whitespace"/>
<suppress files="ConditionMessage\.java" checks="NoWhitespaceBefore" message="'...' is preceded with whitespace"/>
<suppress files="EntityManagerFactoryBuilder\.java" checks="NoWhitespaceBefore" message="'...' is preceded with whitespace"/>
</suppressions>
@@ -26,6 +26,8 @@ import java.util.function.Function;
import javax.sql.DataSource;
import org.jspecify.annotations.Nullable;
import org.springframework.core.task.AsyncTaskExecutor;
import org.springframework.orm.jpa.JpaVendorAdapter;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
@@ -53,15 +55,15 @@ public class EntityManagerFactoryBuilder {
private final JpaVendorAdapter jpaVendorAdapter;
private final PersistenceUnitManager persistenceUnitManager;
private final @Nullable PersistenceUnitManager persistenceUnitManager;
private final Function<DataSource, Map<String, ?>> jpaPropertiesFactory;
private final URL persistenceUnitRootLocation;
private final @Nullable URL persistenceUnitRootLocation;
private AsyncTaskExecutor bootstrapExecutor;
private @Nullable AsyncTaskExecutor bootstrapExecutor;
private PersistenceUnitPostProcessor[] persistenceUnitPostProcessors;
private PersistenceUnitPostProcessor @Nullable [] persistenceUnitPostProcessors;
/**
* Create a new instance passing in the common pieces that will be shared if multiple
@@ -74,7 +76,8 @@ public class EntityManagerFactoryBuilder {
* @since 3.4.4
*/
public EntityManagerFactoryBuilder(JpaVendorAdapter jpaVendorAdapter,
Function<DataSource, Map<String, ?>> jpaPropertiesFactory, PersistenceUnitManager persistenceUnitManager) {
Function<DataSource, Map<String, ?>> jpaPropertiesFactory,
@Nullable PersistenceUnitManager persistenceUnitManager) {
this(jpaVendorAdapter, jpaPropertiesFactory, persistenceUnitManager, null);
}
@@ -91,8 +94,8 @@ public class EntityManagerFactoryBuilder {
* @since 3.4.4
*/
public EntityManagerFactoryBuilder(JpaVendorAdapter jpaVendorAdapter,
Function<DataSource, Map<String, ?>> jpaPropertiesFactory, PersistenceUnitManager persistenceUnitManager,
URL persistenceUnitRootLocation) {
Function<DataSource, Map<String, ?>> jpaPropertiesFactory,
@Nullable PersistenceUnitManager persistenceUnitManager, @Nullable URL persistenceUnitRootLocation) {
this.jpaVendorAdapter = jpaVendorAdapter;
this.persistenceUnitManager = persistenceUnitManager;
this.jpaPropertiesFactory = jpaPropertiesFactory;
@@ -137,15 +140,15 @@ public class EntityManagerFactoryBuilder {
private final DataSource dataSource;
private PersistenceManagedTypes managedTypes;
private @Nullable PersistenceManagedTypes managedTypes;
private String[] packagesToScan;
private String @Nullable [] packagesToScan;
private String persistenceUnit;
private @Nullable String persistenceUnit;
private final Map<String, Object> properties = new HashMap<>();
private String[] mappingResources;
private String @Nullable [] mappingResources;
private boolean jta;
@@ -159,7 +162,7 @@ public class EntityManagerFactoryBuilder {
* @param managedTypes managed types.
* @return the builder for fluent usage
*/
public Builder managedTypes(PersistenceManagedTypes managedTypes) {
public Builder managedTypes(@Nullable PersistenceManagedTypes managedTypes) {
this.managedTypes = managedTypes;
return this;
}
@@ -170,7 +173,7 @@ public class EntityManagerFactoryBuilder {
* @return the builder for fluent usage
* @see #managedTypes(PersistenceManagedTypes)
*/
public Builder packages(String... packagesToScan) {
public Builder packages(String @Nullable ... packagesToScan) {
this.packagesToScan = packagesToScan;
return this;
}
@@ -197,7 +200,7 @@ public class EntityManagerFactoryBuilder {
* @param persistenceUnit the name of the persistence unit
* @return the builder for fluent usage
*/
public Builder persistenceUnit(String persistenceUnit) {
public Builder persistenceUnit(@Nullable String persistenceUnit) {
this.persistenceUnit = persistenceUnit;
return this;
}
@@ -223,7 +226,7 @@ public class EntityManagerFactoryBuilder {
* @param mappingResources the mapping resources to use
* @return the builder for fluent usage
*/
public Builder mappingResources(String... mappingResources) {
public Builder mappingResources(String @Nullable ... mappingResources) {
this.mappingResources = mappingResources;
return this;
}
@@ -264,7 +267,7 @@ public class EntityManagerFactoryBuilder {
entityManagerFactoryBean.setManagedTypes(this.managedTypes);
}
else {
entityManagerFactoryBean.setPackagesToScan(this.packagesToScan);
setPackagesToScan(entityManagerFactoryBean);
}
Map<String, ?> jpaProperties = EntityManagerFactoryBuilder.this.jpaPropertiesFactory.apply(this.dataSource);
entityManagerFactoryBean.getJpaPropertyMap().putAll(new LinkedHashMap<>(jpaProperties));
@@ -286,6 +289,14 @@ public class EntityManagerFactoryBuilder {
return entityManagerFactoryBean;
}
// TODO: Review this. The test
// HibernateJpaAutoConfigurationTests.usesManuallyDefinedLocalContainerEntityManagerFactoryBeanUsingBuilder
// fails if an non-null assert is added
@SuppressWarnings("NullAway")
private void setPackagesToScan(LocalContainerEntityManagerFactoryBean entityManagerFactoryBean) {
entityManagerFactoryBean.setPackagesToScan(this.packagesToScan);
}
}
}
@@ -25,6 +25,7 @@ import javax.sql.DataSource;
import jakarta.persistence.EntityManagerFactory;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jspecify.annotations.Nullable;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.ObjectProvider;
@@ -82,7 +83,7 @@ public abstract class JpaBaseConfiguration {
private final JpaProperties properties;
private final JtaTransactionManager jtaTransactionManager;
private final @Nullable JtaTransactionManager jtaTransactionManager;
protected JpaBaseConfiguration(DataSource dataSource, JpaProperties properties,
ObjectProvider<JtaTransactionManager> jtaTransactionManager) {
@@ -163,7 +164,7 @@ public abstract class JpaBaseConfiguration {
protected void customizeVendorProperties(Map<String, Object> vendorProperties) {
}
private String[] getMappingResources() {
private String @Nullable [] getMappingResources() {
List<String> mappingResources = this.properties.getMappingResources();
return (!ObjectUtils.isEmpty(mappingResources) ? StringUtils.toStringArray(mappingResources) : null);
}
@@ -172,7 +173,7 @@ public abstract class JpaBaseConfiguration {
* Return the JTA transaction manager.
* @return the transaction manager or {@code null}
*/
protected JtaTransactionManager getJtaTransactionManager() {
protected @Nullable JtaTransactionManager getJtaTransactionManager() {
return this.jtaTransactionManager;
}
@@ -21,6 +21,8 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.jspecify.annotations.Nullable;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.orm.jpa.vendor.Database;
@@ -51,13 +53,13 @@ public class JpaProperties {
* Name of the target database to operate on, auto-detected by default. Can be
* alternatively set using the "Database" enum.
*/
private String databasePlatform;
private @Nullable String databasePlatform;
/**
* Target database to operate on, auto-detected by default. Can be alternatively set
* using the "databasePlatform" property.
*/
private Database database;
private @Nullable Database database;
/**
* Whether to initialize the schema on startup.
@@ -73,7 +75,7 @@ public class JpaProperties {
* Register OpenEntityManagerInViewInterceptor. Binds a JPA EntityManager to the
* thread for the entire processing of the request.
*/
private Boolean openInView;
private @Nullable Boolean openInView;
public Map<String, String> getProperties() {
return this.properties;
@@ -87,19 +89,19 @@ public class JpaProperties {
return this.mappingResources;
}
public String getDatabasePlatform() {
public @Nullable String getDatabasePlatform() {
return this.databasePlatform;
}
public void setDatabasePlatform(String databasePlatform) {
public void setDatabasePlatform(@Nullable String databasePlatform) {
this.databasePlatform = databasePlatform;
}
public Database getDatabase() {
public @Nullable Database getDatabase() {
return this.database;
}
public void setDatabase(Database database) {
public void setDatabase(@Nullable Database database) {
this.database = database;
}
@@ -119,11 +121,11 @@ public class JpaProperties {
this.showSql = showSql;
}
public Boolean getOpenInView() {
public @Nullable Boolean getOpenInView() {
return this.openInView;
}
public void setOpenInView(Boolean openInView) {
public void setOpenInView(@Nullable Boolean openInView) {
this.openInView = openInView;
}
@@ -17,4 +17,7 @@
/**
* Base Auto-configuration for JPA and Spring ORM.
*/
@NullMarked
package org.springframework.boot.jpa.autoconfigure;
import org.jspecify.annotations.NullMarked;
@@ -17,4 +17,7 @@
/**
* JPA Support classes.
*/
@NullMarked
package org.springframework.boot.jpa;
import org.jspecify.annotations.NullMarked;