I am trying to read data from the database, using Hibernate.
I have following data model, which holds some user credentials data, split into several entities, with Entity C holding User authorization roles (user can have more than 1 role, hence ManyToMany):
A
-> OneToOne -> B
<- ManyToMany -> C
as written:
@Entity
public class A {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String s1;
private String s2;
//getters, setters, etc.
}
@Entity
public class B {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String s1;
private String s2;
@OneToOne(cascade = CascadeType.REMOVE,
fetch = FetchType.LAZY)
private A aElement;
@ManyToMany(targetEntity = C.class,
fetch = FetchType.EAGER,
cascade = CascadeType.ALL)
@JoinTable(
name = "b_x_c",
joinColumns = @JoinColumn(table = "b", referencedColumnName = "id"),
inverseJoinColumns = @JoinColumn(table = "c", referencedColumnName = "id")
)
private Set<C> cSet;
//getters, setters, etc.
}
@Entity
public class C {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String description;
@ManyToMany(targetEntity = B.class,
mappedBy = "cSet",
cascade = CascadeType.ALL,
fetch = FetchType.EAGER)
private Set<B> bSet;
//getters, setters, etc.
}
I did write a CustomUserDetailService
(using Spring Security for authorizaiton) for some user tweaking:
@Service
public class CustomUserDetailsService implements UserDetailsService {
private final LoginService loginService ;
public CustomUserDetailsService(LoginService loginService ) {
this.loginService = loginService ;
}
@Override
public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
return loginService.findCredentialsByS1(s)
.map(this::createUserDetails)
.orElseThrow(() -> new UsernameNotFoundException("no user found"));
}
private UserDetails createUserDetails(B credentials) {
return User.builder()
.username(credentials.getS1())
.password(credentials.getS2())
.roles(credentials.getCSet().toArray(String[]::new))
.build();
}
}
loginService
is:
@Service
public class LoginService {
public final BRepository bRepository;
public ClientLoginService(BRepository bRepository) {
this.bRepository = bRepository;
}
public Optional<B> findCredentialsByS1(String s) {
return bRepository.findByS1IgnoreCase(s);
}
}
and BRepository
:
public interface BRepository extends JpaRepository<B, Long> {
Optional<B> findByS1IgnoreCase(String s);
}
Now, when I login a User, CustomUserDetailsService
is being invoked and loadUserByUsername()
called, through which a Repository executes a call to the database, but somehow, the contents of C table are not loaded (they are properly connected in the intermediate (connector) database). Data of A table are being loaded, but C table not – and no error is given. What can be a reason here? I don’t quite understand why, especially that when I turn on Hibernate logging, and look into the queries that are being given, it should actually provide correct data, but debugging loadUserByUsername
shows, that it’s empty.