【问题标题】:java hibernate BO passing foreign key as DAO parameter (architecture design)java hibernate BO将外键作为DAO参数传递(架构设计)
【发布时间】:2013-04-16 18:42:25
【问题描述】:

我遇到了以下架构问题(文字很长,但是对于有经验的 java 开发人员来说应该很容易解决):

我正在学习 Java,并且正在开发一个使用 Hibernate 的简单数据库应用程序。有人建议我使用BO 和 DAO 模式来访问数据库。简而言之,DAO 是 HQL/ORM 层(创建、获取、更新、删除等),业务对象执行更抽象的逻辑内容(根据某些条件检索所有记录、获取总和等)。

我想通过 BO/DAO 在树中创建或移动节点。每个节点都有它的父节点,并用 hibernate 映射如下:

@Entity
@Table(name = "category")
public class Category {

    @ManyToOne
    @JoinColumn(name="parent_id")
    private Category parent;

    public Category getParent() {
        return parent;
    }

    public void setParent(Category parent) {
        this.parent = parent;
    }

现在,我希望 BO 能够 createmove 类别对象,这些方法采用 id 参数:

public abstract void createCategory(int parent_id, String name, CategoryType type);
public abstract void moveCategory(int category_id, int new_parent_id);

在实现上述BO方法时,我正在尝试使用hibernate的session.load来延迟加载外键关系:

session.load(Category.class, parent_id)

内部:

public void createCategory(int parent_id, String name, CategoryType type) {
    Category category = new Category();
    category.setName(name);
    category.setParent(session.load(Category.class, parent_id));
    category.setType(type);
    this.categoryDao.save(category);
}

DAO 应该保持休眠会话(准确地说,是抽象 DAO 接口的 DAO-休眠实现),但没有其他类应该知道存在任何类似于休眠会话的东西。特别是,BO 不应该对休眠会话有任何引用。并且上面的代码无法编译(session未知)。

我的问题是 - 我犯了什么错误,应该如何设计它既有用/有弹性/又优雅?我是否应该提供一个Category::setParentId() 方法来临时存储父节点 ID,并且 - 在执行 DAO 的创建/更新时 - 检查它是否已设置并相应地处理?或者也许有更好的解决方案?

【问题讨论】:

  • 能否请您发布完整的堆栈跟踪

标签: java hibernate orm


【解决方案1】:

您应该将您的方法标记为@Transactional(在 xml 设置中添加事务支持)。然后在 dao 中创建 2 个方法:getCategorysaveCategory(你已经有了 - save)并在业务层使用 dao 方法但不使用 hibernate session 进行操作。

@Transactional
public void createCategory(int parent_id, String name, CategoryType type) {
...
}

【讨论】:

    【解决方案2】:

    以下模式应该可以帮助您: 举个例子,如果有一个业务特性在 Foo 表上运行。

    通用 DAO

    @Repository
    public abstract class DAO<T>
    {
        @Autowired
        SessionFactory factory;
    
        /**
        * Some sample generic methods
        */
        public Session getCurrentSession()
        {
            return factory.getCurrentSession();
        }
    
        public void create(T record) {
            getCurrentSession().save(record);
        }
    
        public void update(T record) {
            getCurrentSession().update(record);
        }
    
        public void delete(T record) {
            getCurrentSession().delete(record);
        }
    
        public T get(Class<T> clazz, Integer id) {
            return (T) getCurrentSession().get(clazz, id);
        }
    
        /**
        * Rest of the generic dao methods follow
        */
    }
    

    通用 BO

    @Transactional
    public abstract class BO<T>
    {
        public abstract DAO<T> getDAO();
    
        /**
        * Some sample generic methods
        */
        public abstract void create(T record);
    
        public abstract void update(T record);
    
        public abstract void delete(T record);
    
        public abstract T get(Class<T> clazz, Integer id);
    
        /**
        * Rest of the generic business methods follow
        */
    }
    

    特定的 DAO

    @Transactional
    @Repository
    public FooDAO extends DAO<Foo>
    {
    }
    

    特定的 BO

    @Transactional
    public FooBO extends BO<Foo>
    {
        @AutoWired
        FooDAO dao;
    
        @Override
        public DAO<Foo> getDAO() 
        {
            return dao;
        }
    
        @Override 
        public void create(T record){ 
            dao.create(record);
        }
    
        @Override 
        public void update(T record) { 
            dao.update(record);
        }
    
        @Override 
        public void delete(T record) { 
            dao.delete(record); 
        }
    
        @Override 
        public T get(Class<T> clazz, Integer id) { 
            return dao.get(Foo.class, id); 
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2013-02-02
      • 2019-07-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-24
      • 1970-01-01
      • 2010-09-26
      • 1970-01-01
      相关资源
      最近更新 更多