Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/hibernate/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Hibernate和Spring-load操作执行trich,更新/删除操作不';T_Hibernate_Spring_Dependency Injection_Sessionfactory_Spring Transactions - Fatal编程技术网

Hibernate和Spring-load操作执行trich,更新/删除操作不';T

Hibernate和Spring-load操作执行trich,更新/删除操作不';T,hibernate,spring,dependency-injection,sessionfactory,spring-transactions,Hibernate,Spring,Dependency Injection,Sessionfactory,Spring Transactions,我一直在学习本教程: 设置(前面描述的)可以很好地处理教程文件,但是当我做了更改后,删除/更新操作就不会发生了。没有错误或怪癖,它完全忽略了我!至于检索数据,一切都很完美 几乎所有来自图坦卡蒙的文件都是相同的,但有这些不同之处;本教程使用服务文件: Services.java package services; import org.springframework.transaction.annotation.Transactional; import org.hibernate.Sessio

我一直在学习本教程: 设置(前面描述的)可以很好地处理教程文件,但是当我做了更改后,删除/更新操作就不会发生了。没有错误或怪癖,它完全忽略了我!至于检索数据,一切都很完美

几乎所有来自图坦卡蒙的文件都是相同的,但有这些不同之处;本教程使用服务文件:

Services.java

package services;

import org.springframework.transaction.annotation.Transactional;
import org.hibernate.SessionFactory;
import org.hibernate.Session;
import data.*;
import java.util.List;

// This class is the business services tier in the application.
// @Transactional is needed so that a Hibernate transaction is set up,
//  otherwise updates won't have an affect
@Transactional
public class Services {
    // So Spring can inject the session factory
    SessionFactory sessionFactory;
    public void setSessionFactory(SessionFactory value) {
        sessionFactory = value;
    }

    // Shortcut for sessionFactory.getCurrentSession()
    public Session sess() {
        return sessionFactory.getCurrentSession();
    }

    public Event getEventById(long id) {
        return (Event) sess().load(Event.class, id);
    }

    public Person getPersonById(long id) {
        return (Person) sess().load(Person.class, id);
    }

    public void deleteEventById(long id) {
        sess().delete(getEventById(id));
    }

    public void deletePersonById(long id) {
        sess().delete(getPersonById(id));
    }

    public void createEvent(String name) {
        Event theEvent = new Event();
        theEvent.setName(name);
        sess().save(theEvent);
    }

    public void createPerson(String name) {
        Person p = new Person();
        p.setName(name);
        sess().save(p);
    }

    @SuppressWarnings("unchecked")
    public List getEvents() {
        return sess().createQuery("from Event").list();
    }

    @SuppressWarnings("unchecked")
    public List getPeople() {
        return sess().createQuery("from Person").list();
    }

    public void removePersonFromEvent(int personId, int eventId) {
        getEventById(eventId).getPeople().remove(getPersonById(personId));
    }

    public void addPersonToEvent(int personId, int eventId) {
        getEventById(eventId).getPeople().add(getPersonById(personId));
    }
}
package com.epa.util;

import org.hibernate.SessionFactory;
import org.springframework.transaction.annotation.Transactional;
@Transactional
public class HibernateUtil {

    // So Spring can inject the session factory
    static SessionFactory sessionFactory;
    public void setSessionFactory(SessionFactory value) {
        sessionFactory = value;
    }

    // Shortcut for sessionFactory.getCurrentSession()
    public static SessionFactory getSessionFactory() {
        return sessionFactory;
    }
}
package com.epa.controller.base;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.transaction.annotation.Transactional;

import com.epa.controller.EventController;
import com.epa.controller.PersonController;
import com.epa.util.HibernateUtil;

@Transactional
public class BaseController {

    protected SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
    // Shortcut for sessionFactory.getCurrentSession()
    public Session sess() {
        return sessionFactory.getCurrentSession();
    }

    private PersonController personController = null;
    private EventController eventController = null;

