I am trying to load an entity from the database with hibernate but I get the following error
failed to lazily initialize a collection of role: package.entities.machinegroup.MachineGroup.users
This is my MachineGroup entity:
public class MachineGroup {
@Id
@GeneratedValue(strategy= GenerationType.AUTO, generator = "machine_groups_seq")
@SequenceGenerator(name = "machine_groups_seq", allocationSize = 1, initialValue = 2)
@Column(name = "id")
private long id;
@Column(name = "name")
private String name;
@Column(name = "creation_time")
private Date creationTime;
@Column(name = "is_official")
private boolean official;
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "machine_properties_id", nullable = false)
private ContinuousIntegrationProperties defaultContinuousIntegrationProperties;
@ManyToMany(fetch = FetchType.EAGER)
@JoinTable(name = "machine_groups_to_users",
joinColumns = @JoinColumn(name = "machine_group_id"),
inverseJoinColumns = @JoinColumn(name = "user_id"))
private Set<User> users = new HashSet<>();
@JoinTable(name = "machine_groups_to_versions",
joinColumns = @JoinColumn(name = "machine_group_id"),
inverseJoinColumns = @JoinColumn(name = "version_id"))
private Set<Version> versions = new HashSet<>();
}
This is the entity that I am trying to fetch:
public class MachineGroupToVersion {
@Id
@GeneratedValue(strategy= GenerationType.AUTO, generator = "machine_groups_to_versions_seq")
@SequenceGenerator(name = "machine_groups_to_versions_seq", allocationSize = 1)
@Column(name = "id")
private long id;
@ManyToOne
@JoinColumn(name = "machine_group_id", nullable = false)
private MachineGroup machineGroup;
@ManyToOne
@JoinColumn(name = "version_id", nullable = false)
private Version version;
}
Why does it say that it fails lazily initialize the collection users within MachinGroup if I have explicitly said "fetch = FetchType.EAGER" ?
UPDATE:
User class
public class User {
@Id
@GeneratedValue(strategy= GenerationType.AUTO, generator = "users_seq")
@SequenceGenerator(name = "users_seq", allocationSize = 1, initialValue = 2)
@Column(name = "ID")
private long id;
@Column(name = "username")
private String username;
@Column(name = "creation_time")
private Date creationTime;
@Column(name = "role")
private String role;
@Column(name = "email")
private String email;
@ManyToMany(mappedBy = "users", cascade = CascadeType.MERGE)
private Set<MachineGroup> machineGroups = new HashSet<>();
@OneToMany(mappedBy = "owner")
private Set<Campaign> campaigns = new HashSet<>();
}
UPDATE 2:
full stacktrace:
Could not write JSON: failed to lazily initialize a collection of role: .entities.user.User.machineGroups, could not initialize proxy - no Session; nested exception is com.fasterxml.jackson.databind.JsonMappingException: failed to lazily initialize a collection of role: .entities.user.User.machineGroups, could not initialize proxy - no Session (through reference chain: java.util.ArrayList[0]->.entities.machinegrouptoversion.MachineGroupToVersionDTO[\"machineGroup\"]->.entities.machinegroup.MachineGroup[\"users\"]->org.hibernate.collection.internal.PersistentSet[0]->.entities.user.User[\"machineGroups\"])
UPDATE 3:
MachineGroupToVersionService
@Transactional(transactionManager = "primaryTransactionManager", propagation= Propagation.REQUIRED, readOnly=true, noRollbackFor=Exception.class)
public List<MachineGroupToVersionDTO> getByMachineGroupName(String mgName) {
List<MachineGroupToVersionDTO> mgtvl = new ArrayList<>();
Optional<MachineGroup> mg = machineGroupService.getByName(mgName);
if(mg.isPresent())
mgtvl = machineGroupToVersionRepository.findByMachineGroup(mg.get()).stream()
.map(this::convertToDto).collect(Collectors.toList());
return mgtvl;
}
private MachineGroupToVersionDTO convertToDto(MachineGroupToVersion mgtv) {
MachineGroupToVersionDTO machineGroupToVersionDTO = new MachineGroupToVersionDTO();
machineGroupToVersionDTO.setMachineGroup(mgtv.getMachineGroup());
machineGroupToVersionDTO.setVersion(mgtv.getVersion());
machineGroupToVersionDTO.setCreationTime(mgtv.getCreationTime());
machineGroupToVersionDTO.setState(mgtv.getState());
machineGroupToVersionDTO.setTestedTime(mgtv.getTestedTime());
return machineGroupToVersionDTO;
}