2016-09-27 130 views
1

所以我试图使用Spring Data JPA来使用存储库接口来创建一些其他服务。但我坚持要做一些事情,而不必创建自定义控制器。Spring Data JPA和PUT请求创建

假设此服务只接受PUT和GET请求。 PUT请求用于创建和更新资源。所以这个ID就是客户端生成的。

实体和存储库将是这样的:

@Entity 
public class Document { 
    @Id 
    private String name; 
    private String text; 
     //getters and setters 
} 

@RepositoryRestResource(collectionResourceRel = "documents", path = "documents") 
public interface DocumentRepository extends PagingAndSortingRepository<Document, String> { 
} 

当我尝试做一个PUT请求@本地:8080 /文件/富与以下机构:

{ 
    "text": "Lorem Ipsum dolor sit amet" 
} 

我得到这个消息:

{ 
    "timestamp": 1474930016665, 
    "status": 500, 
    "error": "Internal Server Error", 
    "exception": "org.springframework.orm.jpa.JpaSystemException", 
    "message": "ids for this class must be manually assigned before calling save(): hello.Document; nested exception is org.hibernate.id.IdentifierGenerationException: ids for this class must be manually assigned before calling save(): hello.Document", 
    "path": "/documents/foo" 
} 

所以我在给全身:

{ 
    "name": "foo", 
    "text": "Lorem Ipsum dolor sit amet" 
} 

所以它返回创建与

{ 
    "text": "Lorem Ipsum dolor sit amet", 
    "_links": { 
    "self": { 
     "href": "http://localhost:8080/documents/foo" 
    }, 
    "document": { 
     "href": "http://localhost:8080/documents/foo" 
    } 
    } 
} 

201是否有可能使PUT,而无需发送ID(name字段)JSON身体里面?既然我已经在URI中发送它了?

我知道我可以使用/documents/{document.name}创建一个RestController和一些requestmapping,并在保存之前使用它来设置名称字段,但我想知道是否有任何注释或某些东西。

回答

2

你可以只保存之前定义@HandleBeforeCreate/@HandleBeforeSave方法来改变模式:

@Component 
@RepositoryEventHandler(Document.class) 
public class DocumentBeforeSave { 
    @Autowired 
    private HttpServletRequest req; 

    @HandleBeforeCreate 
    public void handleBeforeSave(Document document) { 
     if("PUT".equals(req.getMethod())){ 
      String uri = req.getRequestURI(); 
      uri = uri.substring(uri.lastIndexOf('/') + 1); 
      document.setName(uri); 
     } 
    } 
} 
  • 因为身体不包含任何ID(在这一点),这两个POSTPUT将触发@HandleBeforeCreate方法(如果主体包含idPUT请求宁愿触发@HandleBeforeSave)。
  • 在分配id(为了让POST主体不变)之前,我们需要检查RequestMethod是否为PUT
  • HttpServletRequest作为代理注入,可以被多个线程使用。阅读它:Can't understand `@Autowired HttpServletRequest` of spring-mvc well
+0

非常感谢!我期待着HandleBeforeCreate,但不知道如何注入并获取URI :) –