    public PersonController getPersonController() {
        if (this.personController == null) {
            this.personController = new PersonController();
        }
        return personController;
    }

    public EventController getEventController() {
        if (this.eventController == null) {
            this.eventController = new EventController();
        }
        return eventController;
    }
}
package com.epa.controller;

import java.util.List;

import org.springframework.transaction.annotation.Transactional;

import com.epa.controller.base.BaseController;
import com.epa.model.Event;

@Transactional
public class EventController extends BaseController {

    public Event getEventById(long id) {
        return (Event) sess().load(Event.class, id);
    }

    public void deleteEventById(long id) {
        sess().delete(getEventById(id));
    }

    public void createEvent(String name) {
        Event theEvent = new Event();
        theEvent.setName(name);
        sess().save(theEvent);
    }

    @SuppressWarnings("unchecked")
    public List getEvents() {
        return sess().createQuery("from Event").list();
    }

}
我尝试使用父控制器和对HibernateUtil的静态调用来分离文件: HibernateUtil.java

package services;

import org.springframework.transaction.annotation.Transactional;
import org.hibernate.SessionFactory;
import org.hibernate.Session;
import data.*;
import java.util.List;

// This class is the business services tier in the application.
// @Transactional is needed so that a Hibernate transaction is set up,
//  otherwise updates won't have an affect
@Transactional
public class Services {
    // So Spring can inject the session factory
    SessionFactory sessionFactory;
    public void setSessionFactory(SessionFactory value) {
        sessionFactory = value;
    }

    // Shortcut for sessionFactory.getCurrentSession()
    public Session sess() {
        return sessionFactory.getCurrentSession();
    }

    public Event getEventById(long id) {
        return (Event) sess().load(Event.class, id);
    }

    public Person getPersonById(long id) {
        return (Person) sess().load(Person.class, id);
    }

    public void deleteEventById(long id) {
        sess().delete(getEventById(id));
    }

    public void deletePersonById(long id) {
        sess().delete(getPersonById(id));
    }

    public void createEvent(String name) {
        Event theEvent = new Event();
        theEvent.setName(name);
        sess().save(theEvent);
    }

    public void createPerson(String name) {
        Person p = new Person();
        p.setName(name);
        sess().save(p);
    }

    @SuppressWarnings("unchecked")
    public List getEvents() {
        return sess().createQuery("from Event").list();
    }

    @SuppressWarnings("unchecked")
    public List getPeople() {
        return sess().createQuery("from Person").list();
    }

    public void removePersonFromEvent(int personId, int eventId) {
        getEventById(eventId).getPeople().remove(getPersonById(personId));
    }

    public void addPersonToEvent(int personId, int eventId) {
        getEventById(eventId).getPeople().add(getPersonById(personId));
    }
}
package com.epa.util;

import org.hibernate.SessionFactory;
import org.springframework.transaction.annotation.Transactional;
@Transactional
public class HibernateUtil {

    // So Spring can inject the session factory
    static SessionFactory sessionFactory;
    public void setSessionFactory(SessionFactory value) {
        sessionFactory = value;
    }

    // Shortcut for sessionFactory.getCurrentSession()
    public static SessionFactory getSessionFactory() {
        return sessionFactory;
    }
}
package com.epa.controller.base;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.transaction.annotation.Transactional;

import com.epa.controller.EventController;
import com.epa.controller.PersonController;
import com.epa.util.HibernateUtil;

@Transactional
public class BaseController {

    protected SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
    // Shortcut for sessionFactory.getCurrentSession()
    public Session sess() {
        return sessionFactory.getCurrentSession();
    }

    private PersonController personController = null;
    private EventController eventController = null;

    public PersonController getPersonController() {
        if (this.personController == null) {
            this.personController = new PersonController();
        }
        return personController;
    }

    public EventController getEventController() {
        if (this.eventController == null) {
            this.eventController = new EventController();
        }
        return eventController;
    }
}
package com.epa.controller;

import java.util.List;

import org.springframework.transaction.annotation.Transactional;

import com.epa.controller.base.BaseController;
import com.epa.model.Event;

@Transactional
public class EventController extends BaseController {

    public Event getEventById(long id) {
        return (Event) sess().load(Event.class, id);
    }

    public void deleteEventById(long id) {
        sess().delete(getEventById(id));
    }

    public void createEvent(String name) {
        Event theEvent = new Event();
        theEvent.setName(name);
        sess().save(theEvent);
    }

    @SuppressWarnings("unchecked")
    public List getEvents() {
        return sess().createQuery("from Event").list();
    }

}
BaseController.java

package services;

import org.springframework.transaction.annotation.Transactional;
import org.hibernate.SessionFactory;
import org.hibernate.Session;
import data.*;
import java.util.List;

// This class is the business services tier in the application.
// @Transactional is needed so that a Hibernate transaction is set up,
//  otherwise updates won't have an affect
@Transactional
public class Services {
    // So Spring can inject the session factory
    SessionFactory sessionFactory;
    public void setSessionFactory(SessionFactory value) {
        sessionFactory = value;
    }

    // Shortcut for sessionFactory.getCurrentSession()
    public Session sess() {
        return sessionFactory.getCurrentSession();
    }

    public Event getEventById(long id) {
        return (Event) sess().load(Event.class, id);
    }

    public Person getPersonById(long id) {
        return (Person) sess().load(Person.class, id);
    }

    public void deleteEventById(long id) {
        sess().delete(getEventById(id));
    }

    public void deletePersonById(long id) {
        sess().delete(getPersonById(id));
    }

    public void createEvent(String name) {
        Event theEvent = new Event();
        theEvent.setName(name);
        sess().save(theEvent);
    }

    public void createPerson(String name) {
        Person p = new Person();
        p.setName(name);
        sess().save(p);
    }

    @SuppressWarnings("unchecked")
    public List getEvents() {
        return sess().createQuery("from Event").list();
    }

    @SuppressWarnings("unchecked")
    public List getPeople() {
        return sess().createQuery("from Person").list();
    }

    public void removePersonFromEvent(int personId, int eventId) {
        getEventById(eventId).getPeople().remove(getPersonById(personId));
    }

    public void addPersonToEvent(int personId, int eventId) {
        getEventById(eventId).getPeople().add(getPersonById(personId));
    }
}
package com.epa.util;

import org.hibernate.SessionFactory;
import org.springframework.transaction.annotation.Transactional;
@Transactional
public class HibernateUtil {

    // So Spring can inject the session factory
    static SessionFactory sessionFactory;
    public void setSessionFactory(SessionFactory value) {
        sessionFactory = value;
    }

    // Shortcut for sessionFactory.getCurrentSession()
    public static SessionFactory getSessionFactory() {
        return sessionFactory;
    }
}
package com.epa.controller.base;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.transaction.annotation.Transactional;

import com.epa.controller.EventController;
import com.epa.controller.PersonController;
import com.epa.util.HibernateUtil;

@Transactional
public class BaseController {

    protected SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
    // Shortcut for sessionFactory.getCurrentSession()
    public Session sess() {
        return sessionFactory.getCurrentSession();
    }

    private PersonController personController = null;
    private EventController eventController = null;

    public PersonController getPersonController() {
        if (this.personController == null) {
            this.personController = new PersonController();
        }
        return personController;
    }

    public EventController getEventController() {
        if (this.eventController == null) {
            this.eventController = new EventController();
        }
        return eventController;
    }
}
package com.epa.controller;

import java.util.List;

import org.springframework.transaction.annotation.Transactional;

import com.epa.controller.base.BaseController;
import com.epa.model.Event;

@Transactional
public class EventController extends BaseController {

    public Event getEventById(long id) {
        return (Event) sess().load(Event.class, id);
    }

    public void deleteEventById(long id) {
        sess().delete(getEventById(id));
    }

