用 dropwizard 编写的简单待办应用程序后端 api 产生 500 错误

Simple todo app backend api written in dropwizard produces 500 error

我是 dropwizard 的新手,或者 java 就此而言。我正在尝试使用 dropwizard 创建一个简单的待办事项后端 api。我已经编写了一些代码,但在邮递员中测试时出现 500 错误。下面是我的代码:

代表 Class:

package com.todo.api.db;

import org.hibernate.annotations.NamedQueries;
import org.hibernate.annotations.NamedQuery;

import javax.persistence.*;

@Entity
@Table(name = "todo")
@NamedQueries({
        @NamedQuery(name = "com.todo.api.db.TodoModel.getAll", query = "select t from TodoModel t"),
        @NamedQuery(name = "com.todo.api.db.TodoModel.getById", query = "select t from TodoModel t where t.id = :id")
})
public class TodoModel {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;

    @Column(name = "task")
    private String task;

    @Column(name = "completed")
    private Boolean completed;

    @Column(name = "created_at")
    private String created_at;

    public TodoModel(String task, Boolean completed, String created_at) {
        this.task = task;
        this.completed = completed;
        this.created_at = created_at;
    }

    public String getTask(){
        return task;
    }

    public void setTask(String task){
        this.task = task;
    }

    public Boolean getCompleted(){
        return completed;
    }

    public void setCompleted(Boolean completed){
        this.completed = completed;
    }

    public String getCreated_at(){
        return created_at;
    }

    public void setCreated_at(String created_at){
        this.created_at = created_at;
    }

}

DAO class:

package com.todo.api.db;

import io.dropwizard.hibernate.AbstractDAO;
import org.hibernate.SessionFactory;

import java.util.List;

public class TodoDAO extends AbstractDAO<TodoModel> {
    public TodoDAO(SessionFactory factory) {
        super(factory);
    }

    public List<TodoModel> getAll(){
        return list(
                namedQuery("com.todo.api.db.TodoModel.getAll")
        );
    }

    public List<TodoModel> getById(){
        return list(
                namedQuery("com.todo.api.db.TodoModel.getById")
        );
    }
}

资源class:

package com.todo.api.resources;

import com.todo.api.db.TodoDAO;
import com.todo.api.db.TodoModel;
import io.dropwizard.jersey.params.LongParam;

import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import java.util.List;

@Path("/api")
@Produces(MediaType.APPLICATION_JSON)
public class HelloResource {

    private TodoDAO todoDao;

    public HelloResource(TodoDAO todoDao){
        this.todoDao = todoDao;
    }
    @GET
    public List<TodoModel> findAll(){
        return (todoDao.getAll());
    }

    @GET
    @Path("/{id}")
    public List<TodoModel> findId(@PathParam("id") LongParam id){
        return todoDao.getById();
    }

    @POST
    public List<TodoModel> postAll(@PathParam("id") LongParam id){
        return todoDao.getById();
    }


}

我遇到的错误:

ERROR [2019-04-23 08:44:08,864] io.dropwizard.jersey.errors.LoggingExceptionMapper: Error handling a request: b49aa01dcd315c8d
! org.hibernate.HibernateException: No session currently bound to execution context
! at org.hibernate.context.internal.ManagedSessionContext.currentSession(ManagedSessionContext.java:58)
! at org.hibernate.internal.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:464)
! at io.dropwizard.hibernate.AbstractDAO.currentSession(AbstractDAO.java:44)
! at io.dropwizard.hibernate.AbstractDAO.namedQuery(AbstractDAO.java:76)
! at com.todo.api.db.TodoDAO.getAll(TodoDAO.java:15)
! at com.todo.api.resources.HelloResource.findAll(HelloResource.java:22)
! 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.invoke(ResourceMethodInvocationHandlerFactory.java:81)
! 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:205)
! at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:99)
! at org.glassfish.jersey.server.model.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:389)
! at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:347)
! at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:102)
! at org.glassfish.jersey.server.ServerRuntime.run(ServerRuntime.java:326)
! 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:317)
! at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:305)
! at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:1154)
! at org.glassfish.jersey.servlet.WebComponent.serviceImpl(WebComponent.java:473)
! at org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:427)
! at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:388)
! at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:341)
! at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:228)
! at io.dropwizard.jetty.NonblockingServletHolder.handle(NonblockingServletHolder.java:49)
! at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1623)
! at io.dropwizard.servlets.ThreadNameFilter.doFilter(ThreadNameFilter.java:35)
! at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1610)
! at io.dropwizard.jersey.filter.AllowedMethodsFilter.handle(AllowedMethodsFilter.java:45)
! at io.dropwizard.jersey.filter.AllowedMethodsFilter.doFilter(AllowedMethodsFilter.java:39)
! at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1610)
! at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:540)
! 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.handler.ScopedHandler.nextScope(ScopedHandler.java:201)
! at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1247)
! at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:144)
! at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132)
! at com.codahale.metrics.jetty9.InstrumentedHandler.handle(InstrumentedHandler.java:239)
! at io.dropwizard.jetty.RoutingHandler.handle(RoutingHandler.java:52)
! at org.eclipse.jetty.server.handler.gzip.GzipHandler.handle(GzipHandler.java:753)
! at io.dropwizard.jetty.BiDiGzipHandler.handle(BiDiGzipHandler.java:67)
! at org.eclipse.jetty.server.handler.RequestLogHandler.handle(RequestLogHandler.java:56)
! at org.eclipse.jetty.server.handler.StatisticsHandler.handle(StatisticsHandler.java:174)
! 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.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.run(EatWhatYouKill.java:126)
! at org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:366)
! at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:765)
! at org.eclipse.jetty.util.thread.QueuedThreadPool.run(QueuedThreadPool.java:683)
! at java.lang.Thread.run(Thread.java:748)
0:0:0:0:0:0:0:1 - - [23/Apr/2019:08:44:08 +0000] "GET /api/ HTTP/1.1" 500 110 "-" "PostmanRuntime/7.11.0" 4

