Java Bean bị IllegalStateException: EntityManagerFactory is closed

Mọi người cho em hỏi lỗi này với ạ, em đã có bean đầy đủ nhưng vẫn báo lỗi là thế nào, ai có thể giải thích giúp em đc ko?

Lỗi:

Exception in thread "task-2" java.lang.IllegalStateException: EntityManagerFactory is closed
	at org.hibernate.internal.SessionFactoryImpl.validateNotClosed(SessionFactoryImpl.java:509)
	at org.hibernate.internal.SessionFactoryImpl.getProperties(SessionFactoryImpl.java:503)
	at org.springframework.boot.autoconfigure.orm.jpa.DataSourceInitializedPublisher.findDataSource(DataSourceInitializedPublisher.java:105)
	at org.springframework.boot.autoconfigure.orm.jpa.DataSourceInitializedPublisher.publishEventIfRequired(DataSourceInitializedPublisher.java:97)
	at org.springframework.boot.autoconfigure.orm.jpa.DataSourceInitializedPublisher.access$100(DataSourceInitializedPublisher.java:50)
	at org.springframework.boot.autoconfigure.orm.jpa.DataSourceInitializedPublisher$DataSourceSchemaCreatedPublisher.lambda$postProcessEntityManagerFactory$0(DataSourceInitializedPublisher.java:200)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at java.lang.Thread.run(Thread.java:748)

Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2021-01-22 11:05:22.168 ERROR 11384 --- [  restartedMain] o.s.b.d.LoggingFailureAnalysisReporter   : 

***************************
APPLICATION FAILED TO START
***************************

Description:

Field encoder in pvars.arsenalquan.controllers.UserController required a bean of type 'org.springframework.security.crypto.password.PasswordEncoder' that could not be found.

The injection point has the following annotations:
	- @org.springframework.beans.factory.annotation.Autowired(required=true)


Action:

Consider defining a bean of type 'org.springframework.security.crypto.password.PasswordEncoder' in your configuration.


Process finished with exit code 0

Config:

package pvars.arsenalquan.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.crypto.password.PasswordEncoder;
import pvars.arsenalquan.service.UserService;


@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    UserService userService;

    @Bean
    public PasswordEncoder passwordEncoder() {
        // Password encoder, để Spring Security sử dụng mã hóa mật khẩu người dùng
        return new BCryptPasswordEncoder();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userService) // Cung cáp userservice cho spring security
                .passwordEncoder(passwordEncoder()); // cung cấp password encoder
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable()
                .authorizeRequests()
                .antMatchers("/api/news/", "/api/category/").permitAll() // Cho phép tất cả mọi người truy cập vào 2 địa chỉ này
                .anyRequest().authenticated() // Tất cả các request khác đều cần phải xác thực mới được truy cập
                .and().logout().permitAll();
    }
}

UserController:

package pvars.arsenalquan.controllers;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.*;
import pvars.arsenalquan.message.ResponseMessage;
import pvars.arsenalquan.message.request.SearchForm;
import pvars.arsenalquan.models.User;
import pvars.arsenalquan.repositories.UserRepository;

import javax.validation.Valid;
import java.io.IOException;
import java.util.List;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/api/user")
@CrossOrigin(origins = "*", allowedHeaders = "*")
public class UserController {

    @Autowired
    UserRepository userRepository;

    @Autowired
    PasswordEncoder encoder;

    @PostMapping("/save")
    public ResponseEntity<?> add(@Valid @RequestBody User user) throws IOException {
        String password = user.getPassword();

        String encryptPassword = encoder.encode(password);
        user.setPassword(encryptPassword);

        userRepository.save(user);
        return new ResponseEntity<>(new ResponseMessage("Lưu thành công"), HttpStatus.OK);
    }
}

Trong SecurityConfig:

            @Bean
            public PasswordEncoder passwordEncoder() {
                // Password encoder, để Spring Security sử dụng mã hóa mật khẩu người dùng
                return new BCryptPasswordEncoder();
            }

Nhưng trong UserController:

    @Autowired
    PasswordEncoder encoder; // Nên sửa thành passwordEncoder

