Issue:
I have User
and Role
entities and the relationship is many to many. First I do a roleRepository.findById()
to get a role and then I do role.getUsers().forEach(user -> System.out.println(user.getId()));
to print the ids of associated users.
When the first method is invoked, query is issued to role
table. And when the second method is invoked, a join query is issued to role_users
and user
tables.
Is it possible to let hibernate know via any annotation that it should create the Role
object with a set of Proxy user
objects so that during the above two methods User
table is never used?
For example, I can annotate the collection association with @LazyCollection(EXTRA)
and then role.getUsers().size()
works perfectly without using the user
table.
Code
@Entity
public class Role {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Access(AccessType.PROPERTY)
private Long id;
private String name;
@ManyToMany
private Set<User> users;
... getters and setters
}
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Access(AccessType.PROPERTY)
private Long id;
private String name;
@ManyToMany(mappedBy = "users")
private Set<Role> roles;
..getters and setters
}
public interface UserRepository
extends JpaRepository<User, Long> {
}
public interface RoleRepository
extends JpaRepository<Role, Long> {
Role findByName(String roleName);
}
@Service
public class UserService {
@Autowired
private UserRepository userRepository;
@Autowired
private RoleRepository roleRepository;
@Transactional
public void setUpSomeUsersAndRoles(){
User userOne = userRepository.save(new User("user-1"));
User userTwo = userRepository.save(new User("user-2"));
User userThree = userRepository.save(new User("user-3"));
Role roleOne = roleRepository.save(new Role("ADMIN"));
userOne.setRoles(singleton(roleOne));
userTwo.setRoles(singleton(roleOne));
userThree.setRoles(singleton(roleOne));
Set<User> users
= new HashSet<>(asList(userOne, userTwo, userThree));
roleOne.setUsers(users);
}
@Transactional
public void findRoleByName(){
Role role = roleRepository.findByName("ADMIN");
//I want the following to be executed
//without query issued to user table
role.getUsers()
.forEach(user -> System.out.println(user.getId()));
}
}
Note
I do know how to get ids of associated entities via separate query. This is specially a question about the possibility of hibernate annotation as highlighted in the question.