服务中的Spring事务和DAO层

时间:2013-05-21 13:44:03

标签: java spring hibernate spring-transactions

在我的示例中,我有一个Hibernate实体和一个DAO。

@Entity
@Table(name="myEntity")
public class MyEntity {

    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name="id")
    private long id;

    @Column(name="action")
    private String actionName;

}

...................

@Repository("myDAO")
@Transactional(propagation = Propagation.REQUIRED)
public class MyDAO {

    @Autowired
    private SessionFactory sessionFactory;

    public void saveObject(MyEntity myEntity){
        sessionFactory.getCurrentSession().save(myEntity);
    }

}

当我以这种方式在服务中使用DAO时

@Service("myService")
@Transactional(propagation = Propagation.REQUIRED)
public class MyService 
{

    @Autowired
    private MyDAO myDAO;

    public void executeTransaction(){
        MyEntity myEntity = new MyEntity();

        myEntity.setActionName("Action1");
        myDAO.saveObject(myEntity);

//      myEntity = new MyEntity();
        myEntity.setActionName("Action2");
        myDAO.saveObject(myEntity);
    }

}

只有一行(Action2)保存在数据库中。当我删除注释时,两行(Action1和Action2)都被保存(这是我需要的行为)。我的问题是服务层上的Transactional注释如何影响事务(方法executeTransaction())执行。为什么没有服务层上的Transactional注释,两行都保存在数据库中,只有最后一行保存在这个注释中?

2 个答案:

答案 0 :(得分:5)

如果没有myEntity = new MyEntity();,您的数据库中的记录会被更新,而不会被插入,因为它是同一个实体。我想在hibernate conf中设置<property name="show_sql">true</property>。这将向您展示正在发生的事情。

答案 1 :(得分:0)

当您存储两个不同的对象时,两个不同的记录将仅保存在数据库中。当您注释该行时,您在同一对象中设置(表示更新)属性。因此,hibernate将更新同一行,而不是创建一个新行。 但是,当您取消注释该行时,您正在创建一个尚未保留的新实例。因此,它将导致在数据库中插入一个新行。