Spring boot - Không phải là loại được quản lý


137

Tôi sử dụng Spring boot + JPA và gặp sự cố khi khởi động dịch vụ.

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)

Đây là tệp Application.java,

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

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

Tôi sử dụng UCp để tổng hợp kết nối và cấu hình DataSource bên dưới,

@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 Thực hiện,

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

    @Autowired
    private UserService userService;

Thực hiện lớp dịch vụ,

@Service
public class PhoneSettingsServiceImpl implements PhoneSettingsService {

}

Lớp kho lưu trữ,

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

}

Lớp thực thể,

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

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

}

Các gói như sau,

  1. Application lớp học trong - com.nervy.dialer
  2. Datasource lớp học trong - com.nervy.dialer.common
  3. Các lớp thực thể đang trong - com.nervy.dialer.domain
  4. Các lớp dịch vụ nằm trong - com.nervy.dialer.domain.service.impl
  5. Bộ điều khiển đang trong - com.nervy.dialer.spring.controller
  6. Các lớp lưu trữ đang trong - com.nervy.dialer.spring.jpa.repository
  7. WebSecurityConfig trong - com.nervy.dialer.spring.security

Cảm ơn


1
Tôi tin rằng bạn vẫn sẽ cần nói với Hibernate để quét gói cho đối tượng thực thể của bạn.
chrylis -cautiouslyoptimistic-

Câu trả lời:


51

Tôi nghĩ thay thế @ComponentScanbằng @ComponentScan("com.nervy.dialer.domain")sẽ làm việc.

Biên tập :

Tôi đã thêm một ứng dụng mẫu để trình bày cách thiết lập kết nối nguồn dữ liệu được gộp chung với BoneCP.

Ứng dụng này có cùng cấu trúc với bạn. Tôi hy vọng điều này sẽ giúp bạn giải quyết vấn đề cấu hình của bạn


Nếu tôi thêm @ComponentScan ("com.nervy.dialer.domain"), tôi sẽ nhận được nguồn dữ liệu không ngoại lệ vì nó nằm trong một gói khác. Đã thêm gói đó cũng như @ComponentScan ({"com.nervy.dialer.domain", "com.nervy.dialer.common"}). Bây giờ gettting cùng một lỗi cũ.
1578872

1
Tôi đã thêm một ứng dụng mẫu để trình bày cách thiết lập kết nối nguồn dữ liệu được gộp chung với BoneCP. github.com/azizunsal/SpringBootBoneCPPooledDataSource Ứng dụng này có cùng cấu trúc với bạn. Tôi hy vọng điều này sẽ giúp bạn giải quyết vấn đề cấu hình của bạn.
azizunal 24/2/2015

Bạn đã làm điều kỳ diệu. Nó hoạt động tốt. Cảm ơn bạn đã giúp đỡ. Tôi đã có chú thích sau trong nguồn dữ liệu. @EnableJpaRepositories (entityManagerFactoryRef = "dialerEntityManagerFactory", TransactionManagerRef = "dialerTransactionManager", basePackages = {"com.nervytech.dialer.reposeective"}). Sau khi loại bỏ điều này và chỉ cần thêm @EnableJpsResposeective trong DialerApplication, nó đã bắt đầu hoạt động tốt.
1578872

Tôi có cùng một vấn đề. Spring boot không nhận ra Thực thể của tôi (@DocateUpdate từ phiên bản 4+ ngủ đông). Tôi đã thử với việc thêm gói mô hình của mình trong ElementScan hoặc EntityScan và tôi cũng gặp lỗi tương tự. Các chú thích của tôi trong lớp Ứng dụng là: SpringBootApplication ElementScan (basePackages = {"com.example.controllers", "com.example.service", "com.example.models"}) EnableAutoConfiguration @Configuration @EnableJpa example.dao "," com.example.models "})
Balflear

Kịch bản tương tự chúng tôi đã sử dụng Hibernated như một nhà cung cấp JPA. Như sau khi thử tất cả các giải pháp vẫn còn vấn đề tồn tại. Đã thêm cấu hình này trong tệp cấu hình ứng dụng của tôi đã giải quyết vấn đề cho tôi. hibernate.annotation.packages.to.scan = $ {myEntityPackage}
Robin

112

Định cấu hình vị trí của các thực thể bằng @EntityScan trong lớp điểm khởi động Spring Boot.

Cập nhật vào tháng 9 năm 2016 : Đối với Spring Boot 1.4+:
sử dụng org.springframework.boot.autoconfigure.domain.EntityScan
thay vì org.springframework.boot.orm.jpa.EntityScan, vì ... boot.orm.jpa.EntityScan không được chấp nhận kể từ Spring Boot 1.4


2
Tùy chọn này cũng không giúp được gì. Tôi đoán, tôi đang thiếu một cái gì đó khác trong cấu hình của tôi.
1578872

3
Không giúp gì trong trường hợp của tôi cả.
Balflear

1
Nó đã làm việc cho tôi nhưng nó là một chú thích không dùng nữa.
Juan Carlos Puerto

Cảm ơn Juan, tôi đã cập nhật câu trả lời với phiên bản hiện tại của Entity Scan.
Manish Maheshwari

