我正在考虑如何处理我的域对象以及hibernate,考虑以下因素:
然而,我正在考虑改进我所知道的,以便减少一点复杂性,或者至少将这种复杂性重新安置在一个更适合的地方,比如实体的相关服务。可能更抽象的是我使用ORM的事实。
这是一个通用的CRUD服务,我的所有业务服务都从该服务继承。此代码用于向您展示当前的工作方式(注释,为清晰起见,删除日志):
public void create(T entity) {
this.entityManager.persist(entity);
}
@Transactional(value = TxType.REQUIRED, rollbackOn=NumeroVersionException.class)
public void update(T entity) throws NumeroVersionException{
try{
this.entityManager.merge(entity);
}catch(OptimisticLockException ole){
throw new NumeroVersionException("for entity "+entity, ole);
}
}
public T read(int id) {
return this.entityManager.find(entityClass, id);
}
public void delete(int id) {
T entity = this.entityManager.getReference(entityClass, id);
this.entityManager.remove(entity);
// edit : removed null test thanks to @JBNizet
}
这种实现的问题在于,如果我想创建一个对象,那么使用代理的优点我基本上必须创建它然后重新获取它。当然,查询可能不会访问数据库,但只能访问hibernat的缓存(尽管不确定)。但这意味着我仍然不得不忘记重新获取代理。
这意味着我泄漏了我在幕后使用ORM和代理的事实。
所以我想把我的界面改为:
public T read(int id);
public T update(T t)throws NumeroVersionException;
public T create(T object);
public void delete(int id);
List<T> list();
含义一旦我将对象传递给该层,我将不得不使用返回的值。 并实现更新,如:
public T update(T t){
if(!(t instanceof [Proxy class goes there])){
//+ check if it is a detached proxy
entityManager.merge(t);
}
}
由于合并每次调用时都会访问数据库,对于某些仅涉及10个实体的操作,这可能很烦人,我不会在使用代理的更新方法中调用它。
当然我希望有一些边缘情况,我需要使用entityManager来刷新东西,等等。但我认为这会显着降低我的代码的当前复杂性,并更好地隔离问题。
我简单地尝试在服务中重新定位ORM代码,这样我就可以隐藏我使用ORM和代理并使用接口的事实,就像我正在使用任何其他实现一样失去使用ORM的好处。
问题是:
注意:尽管我在谈论性能,但我关心的还是关注那些与我合作的ORM和Java不熟悉的开发人员的关注点,可维护性以及更容易使用的问题。
答案 0 :(得分:0)
感谢@JBNizet,我更清楚地看到了一些事情:
所以我只是从原始代码更改我的更新方法,我将保留其余的。