Spring boot - Pas un type géré


137

J'utilise Spring boot + JPA et j'ai un problème lors du démarrage du service.

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)

Voici le fichier Application.java,

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

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

J'utilise UCp pour le regroupement de connexions et la configuration DataSource est ci-dessous,

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

Implémentation de UserDetailsService,

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

    @Autowired
    private UserService userService;

Implémentation de la couche de service,

@Service
public class PhoneSettingsServiceImpl implements PhoneSettingsService {

}

La classe référentiel,

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

}

Classe d'entité,

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

}

Les packages sont les suivants,

  1. Application la classe est en - com.nervy.dialer
  2. Datasource la classe est en - com.nervy.dialer.common
  3. Les classes d'entité sont en - com.nervy.dialer.domain
  4. Les classes de service sont en - com.nervy.dialer.domain.service.impl
  5. Les contrôleurs sont en - com.nervy.dialer.spring.controller
  6. Les classes de référentiel sont dans - com.nervy.dialer.spring.jpa.repository
  7. WebSecurityConfig est dans - com.nervy.dialer.spring.security

Merci


1
Je pense que vous devrez toujours dire à Hibernate de scanner le package pour votre objet entité.
chrylis -cautouslyoptimistic-

Réponses:


51

Je pense que remplacer @ComponentScanpar @ComponentScan("com.nervy.dialer.domain")fonctionnera.

Éditer :

J'ai ajouté un exemple d'application pour montrer comment configurer une connexion de source de données groupée avec BoneCP.

L'application a la même structure que la vôtre. J'espère que cela vous aidera à résoudre vos problèmes de configuration


Si j'ajoute @ComponentScan ("com.nervy.dialer.domain"), j'obtiens une exception à la source de données, car elle est dans un package différent. Ajout de ce package comme @ComponentScan ({"com.nervy.dialer.domain", "com.nervy.dialer.common"}). Obtient maintenant la même vieille erreur.
user1578872

1
J'ai ajouté un exemple d'application pour montrer comment configurer une connexion de source de données groupée avec BoneCP. github.com/azizunsal/SpringBootBoneCPPooledDataSource L'application a la même structure que la vôtre. J'espère que cela vous aidera à résoudre vos problèmes de configuration.
azizunsal

Vous avez fait la magie. Ça fonctionne bien. Merci de votre aide. J'avais l'annotation suivante dans la source de données. @EnableJpaRepositories (entityManagerFactoryRef = "dialerEntityManagerFactory", transactionManagerRef = "dialerTransactionManager", basePackages = {"com.nervytech.dialer.repository"}). Après avoir supprimé cela et simplement ajouté @EnableJpsRespository dans DialerApplication, cela a commencé à fonctionner correctement.
user1578872

J'ai le même problème. Spring Boot ne reconnaît pas mon entité (@DynamicUpdate de la version hibernate 4+). J'ai essayé d'ajouter mon package de modèle dans ComponentScan ou EntityScan et j'obtiens la même erreur. Mes annotations dans la classe Application sont: SpringBootApplication ComponentScan (basePackages = {"com.example.controllers", "com.example.services", "com.example.models"}) EnableAutoConfiguration @Configuration @EnableJpaRepositories (basePackages = {"com. example.dao "," com.example.models "})
Balflear

Le même scénario que nous avons utilisé Hibernated comme fournisseur JPA. Comme après avoir essayé toutes ces solutions, le problème existe toujours. L'ajout de cette configuration dans mon fichier de configuration d'application a résolu le problème pour moi. hibernate.annotation.packages.to.scan = $ {myEntityPackage}
Robin le

112

Configurez l'emplacement des entités à l'aide de @EntityScan dans la classe de point d'entrée Spring Boot.

Mise à jour de septembre 2016 : Pour Spring Boot 1.4+:
utilisez à la org.springframework.boot.autoconfigure.domain.EntityScan
place de org.springframework.boot.orm.jpa.EntityScan, car ... boot.orm.jpa.EntityScan est obsolète à partir de Spring Boot 1.4


2
Cette option n'aide pas non plus. Je suppose qu'il me manque autre chose dans ma configuration.
user1578872

3
Cela n'aide pas non plus dans mon cas.
Balflear

1
Cela a fonctionné pour moi mais c'est une annotation obsolète.
Juan Carlos Puerto

Merci Juan, j'ai mis à jour la réponse avec la version actuelle de Entity Scan.
Manish Maheshwari

