论坛首页 Java企业应用论坛

请教一个接口设计的问题

浏览 7621 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2007-01-08  
OO
对于持久化操作中的保存方法,设计成这样好呢:
public DomainObject saveDomainObject(DomainObject obj);

还是设计成这样好:
public void saveDomainObject(DomainObject obj);

给点建议。
   发表时间:2007-01-08  
可以这样
public ID saveDomainObject(DomainObject obj); 
返回产生的主键
0 请登录后投票
   发表时间:2007-01-08  
public void saveDomainObject(DomainObject obj); 
我喜欢这个,当然执行后obj中应该是更新的数据。

public DomainObject saveDomainObject(DomainObject obj); 
这个函数中返回的对象和传入的对象之间的关系不好定义。
0 请登录后投票
   发表时间:2007-01-08  
public void saveDomainObject(DomainObject obj);好些,而且obj应该被更新,拥有了一个数据库主键,因为可能有很多后续操作要用这个主键
0 请登录后投票
   发表时间:2007-01-08  
这两种操作实际上对应于 JSR-220 所定义的两种不同的原语的语义。

其中第一种是:
java 代码
 
  1. public void persist(Object entity);  
对应于JSR-220的 persist 语义,表示将 entity 持久化,而且把该对象与当前的context相关联。

第二种是:
java 代码
 
  1. public Object merge(Object entity);  
对应于JSR-220 的 merge 语义,表示把 entity 的状态复制到已经存在的 id 相同的 entity 中,并返回被持久化的对象,而原对象不与当前context相关。
0 请登录后投票
   发表时间:2007-01-08  
引用
kdekid: 这两种操作实际上对应于 JSR-220 所定义的两种不同的原语的语义

我就是为这件事烦恼呢。
现在对持久化中的Create和Update操作的普遍做法是合并到一个save方法里,在这个save()里面
根据某种机制(id是否为空)确定是调用persist或者merge(hibernate的merge扩展了JPA的
语义,替用户去做这个判断,不怎么对路阿)。那么,我们自己的save()怎么办?如果返回void,
在merge的情况下就必须去改变传入的参数;如果返回一个Object,那么在persist情况下又多了返回
值这样一道工序。或者C和U显示的分开到2个方法里?



0 请登录后投票
   发表时间:2007-01-08  
刑天战士 写道
public void saveDomainObject(DomainObject obj);好些,而且obj应该被更新,拥有了一个数据库主键,因为可能有很多后续操作要用这个主键

通常我也是这一种写法;
感觉更新后返回DomainObject有一些古怪的味道
0 请登录后投票
   发表时间:2007-01-08  
我通常是这样:

public int saveDomainObject(DomainObject obj); 
0 请登录后投票
   发表时间: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
}
0 请登录后投票
   发表时间: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。这个任务计划今天完成中。
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics