Java 手动回退弹簧MVC+;冬眠

Java 手动回退弹簧MVC+;冬眠,java,spring,hibernate,spring-mvc,manual,Java,Spring,Hibernate,Spring Mvc,Manual,我正在使用SpringMVC+Hibernate //Class for Generic Methods for **save and update** @Service("PersistenceTemplate") @Transactional public class PersistenceTemplate { @Resource(name = "sessionFactory") private SessionFactory sessionFactory; // SAVE publ

我正在使用SpringMVC+Hibernate

//Class for Generic Methods for **save and update** 

@Service("PersistenceTemplate")
@Transactional
public class PersistenceTemplate {

@Resource(name = "sessionFactory")
private SessionFactory sessionFactory;

// SAVE 
public <T> long save(T entity) throws DataAccessException {
    Session session = sessionFactory.getCurrentSession();
    long getGenVal=(Long) session.save(entity);
    return getGenVal;
}
//UPDATE
public <T> void update(T entity) throws DataAccessException {
    sessionFactory.getCurrentSession().update(entity);
}
问题陈述

@Resource(name = "PersistenceTemplate")
private PersistenceTemplate pt;
long result=pt.save(receiveTrxObj1);
pt.Update(receiveTrxObj2);

如果更新未能更新数据库中的实体,如何回滚save语句

可以使用应用程序级异常回滚实体操作。当此自定义异常引发时,相关操作将回滚。请参阅以下文档,了解如何在Spring中进行定义。

如果更新失败,要回滚保存,保存和更新必须在同一事务中进行。服务是放置需要在同一事务中执行的DAO调用的自然场所

在控制器方法上放置@Transactional注释会由于代理控制器而产生复杂问题,请参见17.3.2:

使用带注释的控制器类时的常见陷阱 应用需要为其创建代理的功能时发生 控制器对象(例如@Transactional方法)。通常你会 为控制器引入一个接口,以便使用JDK dynamic 代理。要实现这一点,必须移动@RequestMapping 注释,以及任何其他类型和方法级别的注释 (例如@modeldattribute、@InitBinder)到接口以及 映射机制只能“看到”代理公开的接口。 或者,您可以在中激活代理目标class=“true” 应用于控制器的功能配置(在我们的 中的事务场景)。这样做意味着 应该使用基于CGLIB的子类代理,而不是 基于接口的JDK代理。有关各种代理的详细信息,请参见 机制见第9.6节“代理机制”

请参阅,了解服务中的内容与控制器中的内容不同。

首先,您的@service(“PersistenceTemplate”)应标记为@Repository,因为它执行DAO层的工作

您应该从控制器调用一个服务,该服务应该用@Service和@Transactional注释,并且在该服务中创建一个方法,该方法将调用DAO层

如果“保存”或“更新”未能更新数据库中的实体,则调用该实体的方法(即服务层中的方法)将不会完成,事务将自动取消,因为一旦控件返回,持久化对象将在服务层方法完成后与数据库同步

请参见下面的示例

@Service("authorLoadService")
@Transactional
@Scope(proxyMode=ScopedProxyMode.TARGET_CLASS,value="request")
public class AuthorEntityLoadService implements EntitiesLoadService{

    private AuthorDAO authorDao;//this is my DAO





    @Autowired
    @Qualifier("authorDAO")
    public void setAuthorDao(AuthorDAO authorDao) {
        this.authorDao = authorDao;
    }

    @Override
    public void deleteEntities(Object o) {
        // TODO Auto-generated method stub

    }

    @Override
    public void loadEntities(Object o) {
        Set<author_pojo> author=(Set<author_pojo>)o;
        Iterator<author_pojo> itr=author.iterator();

        while (itr.hasNext()) {
            author_pojo authorPojo = (author_pojo) itr.next();
            authorDao.save(authorPojo);

        }


    }

    @Override
    @Transactional(readOnly=true)
    public List getEntities() {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    @Transactional(readOnly=true)
    public Object getEntity(Object o) {
        String author=(String)o;
    author_pojo fetAuthor=authorDao.findOneByName(author);

        return fetAuthor;
    }

}
@Service(“authorLoadService”)
@交易的
@范围(proxyMode=ScopedProxyMode.TARGET\u类,value=“request”)
公共类AuthorEntityLoadService实现EntityLoadService{
二等兵AuthorDAO AuthorDAO;//这是我的刀
@自动连线
@限定词(“authorDAO”)
公共无效setAuthorDao(AuthorDAO AuthorDAO){
this.authorDao=authorDao;
}
@凌驾
公共void deleteEntities(对象o){
//TODO自动生成的方法存根
}
@凌驾
公共void加载实体(对象o){
集合作者=(集合)o;
迭代器itr=author.Iterator();
while(itr.hasNext()){
author_pojo authorPojo=(author_pojo)itr.next();
authorDao.save(authorPojo);
}
}
@凌驾
@事务(只读=真)
公共列表getEntities(){
//TODO自动生成的方法存根
返回null;
}
@凌驾
@事务(只读=真)
公共对象getEntity(对象o){
字符串作者=(字符串)o;
author\u pojo fetAuthor=authorDao.findOneByName(作者);
返回作者;
}
}
我的抽象泛型刀

public abstract class AbstractHibernateDAO<T extends Serializable> {

    public Class<T> clazz;//class object reference

    protected SessionFactory mysessionFactory;


    @Autowired
    public void setMysessionFactory(SessionFactory mysessionFactory) {
        this.mysessionFactory = mysessionFactory;
    }

    public T findOneByName(final String name){

        return (T) getCurrentSession().createQuery("from "+clazz.getName()).uniqueResult();
    }


    public void setClazz(final Class<T> clazzToSet) {
        this.clazz = clazzToSet;
    }

    public T findOne(final Long id) {
        return (T) getCurrentSession().get(clazz, id);
    }

    @SuppressWarnings("unchecked")
    public List<T> findAll() {
        return getCurrentSession().createQuery("from " + clazz.getName()).list();
    }

    public void save(final T entity) {
        getCurrentSession().merge(entity);
    }

    public void update(final T entity) {
        getCurrentSession().update(entity);
    }

    public void delete(final T entity) {
        getCurrentSession().delete(entity);
    }

    public void deleteById(final Long entityId) {
        final T entity = findOne(entityId);
        delete(entity);
    }

    protected Session getCurrentSession() {

        return mysessionFactory.getCurrentSession();
    }
}
公共抽象类AbstractHibernateDAO{
公共类clazz;//类对象引用
受保护的SessionFactory mysessionFactory;
@自动连线
public void setMysessionFactory(SessionFactory mysessionFactory){
this.mysessionFactory=mysessionFactory;
}
public T findOneByName(最终字符串名){
return(T)getCurrentSession().createQuery(“from”+clazz.getName()).uniqueResult();
}
公共无效集合(最终类别集合){
this.clazz=clazzToSet;
}
公共T findOne(最终长id){
return(T)getCurrentSession().get(clazz,id);
}
@抑制警告(“未选中”)
公共列表findAll(){
返回getCurrentSession().createQuery(“from”+clazz.getName()).list();
}
公共作废保存(最终T实体){
getCurrentSession().merge(实体);
}
公共作废更新(最终T实体){
getCurrentSession().update(实体);
}
公共作废删除(最终T实体){
getCurrentSession().delete(实体);
}
public void deleteById(最终长实体ID){
最终T实体=最终完成(实体ID);
删除(实体);
}
受保护的会话getCurrentSession(){
返回mysessionFactory.getCurrentSession();
}
}
我的剑

@Repository("authorDAO")
@Scope(proxyMode=ScopedProxyMode.TARGET_CLASS,value="request")
public class AuthorDAO extends AbstractHibernateDAO<author_pojo> {

    public AuthorDAO() {

        setClazz(author_pojo.class);
    }

    public author_pojo findOneByName(final String name){
        System.out.println(clazz);
        return (author_pojo) getCurrentSession().createQuery("from "+clazz.getName() +" where authorName=:name").setParameter("name", name).uniqueResult();
    }



}
@Repository(“authorDAO”)
@范围(proxyMode=ScopedProxyMode.TARGET\u类,value=“request”)
公共类AuthorDAO扩展了AbstractHibernateDAO{
公共作者{
setClazz(作者_pojo.class);
}
公共作者_pojo findOneByName(最终字符串名){
系统输出打印(clazz);
return(author_pojo)getCurrentSession().createQuery(“from”+clazz.getName()+“where authorName=:name”).setParameter(“name”,name).uniqueResult();
}
}

从当前会话获取事务并回滚。使用
@Transactional
注释controller通常是个坏主意。@user902691:是的,实际上,我更喜欢使用服务来完成这类事情。@Nathanhues Save与一个会话关联,而Update与另一个会话关联。它们不与同一会话关联@Nathanhughs保存和更新泛型方法位于类PersistenceTemplate中,该类已被注释,例如
@Service(“PersistenceTemplate”)@Transactional公共类PersistenceTemple