    public void createEvent(String name) {
        Event theEvent = new Event();
        theEvent.setName(name);
        sess().save(theEvent);
    }

    @SuppressWarnings("unchecked")
    public List getEvents() {
        return sess().createQuery("from Event").list();
    }

}
EventController.java

package services;

import org.springframework.transaction.annotation.Transactional;
import org.hibernate.SessionFactory;
import org.hibernate.Session;
import data.*;
import java.util.List;

// This class is the business services tier in the application.
// @Transactional is needed so that a Hibernate transaction is set up,
//  otherwise updates won't have an affect
@Transactional
public class Services {
    // So Spring can inject the session factory
    SessionFactory sessionFactory;
    public void setSessionFactory(SessionFactory value) {
        sessionFactory = value;
    }

    // Shortcut for sessionFactory.getCurrentSession()
    public Session sess() {
        return sessionFactory.getCurrentSession();
    }

    public Event getEventById(long id) {
        return (Event) sess().load(Event.class, id);
    }

    public Person getPersonById(long id) {
        return (Person) sess().load(Person.class, id);
    }

    public void deleteEventById(long id) {
        sess().delete(getEventById(id));
    }

    public void deletePersonById(long id) {
        sess().delete(getPersonById(id));
    }

    public void createEvent(String name) {
        Event theEvent = new Event();
        theEvent.setName(name);
        sess().save(theEvent);
    }

    public void createPerson(String name) {
        Person p = new Person();
        p.setName(name);
        sess().save(p);
    }

    @SuppressWarnings("unchecked")
    public List getEvents() {
        return sess().createQuery("from Event").list();
    }

    @SuppressWarnings("unchecked")
    public List getPeople() {
        return sess().createQuery("from Person").list();
    }

    public void removePersonFromEvent(int personId, int eventId) {
        getEventById(eventId).getPeople().remove(getPersonById(personId));
    }

    public void addPersonToEvent(int personId, int eventId) {
        getEventById(eventId).getPeople().add(getPersonById(personId));
    }
}
package com.epa.util;

import org.hibernate.SessionFactory;
import org.springframework.transaction.annotation.Transactional;
@Transactional
public class HibernateUtil {

    // So Spring can inject the session factory
    static SessionFactory sessionFactory;
    public void setSessionFactory(SessionFactory value) {
        sessionFactory = value;
    }

    // Shortcut for sessionFactory.getCurrentSession()
    public static SessionFactory getSessionFactory() {
        return sessionFactory;
    }
}
package com.epa.controller.base;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.transaction.annotation.Transactional;

import com.epa.controller.EventController;
import com.epa.controller.PersonController;
import com.epa.util.HibernateUtil;

@Transactional
public class BaseController {

    protected SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
    // Shortcut for sessionFactory.getCurrentSession()
    public Session sess() {
        return sessionFactory.getCurrentSession();
    }

    private PersonController personController = null;
    private EventController eventController = null;

    public PersonController getPersonController() {
        if (this.personController == null) {
            this.personController = new PersonController();
        }
        return personController;
    }

    public EventController getEventController() {
        if (this.eventController == null) {
            this.eventController = new EventController();
        }
        return eventController;
    }
}
package com.epa.controller;

import java.util.List;

import org.springframework.transaction.annotation.Transactional;

import com.epa.controller.base.BaseController;
import com.epa.model.Event;

@Transactional
public class EventController extends BaseController {

    public Event getEventById(long id) {
        return (Event) sess().load(Event.class, id);
    }

    public void deleteEventById(long id) {
        sess().delete(getEventById(id));
    }

    public void createEvent(String name) {
        Event theEvent = new Event();
        theEvent.setName(name);
        sess().save(theEvent);
    }

