Spring + Hiberante

Odpowiedz Nowy wątek
2018-07-27 20:52
0

Cześć, jestem początkujący użytkownikiem springa i hibernate'a i proszę o poradę, gdyż nie mogę znaleźć rozwiązania.
Najpierw przedstawię kod, a potem pytanie.

HibernateConfig.java

@Configuration
@EnableTransactionManagement
@ComponentScan({ "com.test.config" })
@PropertySource(value = { "classpath:application.properties" })
public class HibernateConfig {

  @Autowired
  private Environment environment;

  @Bean
  public SessionFactory sessionFactory() {
    LocalSessionFactoryBuilder builder =
        new LocalSessionFactoryBuilder(dataSource());
    builder.scanPackages("com.test.business")
        .addProperties(hibernateProperties());

    return builder.buildSessionFactory();
  }

  private Properties hibernateProperties() {
    Properties properties = new Properties();
    properties.put("hibernate.dialect", environment.getRequiredProperty("hibernate.dialect"));
    properties.put("hibernate.show_sql", environment.getRequiredProperty("hibernate.show_sql"));
    properties.put("hibernate.format_sql", environment.getRequiredProperty("hibernate.format_sql"));
    return properties;
  }

  @Bean
  public DataSource dataSource() {
    DriverManagerDataSource dataSource = new DriverManagerDataSource();
    dataSource.setDriverClassName(environment.getRequiredProperty("jdbc.driverClassName"));
    dataSource.setUrl(environment.getRequiredProperty("jdbc.url"));
    dataSource.setUsername(environment.getRequiredProperty("jdbc.username"));
    dataSource.setPassword(environment.getRequiredProperty("jdbc.password"));
    return dataSource;
  }

  @Bean
  public HibernateTransactionManager txManager() {
    return new HibernateTransactionManager(sessionFactory());
  }

  @Bean
  public HibernateTemplate hibernateTemplate() {
    return new HibernateTemplate(sessionFactory());
  }

}

Person.java

@Entity
@Table(name = "person")
public class Person {

  @Id
  @Column(name = "id")
  private int id;
  @Column(name = "name")
  private String name;

  public int getId() {
    return id;
  }

  public void setId(int id) {
    this.id = id;
  }

  public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }
}

PersonDao.java

@Repository
public class PersonDao {

  @Autowired
  private HibernateTemplate hibernateTemplate;

  public void savePerson(){
    Person person = new Person();
    person.setId(2);
    person.setName("NazwaTest");
    hibernateTemplate.save(person);
  }

}

PersonService.java

@Service
@Transactional
public class PersonService {

  private PersonDao personDao = new PersonDao();

  public void addNewPerson(){
    personDao.savePerson();
  }
}

PersonController.java

  @GetMapping(value="/")
  @ResponseBody
  public String printWelcome() {
    PersonService personService = new PersonService();
    personService.addNewPerson();
    return "home";
  }

Kod generalnie bardzo prosty, bo na razie uczę się właśnie schematów i działania.
Problem w tym, że gdy uruchomię aplikację i wejdę na stronę wyrzuca mi błąd java.lang.NullPointerException: null
Generalnie dotoczy to pliku PersonDao.java oraz linii hibernateTemplate.save(person);
Wyczytałem, że to chyba błąd z niewłaściwie zadeklarowanymi beanami i autowire, ale nie mogę sobie z tym poradzić. Czy ktoś mógłby dać jakąś wskazówkę?

Pozostało 580 znaków

2018-07-27 21:37
1

Jak już zdajesz się na Springa, to nie twórz beanów poprzez new, tylko autowiruj. Czyli zamiast

private PersonDao personDao = new PersonDao();

będzie

@Autowired
PersonDao personDao

A już w ogóle najlepiej jakbyś wstrzykiwał te zależności poprzez konstruktor, czyli

@Autowired
public PersonService(PersonDao personDao) {
   this.personDao = personDao;
}

A jak korzystasz ze Springa wyższego lub równego 4.3, to możesz nawet pominąć adnotację i będzie ostatecznie:

public PersonService(PersonDao personDao) {
   this.personDao = personDao;
}

analogicznie później dla serwisu.

Pozostało 580 znaków

2018-07-27 22:08
1

Dobrze wyczytałeś. Zamiast new PersonDao(); dodaj adnotację @Autowired. Tak samo w kontrolerze do serwisu. Po to masz Springa, a raczej jego kontener IoC (nie wiem poczytaj o IoC, dependency injection, bo nie zrozumiałeś chyba czegoś), żebyś nie tworzył obiektów. Inaczej oddajesz Springowi kontrole nad tworzeniem obiektów to są podstawy zobacz sobie Artur Owczarek na yt.

Pozostało 580 znaków

2018-07-27 23:29
0

