【发布时间】:2011-05-15 19:04:07
【问题描述】:
我正在开发一个带有 Web 界面的相当简单的 CRUD 应用程序。我在持久层中使用通用 DAO 模式。我的通用 DAO 的界面如下所示:
public interface GenericDAO<T> {
void create( T entity ) throws CannotPersistException;
T findById( Long id ) throws NotFoundException;
Collection<T> findAll();
void update( T entity ) throws CannotPersistException, NotFoundException;
void delete( Long id ) throws CannotPersistException, NotFoundException;
}
这个接口是使用 JPA 实现的,但我也有一个内存实现,主要用于测试目的。 我在持久层中没有任何其他类,我只是为每个域类创建此 DAO 的一个实例。
我面临的问题是如何正确地持久化一个对象,该对象具有对其他也需要持久化的对象的引用。 我知道 JPA 中的级联可以解决这个问题,而无需我向我的持久层添加新类。 但是,这会使我依赖于特定的实现(并且还会破坏我的内存中 DAO 实现) )。
没错,我正在使用服务层来管理 DAO 类,我通过使用多个 DAO 来解决问题。我将展示一个示例:
public class PlayerServiceImpl implements PlayerService {
private GenericDAO<Player> playerDAO;
private GenericDAO<Club> clubDAO;
//constructor ommited
public Player addNewPlayer( Player player, Long clubId ) throws NotFoundException,
CannotPersistException {
Club club = clubDAO.findById( clubId );
player.setClub( club );
playerDAO.create( player );
club.addPlayer( player );
clubDAO.update( club );
return player;
}
//... other methods
}
这种方法的第一个缺点是它使我的领域模型乏力 - 大多数方法只是 getter 和 setter,大部分业务逻辑都在服务层中。
我在测试应用程序时发现了另一个缺点 - 如果我想使用其集合字段填充有 Player 对象的 Club 对象,我无法真正单独测试 GenericDao 类。
我需要先持久化 Player 对象,以便将其添加到 Club 对象,以便将其传递给正在测试的 GenericDao。
我一直在翻阅 Fowler 的 PoEAA 书籍以寻找解决方案,但我有点困惑像 Hibernate 这样的 O/R 框架是否适合他描述的模式。
【问题讨论】:
标签: design-patterns orm architecture dao