diff --git a/spring-orm/src/main/java/org/springframework/orm/jpa/LocalContainerEntityManagerFactoryBean.java b/spring-orm/src/main/java/org/springframework/orm/jpa/LocalContainerEntityManagerFactoryBean.java index 94fa087dead..7cc91d73b12 100644 --- a/spring-orm/src/main/java/org/springframework/orm/jpa/LocalContainerEntityManagerFactoryBean.java +++ b/spring-orm/src/main/java/org/springframework/orm/jpa/LocalContainerEntityManagerFactoryBean.java @@ -86,14 +86,11 @@ import org.springframework.util.StringUtils; * @author Juergen Hoeller * @author Rod Johnson * @since 2.0 - * @see #setPersistenceXmlLocation * @see #setJpaProperties * @see #setJpaVendorAdapter * @see #setLoadTimeWeaver * @see #setDataSource - * @see EntityManagerFactoryInfo * @see LocalEntityManagerFactoryBean - * @see org.springframework.orm.jpa.support.SharedEntityManagerBean * @see jakarta.persistence.spi.PersistenceProvider#createContainerEntityManagerFactory */ @SuppressWarnings("serial") diff --git a/spring-orm/src/main/java/org/springframework/orm/jpa/LocalEntityManagerFactoryBean.java b/spring-orm/src/main/java/org/springframework/orm/jpa/LocalEntityManagerFactoryBean.java index f6e8386dd3e..0880b12ac1e 100644 --- a/spring-orm/src/main/java/org/springframework/orm/jpa/LocalEntityManagerFactoryBean.java +++ b/spring-orm/src/main/java/org/springframework/orm/jpa/LocalEntityManagerFactoryBean.java @@ -16,6 +16,9 @@ package org.springframework.orm.jpa; +import java.util.LinkedHashSet; +import java.util.Set; + import javax.sql.DataSource; import jakarta.persistence.EntityManagerFactory; @@ -25,8 +28,16 @@ import jakarta.persistence.PersistenceException; import jakarta.persistence.spi.PersistenceProvider; import org.jspecify.annotations.Nullable; +import org.springframework.context.ResourceLoaderAware; +import org.springframework.core.io.ResourceLoader; +import org.springframework.core.io.support.PathMatchingResourcePatternResolver; +import org.springframework.core.io.support.ResourcePatternResolver; +import org.springframework.core.io.support.ResourcePatternUtils; import org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager; +import org.springframework.orm.jpa.persistenceunit.PersistenceManagedTypes; +import org.springframework.orm.jpa.persistenceunit.PersistenceManagedTypesScanner; import org.springframework.util.Assert; +import org.springframework.util.ClassUtils; /** * {@link org.springframework.beans.factory.FactoryBean} that creates a JPA @@ -54,18 +65,26 @@ import org.springframework.util.Assert; * @since 2.0 * @see #setJpaProperties * @see #setJpaVendorAdapter - * @see JpaTransactionManager#setEntityManagerFactory + * @see #setPersistenceConfiguration + * @see #setDataSource * @see LocalContainerEntityManagerFactoryBean - * @see org.springframework.jndi.JndiObjectFactoryBean - * @see org.springframework.orm.jpa.support.SharedEntityManagerBean * @see jakarta.persistence.Persistence#createEntityManagerFactory * @see jakarta.persistence.spi.PersistenceProvider#createEntityManagerFactory */ @SuppressWarnings("serial") -public class LocalEntityManagerFactoryBean extends AbstractEntityManagerFactoryBean { +public class LocalEntityManagerFactoryBean extends AbstractEntityManagerFactoryBean implements ResourceLoaderAware { + + private static final String NON_JTA_DATASOURCE_PROPERTY = "jakarta.persistence.nonJtaDataSource"; + + private static final String PACKAGE_INFO_SUFFIX = ".package-info"; + private @Nullable PersistenceConfiguration configuration; + private String @Nullable [] packagesToScan; + + private ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver(); + /** * Create a {@code LocalEntityManagerFactoryBean}. @@ -151,6 +170,27 @@ public class LocalEntityManagerFactoryBean extends AbstractEntityManagerFactoryB super.setPersistenceUnitName(persistenceUnitName); } + /** + * Set whether to use Spring-based scanning for entity classes in the classpath + * instead of using JPA's standard scanning of jar files with {@code persistence.xml} + * markers in them. In case of Spring-based scanning, no {@code persistence.xml} + * is necessary; all you need to do is to specify base packages to search here. + *
Default is none. Specify packages to search for autodetection of your entity + * classes in the classpath. This is analogous to Spring's component-scan feature + * ({@link org.springframework.context.annotation.ClassPathBeanDefinitionScanner}). + *
The use of this setter switches this {@code LocalEntityManagerFactoryBean}
+ * to a {@link #getPersistenceConfiguration() PersistenceConfiguration}, with no
+ * {@code persistence.xml} reading or provider-driven scanning happening anymore.
+ * Further JPA settings can be applied on the local {@link PersistenceConfiguration}
+ * via {@link #getPersistenceConfiguration()}.
+ * @since 7.0.4
+ * @see LocalContainerEntityManagerFactoryBean#setPackagesToScan
+ * @see org.springframework.orm.jpa.hibernate.LocalSessionFactoryBean#setPackagesToScan
+ */
+ public void setPackagesToScan(String... packagesToScan) {
+ this.packagesToScan = packagesToScan;
+ }
+
/**
* Specify the JDBC DataSource that the JPA persistence provider is supposed
* to use for accessing the database. This is an alternative to keeping the
@@ -165,9 +205,11 @@ public class LocalEntityManagerFactoryBean extends AbstractEntityManagerFactoryB
public void setDataSource(@Nullable DataSource dataSource) {
if (dataSource != null) {
getJpaPropertyMap().put(PersistenceConfiguration.JDBC_DATASOURCE, dataSource);
+ getJpaPropertyMap().put(NON_JTA_DATASOURCE_PROPERTY, dataSource);
}
else {
getJpaPropertyMap().remove(PersistenceConfiguration.JDBC_DATASOURCE);
+ getJpaPropertyMap().remove(NON_JTA_DATASOURCE_PROPERTY);
}
}
@@ -182,6 +224,11 @@ public class LocalEntityManagerFactoryBean extends AbstractEntityManagerFactoryB
return (DataSource) getJpaPropertyMap().get(PersistenceConfiguration.JDBC_DATASOURCE);
}
+ @Override
+ public void setResourceLoader(ResourceLoader resourceLoader) {
+ this.resourcePatternResolver = ResourcePatternUtils.getResourcePatternResolver(resourceLoader);
+ }
+
/**
* Initialize the EntityManagerFactory for the given configuration.
@@ -193,6 +240,25 @@ public class LocalEntityManagerFactoryBean extends AbstractEntityManagerFactoryB
logger.debug("Building JPA EntityManagerFactory for persistence unit '" + getPersistenceUnitName() + "'");
}
+ if (this.packagesToScan != null) {
+ PersistenceManagedTypesScanner scanner = new PersistenceManagedTypesScanner(this.resourcePatternResolver);
+ PersistenceManagedTypes result = scanner.scan(this.packagesToScan);
+ // Expose managed class names from scan result (on JPA 4.0+, this includes
+ // everything meta-annotated with @Discoverable, even package-info classes)
+ Set