Spring Data с двумя базами данных создает исключение IllegalArgumentException: не является объектом - PullRequest
0 голосов
/ 15 октября 2019

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

Теперь я должен сделать некоторую магию с критериями api. Это мой код для формы поиска для поиска определенных объектов отчета:

@Override
public List<Report> findByCriteriaQuery(String lvg, String tnr, String fpd, String state, String reason,
        String version, String supervisor, String bel) {

    CriteriaBuilder cb = em.getCriteriaBuilder();
    CriteriaQuery<Report> reportQuery = cb.createQuery(Report.class);
    Root<Report> reportRoot = reportQuery.from(Report.class);

    reportQuery.select(reportRoot).distinct(true);

    Predicate reportCriteria = cb.conjunction();

    if(lvg != "") {
        Predicate p = cb.equal(reportRoot.get("lvg"), lvg);
        reportCriteria = cb.and(reportCriteria, p);
    }
    if(tnr != "") {
        Predicate p = cb.equal(reportRoot.get("tnr"), tnr);
        reportCriteria = cb.and(reportCriteria, p);
    }
    if(fpd != "") {
        Predicate p = cb.equal(reportRoot.get("fpd"), fpd);
        reportCriteria = cb.and(reportCriteria, p);
    }
    if(state != "") {
        Predicate p = cb.equal(reportRoot.get("orderState"), state);
        reportCriteria = cb.and(reportCriteria, p);
    }
    if(reason != "") {
        Predicate p = cb.equal(reportRoot.get("orderStateReason"), reason);
        reportCriteria = cb.and(reportCriteria, p);
    }
    if(version != "") {
        Predicate p = cb.equal(reportRoot.get("id").get("mobislversion"), version);
        reportCriteria = cb.and(reportCriteria, p);
    }
    if(bel != "") {
        Predicate p = cb.equal(reportRoot.get("bel"), bel);
        reportCriteria = cb.and(reportCriteria, p);
    }

    reportQuery.where(reportCriteria);

    List<Report> criteriaResult = em.createQuery(reportQuery).getResultList();

    List<Report> result = filterReportForSupervisor(supervisor, criteriaResult);

    return result;

}

В этой строке:

Root<Report> reportRoot = reportQuery.from(Report.class);

Я получаю следующее исключение:

java.lang.IllegalArgumentException: Not an entity: class de.fraport.bvd.mobisl.data.shared.entity.Report
at org.hibernate.metamodel.internal.MetamodelImpl.entity(MetamodelImpl.java:457) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
at org.hibernate.query.criteria.internal.QueryStructure.from(QueryStructure.java:126) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
at org.hibernate.query.criteria.internal.CriteriaQueryImpl.from(CriteriaQueryImpl.java:153) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
at de.fraport.bvd.mobisl.data.shared.repository.ReportRepositoryImpl.findByCriteriaQuery(ReportRepositoryImpl.java:65) ~[classes/:na]
at de.fraport.bvd.mobisl.data.shared.repository.ReportRepositoryImpl$$FastClassBySpringCGLIB$$87a17ef4.invoke(<generated>) ~[classes/:na]
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204) ~[spring-core-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:746) ~[spring-aop-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) ~[spring-aop-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:139) ~[spring-tx-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185) ~[spring-aop-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:294) ~[spring-tx-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98) ~[spring-tx-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185) ~[spring-aop-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:688) ~[spring-aop-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at de.fraport.bvd.mobisl.data.shared.repository.ReportRepositoryImpl$$EnhancerBySpringCGLIB$$9f86def2.findByCriteriaQuery(<generated>) ~[classes/:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_172]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_172]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_172]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_172]

Это кажется мне странным, потому что запросы типа:

@Query("select r from Report r where r.id.created >= :now")
public Page<Report> findByDate(@Param("now") String now, Pageable pageable);

работают абсолютно корректно. У меня есть два класса конфигурации для двух баз данных, где фабричные компоненты диспетчера сущностей сканируют правильные пакеты сущностей, а класс Report помечается @ Entity.

База данных 1:

@Primary
@Bean(name="entityManagerFactory")
public LocalContainerEntityManagerFactoryBean entityManagerFactory() throws SQLException {
    final LocalContainerEntityManagerFactoryBean emf = new LocalContainerEntityManagerFactoryBean();
    final HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
    Properties hibernateProperties = new Properties();

    hibernateProperties.put("hibernate.dialect", "org.hibernate.dialect.Oracle10gDialect");
    hibernateProperties.put("hibernate.max_fetch_depth", 3);
    hibernateProperties.put("hibernate.jdbc.batch_size", 10);
    hibernateProperties.put("hibernate.jdvc.fetch_size", 50);

    emf.setPackagesToScan("de.xxxxxx.bvd.xxxxxx.data.entity");
    emf.setDataSource(dataSource());
    emf.setJpaVendorAdapter(vendorAdapter);
    emf.setJpaProperties(hibernateProperties);

    return emf;
}

База данных2:

@Bean(name="sharedEntityManagerFactory")
public LocalContainerEntityManagerFactoryBean sharedEntityManagerFactory() throws SQLException {
    final LocalContainerEntityManagerFactoryBean emf = new LocalContainerEntityManagerFactoryBean();
    final HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
    Properties hibernateProperties = new Properties();

    hibernateProperties.put("hibernate.dialect", "org.hibernate.dialect.Oracle10gDialect");
    hibernateProperties.put("hibernate.max_fetch_depth", 3);
    hibernateProperties.put("hibernate.jdbc.batch_size", 10);
    hibernateProperties.put("hibernate.jdvc.fetch_size", 50);

    emf.setPackagesToScan("de.xxxxxxx.bvd.xxxxxx.data.shared.entity");
    emf.setDataSource(sharedDataSource());
    emf.setJpaVendorAdapter(vendorAdapter);
    emf.setJpaProperties(hibernateProperties);

    return emf;
}

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

@Entity
@Table(name = "T_REPORT")
@Data
public class Report {

    @EmbeddedId
    private ReportPK id;
    .
    .
    .
}

Что здесь не так?

1 Ответ

0 голосов
/ 22 октября 2019

Ответ на эту проблему был довольно прост. В классе репозитория, который имеет метод findByCriteriaQuery, я должен был указать, какой менеджер сущностей я хочу использовать там. Я не знал этого факта. Итак, эта простая строчка делает свое дело:

@PersistenceContext (unitName = "sharedEntityManagerFactory")
private EntityManager em;
...