Spring boot: no es un tipo administrado

137

Uso Spring boot + JPA y tengo un problema al iniciar el servicio.

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)

Aquí está el archivo Application.java,

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

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

Uso UCp para la agrupación de conexiones y la configuración de DataSource está a continuación,

@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 Implementation,

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

    @Autowired
    private UserService userService;

Implementación de la capa de servicio,

@Service
public class PhoneSettingsServiceImpl implements PhoneSettingsService {

}

La clase de repositorio,

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

}

Clase de entidad,

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

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

}

Los paquetes son los siguientes,

  1. Application la clase está en com.nervy.dialer
  2. Datasource la clase está en com.nervy.dialer.common
  3. Las clases de entidad están en - com.nervy.dialer.domain
  4. Las clases de servicio están en - com.nervy.dialer.domain.service.impl
  5. Los controladores están en com.nervy.dialer.spring.controller
  6. Las clases de repositorio están en - com.nervy.dialer.spring.jpa.repository
  7. WebSecurityConfig es en - com.nervy.dialer.spring.security

Gracias

usuario1578872
fuente
1
Creo que aún tendrá que decirle a Hibernate que escanee el paquete en busca de su objeto de entidad.
chrylis -cautiouslyoptimistic-

Respuestas:

51

Creo que reemplazar @ComponentScancon @ComponentScan("com.nervy.dialer.domain")funcionará.

Editar:

He agregado una aplicación de muestra para demostrar cómo configurar una conexión de fuente de datos agrupada con BoneCP.

La aplicación tiene la misma estructura que la tuya. Espero que esto te ayude a resolver tus problemas de configuración

azizunsal
fuente
Si agrego @ComponentScan ("com.nervy.dialer.domain"), obtengo una fuente de datos, no una excepción, ya que está en un paquete diferente. Se agregó ese paquete también como @ComponentScan ({"com.nervy.dialer.domain", "com.nervy.dialer.common"}). Ahora obteniendo el mismo error anterior.
user1578872
1
He agregado una aplicación de muestra para demostrar cómo configurar una conexión de fuente de datos agrupada con BoneCP. github.com/azizunsal/SpringBootBoneCPPooledDataSource La aplicación tiene la misma estructura que la suya. Espero que esto te ayude a resolver tus problemas de configuración.
azizunsal
Hiciste la magia. Funciona bien. Gracias por tu ayuda. Tuve la siguiente anotación en la fuente de datos. @EnableJpaRepositories (entityManagerFactoryRef = "dialerEntityManagerFactory", transactionManagerRef = "dialerTransactionManager", basePackages = {"com.nervytech.dialer.repository"}). Después de eliminar esto y simplemente agregar @EnableJpsRespository en DialerApplication, comenzó a funcionar bien.
user1578872
Tengo el mismo problema. Spring boot no reconoce mi Entidad (@DynamicUpdate de hibernate 4+ version). He intentado agregar mi paquete de modelo en ComponentScan o EntityScan y obtengo el mismo error. Mis anotaciones en la clase de aplicación son: SpringBootApplication ComponentScan (basePackages = {"com.example.controllers", "com.example.services", "com.example.models"}) EnableAutoConfiguration @Configuration @EnableJpaRepositories (basePackages = {"com. example.dao "," com.example.models "})
Balflear
El mismo escenario que utilizamos Hibernated como proveedor de JPA. Como después de probar todas estas soluciones, aún existe el problema. Agregar esta configuración en el archivo de configuración de mi aplicación resolvió el problema por mí. hibernate.annotation.packages.to.scan = $ {myEntityPackage}
Robin
112

Configure la ubicación de las entidades utilizando @EntityScan en la clase de punto de entrada Spring Boot.

Actualización en septiembre de 2016 : para Spring Boot 1.4+:
use en org.springframework.boot.autoconfigure.domain.EntityScan
lugar deorg.springframework.boot.orm.jpa.EntityScan , ya que ... boot.orm.jpa.EntityScan está en desuso a partir de Spring Boot 1.4

Manish Maheshwari
fuente
2
Esta opción tampoco ayuda. Supongo que me falta algo más en mi configuración.
user1578872
3
No ayuda en mi caso también.
Balflear
1
A mí me funcionó, pero es una anotación obsoleta.
Juan Carlos Puerto
Gracias Juan, he actualizado la respuesta con la versión actual de Entity Scan.
Manish Maheshwari
78

