我试图建立一个dropwizard项目,但我卡住了。当我尝试使用@GetGeneratedKeys获取自动生成的id字段时,会出现以下异常:
org.postgresql.util.PSQLException: Bad value for type long : foo.
请求是一个简单的JSON请求
{"name":"foo"}
插入数据库是成功的,但似乎语句返回的是名称的值,而不是生成的id。如何解决这个问题?
我使用postgresql,表项目包含一个带有nextval的主键字段“id”(“project_id_seq”::regclass)。下面是我使用的POJO、DAO和资源类:
public class Project {
private long id;
private String name;
public Project() { // Jackson deserialization }
public Project(long id, String name) {
this.id = id;
this.name = name;
}
...
}
@RegisterMapper(ProjectMapper.class)
public interface ProjectDAO {
@SqlUpdate("insert into project (name) values (:name)")
@GetGeneratedKeys
public long insert(@Bind("name") String name);
}
@Path("/project")
@Consumes({MediaType.APPLICATION_JSON})
@Produces({MediaType.APPLICATION_JSON})
public class ProjectResource {
ProjectDAO projectDAO;
public ProjectResource(ProjectDAO personDAO) {
this.projectDAO = personDAO;
}
@POST
@Timed
public Response add(@Valid Project project) {
long newId = projectDAO.insert(project.getName());
project.setId(newId);
return Response.status(Response.Status.CREATED)
.entity(project).build();
}
}
===============
更新
我刚刚发现这与我的id列不是表中的第一列有关。列名为。出现此问题的原因是@GetGeneratedKeys使用的是org.skife.jdbi.v2.sqlobject.FigureItOutResultSetMapper,它使用的是org.skife.jdbi.v2.PrimitivesMapperFactory,后者返回的是org.skife.jdbi.v2.util.LongMapper.FIRST。这个映射器正在调用
java.sql.ResultSet.getLong(1)通过方法extractByIndex(…)来检索生成的id,在我的例子中,这不是id。。。
我将通过重新组织数据库中的列来解决这个问题,但如果可能的话,我希望有一个健壮的实现:在使用@GetGeneratedKeys注释时,是否有方法指定I d列的列名?(org.skife.jdbi.v2.util.LongMapper类还包含一个名为extractByName(…)的方法)
最佳答案
这是jdbi实现中的一个问题,在较新版本中已修复,如https://github.com/jdbi/jdbi/issues/114中所述