【转载】hibernate3.0+ejb3 annotaion配置实战+spring1.21 annotation事务控制
hibernate3.0+ejb3 annotaion配置实战+spring1.21 annotation事务控制
我是比较讨厌xml的人,没有强类型,很多配置出错,包括xdoclet都无法检查。刚好现在的主流框架总算开始支持annotation了,所以玩了一下配置,供参考:
hibernate3.05
hibernate-annotations-3.0beta2
spring1.21
几个配置文件如下:
spring-database.xml(这个文件基本不变,有新的dao在底下加入一行即可。
<?
xml version="1.0" encoding="UTF-8"
?>
<! DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd" >
< beans >
<!-- ========================= RESOURCE DEFINITIONS ========================= -->
< bean id ="dataSource" class ="org.apache.commons.dbcp.BasicDataSource" destroy-method ="close" >
< property name ="driverClassName" >< value > ${jdbc.driverClassName} </ value ></ property >
< property name ="url" >< value > ${jdbc.url} </ value ></ property >
< property name ="username" >< value > ${jdbc.username} </ value ></ property >
< property name ="password" >< value > ${jdbc.password} </ value ></ property >
</ bean >
< bean id ="sessionFactory" class ="org.springframework.orm.hibernate3.LocalSessionFactoryBean" >
< property name ="configurationClass" >< value > org.hibernate.cfg.AnnotationConfiguration </ value ></ property >
< property name ="dataSource" >< ref bean ="dataSource" /></ property >
< property name ="configLocation" >< value > /hibernate.cfg.xml </ value ></ property >
</ bean >
< bean id ="transactionManager" class ="org.springframework.orm.hibernate3.HibernateTransactionManager" >
< property name ="sessionFactory" >< ref bean ="sessionFactory" /></ property >
< property name ="dataSource" >< ref bean ="dataSource" /></ property >
</ bean >
< bean class ="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" />
< bean class ="org.springframework.transaction.interceptor.TransactionAttributeSourceAdvisor" >
< property name ="transactionInterceptor" >< ref bean ="transactionInterceptor" /></ property >
</ bean >
< bean id ="transactionInterceptor" class ="org.springframework.transaction.interceptor.TransactionInterceptor" >
< property name ="transactionManager" >< ref bean ="transactionManager" /></ property >
< property name ="transactionAttributeSource" >
< bean class ="org.springframework.transaction.annotation.AnnotationTransactionAttributeSource" />
</ property >
</ bean >
<!-- ========================= DAO DEFINITIONS ========================= -->
< bean id ="testDao" class ="org.steeven.TestDaoImpl" >
< property name ="sessionFactory" >
< ref bean ="sessionFactory" />
</ property >
</ bean >
<!-- ========================= DAO DEFINITIONS ========================= -->
<bean id="mitService" class="org.steeven.TestServiceImpl"></bean>
</ beans >
<! DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd" >
< beans >
<!-- ========================= RESOURCE DEFINITIONS ========================= -->
< bean id ="dataSource" class ="org.apache.commons.dbcp.BasicDataSource" destroy-method ="close" >
< property name ="driverClassName" >< value > ${jdbc.driverClassName} </ value ></ property >
< property name ="url" >< value > ${jdbc.url} </ value ></ property >
< property name ="username" >< value > ${jdbc.username} </ value ></ property >
< property name ="password" >< value > ${jdbc.password} </ value ></ property >
</ bean >
< bean id ="sessionFactory" class ="org.springframework.orm.hibernate3.LocalSessionFactoryBean" >
< property name ="configurationClass" >< value > org.hibernate.cfg.AnnotationConfiguration </ value ></ property >
< property name ="dataSource" >< ref bean ="dataSource" /></ property >
< property name ="configLocation" >< value > /hibernate.cfg.xml </ value ></ property >
</ bean >
< bean id ="transactionManager" class ="org.springframework.orm.hibernate3.HibernateTransactionManager" >
< property name ="sessionFactory" >< ref bean ="sessionFactory" /></ property >
< property name ="dataSource" >< ref bean ="dataSource" /></ property >
</ bean >
< bean class ="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" />
< bean class ="org.springframework.transaction.interceptor.TransactionAttributeSourceAdvisor" >
< property name ="transactionInterceptor" >< ref bean ="transactionInterceptor" /></ property >
</ bean >
< bean id ="transactionInterceptor" class ="org.springframework.transaction.interceptor.TransactionInterceptor" >
< property name ="transactionManager" >< ref bean ="transactionManager" /></ property >
< property name ="transactionAttributeSource" >
< bean class ="org.springframework.transaction.annotation.AnnotationTransactionAttributeSource" />
</ property >
</ bean >
<!-- ========================= DAO DEFINITIONS ========================= -->
< bean id ="testDao" class ="org.steeven.TestDaoImpl" >
< property name ="sessionFactory" >
< ref bean ="sessionFactory" />
</ property >
</ bean >
<!-- ========================= DAO DEFINITIONS ========================= -->
<bean id="mitService" class="org.steeven.TestServiceImpl"></bean>
</ beans >
hibernate.cfg.xml
<?
xml version="1.0" encoding="UTF-8"
?>
<! DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd" >
< hibernate-configuration >
< session-factory >
< property name ="hibernate.hbm2ddl.auto" > create-drop </ property >
< property name ="hibernate.dialect" > org.hibernate.dialect.MySQLDialect </ property >
< property name ="hibernate.cglib.use_reflection_optimizer" > true </ property >
< property name ="default-lazy" > false </ property >
<!-- 用于hibernate持久化的对象" -->
< mapping class ="org.steeven.Test" />
< listener type ="pre-update" class ="org.hibernate.validator.event.ValidatePreUpdateEventListener" />
< listener type ="pre-insert" class ="org.hibernate.validator.event.ValidatePreInsertEventListener" />
</ session-factory >
</ hibernate-configuration >
<! DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd" >
< hibernate-configuration >
< session-factory >
< property name ="hibernate.hbm2ddl.auto" > create-drop </ property >
< property name ="hibernate.dialect" > org.hibernate.dialect.MySQLDialect </ property >
< property name ="hibernate.cglib.use_reflection_optimizer" > true </ property >
< property name ="default-lazy" > false </ property >
<!-- 用于hibernate持久化的对象" -->
< mapping class ="org.steeven.Test" />
< listener type ="pre-update" class ="org.hibernate.validator.event.ValidatePreUpdateEventListener" />
< listener type ="pre-insert" class ="org.hibernate.validator.event.ValidatePreInsertEventListener" />
</ session-factory >
</ hibernate-configuration >
上面两个就是配置文件的全部了。下面看看代码:
TestDao.java(注意,就是个普通的dao,事务控制由调用者标注)
public
class
TestDaoImpl extends HibernateDaoSupport implements TestDao
{
public void save(Test data) {
getHibernateTemplate().saveOrUpdateAll(Arrays.asList(data));
}
}
public void save(Test data) {
getHibernateTemplate().saveOrUpdateAll(Arrays.asList(data));
}
}
@Entity
@Proxy(lazy = false )
public class Test {
int id;
String name;
Map<String, String> properties;
@Column(length = 100)
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Id(generate = GeneratorType.AUTO)
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@Transient
public String getNotStoredProp() {
return null;
}
@Type(type = "org.steeven.database.MapUserType")
@Column(name = "properties", length = 1000)
//Map暂时不被支持,自己持久化到一个大字段
public Map<String, String> getProperties() {
return properties;
}
public void setProperties(Map<String, String> properties) {
this.properties = properties;
}
}
@Proxy(lazy = false )
public class Test {
int id;
String name;
Map<String, String> properties;
@Column(length = 100)
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Id(generate = GeneratorType.AUTO)
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@Transient
public String getNotStoredProp() {
return null;
}
@Type(type = "org.steeven.database.MapUserType")
@Column(name = "properties", length = 1000)
//Map暂时不被支持,自己持久化到一个大字段
public Map<String, String> getProperties() {
return properties;
}
public void setProperties(Map<String, String> properties) {
this.properties = properties;
}
}
TestServiceImpl.java(这个类也是从spring中取得,关键就在@Transactional标记)
@Transactional
public class TestServiceImpl implements TestService {
public void save(Test data) {
TestDao dao = (TestDao)ServiceLocator.getInstance().getBean("testDao");
dao.save(data[0]);
if (true) throw new RuntimeException(); //看看数据库是不是什么都没有?!
dao.save(data[1]);
}
}
public class TestServiceImpl implements TestService {
public void save(Test data) {
TestDao dao = (TestDao)ServiceLocator.getInstance().getBean("testDao");
dao.save(data[0]);
if (true) throw new RuntimeException(); //看看数据库是不是什么都没有?!
dao.save(data[1]);
}
}
现在很清爽了,所有的事务控制只需要加几个@Transaction标记。感谢hibernate+spring
另外,hibernate还提供了基于标记的参数校验,请参考下面文档:
参考资源:
spring1.21自带smaples/jpetstore
http://www.hibernate.org/hib_docs/annotations/reference/en/html_single/