Kết quả là cậu sẽ bị nhắc khéo “bean kiểu PasswordEncoder không thể được tìm thấy”.

Vì Spring sử dụng bean name làm default qualifier, nên cậu cần viết đúng tên của encoder trong UserController.

6 Likes

A post was merged into an existing topic: Topic lưu trữ các post off-topic - version 3


Mình đã sửa y như v nhưng nó vẫn báo Field passwordEncoder not found cậu ạ

1 Like

Oh, vậy cậu thử thế này trong UserController xem:

    @Resource(name = "passwordEncoder")
    PasswordEncoder passwordEncoder;
1 Like
Description:

A component required a bean named 'passwordEncoder' that could not be found.


Action:

Consider defining a bean named 'passwordEncoder' in your configuration.

Đây là lỗi mà tôi gặp phải sau khi dùng

@Resource(name = "passwordEncoder")
    PasswordEncoder passwordEncoder;
1 Like

Hm, có vẻ như configuration của cậu không scan được package pvars.arsenalquan.controllers (do nó ở pvars.arsenalquan.config).
Ngoài thay đổi ở trên, cậu thử thêm @ComponentScan annotation vào SecurityConfig xem.

@Configuration
@EnableWebSecurity
@ComponentScan(basePackages = "pvars.arsenalquan.controllers")
public class SecurityConfig extends WebSecurityConfigurerAdapter {
1 Like

Có vẻ nó không có tác dụng

1 Like

Cậu có thể push code của cậu lên git và share được không? Thường config mấy application sử dụng Spring khá tốn công, và cần đọc nhiều thứ trong source code.

1 Like

Được chứ, đây là source git của tôi, cám ơn bạn nhiều

2 Likes

b thử bỏ đoạn

@Autowired
PasswordEncoder passwordEncoder;

trong class SecurityConfig đi xem
bạn bean nó ở

@Bean
public PasswordEncoder passwordEncoder() {
    return new BCryptPasswordEncoder(); // Password encoder, để Spring Security sử dụng mã hóa mật khẩu người dùng
}

rồi mà

mình có thử cách này mà không được, vẫn chưa hiểu vì sao

nhưng chắc chắn ông phải xóa @autowired thằng này trong file kia, nó mới chuẩn.

ông dumb file.sql ra cho tôi đc k? structure & data nhse


bỏ đi thêm lam gi vây -…-

Bỏ nó lỗi mà ko bỏ nó cũng lỗi nên em chưa xoá đấy

vẫn lỗi ấy bro, bro nào thử đoạn code ở git trên chưa ạ?

Còn cách khác là inject bean bằng constructor

  • Bỏ Autowired PasswordEncoder đi
  • Thêm constructor cho controller như sau
private final PasswordEncoder passwordEncoder;

public UserController(PasswordEncoder passwordEncoder) {
    this.passwordEncoder = passwordEncoder;
}

Hoặc config bean paswordEncoder trong BackendArsenalquanApplication.java thay vì SecurityConfig.java

3 Likes

Ủa ủa, project mình clone về vẫn chạy ầm ầm mà, có lỗi gì đâu nhỷ.

//    @Autowired
//    UserService userService;
//
//    @Autowired
//    PasswordEncoder passwordEncoder;

//    @Override
//    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
//        auth.userDetailsService(userService) // Cung cáp userservice cho spring security
//                .passwordEncoder(encoder()); // cung cấp password encoder
//    }

    @Bean
    public PasswordEncoder encoder() {
        return new BCryptPasswordEncoder(); // Password encoder, để Spring Security sử dụng mã hóa mật khẩu người dùng
    }
  • UserController nè:
public class UserController {

    @Autowired
    UserRepository userRepository;

    @Autowired
    PasswordEncoder passwordEncoder;
2 Likes

Cám ơn bạn nha, mình cũng ko rõ sao nó lỗi nữa, để mình build lại xem sao, mình kiểu buổi sáng chạy ok xong tối về nó tự dưng lỗi ấy

Nếu vẫn còn bị thì bạn thử build và chạy thủ công xem
mvn clean package && java -jar target\<app-name>.jar

2 Likes
83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?