EclipseLink, lazy fetch collection is accessible o

2019-05-04 08:42发布

问题:

I have an entity named User which has the following field called roles:

@ManyToMany
@JoinTable(
        name = "user_role",
        joinColumns = {@JoinColumn(name = "user_id", nullable = false)},
        inverseJoinColumns = {@JoinColumn(name = "role_id", nullable = false)}
)
private List<Role> roles;

I load the User via the use of a service method and the service method is wrapped in a transaction (JTA). After calling the service method and retrieving the User, I access this role field outside of the transaction that was used to load the User entity. I was expecting to get an error because the eclipselink documentation states that, by default, the fechtype for a ManyToMany association is lazy. This tells me that when the User entity was loaded in the service method, the roles should not be automatically loaded.

Why was I able to access the roles outside of the transaction? Why does it seem like the roles were fetched eagerly instead of lazy?

Here is the service class which loads the user (I've removed some code not relevant to the question):

@Service
@Transactional(rollbackFor = ServiceException.class)
public class UserServiceImpl implements UserService {

    @Autowired(required = true)
    private UserRepository userRepository;


    @Override
    public User authenticate(String username, String password) throws ServiceException {
        //Get the user
        List<User> users = userRepository.findByUsername(username);

        if (users == null || users.isEmpty() || users.size() > 1) {
            return null;
        }

        User user = users.get(0);
        String hash = getHash(password, user.getSalt());

        return StringUtils.equals(hash, user.getPassword()) ? user : null;
    }
}

回答1:

EclipseLink allows fetching lazy relationships as long as the context is still available as described here: https://forums.oracle.com/forums/thread.jspa?messageID=1706796