Spring集成Hibernate,使用逆向工程生成的POJO类和DAO类

在一次使用了SSH的项目中,使用了hibernate逆向工程来生成POJO类和DAO类,非常的方便,但是刚开始使用的时候发现了一些小问题。

1.逆向工程自动生成的POJO类。

Hibernate可以根据每个不同的表的每个字段生成相应的属性。

如下:

public class Account extends com.common.bean.BasePojo implements
        java.io.Serializable {

    // Fields

    private Integer acId;
    private String acAccount;
    private String acPass;
    private Role role;
    private Date acLastTime;
    private Set peopleAccounts = new HashSet(0);

    // Constructors
    ....

    // Property accessors
    ....
}

省去部分方法,role属性为Role表的外键,peopleAccounts为其他表外键的集合。对应的hbm.xml表

....
<many-to-one name="role" class=text.Account" fetch="select">
            <column name="roleId" not-null="true">
                <comment>权限ID</comment>
            </column>
</many-to-one>

<set name="peopleAccounts" inverse="true">
            <key>
                <column name="AC_ID">
                    <comment>帐号密码ID</comment>
                </column>
            </key>
                <one-to-many class="text.PeopleAccount" />
        </set>

在这个POJO类和XML表中,逆向工程帮我们生成好了所有的属性,但是这也包括了一些我们不一定需要的属性。假设当前对象为A对象,set集合存放的是所有引用A对象的其它对象的集合,用B集合代替,B集合中的每一个对象都还会持有一个A对象,然后就是这样互相持有下去。如果需要将A对象转成json进行数据传输的话,一不小心就会出现大量冗余数据,甚至是

java.lang.StackOverflowError
	java.lang.Class.getClassLoader(Class.java:609)
	java.lang.Package.getPackage(Package.java:330)
	java.lang.Class.getPackage(Class.java:717)
	org.json.JSONObject.populateInternalMap(JSONObject.java:357)
	org.json.JSONObject.<init>(JSONObject.java:310)
	org.json.JSONObject.populateInternalMap(JSONObject.java:361)
	org.json.JSONObject.<init>(JSONObject.java:310)

爆栈了,也有可能是这里将设置了lazy="false"的原因。下次在讨论下懒加载机制。

所以一般情况下如果不是特别需要的话可以选择将这个A类中和xml表中的set集合去掉。

当然,如果需要在A对象里保持这个set集,那么我知道的方法一个就算将set集里面A对象的持有置空。(其他人有什么好的方法处理欢迎留言讨论。)

2.逆向工程生成的DAO类

public class AccountDAO extends HibernateDaoSupport {
    private static final Logger log = LoggerFactory.getLogger(AccountDAO.class);
    // property constants
    public static final String AC_ACCOUNT = "acAccount";
    public static final String AC_PASS = "acPass";

    protected void initDao() {
        // do nothing
    }

    public void save(Account transientInstance) {
        log.debug("saving Account instance");
        try {
            getHibernateTemplate().save(transientInstance);
            log.debug("save successful");
        } catch (RuntimeException re) {
            log.error("save failed", re);
            throw re;
        }
    }

    public void delete(Account persistentInstance) {
        ....
    }

    public Account findById(java.lang.Integer id) {
       ....
    }

    public List findByExample(Account instance) {
        ....
    }

    public List findByProperty(String propertyName, Object value) {
        ....
    }

    public List findByAcAccount(Object acAccount) {
        return findByProperty(AC_ACCOUNT, acAccount);
    }

    public List findByAcPass(Object acPass) {
        return findByProperty(AC_PASS, acPass);
    }

    public List findAll() {
        ....
    }



/** 
* 将传入的游离态的对象的属性复制到持久化对象中,并返回该持久化对象。 
* 如果该session中没有关联的持久化对象,加载一个,如果传入对象未保存,保存一个副本并作为持久对象返回,
*传入对象依然保持游离态。 
*/ 
    public Account merge(Account detachedInstance) {
       log.debug("merging Account instance");
        try {
            Account result = (Account) getHibernateTemplate().merge(
                    detachedInstance);
            log.debug("merge successful");
            return result;
        } catch (RuntimeException re) {
            log.error("merge failed", re);
            throw re;
        }
    }


/** 
* 将传入的对象持久化并保存。 
* 如果对象处于瞬时态,调用save方法保存。如果对象处于游离态,调用update方法将对象与Session重新关联。 
*/ 
    public void attachDirty(Account instance) {
        log.debug("attaching dirty Account instance");
        try {
            getHibernateTemplate().saveOrUpdate(instance);
            log.debug("attach successful");
        } catch (RuntimeException re) {
            log.error("attach failed", re);
            throw re;
        }
    }

/** 
* 将传入的对象状态设置为瞬时态 
*/ 
    public void attachClean(Account instance) {
        log.debug("attaching clean Account instance");
        try {
            getHibernateTemplate().lock(instance, LockMode.NONE);
            log.debug("attach successful");
        } catch (RuntimeException re) {
            log.error("attach failed", re);
            throw re;
        }
    }

    public static AccountDAO getFromApplicationContext(ApplicationContext ctx) {
        return (AccountDAO) ctx.getBean("AccountDAO");
    }
}

这是一个标准生成的DAO类,封装了几个基本常用的方法。在任何一个方法中,这个DAO类对数据库的操作都是使用了HibernateTemplate来完成的。所以如果为imen想要调用这些方法的话则需要这样的调用

ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
AccountDAO accountDAO = AccountDAO.getFromApplicationContext(ac);
accountDAO.XXXX();

因为Hibernate是由Spring托管的,所以需要先加载配置文件,然后根据配置文件中定义好的实体类bean,由Spring的Bean工厂生成DAO类实例。而如果直接new 出这个DAO类对象的话,会使

 getHibernateTemplate();

抛出空指针异常。

自动生成的merge(Account detachedInstance),  attachDirty(Account instance),  attachClean(Account instance)方法作用在注释中给出。


关于ApplicationContext和HibernateTemplate的学习可以参考以下网址

http://www.iteye.com/magazines/72  Spring的源码学习

http://blog.csdn.net/lufeng20/article/details/7314945 HibernateTemplate源码




转载于:https://my.oschina.net/kakakaka/blog/325412

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值