如果在JWTAuthorizationFilter中获取实体,则休眠LazyInitializationException

我正在使用Spring Rest。我有一个叫做Operator的实体,它像这样:

@Entity
@Table(name = "operators")
public class Operator {

    //various properties

    private List<OperatorRole> operatorRoles;

    //various getters and setters

    @LazyCollection(LazyCollectionOption.TRUE)
    @OneToMany(mappedBy = "operator",cascade = CascadeType.ALL)
    public List<OperatorRole> getOperatorRoles() {
        return operatorRoles;
    }

    public void setOperatorRoles(List<OperatorRole> operatorRoles) {
        this.operatorRoles = operatorRoles;
    }
}

我也有相应的OperatorRepository extends JpaRepository
我定义了一个公开此API的控制器:

@RestController
@RequestMapping("/api/operators")
public class OperatorController{

    private final OperatorRepository operatorRepository;

    @Autowired
    public OperatorController(OperatorRepository operatorRepository) {
        this.operatorRepository = operatorRepository;
    }

    @GetMapping(value = "/myApi")
    @Transactional(readOnly = true)
    public MyResponseBody myApi(@ApiIgnore @AuthorizedConsumer Operator operator){

        if(operator.getOperatorRoles()!=null) {
            for (OperatorRole current : operator.getOperatorRoles()) {
                //do things
            }
        }

    }
}

在我使OperatorRoles列表变得懒惰之前,这曾经起作用过;现在,如果我尝试遍历列表,则会抛出LazyInitializationException。
通过扩展Sp​​ring的BasicAuthenticationFilter的过滤器从数据库中获取Operator参数,然后以某种方式将其自动连接到API调用中。
我可以毫无问题地获得其他非延迟初始化的属性。如果我执行类似operator = operatorRepository.getOne(operator.getId());的操作,则一切正常,但是我需要在代码中的太多点处进行更改。
据我了解,问题在于,当我到达OperatorController中的实际API时,用于获取BasicAuthenticationFilter中的Operator的会话不再打开。
我设法将所有内容都包装在OpenSessionInViewFilter中,但仍然无法正常工作。
有人有什么想法吗?

y5897411 回答:如果在JWTAuthorizationFilter中获取实体,则休眠LazyInitializationException

很长一段时间以来,我都遇到过同样的问题,并且正在使用FetchType.EAGER,但是今天我的脑海里有些响亮...

@Transactional无效,所以我认为“声明性交易无效吗?也许可以通过编程方式进行”,而且确实如此!

基于Spring Programmatic Transactions docs

public class JwtAuthorizationFilter extends BasicAuthenticationFilter {        
    
    private final TransactionTemplate transactionTemplate;

    public JwtAuthorizationFilter(AuthenticationManager authenticationManager,PlatformTransactionManager transactionManager) {
        super(authenticationManager);
        this.transactionTemplate = new TransactionTemplate(transactionManager);
        
        // Set your desired propagation behavior,isolation level,readOnly,etc.
        this.transactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
    }

    private void doSomething() {
        transactionTemplate.execute(transactionStatus -> {
            // execute your queries
        });
    }

}

可能对您来说太晚了,但我希望对您有所帮助。

本文链接:https://www.f2er.com/2896727.html

大家都在问