Spring boot - не управляемый тип

137

Я использую Spring boot + JPA, и у меня возникла проблема при запуске службы.

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)

Вот файл Application.java,

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

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

Я использую UCp для пула соединений, а конфигурация источника данных приведена ниже,

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

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

    @Autowired
    private UserService userService;

Реализация сервисного уровня,

@Service
public class PhoneSettingsServiceImpl implements PhoneSettingsService {

}

Класс репозитория,

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

}

Класс сущности,

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

Класс 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());
    }

}

Пакеты следующие:

  1. Application класс в - com.nervy.dialer
  2. Datasource класс в - com.nervy.dialer.common
  3. Классы сущностей находятся в - com.nervy.dialer.domain
  4. Классы обслуживания находятся в - com.nervy.dialer.domain.service.impl
  5. Контроллеры находятся в - com.nervy.dialer.spring.controller
  6. Классы репозитория находятся в - com.nervy.dialer.spring.jpa.repository
  7. WebSecurityConfig в - com.nervy.dialer.spring.security

Спасибо

user1578872
источник
1
Я считаю, что вам все равно нужно указать Hibernate, чтобы сканировать пакет на предмет вашего объекта сущности.
chrylis -cautiouslyoptimistic-

Ответы:

51

Думаю, замена @ComponentScanна @ComponentScan("com.nervy.dialer.domain")сработает.

Редактировать :

Я добавил образец приложения, чтобы продемонстрировать, как настроить соединение с источником данных из пула с BoneCP.

Приложение имеет ту же структуру, что и ваше. Надеюсь, это поможет вам решить проблемы с конфигурацией

azizunsal
источник
Если я добавлю @ComponentScan ("com.nervy.dialer.domain"), я получаю исключение, которое не любит источник данных, поскольку он находится в другом пакете. Этот пакет также добавлен как @ComponentScan ({"com.nervy.dialer.domain", "com.nervy.dialer.common"}). Теперь получаю ту же старую ошибку.
user1578872
1
Я добавил образец приложения, чтобы продемонстрировать, как настроить соединение с источником данных из пула с BoneCP. github.com/azizunsal/SpringBootBoneCPPooledDataSource Приложение имеет ту же структуру, что и ваше. Надеюсь, это поможет вам решить проблемы с конфигурацией.
Azizunsal
Вы творили волшебство. Работает нормально. Спасибо за вашу помощь. В источнике данных была следующая аннотация. @EnableJpaRepositories (entityManagerFactoryRef = "dialerEntityManagerFactory", transactionManagerRef = "dialerTransactionManager", basePackages = {"com.nervytech.dialer.repository"}). После удаления этого и простого добавления @EnableJpsRespository в DialerApplication он начал работать нормально.
user1578872
У меня та же проблема. Spring boot не распознает мою сущность (@DynamicUpdate из версии hibernate 4+). Я попытался добавить свой модельный пакет в ComponentScan или EntityScan, и у меня такая же ошибка. Мои аннотации в классе приложения: SpringBootApplication ComponentScan (basePackages = {"com.example.controllers", "com.example.services", "com.example.models"}) EnableAutoConfiguration @Configuration @EnableJpaRepositories (basePackages = {"com. example.dao "," com.example.models "})
Balflear
По такому же сценарию мы использовали Hibernated в качестве поставщика JPA. После того, как попробовали все эти решения, проблема все еще существует. Добавление этой конфигурации в мой файл конфигурации приложения решило проблему для меня. hibernate.annotation.packages.to.scan = $ {myEntityPackage}
Робин
112

Настройте расположение сущностей с помощью @EntityScan в классе точки входа Spring Boot.

Обновление от сентября 2016 г . : для Spring Boot 1.4+:
используйте org.springframework.boot.autoconfigure.domain.EntityScan
вместо org.springframework.boot.orm.jpa.EntityScan, как ... boot.orm.jpa.EntityScan устарел с Spring Boot 1.4

Маниш Махешвари
источник
2
Этот вариант тоже не помогает. Думаю, мне не хватает чего-то еще в моей конфигурации.
user1578872
3
В моем случае тоже не помогает.
Balflear
1
Это сработало для меня, но это устаревшая аннотация.
Хуан Карлос Пуэрто
Спасибо, Хуан, я обновил ответ с помощью текущей версии Entity Scan.
Маниш Махешвари
78

Попробуйте добавить все следующее: в моем приложении он отлично работает с tomcat

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

