锁定老帖子 主题:请教一个接口设计的问题
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2007-01-08
public DomainObject saveDomainObject(DomainObject obj); 还是设计成这样好: public void saveDomainObject(DomainObject obj); 给点建议。 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2007-01-08
可以这样
public ID saveDomainObject(DomainObject obj); 返回产生的主键 |
|
返回顶楼 | |
发表时间:2007-01-08
public void saveDomainObject(DomainObject obj);
我喜欢这个,当然执行后obj中应该是更新的数据。 public DomainObject saveDomainObject(DomainObject obj); 这个函数中返回的对象和传入的对象之间的关系不好定义。 |
|
返回顶楼 | |
发表时间:2007-01-08
public void saveDomainObject(DomainObject obj);好些,而且obj应该被更新,拥有了一个数据库主键,因为可能有很多后续操作要用这个主键
|
|
返回顶楼 | |
发表时间:2007-01-08
这两种操作实际上对应于 JSR-220 所定义的两种不同的原语的语义。
其中第一种是: java 代码
第二种是: java 代码
|
|
返回顶楼 | |
发表时间:2007-01-08
引用 kdekid: 这两种操作实际上对应于 JSR-220 所定义的两种不同的原语的语义
我就是为这件事烦恼呢。 现在对持久化中的Create和Update操作的普遍做法是合并到一个save方法里,在这个save()里面 根据某种机制(id是否为空)确定是调用persist或者merge(hibernate的merge扩展了JPA的 语义,替用户去做这个判断,不怎么对路阿)。那么,我们自己的save()怎么办?如果返回void, 在merge的情况下就必须去改变传入的参数;如果返回一个Object,那么在persist情况下又多了返回 值这样一道工序。或者C和U显示的分开到2个方法里? |
|
返回顶楼 | |
发表时间:2007-01-08
刑天战士 写道 public void saveDomainObject(DomainObject obj);好些,而且obj应该被更新,拥有了一个数据库主键,因为可能有很多后续操作要用这个主键
通常我也是这一种写法; 感觉更新后返回DomainObject有一些古怪的味道 |
|
返回顶楼 | |
发表时间:2007-01-08
我通常是这样:
public int saveDomainObject(DomainObject obj); |
|
返回顶楼 | |
发表时间:2007-01-08
uiafzhdl 写道 引用 kdekid: 这两种操作实际上对应于 JSR-220 所定义的两种不同的原语的语义
我就是为这件事烦恼呢。 现在对持久化中的Create和Update操作的普遍做法是合并到一个save方法里,在这个save()里面 根据某种机制(id是否为空)确定是调用persist或者merge(hibernate的merge扩展了JPA的 语义,替用户去做这个判断,不怎么对路阿)。那么,我们自己的save()怎么办?如果返回void, 在merge的情况下就必须去改变传入的参数;如果返回一个Object,那么在persist情况下又多了返回 值这样一道工序。或者C和U显示的分开到2个方法里? 假设你要保存的 bean 是 A,如果你要改变 A,使 A 被 JPA 管理,则用 persist;如果希望 A 不被 JPA 管理,而返回新的被管理的 bean B,则需要用 merge。而且 A 的 id 所指的 entity 在 store 中必须存在。 Hibernate 的 merge 并无扩展 JSR-220 的语义。 这是 hibernate 的 merge 的具体 code:(DefaultMergeEventListener) public void onMerge(MergeEvent event, Map copyCache) throws HibernateException { final EventSource source = event.getSession(); final Object original = event.getOriginal(); if ( original != null ) { final Object entity; if ( original instanceof HibernateProxy ) { LazyInitializer li = ( (HibernateProxy) original ).getHibernateLazyInitializer(); if ( li.isUninitialized() ) { log.trace("ignoring uninitialized proxy"); event.setResult( source.load( li.getEntityName(), li.getIdentifier() ) ); return; 由于 Session.load 保证了 bean 必须存在,否则抛出异常,因此 merge 的语义是没有改变的。 BTW,我自己基本是一律用 persist 的,基本的框架是: public void update( Model model ) { int id = model.getId(); Bean bean = null; if (id != null) { bean = session.get(Bean.class, id, LockMode.UPGRADE); if (bean == null) throw new ServiceException("id xx does not exist."); } else { bean = new Bean(); } // copy model's properties to bean // FIXME... you should actually do it session.persist(bean); // session.flush(); if it would not be automatically flushed } |
|
返回顶楼 | |
发表时间:2007-01-09
to kdekid:
这是 hibernate 的 merge 的具体 code:(DefaultMergeEventListener) onMerge()的代码还得往下看啊,接下来hibernate 的persist对DETACHED,TRANSIENT,PERSISTENT 做了区分的。 另外在Hibernate Annotation的手册3.7节有说: The merge operation is clever enough to automatically detect whether the merging of the detached instance has to result in an insert or update. 我现在的想法是这样实现: public void saveObject(Object obj) { if (obj.getId() == null) getEntityManager().persist(obj); else getEntityManager().merge(obj); } 这样就和Hibernate中大家早已熟悉的saveOrUpdate一样了:无论是Create还是Update,参数obj都得到了 我们期望中的更新。现在唯一的问题是obj.getId() == null这句话, 因为我们不能保证实体类的标识一定是id,也许叫其他名字呢。我的想法是,在使用Annotation的情况 下,通过@Id和@EmbeddedId这两个注解,找到真实的Id方法,由此判断传入的实体是否需要persist or merge。这个任务计划今天完成中。 |
|
返回顶楼 | |