我使用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

谢谢


当前回答

在Spring Version 6和JDK 17中,我得到了这个问题,当我使用jakarta.persist . entity时,我正在使用javax. persistence . entity,这个问题得到了解决

其他回答

我得到这个错误是因为我愚蠢地写了

公共接口FooBarRepository扩展CrudRepository<FooBarRepository, Long>{…

A brief explanation: One typically creates a FooBarRepository class to manage FooBar objects (often representing data in a table called something like foo_bar.) When extending the CrudRepository to create the specialized repository class, one needs to specify the type that's being managed -- in this case, FooBar. What I mistakenly typed, though, was FooBarRepository rather than FooBar. FooBarRepository is not the type (the class) I'm trying to manage with the FooBarRepository. Therefore, the compiler issues this error.

我用粗体突出显示了输入错误的地方。在我的示例中删除突出显示的单词Repository,代码将被编译。

如果您正在使用多模块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.

如果您正在使用SessionFactory作为EMF:

在我的例子中,问题是我忘记在Hibernate配置中包含一个带注释的类的新实体类型,为此我得到了错误。

所以,在你的SessionFactory bean中,不要忘记为你的新实体类型添加这一行:

configuration.addAnnotatedClass(MyEntity.class);

我也遇到了同样的问题,但只是在运行需要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 boot 2.0,我通过用@EntityScan替换@ComponentScan来修复这个问题