在我的项目中,我有两个领域模型。父实体和子实体。父对象引用子对象的列表。(如帖子和评论)这两个实体都有他们的spring数据JPACrudepository
HTTP GET和PUT操作工作正常,并返回这些模型的良好HATEOS表示。
现在我需要一个特殊的RESTendpoint“创建一个引用一个或多个现有子实体的新父实体”。我想在请求的正文中以文本/uri-list的形式发布对孩子的引用,如下所示:
POST http://localhost:8080/api/v1/createNewParent
HEADER
Content-Type: text/uri-list
HTTP REQUEST BODY:
http://localhost:8080/api/v1/Child/4711
http://localhost:8080/api/v1/Child/4712
http://localhost:8080/api/v1/Child/4713
如何实现此Rest终结点?这是我目前所尝试的:
@Autowired
ParentRepo parentRepo // Spring Data JPA repository for "parent" entity
@RequestMapping(value = "/createNewParent", method = RequestMethod.POST)
public @ResponseBody String createNewParentWithChildren(
@RequestBody Resources<ChildModel> childList,
PersistentEntityResourceAssembler resourceAssembler
)
{
Collection<ChildModel> childrenObjects = childList.getContent()
// Ok, this gives me the URIs I've posted
List<Link> links = proposalResource.getLinks();
// But now how to convert these URIs to domain objects???
List<ChildModel> listOfChildren = ... ???? ...
ParentModel newParnet = new ParentModel(listOfChildren)
parentRepo.save(newParent)
}
参考/相关https://github.com/spring-projects/spring-hateoas/issues/292
我也有同样的问题。这个问题有点老,但我找到了另一个解决方案:
事实上,您必须在父级上强制合并,但在创建时调用peris。您可以通过使用空的子列表保存父项,将子项添加到列表中,然后再次保存:
List<ChildModel> listOfChildren = ... ???? ...
ParentModel newParnet = new ParentModel()
parent = parentRepo.save(newParent)
parent.getChilds().addAll(listOfChildren)
parentRepo.save(parent)
要有权合并,您必须对自定义回购进行编码:
public interface PollModelRepositoryCustom {
public PollModel merge(PollModel poll);
}
及其实施
@Repository
public class PollModelRepositoryCustomImpl implements PollModelRepositoryCustom {
@PersistenceContext
private EntityManager entityManager;
public PollModel merge(PollModel poll) {
return entityManager.merge(poll);
}
}
然后,您可以调用:括号回购。(new家长)
而不是括号epo.save(new家长)
另一个需要考虑的相关问题是:当我想保存父实体时,我不想以任何方式触摸、保存或更改已经存在的子实体。这在JPA中并不容易。因为JPA还将(尝试)保留从属子实体。此操作失败,但有一个例外:
javax.persistence.PersistenceException: org.hibernate.PersistentObjectException: detached entity passed to persist:
为了避免这种情况,必须将子实体合并到jpasave()调用的transactin中。我发现在一个事务中有两个实体的唯一方法是创建一个单独的@Services,标记为@Transactional。看起来完全是过度的杀戮和过度的冒险。
这是我的密码:
波尔控制器。java//父实体的自定义RESTendpoint
@BasePathAwareController
public class PollController {
@RequestMapping(value = "/createNewPoll", method = RequestMethod.POST)
public @ResponseBody Resource createNewPoll(
@RequestBody Resource<PollModel> pollResource,
PersistentEntityResourceAssembler resourceAssembler
) throws LiquidoRestException
{
PollModel pollFromRequest = pollResource.getContent();
LawModel proposalFromRequest = pollFromRequest.getProposals().iterator().next(); // This propsal is a "detached entity". Cannot simply be saved.
//jpaContext.getEntityManagerByManagedType(PollModel.class).merge(proposal); // DOES NOT WORK IN SPRING. Must handle transaction via a seperate PollService class and @Transactional annotation there.
PollModel createdPoll;
try {
createdPoll = pollService.createPoll(proposalFromRequest, resourceAssembler);
} catch (LiquidoException e) {
log.warn("Cannot /createNewPoll: "+e.getMessage());
throw new LiquidoRestException(e.getMessage(), e);
}
PersistentEntityResource persistentEntityResource = resourceAssembler.toFullResource(createdPoll);
log.trace("<= POST /createNewPoll: created Poll "+persistentEntityResource.getLink("self").getHref());
return persistentEntityResource; // This nicely returns the HAL representation of the created poll
}
PollService。java//用于事务处理
@Service
public class PollService {
@Transactional // This should run inside a transaction (all or nothing)
public PollModel createPoll(@NotNull LawModel proposal, PersistentEntityResourceAssembler resourceAssembler) throws LiquidoException {
//===== some functional/business checks on the passed enties (must not be null etc)
//[...]
//===== create new Poll with one initial proposal
log.debug("Will create new poll. InitialProposal (id={}): {}", proposal.getId(), proposal.getTitle());
PollModel poll = new PollModel();
LawModel proposalInDB = lawRepo.findByTitle(proposal.getTitle()); // I have to lookup the proposal that I already have
Set<LawModel> linkedProposals = new HashSet<>();
linkedProposals.add(proposalInDB);
poll.setProposals(linkedProposals);
PollModel savedPoll = pollRepo.save(poll);
return savedPoll;
}
我正在尝试为实体创建一个域模型(聚合),该实体包含子实体,并且可以有父实体。我们有实体包。我们可以把包裹分成更小的包裹(儿童)。每个分开的包都有一个父包。域的哪个部分应该包含域逻辑:聚合还是域服务?e、 g.聚合包有一个方法 分包还是原包?解决这个问题的正确方法是什么? 我希望我的域模型被ddd(应用程序和基础设施)的其他部分保持干净和幂等
假设我在前面有一个表单,它有常用的字段和下拉列表。在这些下拉列表中,用户可以选择一个选项,并且每个选项都链接到Spring data JPA中的一个实体; 下拉列表包含一些标签和对应实体的链接作为值。然后,这个值在POST-request中传递给我们希望创建的实体的PagingAndSorting存储库。 假设它是一个具有username的用户,并且他必须与其中一个办公室(也是一个实体)关联: 我
我在代码优先的情况下使用EF,我有这样的模型: 我收到一个客户ID和一个产品ID列表。当产品在数据库中不存在时,我想添加它: 问题是EF试图级联更改并尝试插入一个新的对象,其ID与现有对象相同,因此失败。我如何解决这个问题? 这是插入方法:
我的问题很简单,但找到解决办法却成了一项相当乏味和困难的任务。 我有两个冬眠实体, (或“父”实体)有三个字段, (实体的集合-关系)。 当从的集合中删除时(从对象的集合中删除和通过Dog存储库从数据库中删除),以及更新所有者的地址,然后尝试将更新后的对象保存到数据库中,将引发以下异常: 解决这个问题的一种方法是,在更新集合后,通过使用调用所有者的,获取的新版本,然后更新所有者的地址并将实体保存到
我很好奇,在JPA/Hibernate的父实体中,是否可能有几个相同实体的@manytone关系。 示例:我有银行交易,每笔交易都有一个银行合作伙伴,分别担任债权人和债务人。关键是,我只想编辑一次数据。昵称为“情妇”的银行合作伙伴只有一个:),无论是债权人还是债务人。一旦,它将重命名为妻子,所以我不想单独更改。此外,余额是BankPartners在这两个角色中的所有交易的总和。 @实体公共类事务{