mig*_*ain 5 java rest jpa hypermedia spring-data-jpa
我正在开发一个RESTful webservice,其中spring-data作为其数据访问层,由JPA/Hibernate支持.在域实体之间建立关系是很常见的.例如,设想一个实体Product,其具有一个Category实体.
现在,当在客户端POSTSA Product表示到JAX-RS方法.该方法@Transactional用于在事务中包装每个存储库操作进行注释.当然,客户端只发送id一个已经存在的Category,而不是整个表示,只是一个引用(外键).
在那种方法中,如果我这样做:
entity = repository.save(entity);
Run Code Online (Sandbox Code Playgroud)
变量entity现在Category只有id字段集.这并没有让我感到惊讶.我没想到要保存(SQL插入)来检索相关对象的信息.但我需要整个Product对象和相关实体能够返回给用户.
然后我这样做了:
entity = repository.save(entity);
entity = repository.findOne(entity.getId());
Run Code Online (Sandbox Code Playgroud)
也就是说,在持久化之后,在同一个事务/会话中检索对象.
令我惊讶的是,变量entity没有改变任何东西.实际上,数据库甚至没有获得单个选择查询.这与Hibernate的缓存有关.出于某种原因,当在同一事务中时,如果该对象先前已持久化,则查找不会检索整个对象图.
使用Hibernate,解决方案似乎是使用session.refresh(entity)(参见本节和此).说得通.
但是如何通过弹簧数据实现这一目标?
我想避免创建重复的自定义存储库.我认为这个功能应该是spring数据的一部分(有些人已经在spring数据论坛中报告过:thread1,thread2).
太长了;博士
\n\nWeb 层中的实体之间的引用需要通过使用链接来明确,并且不应隐藏在半填充的对象实例后面。持久层中的引用由对象引用表示。因此,应该有一个专门的步骤将一个(链接)转换为另一个(完全填充的对象引用)。
\n\n细节
\n\n这是一种反模式,它会传递后端 id 并假设编组绑定做了正确的事情。因此,客户端应该使用链接并将这些链接交给服务器,以表明他们希望在现有资源和即将创建的资源之间建立连接。
\n\nCategory因此,假设您已经通过 暴露了现有的/categories/4711,您可以发布到您的服务器:
POST /products\n{ links : [ { rel : "category", href : "/categories/4711" } ],\n // further product data\n}\nRun Code Online (Sandbox Code Playgroud)\n\n服务器将实例化一个新Product实例,用附加数据填充它并最终填充关联,如下所示:
category此处的属性)。所以在你的例子中归结为:
\n\nProduct product = new Product();\n// populate primitive properties\nproduct.setCategory(categoryRepository.findOne(4711));\nproductRepository.save(product);\nRun Code Online (Sandbox Code Playgroud)\n\n只需将这样的内容发布到服务器即可:
\n\nPOST /products\n{ category : {\n id : 1, \xe2\x80\xa6 },\n \xe2\x80\xa6 \n}\nRun Code Online (Sandbox Code Playgroud)\n\n由于多种原因,它不是最理想的:
\n\nProduct实例,同时“认识到”所Category引用的实例(实际上仅包含 id)并不意味着要持久保存,而是要使用已存在的数据进行更新Category?我认为这有点神奇。| 归档时间: |
|
| 查看次数: |
1422 次 |
| 最近记录: |