有人可以修复代码以便 api 工作吗?提前致谢!

编辑1: 我似乎已经通过在资源 class 中的请求方法中添加 @unitofWork 注释来解决上述错误。但我现在有一个新问题。当我尝试从邮递员那里执行 GET 或 POST 请求时,我得到一个空列表“[]”。为什么我得到这个?我该如何解决这个问题,以便我可以获得 JSON 的列表,而不仅仅是一个空列表?

编辑2: 我已经添加了一个答案并记录了我到目前为止的进展。我仍在尝试使 POST 请求生效。任何帮助都会很棒..

所以我对我的代码进行了以下更改..

我的 model/representation class: 添加了一个空的构造函数。

package com.todo.api.db;

import org.hibernate.annotations.NamedQueries;
import org.hibernate.annotations.NamedQuery;

import javax.persistence.*;

@Entity
@Table(name = "todo")
@NamedQueries({
        @NamedQuery(name = "com.todo.api.db.TodoModel.getAll", query = "select t from TodoModel t"),
        @NamedQuery(name = "com.todo.api.db.TodoModel.getById", query = "select t from TodoModel t where t.id = :id")
})
public class TodoModel {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;

    @Column(name = "task")
    private String task;

    @Column(name = "completed")
    private Boolean completed;

    @Column(name = "created_at")
    private String created_at;

    public TodoModel(){
    }

    public TodoModel(String task, Boolean completed, String created_at) {
        this.task = task;
        this.completed = completed;
        this.created_at = created_at;
    }

    public String getTask(){
        return task;
    }

    public void setTask(String task){
        this.task = task;
    }

    public Boolean getCompleted(){
        return completed;
    }

    public void setCompleted(Boolean completed){
        this.completed = completed;
    }

    public String getCreated_at(){
        return created_at;
    }

    public void setCreated_at(String created_at){
        this.created_at = created_at;
    }

}

对 DAO 进行了以下更改 class:

package com.todo.api.db;

import io.dropwizard.hibernate.AbstractDAO;
import org.hibernate.Criteria;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.Restrictions;

import java.util.List;

public class TodoDAO extends AbstractDAO<TodoModel> {
    public TodoDAO(SessionFactory factory) {
        super(factory);
    }

    public TodoModel create(TodoModel todoModel){
        return persist(todoModel);
    }

    public List<TodoModel> getAll(){
        final Criteria c = criteria();
        List results = c.list();
        return results;
    }
    public TodoModel getById(Long id){
        final Criteria c = criteria();
        c.add(Restrictions.eq("id", id));

        final List<TodoModel> todoModels = c.list();

        return todoModels.get(0);

    }
}

并对资源进行以下更改 class:

package com.todo.api.resources;

import com.todo.api.db.TodoDAO;
import com.todo.api.db.TodoModel;
import io.dropwizard.hibernate.UnitOfWork;

import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import java.util.List;

@Path("/api")
@Produces(MediaType.APPLICATION_JSON)
public class HelloResource {

    private TodoDAO todoDao;

    public HelloResource(TodoDAO todoDao){
        this.todoDao = todoDao;
    }

    @GET
    @UnitOfWork
    public List<TodoModel> findAll(){
        return (todoDao.getAll());
    }

    @GET
    @UnitOfWork
    @Path("/{id}")
    public TodoModel findId(@PathParam("id") Long id)
    {
        return todoDao.getById(id);

    }

    @POST
    @UnitOfWork
    public TodoModel post(TodoModel todoModel)
    {

        return todoDao.create(todoModel);
    }


}