1:实体类代码
package com.cn.edu; public class Account { private long id; private int version; private String accountId; private String accountName; private float balance; public long getId() { return id; } public void setId(long id) { this.id = id; } public int getVersion() { return version; } public void setVersion(int version) { this.version = version; } public String getAccountId() { return accountId; } public void setAccountId(String accountId) { this.accountId = accountId; } public String getAccountName() { return accountName; } public void setAccountName(String accountName) { this.accountName = accountName; } public float getBalance() { return balance; } public void setBalance(float balance) { this.balance = balance; } }
映射文件:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN" "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd"> <hibernate-mapping> <class name="com.cn.edu.Account" table="accounts" optimistic-lock="version"> <id name="id" type="java.lang.Long"> <column name="id"/> <generator class="native" /> </id> <version name="version" column="version" type="java.lang.Integer" /> <property name="accountId" type="java.lang.String"> <column name="account_id" length="32"/> </property> <property name="accountName" type="java.lang.String"> <column name="account_name" length="30"/> </property> <property name="balance" type="java.lang.Float"> <column name="balance" sql-type="float"/> </property> </class> </hibernate-mapping>
2:操作数据库的类AccountDao
package com.cn.edu.dao; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.Transaction; import org.hibernate.cfg.Configuration; import com.cn.edu.Account; public class AccountDao { public SessionFactory sf = new Configuration().configure().buildSessionFactory(); public Session getSession() { return sf.openSession(); } public void closeSession(Session session) { } public void createAccount(Account account) { Session session = this.getSession(); Transaction tx = session.beginTransaction(); tx.begin(); try { session.save(account); tx.commit(); } catch(Exception e) { tx.rollback(); e.printStackTrace(); } finally { if(session != null) { session.close(); session = null; } } } public void updateAccount(Account account) { Session session = this.getSession(); Transaction tx = session.beginTransaction(); tx.begin(); try { session.saveOrUpdate(account); tx.commit(); } catch(Exception e) { tx.rollback(); e.printStackTrace(); } finally { if(session != null) { session.close(); session = null; } } } public Account getAccountById(long id) { Session session = this.getSession(); Account account = (Account)session.get(Account.class, id); if(session != null) { session.close(); session = null; } return account; } }
3:测试代码
package com.cn.edu.dao; import com.cn.edu.Account; public class AccountDaoTest { private static AccountDao accountDao = new AccountDao(); public static void testCreateAccount() { Account account = new Account(); account.setAccountName("Test"); account.setBalance(new Float(1000)); account.setAccountId("571-123456"); accountDao.createAccount(account); } public static void updateAccount() { Account account = accountDao.getAccountById(1l); account.setBalance(new Float(2000)); accountDao.updateAccount(account); } public static void main(String args[]) { //testCreateAccount(); updateAccount(); } }
testCreateAccount能够正常进行,下面我们测试并发问题,即有多个客户端修改数据时,我们在accountDao.updateAccount(account)处设置
断点,当进行到此处时,我们把数据库里id为1的记录的version值修改为更大的值,然后单步执行,这时会报一个异常,如下图所示:
这时不能更改成功,有org.hibernate.StaleObjectStateException,在web程序中需要catch该异常,并进行相应的处理