Spring Boot - Kein verwalteter Typ

137

Ich verwende Spring Boot + JPA und habe ein Problem beim Starten des Dienstes.

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)

Hier ist die Application.java-Datei,

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

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

Ich verwende UCp für das Verbindungspooling und die DataSource-Konfiguration ist unten aufgeführt.

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

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

    @Autowired
    private UserService userService;

Implementierung der Serviceschicht,

@Service
public class PhoneSettingsServiceImpl implements PhoneSettingsService {

}

Die Repository-Klasse,

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

}

Entitätsklasse,

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

WebSecurityConfig-Klasse,

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

}

Die Pakete sind wie folgt:

  1. Application Klasse ist in - com.nervy.dialer
  2. Datasource Klasse ist in - com.nervy.dialer.common
  3. Entitätsklassen sind in - com.nervy.dialer.domain
  4. Serviceklassen sind in - com.nervy.dialer.domain.service.impl
  5. Controller sind in - com.nervy.dialer.spring.controller
  6. Repository-Klassen sind in - com.nervy.dialer.spring.jpa.repository
  7. WebSecurityConfig ist in - com.nervy.dialer.spring.security

Vielen Dank

user1578872
quelle
1
Ich glaube, Sie müssen Hibernate noch anweisen, das Paket nach Ihrem Entitätsobjekt zu durchsuchen.
Chrylis-vorsichtig optimistisch- 23.

Antworten:

51

Ich denke, das Ersetzen @ComponentScandurch @ComponentScan("com.nervy.dialer.domain")wird funktionieren.

Bearbeiten:

Ich habe eine Beispielanwendung hinzugefügt, um zu demonstrieren, wie eine gepoolte Datenquellenverbindung mit BoneCP eingerichtet wird.

Die Anwendung hat dieselbe Struktur wie Ihre. Ich hoffe, dies wird Ihnen helfen, Ihre Konfigurationsprobleme zu lösen

Azizunsal
quelle
Wenn ich @ComponentScan ("com.nervy.dialer.domain") hinzufüge, erhalte ich keine Ausnahme für Datenquellen, da diese in einem anderen Paket enthalten sind. Dieses Paket wurde auch wie @ComponentScan ({"com.nervy.dialer.domain", "com.nervy.dialer.common"}) hinzugefügt. Jetzt wird der gleiche alte Fehler angezeigt.
Benutzer1578872
1
Ich habe eine Beispielanwendung hinzugefügt, um zu demonstrieren, wie eine gepoolte Datenquellenverbindung mit BoneCP eingerichtet wird. github.com/azizunsal/SpringBootBoneCPPooledDataSource Die Anwendung hat dieselbe Struktur wie Ihre. Ich hoffe, dies wird Ihnen helfen, Ihre Konfigurationsprobleme zu lösen.
Azizunsal
Du hast die Magie gemacht. Es funktioniert gut. Danke für Ihre Hilfe. Ich hatte die folgende Anmerkung in der Datenquelle. @EnableJpaRepositories (entityManagerFactoryRef = "dialerEntityManagerFactory", transactionManagerRef = "dialerTransactionManager", basePackages = {"com.nervytech.dialer.repository"}). Nachdem Sie dies entfernt und nur @EnableJpsRespository in DialerApplication hinzugefügt hatten, funktionierte es einwandfrei.
user1578872
Ich habe das gleiche Problem. Spring Boot erkennt meine Entität nicht (@DynamicUpdate aus der Version 4+ im Ruhezustand). Ich habe versucht, mein Modellpaket in ComponentScan oder EntityScan hinzuzufügen, und es wird der gleiche Fehler angezeigt. Meine Anmerkungen in der Anwendungsklasse sind: SpringBootApplication ComponentScan (basePackages = {"com.example.controllers", "com.example.services", "com.example.models"}) EnableAutoConfiguration @Configuration @EnableJpaRepositories (basePackages = {"com. example.dao "," com.example.models "})
Balflear
Das gleiche Szenario haben wir Hibernated als JPA-Anbieter verwendet. Wie nach all diesen Lösungen besteht immer noch das Problem. Das Hinzufügen dieser Konfiguration in meiner Anwendungskonfigurationsdatei hat das Problem für mich behoben. hibernate.annotation.packages.to.scan = $ {myEntityPackage}
Robin
112

Konfigurieren Sie den Speicherort von Entitäten mithilfe von @EntityScan in der Spring Boot-Einstiegspunktklasse.

Update am September 2016 : Für Spring Boot 1.4+:
Verwenden Sie org.springframework.boot.autoconfigure.domain.EntityScan
anstelle von org.springframework.boot.orm.jpa.EntityScan... boot.orm.jpa.EntityScan ist ab Spring Boot 1.4 veraltet

Manish Maheshwari
quelle
2
Diese Option hilft auch nicht. Ich denke, ich vermisse etwas anderes in meiner Konfiguration.
user1578872
3
Hilft auch in meinem Fall nicht.
Balflear
1
Es hat bei mir funktioniert, aber es ist eine veraltete Anmerkung.
Juan Carlos Puerto
Danke Juan, ich habe die Antwort mit der aktuellen Version von Entity Scan aktualisiert.
Manish Maheshwari
78