78

Essayez d'ajouter tout ce qui suit, dans mon application, cela fonctionne bien avec tomcat

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

J'utilise Spring Boot, et lorsque j'utilise un tomcat intégré, cela fonctionnait bien, @EntityScan("my.package.base.*")mais lorsque j'ai essayé de déployer l'application sur un tomcat externe, j'ai eu une not a managed typeerreur pour mon entité.


Tu es mon héros.
Artur Łysik

27

Dans mon cas, le problème était dû au fait que j'avais oublié d'annoter mes classes Entity avec une @javax.persistence.Entityannotation. Doh!

//The class reported as "not a amanaged type"
@javax.persistence.Entity
public class MyEntityClass extends my.base.EntityClass {
    ....
}

Dans mon cas, j'avais également besoin du nom de la table en @Entityannotation. J'ai mis en place un exemple de projet ici: github.com/mate0021/two_datasources.git
mate00

22

Si vous avez copié-collé la configuration de persistance d'un autre projet, vous devez définir manuellement le package dans EntityManagerFactory :

@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!!!!!");
    //...
}

18

Vous pouvez utiliser l' annotation @EntityScan et fournir votre package d'entités pour analyser toutes vos entités jpa. Vous pouvez utiliser cette annotation sur votre classe d'application de base où vous avez utilisé l'annotation @SpringBootApplication.

par exemple @EntityScan ("com.test.springboot.demo.entity")



12

J'ai eu cette erreur parce que j'ai stupidement écrit

interface publique FooBarRepository étend CrudRepository <FooBar Repository , Long> {...

Une brève explication: on crée généralement une classe FooBarRepository pour gérer les objets FooBar (représentant souvent des données dans une table appelée quelque chose comme foo_bar.) Lors de l'extension de CrudRepository pour créer la classe de référentiel spécialisée, il faut spécifier le type qui est géré - dans ce cas, FooBar. Ce que j'ai tapé par erreur, cependant, était FooBarRepository plutôt que FooBar. FooBarRepository n'est pas le type (la classe) que j'essaie de gérer avec le FooBarRepository. Par conséquent, le compilateur émet cette erreur.

J'ai mis en évidence la faute de frappe en gras . Supprimez le mot en surbrillance Repository dans mon exemple et le code se compile.


6
15 minutes de ma vie que je ne pourrai pas récupérer
Oscar Moncayo

@TayabHussain, j'ai mis à jour le message avec quelques explications. J'espère que cela vous aidera.
Marvo

7

Mettez ceci dans votre Application.javadossier

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

Ceci est un doublon pour la réponse ci-dessus.
Keshu R.

6

Soit vous avez manqué @Entity sur la définition de classe, soit vous avez un chemin de scan de composant explicite et ce chemin ne contient pas votre classe


3

J'utilise Spring Boot 2.0 et j'ai corrigé ce problème en remplaçant @ComponentScan par @EntityScan


1

J'ai eu le même problème, mais uniquement lors de l'exécution de cas de tests de démarrage à ressort nécessitant JPA. Le résultat final était que notre propre configuration de test jpa initialisait une EntityManagerFactory et définissait les packages à analyser. Cela remplacera évidemment les paramètres EntityScan si vous le définissez manuellement.

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

Important à noter: si vous êtes toujours coincé , vous devez définir un point de rupture dans la org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManagersur la setPackagesToScan()méthode et jeter un oeil à où cela est appelé et quels paquets sont transmis.


1

J'ai eu un problème lors de la migration de Spring boot 1.3.x vers 1.5, je l'ai fait fonctionner après la mise à jour du package d'entité au 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;
  }

Ce bean référencé dans la classe Application comme ci-dessous

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

}

0

J'ai le même problème, dans la version Spring Boot v1.3.x ce que j'ai fait est de mettre à niveau Spring Boot vers la version 1.5.7.RELEASE. Puis le problème a disparu.


J'étais sur un 1.3.x puis je suis passé à 1.5.6 et j'ai eu le problème
apkisbossin

0

J'ai eu ce problème car je n'ai pas mappé toutes les entités dans le fichier orm.xml


0

Ci-dessous a travaillé pour moi.

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

}


0

J'ai déplacé ma classe d'application vers le package parent comme:

Classe principale: com.job.application

Entité: com.job.application.entity

De cette façon, vous n'avez pas besoin d'ajouter @EntityScan

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.