Неизвестный объект при вызове EntityManager.persist()

#java #jpa #kotlin #axon

#java #jpa #kotlin #axon

Вопрос:

У меня есть этот класс в QuoteProjection.java :

 package com.mycompany.myapp.query;

import com.mycompany.myapp.command.domain.ProjectedQuote;
import javax.persistence.EntityManager;

public class QuoteProjection {

    private final EntityManager entityManager;
.
.
.
    public void on(CreateSubmissionEvt evt) {
        ProjectedQuote projectedQuote = new ProjectedQuote(evt.getAggregateId(), evt.getJobNumber());
        entityManager.persist(projectedQuote); // error reference this line
    }
  

Я определил ProjectedQuote в myApi.kt :

 package com.mycompany.myapp.command.domain

@Entity
@NamedQueries(
        NamedQuery(name = "ProjectedQuote.fetch",
                query = "SELECT q FROM ProjectedQuote q WHERE q.aggregateId LIKE CONCAT(:idStartsWith, '%') ORDER BY q.id"),
        NamedQuery(name = "ProjectedQuote.count",
                query = "SELECT COUNT(q) FROM ProjectedQuote q WHERE q.aggregateId LIKE CONCAT(:idStartsWith, '%')")
)
data class ProjectedQuote(@Id var aggregateId: String, var jobNumber : String) { constructor() : this("", "") }
  

При запуске я получаю следующую ошибку:

 java.lang.IllegalArgumentException: Unknown entity:
com.mycompany.myapp.command.domain.ProjectedQuote
        at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:787) ~hibernate-core-5.2.17.Final.jar!/:5.2.17.Final]
        at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:768) ~[hibernate-core-5.2.17.Final.jar!/:5.2.17.Final]
.
.
.
  

Согласно приведенному ниже ответу Лесиака, я попытался добавить @EntityScan в приложение, Application.java :

 package com.mycompany.myapp.query;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;

@SpringBootApplication
@EntityScan(basePackages = {"com.mycompany.myapp.command.domain"})
public class Application {
  public static void main(String[] args) {
    SpringApplication.run(Application.class, args);
  }
}
  

…но теперь я получаю следующую ошибку, и приложение завершается:

 2019-04-16 15:34:54.265 ERROR 4212 --- [           main] o.s.boot.SpringApplication
          : Application run failed

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sagaStore' defined in class path resource [org/axonframework/springboot/autoconfig/JpaAutoConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.axonframework.modelling.saga.repository.jpa.JpaSagaStore]: Factory method 'sagaStore' threw exception; nested exception is java.lang.IllegalArgumentException: org.hibernate.hql.internal.ast.QuerySyntaxException: SagaEntry is not mapped [SELECT new org.axonframework.modelling.saga.repository.jpa.SerializedSaga(se.serializedSaga, se.sagaType, se.revision) FROM SagaEntry se WHERE se.sagaId = :sagaId]
        at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:590) ~[spring-beans-5.0.9.RELEASE.jar!/:5.0.9.RELEASE]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1247) ~[spring-beans-5.0.9.RELEASE.jar!/:5.0.9.RELEASE]
.
.
.
  

Саги, на которые ссылается сообщение об ошибке, являются частью фреймворка Axon. Таким образом @EntityScan , выполнение в моих пакетах, похоже, привело к тому, что он НЕ сканировал пакеты Axon, может быть?

Я над головой. Любая помощь приветствуется.

Комментарии:

1. Знакомы ли вы с основами JPA на чистом Java? Используете ли вы плагин Kotlin JPA?

2. @chrylis, я довольно новичок в JPA во всех формах: Java и Kotlin. Плагины не используются.

3. проверьте persistence.xml , ваш объект должен быть сопоставлен с источником данных или все объекты должны быть автоматически сопоставлены конфигурацией

4. @Ioseb, у меня нет persistence.xml , поскольку я копирую из рабочего примера, в котором его нет. Требуется ли это?

5. @JonathanM это приложение spring или обычный проект java / hibernate?

Ответ №1:

Как насчет аннотирования вашего класса с помощью @Entity

Смотрите, например https://docs.jboss.org/hibernate/annotations/3.5/reference/en/html/entity.html#entity-mapping-entity

Обновить

Проверьте, какие объекты сканируются. https://springbootdev.com/2017/11/13/what-are-the-uses-of-entityscan-and-enablejparepositories-annotations/amp/

По умолчанию Spring Boot включит сканирование сущности и посмотрит в пакете (и его подпакетах), где @SpringBootApplication находится. Если в вашей конфигурации есть сущности в другом пакете, используйте @EntityScan

Обновление 2

После некоторого расследования оказалось, что вопрос очень специфичен для Axon.

Axon необходимо зарегистрировать свои собственные сущности, как SagaEntry указано в обновленном вопросе. Для этого он регистрирует эти сущности в jpautoconfiguration, использует свою собственную аннотацию @RegisterDefaultEntities , к сожалению, их конфигурация работает хорошо, если вы полагаетесь на макет проекта по умолчанию (модели домена в подпакете пакета, содержащего ваше приложение), но не подходит для @EntityScan

Проверьте проблему https://github.com/AxonFramework/AxonFramework/issues/245

Мой совет — переупаковать ваше приложение (переместить объекты в подпакет, если ваш пакет приложения) и удалить @EntityScan

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

Комментарии:

1. Задавался вопросом об этом, но у меня был рабочий пример, в котором не было @Entity (хотя он появился в структуре над ним). Есть ли документ, на который вы можете указать мне?

2. Было ли у него отображение XML?

3. Я не создал ни одного, потому что в моем рабочем примере их тоже не было. Требуется ли это?

4. Нет, совсем нет. Он использовался до того, как аннотации были введены в Java. Просто догадываюсь, почему ваш пример работал без аннотации.

5. Понял. Я попробую аннотацию.