Crnk терпит неудачу при получении нулевого отношения один к одному - PullRequest
0 голосов
/ 08 июля 2019

Я пытаюсь сопоставить две сущности с хранилищем данных Google и запросить их через Crnk.

Все работает нормально, за исключением случая отношения один к одному, когда целью отношения является нуль.

@JsonApiResource(type = "drivers")
@Entity
public class Driver {
    @JsonApiId
    @Id
    private String id;

    private String name;

    private Ref<Car> car;

    @JsonApiRelation
    public Car getCar() {
        return this.car != null ? car.get() : null;
    }

    @JsonApiRelation
    public void setCar(Car car) {
        this.car = car != null ? Ref.create(car) : null;
    }

    // other getters and setters
}

@JsonApiResource(type = "cars")
@Entity
public class Car {
    @JsonApiId
    @Id
    private String id;

    private String brand;

    @JsonApiRelation
    public Engine getEngine() {
        return engine != null ? engine.get() : null;
    }

    public void setEngine(Engine engine) {
        this.engine = Ref.create(engine);
    }

    // other getters and setters
}

Я помещаю JsonApiRelation в методы, так как Crnk завершается ошибкой при непосредственном размещении в поле, я полагаю, из-за разницы между типами поля и методов доступа.

Соответствующая часть репозиториев выглядит следующим образом:

public class ObjectifyBasedRepository<TClass>
        extends ResourceRepositoryBase<TClass, String> {

    private Class<TClass> resourceClass;

    private Function<TClass, String> idGetter;
    private BiConsumer<TClass, String> idSetter;

    protected ObjectifyBasedRepository(
            Class<TClass> resourceClass,
            Function<TClass, String> idGetter,
            BiConsumer<TClass, String> idSetter) {
        super(resourceClass);

        this.resourceClass = resourceClass;
        this.idGetter = idGetter;
        this.idSetter = idSetter;
    }

    @Override
    // TODO: remove this method when the filters get implemented in findAll
    // (super.findOne impl simply adds a filter on the id)
    public TClass findOne(String id, QuerySpec queryspec) {
        TClass resource = OfyService.ofy()
                .load()
                .type(resourceClass).id(id)
                .now();

        return resource;
    }

    @Override
    public ResourceList<TClass> findAll(QuerySpec querySpec) {
        List<TClass> resourceList = OfyService.ofy()
                .load()
                .type(resourceClass)
                .list();

        ResourceList<TClass> resources =
                new DefaultResourceList<>(resourceList, null, null);

        return resources;
    }

    @Override
    public <S extends TClass> S save(S resource) {
        OfyService.ofy()
                .save()
                .entity(resource)
                .now();

        return resource;
    }

    // + create and delete
}

При запросе водителя, который владеет автомобилем, все идет хорошо, я могу получить водителя, перейти к машине, используя ссылки, приведенные в ответе, и т. Д. Но как только я пытаюсь получить драйвер, в котором driver.getCar() возвращает null, я получаю следующее исключение:

java.lang.NullPointerException
at io.crnk.core.engine.internal.utils.MultivaluedMap.getUnique(MultivaluedMap.java:46)
at io.crnk.core.engine.internal.utils.MultivaluedMap.getUnique(MultivaluedMap.java:41)
at io.crnk.core.repository.foward.ForwardingRelationshipRepository.findOneTarget(ForwardingRelationshipRepository.java:156)
at io.crnk.core.engine.internal.repository.RelationshipRepositoryAdapterImpl$5.invoke(RelationshipRepositoryAdapterImpl.java:183)
at io.crnk.core.engine.internal.repository.ResponseRepositoryAdapter$RepositoryRequestFilterChainImpl.doFilter(ResponseRepositoryAdapter.java:241)
at io.crnk.core.engine.internal.repository.RelationshipRepositoryAdapterImpl.findOneTarget(RelationshipRepositoryAdapterImpl.java:193)
at io.crnk.core.engine.internal.dispatcher.controller.RelationshipsResourceGet.handleAsync(RelationshipsResourceGet.java:50)
at io.crnk.core.engine.internal.dispatcher.controller.BaseController.handle(BaseController.java:48)
at io.crnk.core.engine.internal.http.DocumentFilterChainImpl.doFilter(DocumentFilterChainImpl.java:28)
at io.crnk.core.engine.internal.http.JsonApiRequestProcessor.processAsync(JsonApiRequestProcessor.java:159)
at io.crnk.core.engine.internal.http.JsonApiRequestProcessor.processAsync(JsonApiRequestProcessor.java:124)
at io.crnk.core.engine.internal.http.HttpRequestDispatcherImpl.process(HttpRequestDispatcherImpl.java:71)
at io.crnk.servlet.CrnkServlet.service(CrnkServlet.java:81)
at com.wizy.jsonapi.SampleCrnkServlet.service(SampleCrnkServlet.java:50)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:867)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1623)
at com.googlecode.objectify.ObjectifyFilter.doFilter(ObjectifyFilter.java:48)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1610)
at com.google.appengine.tools.development.ResponseRewriterFilter.doFilter(ResponseRewriterFilter.java:134)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1610)
at com.google.appengine.tools.development.HeaderVerificationFilter.doFilter(HeaderVerificationFilter.java:34)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1610)
at com.google.appengine.api.blobstore.dev.ServeBlobFilter.doFilter(ServeBlobFilter.java:63)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1610)
at com.google.apphosting.utils.servlet.TransactionCleanupFilter.doFilter(TransactionCleanupFilter.java:48)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1610)
at com.google.appengine.tools.development.jetty9.StaticFileFilter.doFilter(StaticFileFilter.java:123)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1610)
at com.google.appengine.tools.development.DevAppServerModulesFilter.doDirectRequest(DevAppServerModulesFilter.java:366)
at com.google.appengine.tools.development.DevAppServerModulesFilter.doDirectModuleRequest(DevAppServerModulesFilter.java:349)
at com.google.appengine.tools.development.DevAppServerModulesFilter.doFilter(DevAppServerModulesFilter.java:116)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1610)
at com.google.appengine.tools.development.DevAppServerRequestLogFilter.doFilter(DevAppServerRequestLogFilter.java:44)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1602)
at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:540)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:146)
at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:524)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132)
at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:257)
at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:1588)
at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:255)
at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1345)
at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:203)
at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:480)
at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1557)
at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:201)
at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1247)
at com.google.appengine.tools.development.jetty9.DevAppEngineWebAppContext.doScope(DevAppEngineWebAppContext.java:94)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:144)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132)
at com.google.appengine.tools.development.jetty9.JettyContainerService$ApiProxyHandler.handle(JettyContainerService.java:595)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132)
at org.eclipse.jetty.server.Server.handle(Server.java:502)
at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:364)
at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:260)
at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:305)
at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:103)
at org.eclipse.jetty.io.ChannelEndPoint$2.run(ChannelEndPoint.java:118)
at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.runTask(EatWhatYouKill.java:333)
at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.doProduce(EatWhatYouKill.java:310)
at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.tryProduce(EatWhatYouKill.java:168)
at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.produce(EatWhatYouKill.java:132)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:765)
at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:683)
at java.lang.Thread.run(Thread.java:748)

Я что-то упустил?

...