`

Creating DAOs with Hibernate 3.5 & JPA 2.0 Annotations

阅读更多

Creating Good DAOs with Hibernate 3.5 and JPA 2.0 Annotations

In previous tutorials, we configured a 3.5 environment for development and testing, and went through the steps of persisting a very simple POJO, named the GameSummary, to the database. We even created a little class, named the HibernateCrudRunner, that went through the process of creating a persistent object, updating that object, querying that object, and finally, deleting that object. Yeah, it was a pretty awesome tutorial. 

But the problem with the application code was that it made direct calls to the Hibernate Session, and the transaction management was inconsistent and messy. In production applications, you want to minimize the exposure your client applications have to the internal workings of your persistence mechanism, and the best way to do that is to create fairly generic Data Access Object. And that's exactly what I'm going to do here.

By the way, you can find a really awesome and advanced tutorial on creating DAOs right here: Coding Advanced DAOs with Hibernate and JPA Annotations - The Pattern Our DAOs are going to be pretty awesome in their own right, but that tutorial goes really in depth about DAOs and the Factory Pattern and such. Once you've mastered this tutorial, you'll be ready to really advance your knowledge of DAOs by heading over there. But first things first, and with that saying in mind, the first thing we need is a generic interface for our DAOs:

The Very Generic GameSummaryDAO Interface

Our GameSummaryDAO will simply define four methods: save, delete, findByPrimaryKey and findAll.


package com.mcnz.dao;

import java.io.*;
import java.util.*;

public interface GameSummaryDAO < T, ID extends Serializable >{

 T save( T entity);
 void delete( T entity);  
 T findByPrimaryKey( ID id);
 List < T > findAll();

}


We've thrown around a few generics in there, namely the T and the ID. Basically, this will simply ensure that every DAO is associated with a serializable primary key (ID), and a specific Java class (T). For this application, our ID will be of type Long, and of course, our associated Java class is the GameSummary class.

You can see how in the class declaration of the HiberanteGameSummaryDAO how the ID and T attributes are provided concrete values:


package com.mcnz.dao;

import java.util.*;
import org.hibernate.*;
import com.mcnz.model.*;

public class HibernateGameSummaryDAO implements GameSummaryDAO <GameSummary, Long > {

}


Implementation Code In, Transaction Details Out

Now, the rule for creating DAOs is that you keep implementation details inside of them so that the implementation isn't exposed to the client. And even more importantly, you keep transaction details outside of them. I can't tell you how many times I've seen people starting and stopping transactions inside of a DAO method. That is wrong, wrong, wrong, wrong wrong! "Implementation code in, transaction details  out," that should be your mantra when coding DAOs. Since we're using Hibernate, the key Hibernate component each DAO needs is a SessionFactory. So, you'll need to declare a SessionFactory instance, define a setter method for that SessionFactory, and also declare a constructor that takes a SessionFactory as an argument. We'll also add in a default constructor, just for fun, but be warned, if someone calls this default constructor and doesn't set a fully mature SessionFactory into that DAO after it is created, you'll be in a world of NullPointerException hurt.


public class HibernateGameSummaryDAO implements GameSummaryDAO <GameSummary, Long>{

  private SessionFactory sessionFactory = null;

  public void setSessionFactory (SessionFactory sessionFactory) {
    this.sessionFactory = sessionFactory;
  }

  public HibernateGameSummaryDAO() {}

  public HibernateGameSummaryDAO (SessionFactory sessionFactory) {
    setSessionFactory(sessionFactory);
  }

}


Implementing & Overriding the Inherited Methods

With the pleasantries of coding a constructor and declaring our SessionFactory instance, we can go ahead and implement the findAll, findByPrimaryKey, save and delete methods. There's really nothing too interesting about them; they simply invoke the corresponding method on the Hibernate Session, each of which we spoke about in the previous tutorial. Here's the completed class, import statements and all:

package com.mcnz.dao;

import java.util.List;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;

import com.mcnz.model.GameSummary;

public class HibernateGameSummaryDAO implements GameSummaryDAO <GameSummary, Long>{

  private SessionFactory sessionFactory = null;

  public void setSessionFactory(SessionFactory sessionFactory) {
    this.sessionFactory = sessionFactory;
  }

  public HibernateGameSummaryDAO(){}
  public HibernateGameSummaryDAO(SessionFactory sessionFactory){
    setSessionFactory(sessionFactory);
  }

  @Override
  public List findAll() {
    Session session = sessionFactory.getCurrentSession();
    Query queryResult = session.createQuery("from GameSummary");
    return queryResult.list();
  }

  @Override
  public GameSummary findByPrimaryKey(Long id) {
    Session session = sessionFactory.getCurrentSession();
    Object o = session.load(GameSummary.class, id);
    return (GameSummary)o;
  }

  @Override
  public GameSummary save(GameSummary entity) {
    Session session = sessionFactory.getCurrentSession();
    session.saveOrUpdate(entity);
    return entity;
  }

  @Override
  public void delete(GameSummary entity) {
    sessionFactory.getCurrentSession().delete(entity);
  }

}


There are a few interesting changes I have made when compared to a previous tutorial. First of all, I used saveOrUpdate in the save method, rather than having separate create and update methods. With the saveOrUpdate method, Hibernate will create a new representation for any entity it is passed that doesn't have a propery primary key, aka id field. If the entity passed in does have an id field, Hibernate will simply perform an update.

Also, I used the load method in the findByPrimaryKey method, as opposed to the get method. The load method is a bit easier on the database, as it doesn't load in every piece of data about the entity, but it does open the door for LazyLoadingExceptions down the road. I typically use get instead of load, but I thought I'd just demonstrate the load method here for andragogal purposes. Here's a more in depth look at the differences between the two methods: The Difference Between the Hibernate Session's Load and Get Methods

Using a DAO in Client Applications

So, we have our DAO. Now all we need is a client application to call it.

I'm going to create a simple little class called the CrudRunnerDAO that will have a simple main method. Since our DAO needs a SessionFactory, the first thing we'll need to do is create a SessionFactory. Once the SessionFactory is created, we create an instance of our DAO by feeding it to the HibernateGameSummaryDAO's constructor.


package com.mcnz.dao;

import org.hibernate.*;
import org.hibernate.cfg.*;
import com.mcnz.model.*;

public class CrudRunnerDAO {

  public static void main(String[] args) {

    /* Initialize the Hibernate Environment */
    AnnotationConfiguration config = new AnnotationConfiguration();
    config.addAnnotatedClass(GameSummary.class);
    config.configure();
    SessionFactory sessionFactory = config.buildSessionFactory();

    /* Create the DAO, passing in the SessionFactory */
    GameSummaryDAO dao = new HibernateGameSummaryDAO(sessionFactory);

    /* more to come!!! */

  }

}


Adding Records with the DAO

With the DAO created and properly initialized, we can go ahead and create instances and save them to the database. Notice that while the DAO takes care of the actual saving and persisting of the data, the client application is responsible for demarcating the transaction.


/* Create a record and keep track of its assigned id */
Long id = null;
{
GameSummary gs = new GameSummary();
gs.setResult("tie");
System.out.println(gs);
sessionFactory.getCurrentSession().beginTransaction();
dao.save(gs);
id = gs.getId();
sessionFactory.getCurrentSession().getTransaction().commit();
System.out.println(gs);
}


Loading and Updating a Record with the Hibernate DAO

The previous code snippet held onto the unique primary key the database assigned our entity when it was saved to the datastore. Using this id, we will now fetch the entity that was just saved. Note that we can do this, as the previous transaction has finished, and because of the placement of the curly braces, the GameSummary instance that was created earlier is now out of scope. 


/* Find and update the created record that has gone out of scope */
sessionFactory.getCurrentSession().beginTransaction();
GameSummary gs = (GameSummary) dao.findByPrimaryKey(id);
gs.setResult("win");
sessionFactory.getCurrentSession().getTransaction().commit();


Querying the Database

After updating the record, we do a fully query on the database using the findAll method of the DAO. We print out each record returned from this query, and notice that the record with our current id has had the result property updated from a tie to a win .

Deleting a Record from the Database Using the Hibernate DAO

Finally, we delete the record we created from the database. When this transaction is complete, we create another transaction, and print out a findAll query from the database. As this query runs, we will see that the record that we created at the beginning of this method has been permanently deleted.

分享到:
评论

相关推荐

    Spring_JPA_JSF2.0 示例

    综上所述,Spring_JPA_JSF2.0 示例演示了如何将Spring框架的依赖注入和事务管理能力,与JPA的ORM功能,以及JSF2.0的用户界面组件和处理机制结合,实现一个完整的CRUD应用。这样的组合为开发人员提供了一个高效且易于...

    HIbernate Jpa 生成entities

    标题“Hibernate JPA 生成entities”涉及到的是Java开发中的一个重要话题,主要关于如何利用Hibernate的Java Persistence API(JPA)来自动创建数据访问对象(DAOs),也称为实体(Entities)。这个过程通常被称为...

    Struts1.2+Spring2.0+Hibernate3搭建框架例子

    Struts1.2、Spring2.0和Hibernate3是经典的Java Web开发框架组合,被称为SSH框架。这个框架集成示例提供了在项目中整合这三个组件的方法,以实现模型-视图-控制器(MVC)架构,增强应用的可维护性和可扩展性。 ...

    DAOS技术手册.docx

    DAOS技术手册 DAOS(Distributed Asynchronous Object Storage)是一种分布式异步对象存储系统,旨在提供高性能、可靠、可扩展的存储解决方案。下面是DAOS技术手册中的一些重要概念和技术点: 一、Architecture ...

    daos.zip_daos层

    "daos.zip_daos层"这个标题暗示了我们关注的是一个关于DAOS层的代码压缩包,可能包含了一系列与学生信息管理相关的数据操作类。 DAOS层的主要职责是提供对数据库的一系列操作接口,如添加(Add)、删除(Delete)、...

    CXF接口Spring+Hibernate的添加完整版

    在这里,Spring负责管理CXF服务的生命周期,同时通过Spring的IoC(Inversion of Control)容器管理Hibernate的数据访问对象(DAOs),确保服务和数据层之间的解耦。 3. **Hibernate**:Hibernate是一个强大的ORM...

    DAOS_A_Scale-Out_High_Performance_Storage_Stack_fo.pdf

    DAOS分布式异步对象存储系统 DAOS(Distributed Asynchronous Object Storage)是一种开源的分布式存储系统,旨在支持 Storage Class Memory(SCM)和 NVMe 存储在用户空间中。其高级存储 API 支持结构化、半结构化...

    dextraining_2015_contas-jpa:使用JPAHibernate的实现示例的项目。 从16092015到01102015教授的课程

    《使用JPA与Hibernate进行数据库操作的实战指南》 在IT行业中,数据库操作是不可或缺的一环,尤其是在开发大型企业级应用时。Java平台提供了一种强大的工具——Java Persistence API(JPA),它允许开发者以面向...

    DISTRIBUTED ASYNCHRONOUS OBJECT STORAGE (DAOS)

    此外,DAOS还可能利用Intel的Turbo Boost Technology 2.0来动态调整频率,进一步提升性能。 4. **高性能**:DAOS针对特定的计算机系统、组件、软件、操作和功能进行了基准测试,例如SYSmark和MobileMark,以展示其...

    myeclipse中自动生成hibernate的POJO、DAO和hbm.xml文件

    MyEclipse中自动生成Hibernate的POJO、DAO和hbm.xml文件 MyEclipse是一款功能强大且流行的集成开发环境(IDE),它提供了许多实用的功能来帮助开发者快速构建和维护项目。其中,MyEclipse提供了对Hibernate的支持,...

    daos:DAOS存储引擎

    达奥斯 请在我们的提交问题什么是DAOS? 所述d istributed一种同步öbject小号torage(DAOS)是一个开放源码软件定义的对象存储从根本上针对大规模分布的非易失性存储器(NVM)设计的。 DAOS利用诸如存储类内存(SCM...

    Java -- 在Eclipse上使用Hibernate

    - 如果只需要实体类,可以在 `Project -&gt; Properties -&gt; Hibernate Synchronizer -&gt; DataAccess Objects` 中取消勾选 “I would like to have DAOs created for me”。 ### 6. 配置映射资源 映射资源是指在`...

    如何设置和使用附件合并功能(DAOS).

    【Lotus Domino DAOS 设置与使用详解】 IBM Lotus Domino 的 Domino 附件和对象服务(DAOS,Domino Attachment and Object Service)是一种优化存储空间管理的功能,它通过合并和共享附件来减少邮件和文档存储的...

    cxf+spring+hibernate集成整合jar包

    Hibernate支持JPA(Java Persistence API)标准,并提供了高级特性,如缓存、事务管理和查询语言(HQL)。 **集成过程** 集成CXF、Spring和Hibernate时,通常会按照以下步骤进行: 1. **配置Spring**:首先,需要...

    spring mvc2.5+hibernate3.0 整合jar

    2. 配置Spring MVC:创建Spring的配置文件(如`app-config.xml`),配置DispatcherServlet、Controller beans、Data Access Objects(DAOs)以及Hibernate的SessionFactory。同时,还需要配置Hibernate的`hibernate....

    Struts2.3.16.1Hibernate4.3.4Spring4.0.2_框架

    Hibernate4.3.4版本提供了更高效的缓存机制、增强了对JPA的支持以及对最新数据库系统的优化,使得数据库操作更为便捷和高效。 Spring框架是一个全面的企业级应用开发框架,不仅包含了IoC(Inversion of Control)...

    Lotus Domino 8.5中的DAOS备份和恢复

    "Lotus Domino 8.5中的DAOS备份和恢复" DAOS(DatabaseAnchor Object Storage)是一种基于磁盘的附件存储机制,旨在提高 Lotus Domino 服务器的存储效率和可扩展性。DAOS 通过将附件存储在独立的文件中,而不是存储...

Global site tag (gtag.js) - Google Analytics