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

@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

ขอบคุณ


1
ฉันเชื่อว่าคุณจะต้องบอกให้ Hibernate สแกนแพ็คเกจสำหรับวัตถุเอนทิตีของคุณ
chrylis -cautiouslyoptimistic-

คำตอบ:


51

ฉันคิดว่าการแทนที่@ComponentScanด้วย@ComponentScan("com.nervy.dialer.domain")จะได้ผล

แก้ไข:

ฉันได้เพิ่มแอปพลิเคชันตัวอย่างเพื่อสาธิตวิธีตั้งค่าการเชื่อมต่อแหล่งข้อมูลร่วมกับ BoneCP

แอปพลิเคชันมีโครงสร้างเดียวกันกับของคุณ ฉันหวังว่านี่จะช่วยคุณแก้ไขปัญหาการกำหนดค่าของคุณ


ถ้าฉันเพิ่ม @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 แล้วและฉันได้รับข้อผิดพลาดเดียวกัน คำอธิบายประกอบของฉันในคลาส Application ได้แก่ 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}
Robin

112

กำหนดค่าตำแหน่งของเอนทิตีโดยใช้@EntityScanในคลาสจุดเข้า Spring Boot

อัปเดตเมื่อกันยายน 2559 : สำหรับ 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
มันใช้ได้ผลสำหรับฉัน แต่เป็นคำอธิบายประกอบที่เลิกใช้งานแล้ว
Juan Carlos Puerto

ขอบคุณ Juan ฉันได้อัปเดตคำตอบด้วย Entity Scan เวอร์ชันปัจจุบัน
Manish Maheshwari

78

ลองเพิ่มสิ่งต่อไปนี้ทั้งหมดในแอปพลิเคชันของฉันมันทำงานได้ดีกับแมวตัวผู้

 @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

ในกรณีของฉันปัญหาเกิดจากการที่ฉันลืมใส่คำอธิบายประกอบคลาสเอนทิตีพร้อม@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!!!!!");
    //...
}

18

คุณสามารถใช้คำอธิบายประกอบ@EntityScanและจัดเตรียมแพ็คเกจเอนทิตีของคุณสำหรับการสแกนเอนทิตี jpa ทั้งหมดของคุณ คุณสามารถใช้คำอธิบายประกอบนี้กับคลาสแอ็พพลิเคชันพื้นฐานของคุณที่คุณใช้คำอธิบายประกอบ @SpringBootApplication

เช่น @EntityScan ("com.test.springboot.demo.entity")



12

ฉันได้รับข้อผิดพลาดนี้เพราะฉันเขียนโง่ ๆ

ส่วนต่อประสานสาธารณะ FooBarRepository ขยาย CrudRepository <FooBar Repositoryยาว> {...

คำอธิบายสั้น ๆ : โดยทั่วไปแล้วเราจะสร้างคลาส FooBarRepository เพื่อจัดการอ็อบเจ็กต์ FooBar (มักจะแสดงข้อมูลในตารางที่เรียกว่า foo_bar) เมื่อขยาย CrudRepository เพื่อสร้างคลาสที่เก็บเฉพาะเราจำเป็นต้องระบุประเภทที่กำลังจัดการ - ใน กรณีนี้ FooBar สิ่งที่ฉันพิมพ์ผิดพลาดคือ FooBarRepository แทนที่จะเป็น FooBar FooBarRepository ไม่ใช่ประเภท (คลาส) ที่ฉันพยายามจัดการด้วย FooBarRepository ดังนั้นคอมไพเลอร์จึงออกข้อผิดพลาดนี้

ผมไฮไลต์บิตเข้าใจผิดของการพิมพ์ในตัวหนา ลบคำที่ไฮไลต์ Repository ในตัวอย่างของฉันและโค้ดคอมไพล์


6
15 นาทีในชีวิตของฉันที่ฉันจะไม่สามารถกู้คืนได้
Oscar Moncayo

@TayabHussain ฉันอัปเดตโพสต์พร้อมคำอธิบาย หวังว่ามันจะช่วยคุณได้
Marvo


6

คุณพลาด @Entity ในการกำหนดคลาสหรือคุณมีเส้นทางการสแกนคอมโพเนนต์ที่ชัดเจนและเส้นทางนี้ไม่มีคลาสของคุณ



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()และดูว่าสิ่งนี้ถูกเรียกใช้ที่ใดและแพ็กเกจใดที่จะถูกส่งไป


1

ฉันมีปัญหาบางอย่างขณะย้ายจาก Spring boot 1.3.x เป็น 1.5 ฉันทำให้มันใช้งานได้หลังจากอัปเดตแพ็คเกจเอนทิตีที่ 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;
  }

ถั่วนี้อ้างถึงในคลาส Application ดังต่อไปนี้

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

}

0

ฉันมีปัญหาเดียวกันในเวอร์ชัน spring boot v1.3.x สิ่งที่ฉันทำคืออัปเกรดสปริงบูตเป็นเวอร์ชัน 1.5.7 รีลีส จากนั้นปัญหาก็หายไป


ฉันใช้ 1.3.x จากนั้นฉันเปลี่ยนเป็น 1.5.6 และได้รับปัญหา
apkisbossin


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

}


0

ฉันได้ย้ายคลาสแอปพลิเคชันของฉันไปยังแพ็คเกจหลักเช่น:

คลาสหลัก: com.job.application

เอนทิตี: com.job.application.entity

วิธีนี้คุณไม่ต้องเพิ่ม @EntityScan

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.