调用 EntityManager.persist() 时出现未知实体
Unknown Entity when calling EntityManager.persist()
我在 QuoteProjection.java
中有这个 class:
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
}
我在 myApi.kt
中定义了 ProjectedQuote
:
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]
.
.
.
根据下面 Lesiak 的回答,我尝试将 @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]
.
.
.
错误消息中引用的 Sagas 是 Axon 框架的一部分。所以通过在我的包裹上做一个 @EntityScan
,它看起来像是导致它不扫描 Axon 包裹,也许吧?
我有点头疼了。感谢您的帮助。
用 @Entity
注释你的 class 怎么样?
参见示例https://docs.jboss.org/hibernate/annotations/3.5/reference/en/html/entity.html#entity-mapping-entity
更新
默认情况下,Spring Boot 将启用实体扫描并查找 @SpringBootApplication
所在的包(及其子包)。如果您的配置在另一个包中有实体,请使用 @EntityScan
更新 2
经过一番调查,发现这个问题是 Axon 特有的。
Axon 需要注册自己的实体,如更新问题中提到的 SagaEntry
。
它在 JpaAutoConfiguration 中注册这些实体
为此,它使用自己的注释 @RegisterDefaultEntities
不幸的是,如果您依赖默认的项目布局(域模型在包含您的应用程序的包的子包中),它们的配置会很好地工作,
但不适合 @EntityScan
检查问题https://github.com/AxonFramework/AxonFramework/issues/245
我的建议是重新打包您的应用程序(如果您的应用程序包,请将实体移至子包)并删除 @EntityScan
如果您喜欢冒险,您可以尝试扫描通过自定义注释扫描的相同包,但我不确定这是否会成功。
我在 QuoteProjection.java
中有这个 class:
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
}
我在 myApi.kt
中定义了 ProjectedQuote
:
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]
.
.
.
根据下面 Lesiak 的回答,我尝试将 @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]
.
.
.
错误消息中引用的 Sagas 是 Axon 框架的一部分。所以通过在我的包裹上做一个 @EntityScan
,它看起来像是导致它不扫描 Axon 包裹,也许吧?
我有点头疼了。感谢您的帮助。
用 @Entity
参见示例https://docs.jboss.org/hibernate/annotations/3.5/reference/en/html/entity.html#entity-mapping-entity
更新
默认情况下,Spring Boot 将启用实体扫描并查找 @SpringBootApplication
所在的包(及其子包)。如果您的配置在另一个包中有实体,请使用 @EntityScan
更新 2
经过一番调查,发现这个问题是 Axon 特有的。
Axon 需要注册自己的实体,如更新问题中提到的 SagaEntry
。
它在 JpaAutoConfiguration 中注册这些实体
为此,它使用自己的注释 @RegisterDefaultEntities
不幸的是,如果您依赖默认的项目布局(域模型在包含您的应用程序的包的子包中),它们的配置会很好地工作,
但不适合 @EntityScan
检查问题https://github.com/AxonFramework/AxonFramework/issues/245
我的建议是重新打包您的应用程序(如果您的应用程序包,请将实体移至子包)并删除 @EntityScan
如果您喜欢冒险,您可以尝试扫描通过自定义注释扫描的相同包,但我不确定这是否会成功。