    @SuppressWarnings("unchecked")
    public List getEvents() {
        return sess().createQuery("from Event").list();
    }

}
和spring的applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="
       http://www.springframework.org/schema/beans 
       http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
       http://www.springframework.org/schema/tx 
       http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
       http://www.springframework.org/schema/aop 
       http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">

    <!-- The singleton hibernate session factory -->
    <bean id="sessionFactory" scope="singleton"
        class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
        <property name="configLocation" value="classpath:hibernate.cfg.xml" />
    </bean>

    <!-- Spring's hibernate transaction manager, in charge of making hibernate sessions/txns -->
    <bean id="transactionManager"
        class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>

    <!-- So classes/functions with @Transactional get a hibernate txn -->
    <tx:annotation-driven />

    <!-- Inject my business services class to the actions 
    <bean id="services" class="com.epa.services.Services" scope="singleton">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>-->

    <!-- Inject my business services class to the actions -->
    <bean id="hibernateUtil" class="com.epa.util.HibernateUtil" scope="singleton">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean> 

    <bean id="baseController" class="com.epa.controller.base.BaseController" scope="singleton" />

</beans>

您的代码看起来好像没有完全理解Spring依赖项注入的概念,因为您的
BaseController
执行Spring管理单例和提供依赖项的工作

问题

您正在
BaseController
中自己创建
EventController
PersonController
实例,而不是依赖Spring。Spring无法拦截类实例的手动创建,并通过使用Spring注释
@transactional
来为它们提供此处所需的事务行为

解决方案

因此,让我们找到一条路径来清理这段代码。首先删除HibernateUtil类,因为它是静态调用、javabean概念和未使用的事务行为的混合体,同时它带来了一个新的抽象层,没有任何好处。请记住也将其从
applicationContext.xml
中删除

现在从
applicationContext.xml
中删除
BaseController
,并对其进行重大重写,因为它是
PersonController
EventController
的单例工厂,在这样的环境中,它将由Spring自身正确管理

public abstract class BaseController {

    private SessionFactory sessionFactory;

    public void setSessionFactory(SessionFactory sessionFactory) {
        this.sessionFactory = sessionFactory;
    }

    protected Session getCurrentSession() {
        return sessionFactory.getCurrentSession();
    }

}
这样,
BaseController
就成为其他扩展类的抽象基类,这些扩展类可以利用提供的Hibernate
Session
对象。现在,让我们为您的
EventController
创建一个漂亮的界面

public interface EventController {

    Event getEventById(long id);

    void deleteEventById(long id);

    Event createEvent(String name);

    List getEvents();

}
接下来,我们需要为Hibernate实现上述接口,因此让我们使用先前创建的
BaseController
实现调用新类
EventControllerHibernate

public class EventControllerHibernate extends BaseController implements EventController {

    @Transactional(propagation = Propagation.SUPPORTS, readOnly = true)
    public Event getEventById(long id) {
        return (Event) getCurrentSession().get(Event.class, id);
    }

    @Transactional(propagation = Propagation.REQUIRED)
    public void deleteEventById(long id) {
        getCurrentSession().delete(getEventById(id));
    }

    @Transactional(propagation = Propagation.REQUIRED)
    public Event createEvent(String name) {
         return (Event) getCurrentSession().save(new Event(name));
    }

    @Transactional(propagation = Propagation.SUPPORTS, readOnly = true)
    @SuppressWarnings("unchecked")
    public List getEvents() {
        return getCurrentSession().createQuery("from Event").list();
    }

}
请记住在Spring
applicationContext.xml
中正确注册此类,以便也提供所需的
SessionFactory

<bean id="eventController" class="com.epa.controller.EventControllerHibernate">
    <property name="sessionFactory" ref="sessionFactory" />
</bean> 

控制器代码不是很优雅。您应该遵循codescape在这里所说的一切。然而,解决这个问题的一个简单方法是:不返回新的PersonController()或新的EventController(),而是返回已注入BaseController()的相同bean实例。这将返回一个代理对象,spring可以在其上拦截@Transactional。但是,正如我所说的,由定义的控制器不是好代码