【发布时间】:2013-02-24 09:07:51
【问题描述】:
我是 Spring 世界的新手,我开发了一个使用 Spring 3.2.1 和 Hibernate 4.1.9 来实现 DAO 的简单项目。该项目工作正常,但我对在此 DAO 的 CRUD 方法上使用 @Transactional Spring 注释有一些疑问。
这是实现我项目的CRUD操作的类的全部代码:
package org.andrea.myexample.HibernateOnSpring.dao;
import java.util.List;
import org.andrea.myexample.HibernateOnSpring.entity.Person;
import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.ServiceRegistryBuilder;
import org.springframework.transaction.annotation.Transactional;
public class PersonDAOImpl implements PersonDAO {
// Factory per la creazione delle sessioni di Hibernate:
private static SessionFactory sessionFactory;
// Metodo Setter per l'iniezione della dipendenza della SessionFactory:
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
/** CREATE CRUD Operation:
* Aggiunge un nuovo record rappresentato nella tabella rappresentato
* da un oggetto Person
*/
@Transactional(readOnly = false)
public Integer addPerson(Person p) {
System.out.println("Inside addPerson()");
Session session = sessionFactory.openSession();
Transaction tx = null;
Integer personID = null;
try {
tx = session.beginTransaction();
personID = (Integer) session.save(p);
tx.commit();
} catch (HibernateException e) {
if (tx != null)
tx.rollback();
e.printStackTrace();
} finally {
session.close();
}
return personID;
}
// READ CRUD Operation (legge un singolo record avente uno specifico id):
public Person getById(int id) {
System.out.println("Inside getById()");
Session session = sessionFactory.openSession();
Transaction tx = null;
Person retrievedPerson = null;
try {
tx = session.beginTransaction();
retrievedPerson = (Person) session.get(Person.class, id);
tx.commit();
}catch (HibernateException e) {
if (tx != null)
tx.rollback();
e.printStackTrace();
} finally {
session.close();
}
return retrievedPerson;
}
// READ CRUD Operation (recupera la lista di tutti i record nella tabella):
@SuppressWarnings("unchecked")
public List<Person> getPersonsList() {
System.out.println("Inside getPersonsList()");
Session session = sessionFactory.openSession();
Transaction tx = null;
List<Person> personList = null;
try {
tx = session.beginTransaction();
Criteria criteria = session.createCriteria(Person.class);
personList = criteria.list();
System.out.println("personList: " + personList);
tx.commit();
}catch (HibernateException e) {
if (tx != null)
tx.rollback();
e.printStackTrace();
} finally {
session.close();
}
return personList;
}
// DELETE CRUD Operation (elimina un singolo record avente uno specifico id):
public void delete(int id) {
System.out.println("Inside delete()");
Session session = sessionFactory.openSession();
Transaction tx = null;
try {
tx = session.beginTransaction();
Person personToDelete = getById(id);
session.delete(personToDelete);
tx.commit();
}catch (HibernateException e) {
if (tx != null)
tx.rollback();
e.printStackTrace();
} finally {
session.close();
}
}
@Transactional
public void update(Person personToUpdate) {
System.out.println("Inside update()");
Session session = sessionFactory.openSession();
Transaction tx = null;
try {
System.out.println("Insite update() method try");
tx = session.beginTransaction();
session.update(personToUpdate);
tx.commit();
}catch (HibernateException e) {
if (tx != null)
tx.rollback();
e.printStackTrace();
} finally {
session.close();
}
}
}
好的,你可以看到一些方法是使用@Transactional注解来注解的。
我在这里阅读了http://static.springsource.org/spring/docs/3.2.x/spring-framework-reference/html/transaction.html 的官方文档,关于在方法上使用这个注释,它看到:使用@Transactional 注释的方法必须具有事务语义,但它对事务语义意味着什么?
意思是methos的执行必须被认为是事务的执行?所以这意味着方法操作必须被视为可能导致成功或失败的单个操作,如果成功,则操作结果必须是永久的,而如果失败则返回到之前的状态交易的开始。
这就是在方法上使用@Transactional注解的意思吗?
addPerson() 方法的@Transactional 注释中的readOnly = false 属性究竟是什么意思?这意味着我也可以在数据库中写入一条记录(而不仅仅是读取它)还是什么?这个疑问是相关的,因为我知道,默认情况下,使用 @Transactional 注释定义的事务是 read/write 而不仅仅是读取... 我也尝试删除 (readOnly = false) 属性并且仍然可以正常工作(在数据库表中插入新记录)
下面的问题是:“为什么有些方法使用@Transactional 注释而其他一些方法没有?用@Transactional 注释所有CRUD 方法是一个好习惯吗?”
Tnx
安德烈亚
【问题讨论】:
-
我猜您的事务配置无效,因为您可以插入带有只读事务的内容。我的猜测是你根本不使用交易。请向我们提供更多详细信息,您是如何配置交易环境(appcontext)的。也不要在 DAO 级别声明您的交易,而是在业务级别(您实际使用 DAO 的地方)。
标签: java spring hibernate spring-mvc annotations