我使用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进行连接池,DataSource配置如下,
@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());
}
}
包裹如下,
1) Application class is in - com.nervy.dialer
2) Datasource class is in - com.nervy.dialer.common
3) Entity classes are in - com.nervy.dialer.domain
4) Service classes are in - com.nervy.dialer.domain.service.impl
5) Controllers are in - com.nervy.dialer.spring.controller
6) Repository classes are in - com.nervy.dialer.spring.jpa.repository
7) WebSecurityConfig is in - com.nervy.dialer.spring.security
由于
答案 0 :(得分:84)
在Spring Boot入口点类中使用@EntityScan配置实体的位置。
2016年9月更新:对于Spring Boot 1.4+:
使用org.springframework.boot.autoconfigure.domain.EntityScan
而不是org.springframework.boot.orm.jpa.EntityScan
,因为从Spring Boot 1.4开始,... boot.orm.jpa.EntityScan是deprecated
答案 1 :(得分:56)
尝试添加以下所有内容,在我的应用程序中,它与tomcat一起正常工作
@EnableJpaRepositories("my.package.base.*")
@ComponentScan(basePackages = { "my.package.base.*" })
@EntityScan("my.package.base.*")
我正在使用spring boot,当我使用嵌入式tomcat时,它正常工作@EntityScan("my.package.base.*")
但当我尝试将应用程序部署到外部tomcat时,我的实体出现not a managed type
错误
答案 2 :(得分:32)
我认为用@ComponentScan
替换@ComponentScan("com.nervy.dialer.domain")
会有效。
编辑:
我添加了一个sample application来演示如何与BoneCP建立池数据源连接。
该应用程序与您的结构相同。我希望这可以帮助您解决配置问题
答案 3 :(得分:16)
在我的情况下,问题是由于我忘记使用@javax.persistence.Entity注释注释了我的Entity类。卫生署!
//The class reported as "not a amanaged type"
@javax.persistence.Entity
public class MyEntityClass extends my.base.EntityClass {
....
}
答案 4 :(得分:12)
您可以使用 @EntityScan 注释并提供实体包以扫描所有jpa实体。您可以在已使用@SpringBootApplication批注的基础应用程序类上使用此批注。
e.g。 的 @EntityScan(&#34; com.test.springboot.demo.entity&#34) 强>
答案 5 :(得分:7)
永远不要忘记添加 @实体 在域类
答案 6 :(得分:5)
您在类定义上错过了@Entity,或者您有明确的组件扫描路径,并且此路径不包含您的类
答案 7 :(得分:4)
我因为愚蠢地写了这个错误
公共接口FooBarRepository扩展了CrudRepository
存储库,Long> {...
答案 8 :(得分:2)
从Spring Boot 1.3.x迁移到1.5时遇到了一些问题,在EntityManagerFactory bean上更新了实体包后,它可以正常工作
@Bean(name="entityManagerFactoryDef")
@Primary
public LocalContainerEntityManagerFactoryBean defaultEntityManager() {
Map map = new HashMap();
map.put("hibernate.default_schema", env.getProperty("spring.datasource.username"));
map.put("hibernate.hbm2ddl.auto", env.getProperty("spring.jpa.hibernate.ddl-auto"));
LocalContainerEntityManagerFactoryBean em = createEntityManagerFactoryBuilder(jpaVendorProperties())
.dataSource(primaryDataSource()).persistenceUnit("default").properties(map).build();
em.setPackagesToScan("com.simple.entity");
em.afterPropertiesSet();
return em;
}
此bean在Application类中的引用如下所示
@SpringBootApplication
@EnableJpaRepositories(entityManagerFactoryRef = "entityManagerFactoryDef")
public class SimpleApp {
}
答案 9 :(得分:1)
如果您已从另一个项目复制粘贴了持久性配置,则必须在 EntityManagerFactory 中手动设置包:
@Bean
public EntityManagerFactory entityManagerFactory() throws PropertyVetoException {
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
vendorAdapter.setGenerateDdl(true);
LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
factory.setPackagesToScan("!!!!!!misspelled.package.path.to.entities!!!!!");
....
}
答案 10 :(得分:1)
我已将我的应用程序类移至父包,如:
主类:com.job.application
实体:com.job.application.entity
这样,您不必添加@EntityScan
答案 11 :(得分:1)
将此内容放入您的Application Java文件
@ComponentScan(basePackages = {“ com.nervy.dialer”}) @EntityScan(basePackages =“ domain”)
答案 12 :(得分:0)
以下为我工作。
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import org.apache.catalina.security.SecurityConfig;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
import com.something.configuration.SomethingConfig;
@RunWith(SpringRunner.class)
@SpringBootTest(classes = { SomethingConfig.class, SecurityConfig.class }) //All your configuration classes
@EnableAutoConfiguration
@WebAppConfiguration // for MVC configuration
@EnableJpaRepositories("com.something.persistence.dataaccess") //JPA repositories
@EntityScan("com.something.domain.entity.*") //JPA entities
@ComponentScan("com.something.persistence.fixture") //any component classes you have
public class SomethingApplicationTest {
@Autowired
private WebApplicationContext ctx;
private MockMvc mockMvc;
@Before
public void setUp() {
this.mockMvc = MockMvcBuilders.webAppContextSetup(ctx).build();
}
@Test
public void loginTest() throws Exception {
this.mockMvc.perform(get("/something/login")).andDo(print()).andExpect(status().isOk());
}
}
答案 13 :(得分:0)
我有同样的问题,但仅在运行需要JPA的Spring Boot测试用例时才出现。最终结果是,我们自己的jpa测试配置正在初始化EntityManagerFactory并将包设置为扫描。如果您手动设置,显然这将覆盖EntityScan参数。
final LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
factory.setJpaVendorAdapter( vendorAdapter );
factory.setPackagesToScan( Project.class.getPackage().getName());
factory.setDataSource( dataSource );
重要注意事项:如果您仍然遇到问题,则应在org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager
方法的setPackagesToScan()
中设置一个断点,并查看在何处调用该断点以及正在传递哪些软件包。
答案 14 :(得分:0)
我在版本的spring boot v1.3.x中遇到了同样的问题 我所做的是将spring boot升级到1.5.7版本.RELEASE。然后问题就消失了。
答案 15 :(得分:0)
遇到了类似的问题。 在我的情况下,存储库和被管理的类型不在同一个包中。
答案 16 :(得分:0)
如果您正在使用多模块 Spring 数据 JPA 项目。
如果您使用多个模块并且它们具有 Jpa 实体和存储库。这可能对你有用。我曾经在外部 tomcat 上部署时遇到“不是托管类型”错误(从未在嵌入式 tomcat 中遇到过)。
我有 1 个主模块和 2 个其他模块作为依赖项。当将主项目部署为 war 时,我可以看到总共有 3 个 Spring 应用程序正在初始化。当执行顺序是先主模块然后是子模块时,没有错误。但有时,子模块过去常常在主模块之前被调用。这曾经导致“不是托管类型实体异常”
棘手的是,错误不会出现在 spring boot 嵌入式 tomcat 中。但是当我们将其部署在外部 tomcat 中时。这个异常过去来得太随机了。我不得不多次部署同一场战争才能获得正确的顺序。
我花了一整天的时间试图解决这个问题。但事实证明,问题在于我将其他模块添加为 Main 模块中的依赖项的方式。如果在另一个项目中添加 spring boot 模块作为依赖项,请确保 jar 中不涉及主类。当您有另一个 Spring Boot 项目作为依赖项并且您尝试将该项目部署为 war 时。不保证主应用程序类的执行顺序。去掉主类,基本上可以避免子模块的独立执行。因此,不会有任何执行顺序问题的余地。
答案 17 :(得分:0)
对于未来的读者:
这里是多个包扫描的语法糖。
注意,我的两个包也在不同的 jar 中,但包是主要驱动程序。只是记下我的 2 罐情况。
em.setPackagesToScan(new String[] {"com.package.ONE.jpa.entities" , "com.package.TWO.jpa.entities"});
我的原始错误代码如下:
em.setPackagesToScan("com.package.ONE.jpa.entities, com.package.TWO.jpa.entities");
让我失望的是我的“xml 到 java-config 交换”。下面显示了一个简单的逗号分隔值。
逗号分隔的列表似乎适用于 di.xml,但不适用于“java config”。
Java,它是 ::: “什么时候用逗号分隔,什么时候用字符串数组,什么时候用字符串可变参数”....... 拼图游戏有时让我发疯。
> <!-- the value of "id" attribute below MUST BE "entityManagerFactory" spring-data voodoo -->
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="packagesToScan" value="com.package.ONE.jpa.entities, com.package.TWO.jpa.entities"/>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="${spring.jpa.show-sql}"/>
<property name="generateDdl" value="${spring.jpa.generate-ddl}"/>
</bean>
</property>
<!-- See https://stackoverflow.com/questions/16088112/how-to-auto-detect-entities-in-jpa-2-0/16088340#16088340 -->
<property name="jpaProperties">
<props>
<prop key="hibernate.hbm2ddl.auto">${spring.jpa.hibernate.ddl-auto}</prop>
<prop key="hibernate.dialect">${spring.jpa.properties.hibernate.dialect}</prop>
</props>
</property>
</bean>
答案 18 :(得分:-1)
我遇到了这个问题,因为我没有映射 orm.xml 文件中的所有实体
答案 19 :(得分:-1)
我正在使用spring boot 2.0,我通过将@ComponentScan替换为@EntityScan
来修复此问题