我使用Spring boot+JPA,在启动服务时遇到了一个问题。

Caused by: java.lang.IllegalArgumentException: Not an managed type: class com.nervytech.dialer.domain.PhoneSettings
    at org.hibernate.jpa.internal.metamodel.MetamodelImpl.managedType(MetamodelImpl.java:219)
    at org.springframework.data.jpa.repository.support.JpaMetamodelEntityInformation.<init>(JpaMetamodelEntityInformation.java:68)
    at org.springframework.data.jpa.repository.support.JpaEntityInformationSupport.getMetadata(JpaEntityInformationSupport.java:65)
    at org.springframework.data.jpa.repository.support.JpaRepositoryFactory.getEntityInformation(JpaRepositoryFactory.java:145)
    at org.springframework.data.jpa.repository.support.JpaRepositoryFactory.getTargetRepository(JpaRepositoryFactory.java:89)
    at org.springframework.data.jpa.repository.support.JpaRepositoryFactory.getTargetRepository(JpaRepositoryFactory.java:69)
    at org.springframework.data.repository.core.support.RepositoryFactorySupport.getRepository(RepositoryFactorySupport.java:177)
    at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.initAndReturn(RepositoryFactoryBeanSupport.java:239)
    at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.afterPropertiesSet(RepositoryFactoryBeanSupport.java:225)
    at org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean.afterPropertiesSet(JpaRepositoryFactoryBean.java:92)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1625)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1562)

这是Application.java文件,

@Configuration
@ComponentScan
@EnableAutoConfiguration(exclude = { DataSourceAutoConfiguration.class })
@SpringBootApplication
public class DialerApplication {

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

我使用UCp进行连接池,数据源配置如下:

@Configuration
@ComponentScan
@EnableTransactionManagement
@EnableAutoConfiguration
@EnableJpaRepositories(entityManagerFactoryRef = "dialerEntityManagerFactory", transactionManagerRef = "dialerTransactionManager", basePackages = { "com.nervy.dialer.spring.jpa.repository" })
public class ApplicationDataSource {

    /** The Constant LOGGER. */
    private static final Logger LOGGER = LoggerFactory
            .getLogger(ApplicationDataSource.class);

    /** The Constant TEST_SQL. */
    private static final String TEST_SQL = "select 1 from dual";

    /** The pooled data source. */
    private PoolDataSource pooledDataSource;

UserDetailsService实现,

@Service("userDetailsService")
@SessionAttributes("user")
public class UserDetailsServiceImpl implements UserDetailsService {

    @Autowired
    private UserService userService;

服务层实现,

@Service
public class PhoneSettingsServiceImpl implements PhoneSettingsService {

}

存储库类,

@Repository
public interface PhoneSettingsRepository extends JpaRepository<PhoneSettings, Long> {

}

实体类,

@Entity
@Table(name = "phone_settings", catalog = "dialer")
public class PhoneSettings implements java.io.Serializable {

WebSecurityConfig类,

@Configuration
@EnableWebMvcSecurity
@ComponentScan
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private UserDetailsServiceImpl userDetailsService;

    /**
     * Instantiates a new web security config.
     */
    public WebSecurityConfig() {

        super();
    }

    /**
     * {@inheritDoc}
     * @see org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter#configure(org.springframework.security.config.annotation.web.builders.HttpSecurity)
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {

        http.authorizeRequests()
            .antMatchers("/login", "/logoffUser", "/sessionExpired", "/error", "/unauth", "/redirect", "*support*").permitAll()
            .anyRequest().authenticated().and().rememberMe().and().httpBasic()
            .and()
            .csrf()
            .disable().logout().deleteCookies("JSESSIONID").logoutSuccessUrl("/logoff").invalidateHttpSession(true);
    }


    @Autowired
    public void configAuthentication(AuthenticationManagerBuilder auth) throws Exception {

      auth.userDetailsService(userDetailsService).passwordEncoder(new BCryptPasswordEncoder());
    }

}

包装如下:

应用程序类在- com. nerve .dialer中 数据源类在- com. nerver .dialer.common中 实体类在- com. nerver .dialer.domain 服务类在- com.nervy.dialer.domain.service.impl 控制器在- com.nervy.dialer.spring.controller 存储库类在- com.nervy.dialer.spring.jpa.repository中 WebSecurityConfig在- com.nervy.dialer.spring.security

谢谢


当前回答

把它放到你的Application.java文件中

@ComponentScan(basePackages={"com.nervy.dialer"})
@EntityScan(basePackages="domain")

其他回答

我正在使用spring boot 2.0,我通过用@EntityScan替换@ComponentScan来修复这个问题

您可以使用@EntityScan注释,并提供用于扫描所有jpa实体的实体包。您可以在使用@SpringBootApplication注释的基应用程序类上使用此注释。

如。 @EntityScan(“com.test.springboot.demo.entity”)

我也遇到了同样的问题,但只是在运行需要JPA的spring引导测试用例时。最终的结果是,我们自己的jpa测试配置初始化了一个EntityManagerFactory,并设置了要扫描的包。如果您手动设置,这显然会覆盖EntityScan参数。

    final LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
    factory.setJpaVendorAdapter( vendorAdapter );
    factory.setPackagesToScan( Project.class.getPackage().getName());
    factory.setDataSource( dataSource );

重要的是要注意:如果你仍然卡住了,你应该在setPackagesToScan()方法的org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager中设置一个断点,并查看它被调用的位置以及传递给它的包是什么。

如果您正在使用多模块spring数据jpa项目。

如果您正在处理多个模块,并且它们有Jpa实体和存储库。这可能对你有用。我曾经在外部tomcat上部署时得到一个“Not a managed type”错误(在嵌入式tomcat中从未遇到过)。

我有一个主模块和另外两个依赖模块。当将主项目部署为war时,我可以看到总共有3个Spring应用程序正在初始化。当执行顺序是Main模块先执行,然后是子模块时,就不会出现错误。但有时,子模块通常在主模块之前被调用。这通常会导致“非托管类型实体异常”

棘手的是,错误不会出现在spring引导嵌入式tomcat中。但是当我们在外部tomcat中部署它时。这种例外过去来得太随意了。我必须多次部署相同的战争才能获得正确的命令。

I spent the whole day trying to solve the issue. But turned out the problem was with the way I added my other modules as a dependency in the Main module. If you are adding the spring boot module as a dependency in another project, make sure that the main class is not involved in the jar. When you have another spring boot project as a dependency and when you try to deploy the project as a war. The order of execution of the main application class is not guaranteed. Removing the main class will basically avoid the independent execution of child modules. Hence, there won't be any room for order of execution issue.

根据我的经验,您应该检查您的注释。如果将其用作bean,则必须使用@Component。但是作为存储库中的实体,您应该在类上面使用@Entity。