Я использую весеннюю загрузку, и когда я использую встроенный tomcat, он отлично работал, @EntityScan("my.package.base.*")но когда я попытался развернуть приложение на внешнем tomcat, у меня возникла not a managed typeошибка для моей сущности.

Манодж
источник
Ты мой герой.
Artur ysik,
27

В моем случае проблема была связана с тем, что я забыл аннотировать свои классы Entity @javax.persistence.Entityаннотациями. Doh!

//The class reported as "not a amanaged type"
@javax.persistence.Entity
public class MyEntityClass extends my.base.EntityClass {
    ....
}
Фаррух Наджми
источник
В моем случае мне также понадобилось имя таблицы в @Entityаннотации. Я создал образец проекта здесь: github.com/mate0021/two_datasources.git
mate00
22

Если вы скопировали конфигурацию сохраняемости из другого проекта, вы должны вручную установить пакет в 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!!!!!");
    //...
}
Lazaruss
источник
18

Вы можете использовать @EntityScan аннотацию и предоставить свой пакет сущностей для сканирования всех ваших сущностей jpa. Вы можете использовать эту аннотацию в своем базовом классе приложения, где вы использовали аннотацию @SpringBootApplication.

например, @EntityScan ("com.test.springboot.demo.entity")

Нитеш Саксена
источник
16

никогда не забывайте добавлять @Entity в доменный класс

Мохаммад Бадиуззаман
источник
12

Получил эту ошибку потому что тупо написал

открытый интерфейс FooBarRepository расширяет CrudRepository <FooBar Repository , Long> {...

Краткое объяснение: обычно создается класс FooBarRepository для управления объектами FooBar (часто представляющими данные в таблице, называемой чем-то вроде foo_bar.) При расширении CrudRepository для создания специализированного класса репозитория необходимо указать управляемый тип - в в данном случае FooBar. Однако я по ошибке набрал FooBarRepository, а не FooBar. FooBarRepository - это не тот тип (класс), которым я пытаюсь управлять с помощью FooBarRepository. Поэтому компилятор выдает эту ошибку.

Я выделил жирным шрифтом ошибочный набор текста . Удалите выделенное слово Repository в моем примере, и код компилируется.

Marvo
источник
6
15 минут моей жизни, которые я не смогу восстановить
Оскар Монкайо
@TayabHussain, я обновил пост с некоторыми пояснениями. Надеюсь, это поможет вам.
Марво
7

Поместите это в свой Application.java файл

@ComponentScan(basePackages={"com.nervy.dialer"})
@EntityScan(basePackages="domain")
РК Шреста
источник
Это дубликат приведенного выше ответа.
iOSArchitect.com
6

Вы либо пропустили @Entity в определении класса, либо у вас есть явный путь сканирования компонентов, и этот путь не содержит ваш класс

Укротитель Авад
источник
3

Я использую Spring boot 2.0 и исправил это, заменив @ComponentScan на @EntityScan

Арун Раадж
источник
1

У меня была такая же проблема, но только при запуске тестов весенней загрузки, для которых требовался JPA. Конечным результатом было то, что наша собственная тестовая конфигурация jpa инициализировала EntityManagerFactory и настраивала пакеты для сканирования. Очевидно, это переопределит параметры EntityScan, если вы устанавливаете их вручную.

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

Важно отметить: если вы все еще застряли, вам следует установить точку org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManagerостанова в setPackagesToScan()методе on и посмотреть, где он вызывается и какие пакеты ему передаются.

Крис Хиншоу
источник
1

У меня возникла проблема при переходе с Spring boot 1.3.x на 1.5, он заработал после обновления пакета сущностей в 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;
  }

Этот bean-компонент упоминается в классе Application, как показано ниже.

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

}
Рави М
источник
0

У меня та же проблема, в версии Spring boot v1.3.x я обновил Spring Boot до версии 1.5.7.RELEASE. Тогда проблема исчезла.

Маошэн Ван
источник
У меня был 1.3.x, затем я переключился на 1.5.6 и получил проблему
apkisbossin
0

У меня была эта проблема, потому что я не сопоставил все объекты в файле orm.xml

Павел Зварыч
источник
0

Ниже работал у меня ..

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
источник
0

Я переместил свой класс приложения в родительский пакет, например:

Основной класс: com.job.application

Сущность: com.job.application.entity

Таким образом, вам не нужно добавлять @EntityScan

Тушар Васон
источник