会话工厂不知道带注释的实体

Session factory not knowing annotated entities

我在从另一个项目继承会话工厂和配置时遇到了一些问题: 我有两个独立的项目(核心项目,项目使用核心作为库) 我的核心项目的配置是以下代码:

    package ir.badnava.pressmining.core.config;

import java.util.Properties;

import javax.sql.DataSource;

import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.hibernate5.HibernateTransactionManager;
import org.springframework.orm.hibernate5.LocalSessionFactoryBean;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import ir.badnava.pressmining.core.models.raw.base.BaseRawEntity;
import ir.badnava.pressmining.core.models.raw.page.RawPageEntity;

@Configuration
@ComponentScan(basePackages = { "ir.badnava.pressmining" })
@EnableTransactionManagement
@PropertySource(value = { "classpath:database.properties" })
public class AppConfig {

    @Autowired
    private Environment environment;

    @Bean(name = "sessionFactory")
    public LocalSessionFactoryBean getSessionFactory() {
        LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
        sessionFactory.setDataSource(getDataSource());
        setAnotatedClasses(sessionFactory);
        sessionFactory.setHibernateProperties(getHibernateProperties());
        return sessionFactory;
    }

    protected void setAnotatedClasses(LocalSessionFactoryBean sessionFactory) {
        sessionFactory.setAnnotatedClasses(new Class<?>[]{BaseRawEntity.class, RawPageEntity.class});
    }

    @Bean(name = "dataSource")
    public DataSource getDataSource() {
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName(environment.getRequiredProperty("jdbc.driverClassName"));
        dataSource.setUrl(environment.getRequiredProperty("jdbc.url"));
        dataSource.setUsername(environment.getRequiredProperty("jdbc.username"));
        dataSource.setPassword(environment.getRequiredProperty("jdbc.password"));
        return dataSource;
    }

    private Properties getHibernateProperties() {
        Properties properties = new Properties();
        properties.put("hibernate.dialect", environment.getRequiredProperty("hibernate.dialect"));
        properties.put("hibernate.show_sql", environment.getRequiredProperty("hibernate.show_sql"));
        properties.put("hibernate.format_sql", environment.getRequiredProperty("hibernate.format_sql"));
        properties.put("hibernate.hbm2ddl.auto", environment.getRequiredProperty("hibernate.hbm2ddl.auto"));
        return properties;
    }

    @Autowired
    @Bean(name = "transactionManager")
    public HibernateTransactionManager getTransactionManager(SessionFactory s) {
        HibernateTransactionManager txManager = new HibernateTransactionManager(s);
        return txManager;
    }

}

子项目配置如下代码:

package com.badnava.pressmining.web.crawler.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.orm.hibernate5.LocalSessionFactoryBean;

import com.badnava.pressmining.web.crawler.crawler.WebCrawler;
import com.badnava.pressmining.web.crawler.models.speciallist.RepositoryList;
import com.badnava.pressmining.web.crawler.models.speciallist.RepositoryListManager;
import com.badnava.pressmining.web.crawler.models.urlrepo.UrlRepository;
import com.badnava.pressmining.web.crawler.models.urlrepo.UrlRepositoryManager;

@Configuration
public class AppConfig extends ir.badnava.pressmining.core.config.AppConfig{

    @Bean
    public RepositoryListManager getRepositoryListManager() {
        return new RepositoryListManager();
    }

    @Bean
    public UrlRepositoryManager getUrlRepositoryManager() {
        return new UrlRepositoryManager();
    }

    @Bean
    public WebCrawler getWebCrawler(){
        return new WebCrawler();
    }

    @Override
    protected void setAnotatedClasses(LocalSessionFactoryBean sessionFactory) {
        super.setAnotatedClasses(sessionFactory);
        sessionFactory.setAnnotatedClasses(new Class<?>[]{RepositoryList.class, UrlRepository.class});
    }

}

我的问题是,在子项目中我重载了 setAnnotatedClass 方法并调用它的超级方法并将我的实体提供给会话工厂 class 但是在执行诸如保存或更新之类的操作后会话工厂说未知映射实体

我不知道我在这些代码中做错了什么,因为我之前使用 XML 文件配置

更新: 日志:

Exception in thread "Thread-3" org.hibernate.MappingException: Unknown entity: ir.badnava.pressmining.core.models.raw.page.RawPageEntity
    at org.hibernate.internal.SessionFactoryImpl.getEntityPersister(SessionFactoryImpl.java:776)
    at org.hibernate.internal.SessionImpl.getEntityPersister(SessionImpl.java:1533)
    at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:104)
    at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:192)
    at org.hibernate.event.internal.DefaultSaveEventListener.saveWithGeneratedOrRequestedId(DefaultSaveEventListener.java:38)
    at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:177)
    at org.hibernate.event.internal.DefaultSaveEventListener.performSaveOrUpdate(DefaultSaveEventListener.java:32)
    at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:73)
    at org.hibernate.internal.SessionImpl.fireSave(SessionImpl.java:682)
    at org.hibernate.internal.SessionImpl.save(SessionImpl.java:674)
    at org.hibernate.internal.SessionImpl.save(SessionImpl.java:669)
    at ir.badnava.pressmining.core.models.raw.base.BaseDao.save(BaseDao.java:16)
    at ir.badnava.pressmining.core.models.raw.base.BaseDao$$FastClassBySpringCGLIB$$d95ff2ca.invoke(<generated>)
    at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:720)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
    at org.springframework.transaction.interceptor.TransactionInterceptor.proceedWithInvocation(TransactionInterceptor.java:99)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:280)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:655)
    at ir.badnava.pressmining.core.models.raw.base.BaseDao$$EnhancerBySpringCGLIB$dae3fd.save(<generated>)
    at ir.badnava.pressmining.core.models.raw.base.BaseManager.save(BaseManager.java:23)
    at com.badnava.pressmining.web.crawler.crawler.WebCrawler.run(WebCrawler.java:142)
    at java.lang.Thread.run(Thread.java:745)

问题已解决: 问题是 setAnnotatedClasses 方法是一个 setter 方法,我将我的代码更改为下面的代码,这是有效的

@Override
    protected Class<?>[] setAnotatedClasses() {
        Class<?>[] superClasses = super.setAnotatedClasses(sessionFactory);
        Class<?>[] childClasses = new Class<?>[]{RepositoryList.class, UrlRepository.class};
        Class<?>[] allClasses = new Class<?>[childClasses.length + superClasses.length]; 
        for (int i = 0; i < allClasses.length; i++) {
            if (i < superClasses.length)
                allClasses[i] = superClasses[i];
            else
                allClasses[i] = childClasses[i-childClasses.length];
        }
        return allClasses;
    }

感谢@sura2k