Inicialização por mola - Não é um tipo gerenciado

137

Uso o Spring boot + JPA e estou com um problema ao iniciar o serviço.

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)

Aqui está o arquivo Application.java,

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

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

Eu uso o UCp para o pool de conexões e a configuração do DataSource está abaixo,

@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;

Implementação UserDetailsService,

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

    @Autowired
    private UserService userService;

Implementação da camada de serviço,

@Service
public class PhoneSettingsServiceImpl implements PhoneSettingsService {

}

A classe do repositório,

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

}

Classe de entidade,

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

Classe 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());
    }

}

Os pacotes são os seguintes,

  1. Application classe está em - com.nervy.dialer
  2. Datasource classe está em - com.nervy.dialer.common
  3. As classes de entidade estão em - com.nervy.dialer.domain
  4. As classes de serviço estão em - com.nervy.dialer.domain.service.impl
  5. Os controladores estão em - com.nervy.dialer.spring.controller
  6. As classes de repositório estão em - com.nervy.dialer.spring.jpa.repository
  7. WebSecurityConfig é em - com.nervy.dialer.spring.security

obrigado

user1578872
fonte
1
Acredito que você ainda precisará solicitar ao Hibernate que verifique o pacote para o objeto da sua entidade.
chrylis -cautiouslyoptimistic-

Respostas:

51

Eu acho que substituir @ComponentScanpor @ComponentScan("com.nervy.dialer.domain")funcionará.

Editar:

Adicionei um aplicativo de exemplo para demonstrar como configurar uma conexão de fonte de dados em pool com o BoneCP.

O aplicativo tem a mesma estrutura que a sua. Espero que isso ajude você a resolver seus problemas de configuração

azizunsal
fonte
Se eu adicionar @ComponentScan ("com.nervy.dialer.domain"), estou obtendo uma fonte de dados que não é exceção, pois está em um pacote diferente. Adicionado esse pacote também como @ComponentScan ({"com.nervy.dialer.domain", "com.nervy.dialer.common"}). Agora obtendo o mesmo erro antigo.
User1578872
1
Adicionei um aplicativo de exemplo para demonstrar como configurar uma conexão de fonte de dados em pool com o BoneCP. github.com/azizunsal/SpringBootBoneCPPooledDataSource O aplicativo tem a mesma estrutura que a sua. Espero que isso ajude você a resolver seus problemas de configuração.
azizunsal
Você fez a mágica. Funciona bem. Obrigado pela ajuda. Eu tinha a seguinte anotação na fonte de dados. @EnableJpaRepositories (entityManagerFactoryRef = "dialerEntityManagerFactory", transactionManagerRef = "dialerTransactionManager", basePackages = {"com.nervytech.dialer.repository"}). Depois de remover isso e adicionar o @EnableJpsRespository no DialerApplication, ele começou a funcionar bem.
user1578872
Eu tenho o mesmo problema. A inicialização do Spring não reconhece minha Entidade (@DynamicUpdate da versão do hibernate 4+). Eu tentei adicionar meu pacote de modelo no ComponentScan ou EntityScan e recebo o mesmo erro. Minhas anotações na classe Aplicativo são: SpringBootApplication ComponentScan (basePackages = {"com.example.controllers", "com.example.services", "com.example.services", "com.example.models"})) EnableAutoConfiguration @Configuration @EnableJpaRepositories (basePackages = {"com. example.dao "," com.example.models "})
Balflear 12/01
O mesmo cenário que usamos Hibernated como um provedor de JPA. Como depois tentei todas essas soluções ainda existe o problema. A adição desta configuração no meu arquivo de configuração do aplicativo resolveu o problema para mim. hibernate.annotation.packages.to.scan = $ {myEntityPackage}
Robin
112

Configure o local das entidades usando @EntityScan na classe de ponto de entrada do Spring Boot.

Atualização em setembro de 2016 : para o Spring Boot 1.4+:
use em org.springframework.boot.autoconfigure.domain.EntityScan
vez de org.springframework.boot.orm.jpa.EntityScan, como ... boot.orm.jpa.EntityScan está obsoleto a partir do Spring Boot 1.4

Manish Maheshwari
fonte
2
Esta opção também não ajuda. Acho que estou faltando outra coisa na minha configuração.
user1578872
3
Não ajuda no meu caso também.
Balflear 12/01
1
Funcionou para mim, mas é uma anotação obsoleta.
Juan Carlos Puerto
Obrigado Juan, atualizei a resposta com a versão atual do Entity Scan.
Manish Maheshwari
78

Tente adicionar Tudo o seguinte: No meu aplicativo, ele está funcionando bem com o tomcat

 @EnableJpaRepositories("my.package.base.*")
 @ComponentScan(basePackages = { "my.package.base.*" })
 @EntityScan("my.package.base.*")   

Estou usando o boot de primavera e, quando estou usando o tomcat incorporado, ele estava funcionando bem, @EntityScan("my.package.base.*")mas quando tentei implantar o aplicativo em um tomcat externo, recebi um not a managed typeerro para minha entidade.

