EclipseLink:继承 mongoDB 作为持久层
EclipseLink: Inheritance with mongoDB as persistence layer
我正在尝试使用 MongoDB 作为持久层使用 Jersey 设置 Web 应用程序。我的 JPA 框架是 EclipseLink。
我 运行 遇到了持久化对象的问题,classes 正在扩展其他(抽象)classes。
例如给定以下摘要class:
@Entity
@NoSql(dataFormat=DataFormatType.MAPPED)
public abstract class AbstractClass {
@Id
@Field(name="_id")
protected String id;
public String getId() {
return this.id;
}
}
并且这个扩展 class:
@Entity
@NoSql(dataFormat=DataFormatType.MAPPED)
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class ExtendedClass extends AbstractClass {
@Basic
private String name;
public ExtendedClass() {
}
public ExtendedClass(String id, String name) {
this.id = id;
this.name = name;
}
public String getName() {
return this.name;
}
}
这是我正在使用的persistence.xml
文件:
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
<persistence-unit name="persistence-unit" transaction-type="RESOURCE_LOCAL">
<class>org.example.webapp.resources.test.AbstractClass</class>
<class>org.example.webapp.resources.test.ExtendedClass</class>
<properties>
<property name="eclipselink.target-database" value="org.eclipse.persistence.nosql.adapters.mongo.MongoPlatform"/>
<property name="eclipselink.nosql.connection-spec" value="org.eclipse.persistence.nosql.adapters.mongo.MongoConnectionSpec"/>
<property name="eclipselink.nosql.property.mongo.port" value="27017"/>
<property name="eclipselink.nosql.property.mongo.host" value="ip-address"/>
<property name="eclipselink.nosql.property.mongo.db" value="database-name"/>
<property name="eclipselink.logging.level" value="FINEST"/>
</properties>
</persistence-unit>
</persistence>
以及创建并保存 ExtendedClass
:
实例的网络服务
@PUT
@Path("persist/extended-object")
@Consumes(MediaType.APPLICATION_JSON)
public String addObject(@QueryParam("name") final String name) {
final String id = UUID.randomUUID().toString();
ExtendedClass theObject = new ExtendedClass(id, name);
EntityManagerFactory emf = Persistence.createEntityManagerFactory("persistence-unit");
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
em.persist(theObject);
em.getTransaction().commit();
em.close();
return "Persisted object with name: " + name;
}
调用网络服务时:
http://localhost:8080/webapp/webapi/test/persist/extended-object?name=test-abstraction
我可以在 mongoDb 数据库中创建一个新条目,如下所示:
到目前为止一切顺利。但是,如果我尝试获取包含所有持久对象的列表,我 运行 就会遇到问题。这是示例网络服务:
@GET
@Path("get/all")
@Produces(MediaType.APPLICATION_JSON)
public List<ExtendedClass> getAllExtendedClasses() {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("persistence-unit");
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
List<ExtendedClass> extendedClassList = em.createQuery("SELECT a FROM ExtendedClass a", ExtendedClass.class).getResultList();
em.getTransaction().commit();
em.close();
return extendedClassList;
}
这会产生以下异常:
javax.resource.ResourceException: org.bson.codecs.configuration.CodecConfigurationException: Can't find a codec for class org.eclipse.persistence.internal.helper.DatabaseField.
完整堆栈跟踪:
Exception [EclipseLink-90000] (Eclipse Persistence Services - 2.5.0.v20130507-3faac2b): org.eclipse.persistence.eis.EISException
Internal Exception: javax.resource.ResourceException: org.bson.codecs.configuration.CodecConfigurationException: Can't find a codec for class org.eclipse.persistence.internal.helper.DatabaseField.
Error Code: 000
Call: Executing MappedInteraction()
spec => null
properties => {mongo.operation=FIND, mongo.collection=ABSTRACTCLASS}
input => [DatabaseRecord(
$and => [DatabaseRecord(
EXTENDEDCLASS._id => ABSTRACTCLASS._id), DatabaseRecord(
ABSTRACTCLASS.DTYPE => ExtendedClass)])]
Query: ReadAllQuery(referenceClass=ExtendedClass jpql="SELECT a FROM ExtendedClass a")
at org.eclipse.persistence.eis.EISException.resourceException(EISException.java:65)
at org.eclipse.persistence.eis.EISException.resourceException(EISException.java:74)
at org.eclipse.persistence.eis.EISException.resourceException(EISException.java:78)
at org.eclipse.persistence.eis.EISAccessor.basicExecuteCall(EISAccessor.java:212)
at org.eclipse.persistence.eis.EISAccessor.executeCall(EISAccessor.java:112)
at org.eclipse.persistence.internal.sessions.AbstractSession.basicExecuteCall(AbstractSession.java:1995)
at org.eclipse.persistence.sessions.server.ServerSession.executeCall(ServerSession.java:570)
at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.executeCall(DatasourceCallQueryMechanism.java:242)
at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.executeCall(DatasourceCallQueryMechanism.java:228)
at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.executeSelectCall(DatasourceCallQueryMechanism.java:299)
at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.selectAllRows(DatasourceCallQueryMechanism.java:694)
at org.eclipse.persistence.internal.queries.ExpressionQueryMechanism.selectAllRowsFromTable(ExpressionQueryMechanism.java:2714)
at org.eclipse.persistence.internal.queries.ExpressionQueryMechanism.selectAllRows(ExpressionQueryMechanism.java:2667)
at org.eclipse.persistence.queries.ReadAllQuery.executeObjectLevelReadQuery(ReadAllQuery.java:477)
at org.eclipse.persistence.queries.ObjectLevelReadQuery.executeDatabaseQuery(ObjectLevelReadQuery.java:1155)
at org.eclipse.persistence.queries.DatabaseQuery.execute(DatabaseQuery.java:899)
at org.eclipse.persistence.queries.ObjectLevelReadQuery.execute(ObjectLevelReadQuery.java:1114)
at org.eclipse.persistence.queries.ReadAllQuery.execute(ReadAllQuery.java:402)
at org.eclipse.persistence.queries.ObjectLevelReadQuery.executeInUnitOfWork(ObjectLevelReadQuery.java:1202)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.internalExecuteQuery(UnitOfWorkImpl.java:2894)
at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1797)
at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1779)
at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1744)
at org.eclipse.persistence.internal.jpa.QueryImpl.executeReadQuery(QueryImpl.java:258)
at org.eclipse.persistence.internal.jpa.QueryImpl.getResultList(QueryImpl.java:468)
at org.example.webapp.resources.test.ObjectWebServices.getAllExtendedClasses(ObjectWebServices.java:54)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.glassfish.jersey.server.model.internal.ResourceMethodInvocationHandlerFactory.lambda$static[=16=](ResourceMethodInvocationHandlerFactory.java:74)
at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.run(AbstractJavaResourceMethodDispatcher.java:144)
at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.invoke(AbstractJavaResourceMethodDispatcher.java:161)
at org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$TypeOutInvoker.doDispatch(JavaResourceMethodDispatcherProvider.java:247)
at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:99)
at org.glassfish.jersey.server.model.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:388)
at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:346)
at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:102)
at org.glassfish.jersey.server.ServerRuntime.run(ServerRuntime.java:337)
at org.glassfish.jersey.internal.Errors.call(Errors.java:271)
at org.glassfish.jersey.internal.Errors.call(Errors.java:267)
at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
at org.glassfish.jersey.internal.Errors.process(Errors.java:267)
at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:280)
at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:316)
at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:1084)
at org.glassfish.jersey.servlet.WebComponent.serviceImpl(WebComponent.java:418)
at org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:372)
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:389)
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:342)
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:229)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:219)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:506)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:142)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:610)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:537)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1081)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:658)
at org.apache.coyote.http11.Http11NioProtocol$Http11ConnectionHandler.process(Http11NioProtocol.java:222)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1566)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1523)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:745)
Caused by: javax.resource.ResourceException: org.bson.codecs.configuration.CodecConfigurationException: Can't find a codec for class org.eclipse.persistence.internal.helper.DatabaseField.
at org.eclipse.persistence.internal.nosql.adapters.mongo.MongoDatabaseInteraction.execute(MongoDatabaseInteraction.java:201)
at org.eclipse.persistence.eis.EISAccessor.basicExecuteCall(EISAccessor.java:163)
... 70 more
Caused by: org.bson.codecs.configuration.CodecConfigurationException: Can't find a codec for class org.eclipse.persistence.internal.helper.DatabaseField.
at org.bson.codecs.configuration.CodecCache.getOrThrow(CodecCache.java:46)
at org.bson.codecs.configuration.ProvidersCodecRegistry.get(ProvidersCodecRegistry.java:63)
at org.bson.codecs.configuration.ChildCodecRegistry.get(ChildCodecRegistry.java:51)
at com.mongodb.DBObjectCodec.writeValue(DBObjectCodec.java:231)
at com.mongodb.DBObjectCodec.encodeMap(DBObjectCodec.java:241)
at com.mongodb.DBObjectCodec.writeValue(DBObjectCodec.java:217)
at com.mongodb.DBObjectCodec.encodeIterable(DBObjectCodec.java:292)
at com.mongodb.DBObjectCodec.writeValue(DBObjectCodec.java:219)
at com.mongodb.DBObjectCodec.encode(DBObjectCodec.java:149)
at com.mongodb.DBObjectCodec.encode(DBObjectCodec.java:65)
at org.bson.codecs.BsonDocumentWrapperCodec.encode(BsonDocumentWrapperCodec.java:63)
at org.bson.codecs.BsonDocumentWrapperCodec.encode(BsonDocumentWrapperCodec.java:29)
at org.bson.codecs.EncoderContext.encodeWithChildContext(EncoderContext.java:91)
at org.bson.codecs.BsonDocumentCodec.writeValue(BsonDocumentCodec.java:136)
at org.bson.codecs.BsonDocumentCodec.encode(BsonDocumentCodec.java:115)
at org.bson.codecs.BsonDocumentCodec.encode(BsonDocumentCodec.java:41)
at com.mongodb.connection.RequestMessage.addDocument(RequestMessage.java:238)
at com.mongodb.connection.RequestMessage.addDocument(RequestMessage.java:188)
at com.mongodb.connection.CommandMessage.encodeMessageBodyWithMetadata(CommandMessage.java:154)
at com.mongodb.connection.RequestMessage.encode(RequestMessage.java:138)
at com.mongodb.connection.InternalStreamConnection.sendAndReceive(InternalStreamConnection.java:236)
at com.mongodb.connection.UsageTrackingInternalConnection.sendAndReceive(UsageTrackingInternalConnection.java:98)
at com.mongodb.connection.DefaultConnectionPool$PooledConnection.sendAndReceive(DefaultConnectionPool.java:441)
at com.mongodb.connection.CommandProtocolImpl.execute(CommandProtocolImpl.java:70)
at com.mongodb.connection.DefaultServer$DefaultServerProtocolExecutor.execute(DefaultServer.java:192)
at com.mongodb.connection.DefaultServerConnection.executeProtocol(DefaultServerConnection.java:264)
at com.mongodb.connection.DefaultServerConnection.command(DefaultServerConnection.java:126)
at com.mongodb.connection.DefaultServerConnection.command(DefaultServerConnection.java:118)
at com.mongodb.operation.CommandOperationHelper.executeWrappedCommandProtocol(CommandOperationHelper.java:226)
at com.mongodb.operation.CommandOperationHelper.executeWrappedCommandProtocol(CommandOperationHelper.java:217)
at com.mongodb.operation.CommandOperationHelper.executeWrappedCommandProtocol(CommandOperationHelper.java:120)
at com.mongodb.operation.FindOperation.call(FindOperation.java:717)
at com.mongodb.operation.FindOperation.call(FindOperation.java:711)
at com.mongodb.operation.OperationHelper.withConnectionSource(OperationHelper.java:471)
at com.mongodb.operation.OperationHelper.withConnection(OperationHelper.java:415)
at com.mongodb.operation.FindOperation.execute(FindOperation.java:711)
at com.mongodb.operation.FindOperation.execute(FindOperation.java:83)
at com.mongodb.client.internal.MongoClientDelegate$DelegateOperationExecutor.execute(MongoClientDelegate.java:140)
at com.mongodb.client.internal.MongoIterableImpl.execute(MongoIterableImpl.java:132)
at com.mongodb.client.internal.MongoIterableImpl.iterator(MongoIterableImpl.java:86)
at org.eclipse.persistence.internal.nosql.adapters.mongo.MongoDatabaseInteraction.execute(MongoDatabaseInteraction.java:173)
... 71 more
有谁知道为什么会出现这个错误。根据 EclipseLink 的文档,在使用 NoSQL 数据库时,它应该能够很好地处理继承:https://wiki.eclipse.org/EclipseLink/FAQ/NoSQL
搜索错误消息也没有得到明确的答案我的实施可能出了什么问题。
我还测试了一个没有继承的版本,提取网络服务工作正常。
此外,我测试了一个 AbstractClass
不是抽象 class 的实现,我收到了相同的错误消息,这表明这是继承的一般问题。
我还测试了一个变体,其中抽象 class 没有任何字段,提取工作按预期进行,但对象没有存储为 ABSTRACTCLASS
而是存储为 EXTENDEDCLASS
字段 mongoDB 这似乎表明继承部分有问题。
从其他 webapps 我也知道使用具有继承的 SQL 数据库不是问题所以我假设它已经对 mongoDB.
做了一些事情
所以我的问题是为什么会出现这个问题以及如何解决这个问题。
一如既往,我们将不胜感激。
[更新:] 回答引导我找到一个利用 @Inheritance
属性的可行解决方案。这就是我的摘要 class 对似乎正在为我的目的工作的时刻的看法:
@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
@NoSql(dataFormat=DataFormatType.MAPPED)
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public abstract class AbstractClass {
@Id
@Field(name="_id")
protected String id;
public String getId() {
return this.id;
}
}
你需要鉴别器。
@Entity
@NoSql(dataFormat=DataFormatType.MAPPED)
@DiscriminatorColumn(name = "type")
public abstract class AbstractClass {
@Id
@Field(name="_id")
protected String id;
public String getId() {
return this.id;
}
}
@Entity
@NoSql(dataFormat=DataFormatType.MAPPED)
@DiscriminatorValue("extended")
public class ExtendedClass extends AbstractClass {
@Basic
private String name;
public ExtendedClass() {
}
public ExtendedClass(String id, String name) {
this.id = id;
this.name = name;
}
public String getName() {
return this.name;
}
}
您可能还需要在@NoSql 中使用 dataType 设置集合名称。
我使用 @Inheritace
属性让它工作。这就是摘要 class 看起来知道哪个对我来说似乎是可行的解决方案:
@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
@NoSql(dataFormat=DataFormatType.MAPPED)
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public abstract class AbstractClass {
@Id
@Field(name="_id")
protected String id;
public String getId() {
return this.id;
}
}
我希望这是正确的做法。如果没有请告诉我。
我正在尝试使用 MongoDB 作为持久层使用 Jersey 设置 Web 应用程序。我的 JPA 框架是 EclipseLink。
我 运行 遇到了持久化对象的问题,classes 正在扩展其他(抽象)classes。
例如给定以下摘要class:
@Entity
@NoSql(dataFormat=DataFormatType.MAPPED)
public abstract class AbstractClass {
@Id
@Field(name="_id")
protected String id;
public String getId() {
return this.id;
}
}
并且这个扩展 class:
@Entity
@NoSql(dataFormat=DataFormatType.MAPPED)
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class ExtendedClass extends AbstractClass {
@Basic
private String name;
public ExtendedClass() {
}
public ExtendedClass(String id, String name) {
this.id = id;
this.name = name;
}
public String getName() {
return this.name;
}
}
这是我正在使用的persistence.xml
文件:
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
<persistence-unit name="persistence-unit" transaction-type="RESOURCE_LOCAL">
<class>org.example.webapp.resources.test.AbstractClass</class>
<class>org.example.webapp.resources.test.ExtendedClass</class>
<properties>
<property name="eclipselink.target-database" value="org.eclipse.persistence.nosql.adapters.mongo.MongoPlatform"/>
<property name="eclipselink.nosql.connection-spec" value="org.eclipse.persistence.nosql.adapters.mongo.MongoConnectionSpec"/>
<property name="eclipselink.nosql.property.mongo.port" value="27017"/>
<property name="eclipselink.nosql.property.mongo.host" value="ip-address"/>
<property name="eclipselink.nosql.property.mongo.db" value="database-name"/>
<property name="eclipselink.logging.level" value="FINEST"/>
</properties>
</persistence-unit>
</persistence>
以及创建并保存 ExtendedClass
:
@PUT
@Path("persist/extended-object")
@Consumes(MediaType.APPLICATION_JSON)
public String addObject(@QueryParam("name") final String name) {
final String id = UUID.randomUUID().toString();
ExtendedClass theObject = new ExtendedClass(id, name);
EntityManagerFactory emf = Persistence.createEntityManagerFactory("persistence-unit");
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
em.persist(theObject);
em.getTransaction().commit();
em.close();
return "Persisted object with name: " + name;
}
调用网络服务时:
http://localhost:8080/webapp/webapi/test/persist/extended-object?name=test-abstraction
我可以在 mongoDb 数据库中创建一个新条目,如下所示:
到目前为止一切顺利。但是,如果我尝试获取包含所有持久对象的列表,我 运行 就会遇到问题。这是示例网络服务:
@GET
@Path("get/all")
@Produces(MediaType.APPLICATION_JSON)
public List<ExtendedClass> getAllExtendedClasses() {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("persistence-unit");
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
List<ExtendedClass> extendedClassList = em.createQuery("SELECT a FROM ExtendedClass a", ExtendedClass.class).getResultList();
em.getTransaction().commit();
em.close();
return extendedClassList;
}
这会产生以下异常:
javax.resource.ResourceException: org.bson.codecs.configuration.CodecConfigurationException: Can't find a codec for class org.eclipse.persistence.internal.helper.DatabaseField.
完整堆栈跟踪:
Exception [EclipseLink-90000] (Eclipse Persistence Services - 2.5.0.v20130507-3faac2b): org.eclipse.persistence.eis.EISException
Internal Exception: javax.resource.ResourceException: org.bson.codecs.configuration.CodecConfigurationException: Can't find a codec for class org.eclipse.persistence.internal.helper.DatabaseField.
Error Code: 000
Call: Executing MappedInteraction()
spec => null
properties => {mongo.operation=FIND, mongo.collection=ABSTRACTCLASS}
input => [DatabaseRecord(
$and => [DatabaseRecord(
EXTENDEDCLASS._id => ABSTRACTCLASS._id), DatabaseRecord(
ABSTRACTCLASS.DTYPE => ExtendedClass)])]
Query: ReadAllQuery(referenceClass=ExtendedClass jpql="SELECT a FROM ExtendedClass a")
at org.eclipse.persistence.eis.EISException.resourceException(EISException.java:65)
at org.eclipse.persistence.eis.EISException.resourceException(EISException.java:74)
at org.eclipse.persistence.eis.EISException.resourceException(EISException.java:78)
at org.eclipse.persistence.eis.EISAccessor.basicExecuteCall(EISAccessor.java:212)
at org.eclipse.persistence.eis.EISAccessor.executeCall(EISAccessor.java:112)
at org.eclipse.persistence.internal.sessions.AbstractSession.basicExecuteCall(AbstractSession.java:1995)
at org.eclipse.persistence.sessions.server.ServerSession.executeCall(ServerSession.java:570)
at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.executeCall(DatasourceCallQueryMechanism.java:242)
at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.executeCall(DatasourceCallQueryMechanism.java:228)
at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.executeSelectCall(DatasourceCallQueryMechanism.java:299)
at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.selectAllRows(DatasourceCallQueryMechanism.java:694)
at org.eclipse.persistence.internal.queries.ExpressionQueryMechanism.selectAllRowsFromTable(ExpressionQueryMechanism.java:2714)
at org.eclipse.persistence.internal.queries.ExpressionQueryMechanism.selectAllRows(ExpressionQueryMechanism.java:2667)
at org.eclipse.persistence.queries.ReadAllQuery.executeObjectLevelReadQuery(ReadAllQuery.java:477)
at org.eclipse.persistence.queries.ObjectLevelReadQuery.executeDatabaseQuery(ObjectLevelReadQuery.java:1155)
at org.eclipse.persistence.queries.DatabaseQuery.execute(DatabaseQuery.java:899)
at org.eclipse.persistence.queries.ObjectLevelReadQuery.execute(ObjectLevelReadQuery.java:1114)
at org.eclipse.persistence.queries.ReadAllQuery.execute(ReadAllQuery.java:402)
at org.eclipse.persistence.queries.ObjectLevelReadQuery.executeInUnitOfWork(ObjectLevelReadQuery.java:1202)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.internalExecuteQuery(UnitOfWorkImpl.java:2894)
at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1797)
at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1779)
at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1744)
at org.eclipse.persistence.internal.jpa.QueryImpl.executeReadQuery(QueryImpl.java:258)
at org.eclipse.persistence.internal.jpa.QueryImpl.getResultList(QueryImpl.java:468)
at org.example.webapp.resources.test.ObjectWebServices.getAllExtendedClasses(ObjectWebServices.java:54)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.glassfish.jersey.server.model.internal.ResourceMethodInvocationHandlerFactory.lambda$static[=16=](ResourceMethodInvocationHandlerFactory.java:74)
at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.run(AbstractJavaResourceMethodDispatcher.java:144)
at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.invoke(AbstractJavaResourceMethodDispatcher.java:161)
at org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$TypeOutInvoker.doDispatch(JavaResourceMethodDispatcherProvider.java:247)
at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:99)
at org.glassfish.jersey.server.model.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:388)
at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:346)
at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:102)
at org.glassfish.jersey.server.ServerRuntime.run(ServerRuntime.java:337)
at org.glassfish.jersey.internal.Errors.call(Errors.java:271)
at org.glassfish.jersey.internal.Errors.call(Errors.java:267)
at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
at org.glassfish.jersey.internal.Errors.process(Errors.java:267)
at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:280)
at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:316)
at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:1084)
at org.glassfish.jersey.servlet.WebComponent.serviceImpl(WebComponent.java:418)
at org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:372)
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:389)
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:342)
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:229)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:219)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:506)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:142)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:610)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:537)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1081)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:658)
at org.apache.coyote.http11.Http11NioProtocol$Http11ConnectionHandler.process(Http11NioProtocol.java:222)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1566)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1523)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:745)
Caused by: javax.resource.ResourceException: org.bson.codecs.configuration.CodecConfigurationException: Can't find a codec for class org.eclipse.persistence.internal.helper.DatabaseField.
at org.eclipse.persistence.internal.nosql.adapters.mongo.MongoDatabaseInteraction.execute(MongoDatabaseInteraction.java:201)
at org.eclipse.persistence.eis.EISAccessor.basicExecuteCall(EISAccessor.java:163)
... 70 more
Caused by: org.bson.codecs.configuration.CodecConfigurationException: Can't find a codec for class org.eclipse.persistence.internal.helper.DatabaseField.
at org.bson.codecs.configuration.CodecCache.getOrThrow(CodecCache.java:46)
at org.bson.codecs.configuration.ProvidersCodecRegistry.get(ProvidersCodecRegistry.java:63)
at org.bson.codecs.configuration.ChildCodecRegistry.get(ChildCodecRegistry.java:51)
at com.mongodb.DBObjectCodec.writeValue(DBObjectCodec.java:231)
at com.mongodb.DBObjectCodec.encodeMap(DBObjectCodec.java:241)
at com.mongodb.DBObjectCodec.writeValue(DBObjectCodec.java:217)
at com.mongodb.DBObjectCodec.encodeIterable(DBObjectCodec.java:292)
at com.mongodb.DBObjectCodec.writeValue(DBObjectCodec.java:219)
at com.mongodb.DBObjectCodec.encode(DBObjectCodec.java:149)
at com.mongodb.DBObjectCodec.encode(DBObjectCodec.java:65)
at org.bson.codecs.BsonDocumentWrapperCodec.encode(BsonDocumentWrapperCodec.java:63)
at org.bson.codecs.BsonDocumentWrapperCodec.encode(BsonDocumentWrapperCodec.java:29)
at org.bson.codecs.EncoderContext.encodeWithChildContext(EncoderContext.java:91)
at org.bson.codecs.BsonDocumentCodec.writeValue(BsonDocumentCodec.java:136)
at org.bson.codecs.BsonDocumentCodec.encode(BsonDocumentCodec.java:115)
at org.bson.codecs.BsonDocumentCodec.encode(BsonDocumentCodec.java:41)
at com.mongodb.connection.RequestMessage.addDocument(RequestMessage.java:238)
at com.mongodb.connection.RequestMessage.addDocument(RequestMessage.java:188)
at com.mongodb.connection.CommandMessage.encodeMessageBodyWithMetadata(CommandMessage.java:154)
at com.mongodb.connection.RequestMessage.encode(RequestMessage.java:138)
at com.mongodb.connection.InternalStreamConnection.sendAndReceive(InternalStreamConnection.java:236)
at com.mongodb.connection.UsageTrackingInternalConnection.sendAndReceive(UsageTrackingInternalConnection.java:98)
at com.mongodb.connection.DefaultConnectionPool$PooledConnection.sendAndReceive(DefaultConnectionPool.java:441)
at com.mongodb.connection.CommandProtocolImpl.execute(CommandProtocolImpl.java:70)
at com.mongodb.connection.DefaultServer$DefaultServerProtocolExecutor.execute(DefaultServer.java:192)
at com.mongodb.connection.DefaultServerConnection.executeProtocol(DefaultServerConnection.java:264)
at com.mongodb.connection.DefaultServerConnection.command(DefaultServerConnection.java:126)
at com.mongodb.connection.DefaultServerConnection.command(DefaultServerConnection.java:118)
at com.mongodb.operation.CommandOperationHelper.executeWrappedCommandProtocol(CommandOperationHelper.java:226)
at com.mongodb.operation.CommandOperationHelper.executeWrappedCommandProtocol(CommandOperationHelper.java:217)
at com.mongodb.operation.CommandOperationHelper.executeWrappedCommandProtocol(CommandOperationHelper.java:120)
at com.mongodb.operation.FindOperation.call(FindOperation.java:717)
at com.mongodb.operation.FindOperation.call(FindOperation.java:711)
at com.mongodb.operation.OperationHelper.withConnectionSource(OperationHelper.java:471)
at com.mongodb.operation.OperationHelper.withConnection(OperationHelper.java:415)
at com.mongodb.operation.FindOperation.execute(FindOperation.java:711)
at com.mongodb.operation.FindOperation.execute(FindOperation.java:83)
at com.mongodb.client.internal.MongoClientDelegate$DelegateOperationExecutor.execute(MongoClientDelegate.java:140)
at com.mongodb.client.internal.MongoIterableImpl.execute(MongoIterableImpl.java:132)
at com.mongodb.client.internal.MongoIterableImpl.iterator(MongoIterableImpl.java:86)
at org.eclipse.persistence.internal.nosql.adapters.mongo.MongoDatabaseInteraction.execute(MongoDatabaseInteraction.java:173)
... 71 more
有谁知道为什么会出现这个错误。根据 EclipseLink 的文档,在使用 NoSQL 数据库时,它应该能够很好地处理继承:https://wiki.eclipse.org/EclipseLink/FAQ/NoSQL
搜索错误消息也没有得到明确的答案我的实施可能出了什么问题。
我还测试了一个没有继承的版本,提取网络服务工作正常。
此外,我测试了一个 AbstractClass
不是抽象 class 的实现,我收到了相同的错误消息,这表明这是继承的一般问题。
我还测试了一个变体,其中抽象 class 没有任何字段,提取工作按预期进行,但对象没有存储为 ABSTRACTCLASS
而是存储为 EXTENDEDCLASS
字段 mongoDB 这似乎表明继承部分有问题。
从其他 webapps 我也知道使用具有继承的 SQL 数据库不是问题所以我假设它已经对 mongoDB.
做了一些事情所以我的问题是为什么会出现这个问题以及如何解决这个问题。
一如既往,我们将不胜感激。
[更新:] @Inheritance
属性的可行解决方案。这就是我的摘要 class 对似乎正在为我的目的工作的时刻的看法:
@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
@NoSql(dataFormat=DataFormatType.MAPPED)
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public abstract class AbstractClass {
@Id
@Field(name="_id")
protected String id;
public String getId() {
return this.id;
}
}
你需要鉴别器。
@Entity
@NoSql(dataFormat=DataFormatType.MAPPED)
@DiscriminatorColumn(name = "type")
public abstract class AbstractClass {
@Id
@Field(name="_id")
protected String id;
public String getId() {
return this.id;
}
}
@Entity
@NoSql(dataFormat=DataFormatType.MAPPED)
@DiscriminatorValue("extended")
public class ExtendedClass extends AbstractClass {
@Basic
private String name;
public ExtendedClass() {
}
public ExtendedClass(String id, String name) {
this.id = id;
this.name = name;
}
public String getName() {
return this.name;
}
}
您可能还需要在@NoSql 中使用 dataType 设置集合名称。
我使用 @Inheritace
属性让它工作。这就是摘要 class 看起来知道哪个对我来说似乎是可行的解决方案:
@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
@NoSql(dataFormat=DataFormatType.MAPPED)
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public abstract class AbstractClass {
@Id
@Field(name="_id")
protected String id;
public String getId() {
return this.id;
}
}
我希望这是正确的做法。如果没有请告诉我。