Почему бы не @Autovired Session Factory?Java Hibernate Spring - PullRequest
0 голосов
/ 24 июня 2018

Не могу понять, почему bean sessionFactory не заполняется.Почему это происходит?

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:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

      <context:component-scan base-package="config"/>


    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/"/>
        <property name="suffix" value=".jsp"/>
    </bean>
</beans>

AppConfiguration, в которой объявлено @Bean sessionFactory:

@Configuration
@ComponentScan({"controllers","model","dao","service"})
public class AppConfiguration {

    @Bean
    LocalSessionFactoryBean sessionFactory(){
        LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
        sessionFactory.setPackagesToScan(new String[]{"model"});
        sessionFactory.setDataSource(datasource());
        return sessionFactory;
    }

    @Bean
    JdbcTemplate jdbcTemplate(){return new JdbcTemplate(datasource());}

    @Bean
    public DataSource datasource(){
        BasicDataSource dataSource=new BasicDataSource();
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql://localhost:3306/quizzes");
        dataSource.setUsername("root");
        dataSource.setPassword("dbpass");
        return dataSource;
    }

    @Bean
    HibernateTransactionManager transactionManager(@Autowired SessionFactory sessionFactory){
        HibernateTransactionManager manager= new HibernateTransactionManager();
        manager.setDataSource(datasource());
        manager.setSessionFactory(sessionFactory);
        return manager;
    }


}

Класс, который использует bean sessionFactory,Он не является @Autowired, в результате чего он имеет значение null:

@Service
public class AnswerDAOReal extends EntityDAO<Answer, Integer> {
    @Autowired SessionFactory sessionFactory;

    public AnswerDAOReal() {
        session=sessionFactory.openSession();
    }
}

абстрактный класс EntityDAO - это родительский класс таких классов, как: AnswerDAOReal, UserDAOReal ... XxxDAOReal

abstract class EntityDAO<T, Id extends Serializable> {//Wnen: T- is type of Entity, iD- Type of ID// and DAOEntity- inheritor type of DAOEntity
     SessionFactory sessionFactory;
     Session session;

     EntityDAO(){}

    public void persist(T entity) {
        Transaction transaction = session.beginTransaction();
        session.persist(entity);
        session.flush();
        transaction.commit();
    }

    public void update(T entity) {
        Transaction transaction = session.beginTransaction();
        session.update(entity);
        session.flush();
        transaction.commit();
    }

    public T findById(Id id) {
        Transaction transaction = session.beginTransaction();
        T entity= (T) session.get(getGenericType(),id);
        session.flush();
        transaction.commit();
        return  entity;
    }

    public void delete(Id id) {
        Transaction transaction = session.beginTransaction();
        T entity = (T) findById(id);
        session.delete(entity);
        session.flush();
        transaction.commit();
    }

    public List<T> findAll() {
        Transaction transaction = session.beginTransaction();
        List<T> collection = session.createQuery("from "+getGenericType().getSimpleName()).list();
        session.flush();
        transaction.commit();
        return collection;
    }
    public void deleteAll() {
        Transaction transaction = session.beginTransaction();
        List<T> entityList = findAll();
        for (T entity : entityList) {
            session.delete(entity);
        }
        session.flush();
        transaction.commit();
    }


    public Class getGenericType(){
        Class type= (Class) ((ParameterizedType) getClass()
                .getGenericSuperclass()).getActualTypeArguments()[0];
        return type;
    }
}

Исключение:

 org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'accountController': Unsatisfied dependency expressed through field 'userService'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'userService': Unsatisfied dependency expressed through field 'userDAOReal'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userDAOReal' defined in file [C:\JProjects\Hillel\SpringQuiz\out\artifacts\Servlet1_war_exploded\WEB-INF\classes\dao\UserDAOReal.class]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [dao.UserDAOReal]: Constructor threw exception; nested exception is java.lang.NullPointerException

    Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'userService': Unsatisfied dependency expressed through field 'userDAOReal'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userDAOReal' defined in file [C:\JProjects\Hillel\SpringQuiz\out\artifacts\Servlet1_war_exploded\WEB-INF\classes\dao\UserDAOReal.class]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [dao.UserDAOReal]: Constructor threw exception; nested exception is java.lang.NullPointerException
    Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userDAOReal' defined in file [C:\JProjects\Hillel\SpringQuiz\out\artifacts\Servlet1_war_exploded\WEB-INF\classes\dao\UserDAOReal.class]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [dao.UserDAOReal]: Constructor threw exception; nested exception is java.lang.NullPointerException
    Caused by: java.lang.NullPointerException
        at dao.UserDAOReal.<init>(UserDAOReal.java:16)

1 Ответ

0 голосов
/ 24 июня 2018

Кажется, ваша автопроводка неправильная.Вы вводите свойство в поле, но у вас также есть конструктор, который открывает сеанс.

Во-первых, я бы предложил не вводить свойство в само поле, и я бы настоятельно рекомендовал внедрение в конструктор.Во-вторых, где объявление атрибута session в вашем примере AnswerDAOReal?

Имея это в виду, я бы предложил следующее:

  • Использовать внедрение зависимости на основе конструктора.Делать это на поле не рекомендуется.
  • Добавьте метод, помеченный @PostConstruct, который будет отвечать за открытие вашей сессии.Использование этой аннотации гарантирует, что this будет вызываться сразу после инициализации bean-компонента, завершившего работу.

Примером этого может быть:

@Service
public class AnswerDAOReal extends EntityDAO<Answer, Integer> {

    private final SessionFactory sessionFactory;
    private Session session;

    @Autowired
    public AnswerDAOReal(SessionFactory sessionFactory) {
        this.sessionFactory = sessionFactory;
    }

    @PostConstruct
    private void openSession() {
        this.session = sessionFactory.openSession();
    }

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...