78

Hãy thử thêm Tất cả các mục sau, Trong ứng dụng của tôi, nó hoạt động tốt với tomcat

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

Tôi đang sử dụng boot mùa xuân và khi tôi đang sử dụng tomcat nhúng thì nó vẫn hoạt động tốt @EntityScan("my.package.base.*")nhưng khi tôi cố gắng triển khai ứng dụng lên một tomcat bên ngoài thì tôi đã not a managed typegặp lỗi cho thực thể của mình.


Bạn là người hùng của tôi.
Artur Łysik

27

Trong trường hợp của tôi, vấn đề là do tôi quên không chú thích các lớp Thực thể của mình với @javax.persistence.Entitychú thích. Đừng!

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

Trong trường hợp của tôi, tôi cũng cần tên bảng trong @Entitychú thích. Tôi thiết lập một dự án mẫu tại đây: github.com/mate0021/two_datasource.git
mate00

22

Nếu bạn đã dán bản sao cấu hình bền vững từ một dự án khác, bạn phải đặt gói trong EntityManagerFactory theo cách thủ công:

@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

Bạn có thể sử dụng chú thích @EntityScan và cung cấp gói thực thể của bạn để quét tất cả các thực thể jpa của bạn. Bạn có thể sử dụng chú thích này trên lớp ứng dụng cơ sở nơi bạn đã sử dụng chú thích @SpringBootApplication.

ví dụ: @EntityScan ("com.test.springboot.demo.entity")



12

Tôi đã nhận được lỗi này vì tôi đã viết một cách ngu ngốc

giao diện công cộng FooBarRep repository mở rộng CrudRep repository < Kho lưu trữ FooBar , Long> {...

Một lời giải thích ngắn gọn: Người ta thường tạo một lớp FooBarRep repository để quản lý các đối tượng FooBar (thường biểu thị dữ liệu trong một bảng gọi là foo_bar.) Khi mở rộng CrudRep repository để tạo lớp kho lưu trữ chuyên dụng, người ta cần chỉ định loại được quản lý - trong trường hợp này, FooBar. Tuy nhiên, thứ tôi gõ nhầm là FooBarRep repository chứ không phải FooBar. FooBarRep repository không phải là loại (lớp) Tôi đang cố gắng quản lý với FooBarRep repository. Do đó, trình biên dịch phát sinh lỗi này.

Tôi nhấn mạnh một chút sai lầm khi gõ đậm . Xóa kho lưu trữ từ được tô sáng trong ví dụ của tôi và mã biên dịch.


6
15 phút trong cuộc đời tôi sẽ không thể phục hồi
Oscar Moncayo

@TayabHussain, tôi đã cập nhật bài viết với một số lời giải thích. Hy vọng nó sẽ giúp bạn hiểu.
Marvo

7

Đặt cái này trong Application.javatập tin của bạn

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

Đây là một bản sao cho câu trả lời trên.
Keshu R. 7/12/19

6

Bạn đã bỏ lỡ @Entity trên định nghĩa lớp hoặc bạn có đường dẫn quét thành phần rõ ràng và đường dẫn này không chứa lớp của bạn


3

Tôi đang sử dụng spring boot 2.0 và tôi đã sửa lỗi này bằng cách thay thế @ComponentScan bằng @EntityScan


1

Tôi đã có vấn đề tương tự nhưng chỉ khi chạy các trường hợp kiểm tra khởi động mùa xuân yêu cầu JPA. Kết quả cuối cùng là cấu hình kiểm tra jpa của chính chúng ta đã khởi tạo EntityManagerFactory và đặt các gói để quét. Điều này rõ ràng sẽ ghi đè các tham số EntityScan nếu bạn đang đặt thủ công.

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

Điều quan trọng cần lưu ý: nếu bạn vẫn đang bị mắc kẹt, bạn nên thiết lập một điểm break ở org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManagertrên setPackagesToScan()phương pháp và có một cái nhìn tại nơi này đang được gọi là và những gì gói được truyền cho nó.


1

Tôi đã gặp một số vấn đề khi di chuyển từ Spring boot 1.3.x sang 1.5, tôi đã làm cho nó hoạt động sau khi cập nhật gói thực thể tại 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;
  }

Bean này được gọi trong lớp Ứng dụng như dưới đây

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

}

0

Tôi có cùng một vấn đề, trong phiên bản spring boot v1.3.x, những gì tôi đã làm là nâng cấp boot mùa xuân lên phiên bản 1.5.7.RELEASE. Rồi cái xác đi.


Tôi đang dùng bản 1.3.x sau đó tôi chuyển sang 1.5.6 và gặp sự cố
apkvdossin

0

Tôi gặp vấn đề này vì tôi đã không ánh xạ tất cả các thực thể trong tệp orm.xml


0

Dưới đây làm việc cho tôi ..

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

Tôi đã chuyển lớp ứng dụng của mình sang gói cha mẹ như:

Lớp chính: com.job.application

Thực thể: com.job.application.entity

Bằng cách này, bạn không phải thêm @EntityScan

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.