Versuchen Sie Folgendes hinzuzufügen: In meiner Anwendung funktioniert es einwandfrei mit Tomcat

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

Ich verwende Spring Boot und wenn ich Embedded Tomcat verwende, hat es einwandfrei funktioniert, @EntityScan("my.package.base.*")aber als ich versuchte, die App auf einem externen Tomcat bereitzustellen, wurde ein not a managed typeFehler für meine Entität angezeigt.

Manoj
quelle
Sie sind mein Held.
Artur Łysik
27

In meinem Fall lag das Problem daran, dass ich vergessen hatte, meine Entity-Klassen mit @ javax.persistence.Entity-Annotation versehen zu haben. Doh!

//The class reported as "not a amanaged type"
@javax.persistence.Entity
public class MyEntityClass extends my.base.EntityClass {
    ....
}
Farrukh Najmi
quelle
In meinem Fall brauchte ich auch einen Tabellennamen in @EntityAnmerkungen. Ich habe hier ein Beispielprojekt eingerichtet: github.com/mate0021/two_datasources.git
mate00
22

Wenn Sie die Persistenzkonfiguration aus einem anderen Projekt kopiert und eingefügt haben, müssen Sie das Paket in EntityManagerFactory manuell festlegen :

@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
quelle
18

Sie können die Annotation @EntityScan verwenden und Ihr Entitätspaket zum Scannen aller Ihrer jpa-Entitäten bereitstellen. Sie können diese Annotation für Ihre Basisanwendungsklasse verwenden, in der Sie die Annotation @SpringBootApplication verwendet haben.

zB @EntityScan ("com.test.springboot.demo.entity")

Nitesh Saxena
quelle
16

Vergessen Sie niemals, @Entity zur Domänenklasse hinzuzufügen

Mohammad Badiuzzaman
quelle
12

Ich habe diesen Fehler bekommen, weil ich dumm geschrieben habe

öffentliche Schnittstelle FooBarRepository erweitert CrudRepository <FooBar Repository , Long> {...

Eine kurze Erklärung: In der Regel wird eine FooBarRepository-Klasse zum Verwalten von FooBar-Objekten erstellt (die häufig Daten in einer Tabelle mit dem Namen foo_bar darstellt). Wenn Sie das CrudRepository erweitern, um die spezialisierte Repository-Klasse zu erstellen, müssen Sie den Typ angeben, der verwaltet wird in diesem Fall FooBar. Was ich jedoch fälschlicherweise eingegeben habe, war FooBarRepository und nicht FooBar. FooBarRepository ist nicht der Typ (die Klasse), den ich mit dem FooBarRepository verwalten möchte. Daher gibt der Compiler diesen Fehler aus.

Ich habe das fehlerhafte Tippen fett hervorgehoben . Löschen Sie das markierte Wort Repository in meinem Beispiel und der Code wird kompiliert.

Marvo
quelle
6
15 Minuten meines Lebens, die ich nicht erholen kann
Oscar Moncayo
@TayabHussain, ich habe den Beitrag mit einigen Erklärungen aktualisiert. Hoffe es hilft dir weiter.
Marvo
7

Fügen Sie dies in Ihre Java-Anwendungsdatei ein

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

RK Shrestha
quelle
Dies ist ein Duplikat für die obige Antwort.
Keshu R.
6

Sie haben entweder @Entity bei der Klassendefinition verpasst oder Sie haben einen expliziten Komponenten-Scan-Pfad, und dieser Pfad enthält Ihre Klasse nicht

Tamer Awad
quelle
3

Ich verwende Spring Boot 2.0 und habe dies behoben, indem ich @ComponentScan durch ersetzt habe @EntityScan

Arun Raaj
quelle
1

Ich hatte das gleiche Problem, aber nur, wenn Spring Boot-Testfälle ausgeführt wurden, für die JPA erforderlich war. Das Endergebnis war, dass unsere eigene jpa-Testkonfiguration eine EntityManagerFactory initialisierte und die zu scannenden Pakete festlegte. Dies überschreibt offensichtlich die EntityScan-Parameter, wenn Sie sie manuell einstellen.

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

Wichtig zu beachten: Wenn Sie immer noch nicht weiterkommen, sollten Sie in der Methode org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManageron einen Haltepunkt setzen setPackagesToScan()und sich ansehen, wo dies aufgerufen wird und welche Pakete an sie übergeben werden.

Chris Hinshaw
quelle
1

Ich hatte ein Problem bei der Migration von Spring Boot 1.3.x auf 1.5. Nach dem Aktualisieren des Entity-Pakets in der EntityManagerFactory-Bean funktionierte es

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

Diese Bean wird in der Anwendungsklasse wie folgt bezeichnet

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

}
Ravi M.
quelle
0

Ich habe das gleiche Problem, in Version Spring Boot v1.3.x habe ich Spring Boot auf Version 1.5.7.RELEASE aktualisiert. Dann war das Problem verschwunden.

Maosheng Wang
quelle
Ich war auf einem 1.3.x, dann wechselte ich zu 1.5.6 und bekam das Problem
apkisbossin
0

Ich hatte dieses Problem, weil ich nicht alle Entitäten in der Datei orm.xml zugeordnet habe

Pavlo Zvarych
quelle
0

Unten hat für mich gearbeitet ..

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
quelle