manoj
fonte
Você é meu herói.
Artur Łysik 18/07
27

No meu caso, o problema foi devido ao meu esquecimento de ter anotado minhas classes de entidade com @javax.persistence.Entityanotação. Doh!

//The class reported as "not a amanaged type"
@javax.persistence.Entity
public class MyEntityClass extends my.base.EntityClass {
    ....
}
Farrukh Najmi
fonte
No meu caso, eu também precisava do nome da tabela na @Entityanotação. Eu configurei um projeto de amostra aqui: github.com/mate0021/two_datasources.git
mate00
22

Se você copiou e colou a configuração de persistência de outro projeto, defina o pacote no EntityManagerFactory manualmente:

@Bean
public EntityManagerFactory entityManagerFactory() throws PropertyVetoException {
    HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
    vendorAdapter.setGenerateDdl(true);
    LocalContainerEntityManagerFactoryBean factory;
    factory = new LocalContainerEntityManagerFactoryBean();
    factory.setPackagesToScan("!!!!!!misspelled.package.path.to.entities!!!!!");
    //...
}
Lazaruss
fonte
18

Você pode usar @EntityScan anotação e fornecer seu pacote de entidades para verificar todas as suas entidades jpa. Você pode usar esta anotação na classe de aplicativo base em que usou a anotação @SpringBootApplication.

por exemplo, @EntityScan ("com.test.springboot.demo.entity")

Nitesh Saxena
fonte
16

nunca se esqueça de adicionar @Entity na classe de domínio

Mohammad Badiuzzaman
fonte
12

Eu recebi esse erro porque escrevi estupidamente

interface pública FooBarRepository estende CrudRepository <FooBar Repository , Long> {...

Uma breve explicação: Normalmente, cria-se uma classe FooBarRepository para gerenciar objetos FooBar (geralmente representando dados em uma tabela chamada algo como foo_bar). Ao estender o CrudRepository para criar a classe de repositório especializada, é necessário especificar o tipo que está sendo gerenciado. neste caso, FooBar. O que eu digitei por engano, porém, foi FooBarRepository em vez de FooBar. FooBarRepository não é o tipo (a classe) que estou tentando gerenciar com o FooBarRepository. Portanto, o compilador emite esse erro.

Eu destaquei a parte errada da digitação em negrito . Exclua a palavra destacada Repositório no meu exemplo e o código é compilado.

Marvo
fonte
6
15 minutos da minha vida que eu não será capaz de recuperar
Oscar Moncayo
@TayabHussain, atualizei o post com algumas explicações. Espero que te ajude.
Marvo 07/02
7

Coloque isso no seu Application.javaarquivo

@ComponentScan(basePackages={"com.nervy.dialer"})
@EntityScan(basePackages="domain")
RK Shrestha
fonte
Esta é uma duplicata para a resposta acima.
Keshu R.
6

Você perdeu o @Entity na definição de classe ou possui um caminho explícito de verificação de componente e esse caminho não contém sua classe

Tamer Awad
fonte
3

Estou usando o spring boot 2.0 e corrigi isso substituindo @ComponentScan por @EntityScan

Arun Raaj
fonte
1

Eu tive esse mesmo problema, mas apenas ao executar casos de testes de inicialização que exigiam JPA. O resultado final foi que nossa própria configuração de teste jpa estava inicializando um EntityManagerFactory e definindo os pacotes para varredura. Evidentemente, isso substituirá os parâmetros do EntityScan se você estiver configurando manualmente.

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

Importante notar: se você ainda está preso você deve definir um ponto de ruptura no org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManagerno setPackagesToScan()método e dar uma olhada no que isso está sendo chamado e que pacotes estão sendo passados para ele.

Chris Hinshaw
fonte
1

Tive algum problema ao migrar do Spring boot 1.3.x para o 1.5, consegui funcionar depois de atualizar o pacote de entidades no bean EntityManagerFactory

  @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;
  }

Este bean referido na classe Application como abaixo

@SpringBootApplication
@EnableJpaRepositories(entityManagerFactoryRef = "entityManagerFactoryDef")
public class SimpleApp {

}
Ravi M
fonte
0

Eu tenho o mesmo problema, na versão spring boot v1.3.x, o que eu fiz foi atualizar o spring boot para a versão 1.5.7.RELEASE. Então o problema se foi.

Maosheng Wang
fonte
Eu estava em um 1.3.x, então eu mudei para 1.5.6 e tem o problema
apkisbossin
0

Eu tive esse problema porque não mapeei todas as entidades no arquivo orm.xml

Pavlo Zvarych
fonte
0

Abaixo funcionou para mim ..

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());
}

}

Debadatta
fonte
0

Mudei minha classe de aplicativo para o pacote pai como:

Classe principal: com.job.application

Entidade: com.job.application.entity

Dessa forma, você não precisa adicionar @EntityScan

Tushar Wason
fonte