Spring boot - Not a managed type

149

Używam Spring boot + JPA i mam problem z uruchomieniem usługi.

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)

Oto plik Application.java,

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

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

Używam UCp do buforowania połączeń, a konfiguracja DataSource jest poniżej,

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

Implementacja usługi UserDetailsService,

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

    @Autowired
    private UserService userService;

Wdrożenie warstwy usług,

@Service
public class PhoneSettingsServiceImpl implements PhoneSettingsService {

}

Klasa repozytorium,

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

}

Klasa podmiotu,

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

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

}

Pakiety są następujące,

  1. Application klasa jest w - com.nervy.dialer
  2. Datasource klasa jest w - com.nervy.dialer.common
  3. Klasy jednostek znajdują się w - com.nervy.dialer.domain
  4. Zajęcia serwisowe są w - com.nervy.dialer.domain.service.impl
  5. Kontrolery są w - com.nervy.dialer.spring.controller
  6. Klasy repozytorium znajdują się w - com.nervy.dialer.spring.jpa.repository
  7. WebSecurityConfig jest w - com.nervy.dialer.spring.security

Dzięki

user1578872
źródło
1
Uważam, że nadal będziesz musiał powiedzieć Hibernate, aby przeskanował pakiet w poszukiwaniu obiektu encji.
chrylis

Odpowiedzi:

53

Myślę wymianie @ComponentScanz @ComponentScan("com.nervy.dialer.domain")pracy będzie.

Edytować :

Dodałem przykładową aplikację, aby zademonstrować, jak skonfigurować połączenie źródła danych w puli z BoneCP.

Aplikacja ma taką samą strukturę jak Twoja. Mam nadzieję, że pomoże ci to rozwiązać problemy z konfiguracją

azizunsal
źródło
Jeśli dodam @ComponentScan ("com.nervy.dialer.domain"), otrzymuję źródło danych, które nie lubi wyjątku, ponieważ znajduje się w innym pakiecie. Dodałem ten pakiet również jak @ComponentScan ({"com.nervy.dialer.domain", "com.nervy.dialer.common"}). Teraz otrzymuję ten sam stary błąd.
user1578872
1
Dodałem przykładową aplikację, aby zademonstrować, jak skonfigurować połączenie źródła danych w puli z BoneCP. github.com/azizunsal/SpringBootBoneCPPooledDataSource Aplikacja ma taką samą strukturę jak Twoja. Mam nadzieję, że pomoże ci to rozwiązać problemy z konfiguracją.
azizunsal
Zrobiłeś magię. To działa dobrze. Dzięki za pomoc. W źródle danych miałem następującą adnotację. @EnableJpaRepositories (entityManagerFactoryRef = "dialerEntityManagerFactory", transactionManagerRef = "dialerTransactionManager", basePackages = {"com.nervytech.dialer.repository"}). Po usunięciu tego i po prostu dodaniu @EnableJpsRespository w DialerApplication zaczęło działać dobrze.
user1578872,
Mam ten sam problem. Spring boot nie rozpoznaje mojej jednostki (@DynamicUpdate z wersji hibernacji 4+). Próbowałem dodać pakiet modelu w ComponentScan lub EntityScan i otrzymuję ten sam błąd. Moje adnotacje w klasie Application to: SpringBootApplication ComponentScan (basePackages = {"com.example.controllers", "com.example.services", "com.example.models"}) EnableAutoConfiguration @Configuration @EnableJpaRepositories (basePackages = {"com. example.dao "," com.example.models "})
Balflear
W tym samym scenariuszu wykorzystaliśmy Hibernated jako dostawcę JPA. Po wypróbowaniu wszystkich tych rozwiązań problem nadal istnieje. Dodanie tej konfiguracji do mojego pliku konfiguracyjnego aplikacji rozwiązało problem. hibernate.annotation.packages.to.scan = $ {myEntityPackage}
Robin
116

Skonfiguruj lokalizację jednostek za pomocą @EntityScan w klasie punktu wejścia Spring Boot.

Aktualizacja z września 2016 r . : W przypadku Spring Boot 1.4+:
użyj org.springframework.boot.autoconfigure.domain.EntityScan
zamiast org.springframework.boot.orm.jpa.EntityScan, as ... boot.orm.jpa.EntityScan jest przestarzały od Spring Boot 1.4

Manish Maheshwari
źródło
2
Ta opcja również nie pomaga. Chyba brakuje mi czegoś innego w mojej konfiguracji.
user1578872
3
W moim przypadku też nie pomaga.
Balflear
1
U mnie zadziałało, ale jest to przestarzała adnotacja.
Juan Carlos Puerto
Dzięki Juan, zaktualizowałem odpowiedź o aktualną wersję Entity Scan.
Manish Maheshwari
82

Spróbuj dodać wszystkie następujące elementy, w mojej aplikacji działa dobrze z tomcat

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

Używam rozruchu sprężynowego, a kiedy używam osadzonego tomcat, działało dobrze bez wyjścia, @EntityScan("my.package.base.*")ale kiedy próbowałem wdrożyć aplikację na zewnętrznym tomcat, not a managed typewystąpił błąd dla mojej jednostki.

