包结构影响托管 类

Package structure affects managed classes

我有几个 Spring 启动项目。出于这个问题的目的,假设我有以下项目 类:

我的项目-公地: cz.myproject.commons.model.MyEntity;

我的项目工人: cz.myproject.worker.repository.EntityRepository;

MyProject-workerMyProject-commons 作为 Maven 依赖项。

EntityRepository 是 Spring JPA 存储库,用于 MyEntity:

public interface ImageMetadataRepository extends CrudRepository<MyEntity, Long> {
}

问题是使用此设置我总是遇到以下异常:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'EntityRepository': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Not an managed type: class cz.myproject.commons.model.MyEntity

如果我将存储库移动到以下包 (cz.myproject.repository.EntityRepository),一切都会开始工作!我很困惑为什么包结构会影响这样的行为。

有人可以解释发生了什么吗?我怎样才能让它与我描述的包结构一起工作?感谢您提供任何提示!

我的 Spring 开机 application.java:

@SpringBootApplication
@EnableJpaRepositories(basePackages = "cz.myproject.worker.repository")
@EntityScan(basePackages = "cz.myproject.commons.model")
public class Application extends SpringBootServletInitializer {

  public static void main(String[] args) {
    SpringApplication.run(Application.class, args);
  }
}

在你的资源文件夹的 META-INF 文件夹中确保你有 persistance.xml 你必须有 MyEntity 全名如下 cz.myproject.commons.model.MyEntity ,如果您在包通用元数据中有它,请确保您在应用程序上下文中有以下内容

<bean class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" id="myEMF">
        <property name="persistenceXmlLocation" value="classpath:META-INF/persistence.xml" />
        <property name="persistenceUnitName" value="YOUR_PU" />
        <property name="jpaVendorAdapter" ref="hibernateJpaAdapter" />
        <property name="jpaProperties">
             <props>
                <prop key="hibernate.hbm2ddl.auto">none</prop>
            </props>
        </property>

    </bean>

如果 persistance.xml 在 jar 中那么你必须有 classpath: 在路径

之前

如果您使用 class 上下文,请确保在创建实体 bean 时具有以下内容

@Bean
   public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
      LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
      em.setDataSource(dataSource());
      em.setPackagesToScan(new String[] { "cz.myproject.commons.model" });

      JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
      em.setJpaVendorAdapter(vendorAdapter);
      em.setJpaProperties(additionalProperties());

      return em;
   }

Spring Boot 将扫描 @Entity 类 如果它们位于您指定 @SpringBootApplication 注释的同一包或子包中。

您必须使用 @EntityScan 注释,因为您的 Entities 在不同的包中。

@EntityScan(basePackages = "cz.myproject.commons.model")

@EntityScan(basePackageClasses=MyEntity.class) .

我们可以使用 basePackageClasses 而不是指定 basePackages 属性,这样 MyEntity.java 所在的 package 将被扫描。

从 Spring 启动 documentation -

public @interface EntityScan

Configures the LocalContainerEntityManagerFactoryBean to scan for entity classes in the classpath. This annotation provides an alternative to manually setting LocalContainerEntityManagerFactoryBean.setPackagesToScan(String...) and is particularly useful if you want to configure entity scanning in a type-safe way, or if your LocalContainerEntityManagerFactoryBean is auto-configured. A LocalContainerEntityManagerFactoryBean must be configured within your Spring ApplicationContext in order to use entity scanning. Furthermore, any existing packagesToScan setting will be replaced.

One of basePackageClasses(), basePackages() or its alias value() may be specified to define specific packages to scan. If specific packages are not defined scanning will occur from the package of the class with this annotation.