Okej, dokonałem pewnych modyfikacji. Wygląda to teraz tak:

PersonDao.java

@Repository
public class PersonDao implements IPersonDao {

  @Autowired
  private HibernateTemplate hibernateTemplate;

  public PersonDao(){}

  public void savePerson(){
    Person person = new Person();
    person.setId(2);
    person.setName("NazwaTest");
    hibernateTemplate.save(person);
  }

}

PersonService.java

@Service
public class PersonService{

  @Autowired
  PersonDao personDao;

  public  PersonService(){}

  public void addNewPerson(){
    personDao.savePerson();
  }
}

PersonController.java


@Controller
public class PersonController {

  @Autowired
  PersonService personService;

  @GetMapping(value="/")
  @ResponseBody
  public String printWelcome() {
    personService.addNewPerson();
    return "home";
  }
}

Niestety, teraz program nie chce się uruchomić. Problem jest z plikiem PersonService.java a konkretnie:

  @Autowired
  PersonDao personDao;

Gdyż nie może dokonać autowire, bo taki bean nie może zostać odnaleziony, ale przez adnotację @Repository i konstruktor bezparametrowy powinno zadziałać.

Co może być nie tak?

Dodatkowo załączam Initializer, który może ma jakiś błąd, dlatego jest problem.
MyWebInitializer.java

public class MyWebInitializer extends
    AbstractAnnotationConfigDispatcherServletInitializer {

  @Override
  protected Class<?>[] getRootConfigClasses() {
    return new Class[] { SpringRootConfig.class };
  }

  @Override
  protected Class<?>[] getServletConfigClasses() {
    return new Class[] { SpringWebConfig.class };
  }

  @Override
  protected String[] getServletMappings() {
    return new String[] { "/" };
  }

}

SpringWebConfig.java

@EnableWebMvc //<mvc:annotation-driven />
@Configuration
@ComponentScan({ "com.test.controller" })
public class SpringWebConfig implements WebMvcConfigurer {

  @Override
  public void addResourceHandlers(ResourceHandlerRegistry registry) {
    registry.addResourceHandler("/resources/**")
        .addResourceLocations("/resources/");
  }

  @Bean
  public InternalResourceViewResolver viewResolver() {
    InternalResourceViewResolver viewResolver
        = new InternalResourceViewResolver();
    viewResolver.setViewClass(JstlView.class);
    viewResolver.setPrefix("/WEB-INF/views/jsp/");
    viewResolver.setSuffix(".jsp");
    return viewResolver;
  }

}

SpringRootConfig.java

@Configuration
@ComponentScan({ "com.test.service" })
public class SpringRootConfig {

}

HibertnateConfig.java

@Configuration
@EnableTransactionManagement
@ComponentScan({ "com.test.config" })
@PropertySource(value = { "classpath:application.properties" })
public class HibernateConfig {

  @Autowired
  private Environment environment;

  @Bean
  public SessionFactory sessionFactory() {
    LocalSessionFactoryBuilder builder =
        new LocalSessionFactoryBuilder(dataSource());
    builder.scanPackages("com.test.business")
        .addProperties(hibernateProperties());

    return builder.buildSessionFactory();
  }

  private Properties hibernateProperties() {
    Properties properties = new Properties();
    properties.put("hibernate.dialect", environment.getRequiredProperty("hibernate.dialect"));
    properties.put("hibernate.show_sql", environment.getRequiredProperty("hibernate.show_sql"));
    properties.put("hibernate.format_sql", environment.getRequiredProperty("hibernate.format_sql"));
    return properties;
  }

  @Bean
  public DataSource dataSource() {
    DriverManagerDataSource dataSource = new DriverManagerDataSource();
    dataSource.setDriverClassName(environment.getRequiredProperty("jdbc.driverClassName"));
    dataSource.setUrl(environment.getRequiredProperty("jdbc.url"));
    dataSource.setUsername(environment.getRequiredProperty("jdbc.username"));
    dataSource.setPassword(environment.getRequiredProperty("jdbc.password"));
    return dataSource;
  }

  @Bean
  public HibernateTransactionManager txManager() {
    return new HibernateTransactionManager(sessionFactory());
  }

  @Bean
  public HibernateTemplate hibernateTemplate() {
    return new HibernateTemplate(sessionFactory());
  }
}

Pozostało 580 znaków

2018-07-28 18:25
0

@Warmix: Masz ustawione component scan w package (po pl pakiet? już mi nazwy uciekają) gdzie jest PersonDao.java? Ten HibernateTemplate skąd wziąłeś? To nie jest czasem przestarzałe? Poczytaj o SessionFactory w dokumentacji Springa.

Korzystasz z mavena czy gradla?

EDIT: https://stackoverflow.com/a/43801315

edytowany 2x, ostatnio: discoStar, 2018-07-28 18:28

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0