manoj
źródło
1
Jesteś moim bohaterem.
Artur Łysik
29

W moim przypadku problem wynikał z tego, że zapomniałem dodać adnotację do moich klas Entity @javax.persistence.Entity. No!

//The class reported as "not a amanaged type"
@javax.persistence.Entity
public class MyEntityClass extends my.base.EntityClass {
    ....
}
Farrukh Najmi
źródło
W moim przypadku potrzebowałem również nazwy tabeli w @Entityadnotacji. Ustawiłem
mate00
26

Jeśli konfigurujesz własny EntityManagerFactory Bean lub jeśli skopiowałeś i wkleiłeś taką konfigurację trwałości z innego projektu, musisz ustawić lub dostosować pakiet w konfiguracji EntityManagerFactory :

@Bean
public EntityManagerFactory entityManagerFactory() throws PropertyVetoException {
    HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
    vendorAdapter.setGenerateDdl(true);
    LocalContainerEntityManagerFactoryBean factory;
    factory = new LocalContainerEntityManagerFactoryBean();
    factory.setPackagesToScan("!!!!!!package.path.to.entities!!!!!");
    //...
}
Lazaruss
źródło
19

Możesz użyć adnotacji @EntityScan i dostarczyć pakiet jednostek do skanowania wszystkich jednostek jpa. Możesz użyć tej adnotacji w swojej podstawowej klasie aplikacji, w której użyto adnotacji @SpringBootApplication.

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

Nitesh Saxena
źródło
16

nigdy nie zapomnij dodać @Entity w klasie domeny

Mohammad Badiuzzaman
źródło
14

Mam ten błąd bo głupio pisałem

publiczny interfejs FooBarRepository rozszerza CrudRepository <FooBar Repository , Long> {...

Krótkie wyjaśnienie: zazwyczaj tworzy się klasę FooBarRepository do zarządzania obiektami FooBar (często reprezentującą dane w tabeli zwanej czymś w rodzaju foo_bar). Podczas rozszerzania CrudRepository w celu utworzenia wyspecjalizowanej klasy repozytorium, należy określić typ, który jest zarządzany - w w tym przypadku FooBar. Jednak błędnie wpisałem FooBarRepository zamiast FooBar. FooBarRepository nie jest typem (klasą), którym próbuję zarządzać za pomocą FooBarRepository. Dlatego kompilator wyświetla ten błąd.

Podkreśliłem błędne wpisanie pogrubioną czcionką . Usuń zaznaczone słowo Repository w moim przykładzie i kod zostanie skompilowany.

Marvo
źródło
7
15 minut mojego życia, których nie będę w stanie odzyskać
Oscar Moncayo
@TayabHussain, zaktualizowałem post z pewnym wyjaśnieniem. Mam nadzieję, że ci to pomoże.
Marvo
1
To, to, to, to
Ben Arceneaux
11

Umieść to w swoim Application.javapliku

@ComponentScan(basePackages={"com.nervy.dialer"})
@EntityScan(basePackages="domain")
RK Shrestha
źródło
To jest duplikat powyższej odpowiedzi.
iOSArchitect.com
6

Albo przegapiłeś @Entity w definicji klasy, albo masz jawną ścieżkę skanowania komponentów, a ta ścieżka nie zawiera Twojej klasy

Tamer Awad
źródło
3

Używam Spring Boot 2.0 i naprawiłem to, zastępując @ComponentScan @EntityScan

Arun Raaj
źródło
3

Miałem ten sam problem, ale tylko podczas uruchamiania testów rozruchu wiosennego, które wymagały JPA. W rezultacie nasza własna konfiguracja testowa jpa inicjowała EntityManagerFactory i ustawiała pakiety do skanowania. To ewidentnie spowoduje zastąpienie parametrów EntityScan, jeśli ustawiasz je ręcznie.

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

Ważne, aby pamiętać: jeśli nadal tkwi należy ustawić punkt przerwy w org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManagersprawie setPackagesToScan()sposobu i przyjrzeć się, gdzie to jest nazywane i jakie pakiety są przekazywane do niej.

Chris Hinshaw
źródło
2

Miałem problem podczas migracji ze Spring boot 1.3.x do 1.5, działało po zaktualizowaniu pakietu jednostek w fasoli 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;
  }

Ta fasola, o której mowa w klasie aplikacji, jak poniżej

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

}
Ravi M
źródło
0

Mam ten sam problem, w wersji spring boot v1.3.x to co zrobiłem to upgrade spring boot do wersji 1.5.7.RELEASE. Wtedy problem zniknął.

Maosheng Wang
źródło
1
Byłem na 1.3.x, potem przeszedłem na 1.5.6 i
napotkałem
0

Miałem ten problem, ponieważ nie mapowałem wszystkich jednostek w pliku orm.xml

Pavlo Zvarych
źródło
0

Poniżej pracował dla mnie ..

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
źródło
0

Przeniosłem moją klasę aplikacji do pakietu nadrzędnego, takiego jak:

Klasa główna: com.job.application

Jednostka: com.job.application.entity

W ten sposób nie musisz dodawać @EntityScan

tushar wason
źródło