DAO / repository:插入/更新后返回值的良好实践

12
虽然这可能是一个微不足道的问题,但我一直想知道。通常,在将数据插入到数据库后,返回业务实体的 ID 似乎是常见做法。
@Override
public Long createUser(UserEntity user) {
    em.merge(user); 
    em.flush(); 

    return user.getId(); 
}

返回id而不是业务对象本身的原因是否有说服力?

同样,我看到过update返回void,而它也可以返回id / User。

如果我要为其他人编写DAO / Repository,建议的返回值(如果有)是什么,以及为什么?


2
merge方法使传递的实体分离,将其状态复制到受管理的实体中并返回该受管理的实体。返回ID是无用的:调用者已经知道它,因为它在实体中传递了。调用者需要的是被创建或更新的受管理实体。 - JB Nizet
@JBNizet 谢谢,那很有道理。 - html_programmer
是的,重点在于合并命令返回合并后的实体对象。在我看来,这是最佳实践。只需返回由合并命令返回的UserEntity对象即可。原因是通常最好不要更改作为参数传递的对象。因此,您可能应该期望合并方法不会更改传递的对象。始终返回相同的未更改对象(或其部分),可能并没有那么有意义。 - Frank
4个回答

7
如果创建/更新成功,为什么不返回整个实例呢?就像Spring Data一样。
<S extends T> S save(S entity);
<S extends T> Iterable<S> save(Iterable<S> entities);
  1. 如果我需要创建/更新对象的另一个部分,除了id之外,我该怎么办?(例如对于User实体,namedate)。
  2. 如果有几个字段完全描述一个实例(组合主键),为什么会返回id

返回整个对象并不难(如@Danny Fonk所提到的,这里没有任何“额外开销”),但这样做可以节省您未来的时间。


1
根据我的经验,在插入过程中将id返回给业务实体是一种好的做法,因为该id可能对于继续业务流程非常有用,特别是对于新输入的记录而言。此外,在更新过程中,在更新记录之前我们会先获取实体,这意味着我们已经获得了id,因此不必返回id。

是的,但是关于插入(操作),如果在返回之前设置了 ID,则还会返回业务对象引用。对于更新部分达成一致! - html_programmer

1
我认为通常情况下返回ID是最好的做法。或者你也可以返回整个对象,但如果在创建后不需要再与其一起工作,这有点“过度”。在更新/修改数据库中的对象时,我们总是返回对象本身,或者最有可能只返回一个布尔值,表示更新是否成功,因为我们已经拥有了该对象。

1
如果您返回实体,则客户端代码将如下所示:
MyEntity e = ...;
MyEntity created = dao.create(e);

但是 "e" 和 "created" 是同一个对象。这可能会导致混淆。你可以认为在将来更改 create 方法的实现使其真正返回不同的实体。我见过这种情况。我不喜欢它。在我看来,这是一种可怕的持久化设计。
现在有一种情况,我认为返回 id 是一个好选择:如果你的 create 方法周围有一个事务边界(REQUIRES_NEW)。通过事务边界传递 id 而不是实体并不是坏事。

不确定为什么会出现这种情况。您只需将返回的实体引用原始实体即可...现在我想,甚至可以返回void(虽然那不是很明确),因为传递的是引用的副本,并且只需在dao中设置id即可。 - html_programmer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接