Intente agregar todo lo siguiente, en mi aplicación funciona bien con tomcat

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

Estoy usando Spring Boot, y cuando estoy usando Tomcat incrustado funcionaba bien, @EntityScan("my.package.base.*")pero cuando traté de implementar la aplicación en un Tomcat externo recibí un not a managed typeerror para mi entidad.

manoj
fuente
Eres mi héroe.
Artur Łysik
27

En mi caso, el problema se debió a mi olvido de haber anotado mis clases de Entidad con @javax.persistence.Entityanotaciones. Doh!

//The class reported as "not a amanaged type"
@javax.persistence.Entity
public class MyEntityClass extends my.base.EntityClass {
    ....
}
Farrukh Najmi
fuente
En mi caso, también necesitaba el nombre de la tabla en la @Entityanotación. Configuré un proyecto de muestra aquí: github.com/mate0021/two_datasources.git
mate00
22

Si ha copiado y pegado la configuración de persistencia de otro proyecto, debe configurar el paquete en 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
fuente
18

Puedes usar @EntityScan anotación y proporcionar su paquete de entidad para escanear todas sus entidades jpa. Puede usar esta anotación en su clase de aplicación base donde ha usado la anotación @SpringBootApplication.

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

Nitesh Saxena
fuente
16

nunca olvides agregar @Entity en la clase de dominio

Mohammad Badiuzzaman
fuente
12

Recibí este error porque escribí estúpidamente

interfaz pública FooBarRepository extiende CrudRepository <FooBar Repository , Long> {...

Una breve explicación: por lo general, se crea una clase FooBarRepository para administrar objetos FooBar (a menudo representando datos en una tabla llamada algo así como foo_bar). Al extender CrudRepository para crear la clase de repositorio especializado, se necesita especificar el tipo que se está administrando, en este caso, FooBar. Sin embargo, lo que escribí por error fue FooBarRepository en lugar de FooBar. FooBarRepository no es el tipo (la clase) que estoy tratando de administrar con FooBarRepository. Por lo tanto, el compilador emite este error.

Destaqué la parte equivocada de escribir en negrita . Eliminar la palabra resaltada Repositorio en mi ejemplo y el código se compila.

Marvo
fuente
66
15 minutos de mi vida que no podré recuperar
Oscar Moncayo
@TayabHussain, actualicé la publicación con alguna explicación. Espero que te ayude.
Marvo
7

Pon esto en tu Application.javaarchivo

@ComponentScan(basePackages={"com.nervy.dialer"})
@EntityScan(basePackages="domain")
RK Shrestha
fuente
Este es un duplicado para la respuesta anterior.
Keshu R.
6

O perdió @Entity en la definición de clase o tiene una ruta de exploración de componentes explícita y esta ruta no contiene su clase

Tamer Awad
fuente
3

Estoy usando Spring Boot 2.0 y lo arreglé reemplazando @ComponentScan con @EntityScan

Arun Raaj
fuente
1

Tuve este mismo problema, pero solo cuando ejecuté casos de pruebas de arranque de primavera que requerían JPA. El resultado final fue que nuestra propia configuración de prueba jpa estaba inicializando un EntityManagerFactory y configurando los paquetes para escanear. Evidentemente, esto anulará los parámetros de EntityScan si lo configura manualmente.

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

Es importante tener en cuenta: si todavía está atascado, debe establecer un punto de interrupción org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManageren el setPackagesToScan()método y observar dónde se llama y qué paquetes se le pasan.

Chris Hinshaw
fuente
1

Tuve algunos problemas al migrar desde Spring boot 1.3.xa 1.5, lo hice funcionar después de actualizar el paquete de entidad en 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;
  }

Este bean se refiere en la clase de aplicación a continuación

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

}
Ravi M
fuente
0

Tengo el mismo problema, en la versión spring boot v1.3.x lo que hice fue actualizar spring boot a la versión 1.5.7. Entonces el problema desapareció.

Maosheng Wang
fuente
Estaba en un 1.3.x, luego cambié a 1.5.6 y obtuve el problema
apkisbossen
0

Tuve este problema porque no asigné todas las entidades en el archivo orm.xml

Pavlo Zvarych
fuente
0

A continuación funcionó para mí ...

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
fuente
0

He movido mi clase de aplicación al paquete principal como:

Clase principal: com.job.application

Entidad: com.job.application.entity

De esta manera no tiene que agregar @EntityScan

Tushar Wason
fuente