Home > Software design >  hibernate reactive: keep session opened for ontToMany fields
hibernate reactive: keep session opened for ontToMany fields

Time:10-26

Here my entity:

@NoArgsConstructor
@AllArgsConstructor
@Builder
@Data
@Entity
@Table(name = "GITTBUSUARIS")
public class Usuari {
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "USUARIS_ID")
    private Integer id;
    
    @Column(name = "USUARIS_CODI")
    private String codi;

    @Column(name = "USUARIS_NOM")
    private String nom;

    // @OneToMany(cascade = CascadeType.ALL, mappedBy = "id.usuari", fetch = FetchType.EAGER)
    // private Set<PermisUsuari> permisos;
    
}

As you can see, permisos field is commented.

Here my repository:

@RequiredArgsConstructor
public class ReactiveJpaSpecificationExecutorBase<T> implements ReactiveJpaSpecificationExecutor<T> {

    private final Mutiny.SessionFactory sessionFactory;

    @Override
    public Mono<T> findOne(Specification<T> spec) {
        CriteriaQuery<T> criteriaQuery = this.buildQuery(spec, Sort.unsorted());

        return this.sessionFactory
            .withSession(session -> session.createQuery(criteriaQuery).getSingleResultOrNull())
            .convert().with(UniReactorConverters.toMono());
    }

}

Above code works right. However, when I uncomment permisos field, I'm getting this exception message:

Failed to execute statement [select rol0_.ROLS_ID as rols_id1_12_0_, rol0_.ROLS_CODI as rols_cod2_12_0_, rol0_.ROLS_DENOMINACIO as rols_den3_12_0_ from GITTBROLS rol0_ where rol0_.ROLS_ID=@P1]: could not load an entity: [cat.gencat.clt.git.backend.model.persistency.Rol#1]



java.util.concurrent.CompletionException: java.lang.IllegalStateException: Session/EntityManager is closed

I'm reaching my code:

@RestController
@RequestMapping(value = "/qdcf")
@RequiredArgsConstructor
@Timed
public class QdCFController {

    private final QdCFService qdcfService;
    private final UsuariRepository usuariRepository;

    @GetMapping("/user")
    public Mono<Usuari> user() {
        return this.usuariRepository.findOne(UsuariSpecs.hasCodi("11111111A"));
    }
}

How could I keep session opened per thread?

CodePudding user response:

The error happens because the app is trying to load the entity Rol. You are not showing the association with Rol in the question but I assume it's a lazy association.

Hibernate Reactive doesn't load lazy associations on demand like Hibernate ORM. If that's the case, you have two options:

  • Load the association eagerly with a fetch join in the criteria
  • Fetch the roles when you have the result. Assuming the association is called roles, it should look something like:
    return this.sessionFactory
              .withSession(session -> session
                  .createQuery(criteriaQuery).getSingleResultOrNull()
                  .onItem().ifNotNull().call( result -> Mutiny.fetch(result.getRoles()) )
              )
              .convert().with(UniReactorConverters.toMono());
    

I would need to see the mapping of all the entities involved to help you more

  • Related