I have a basic SpringBoot 2.0.3.RELEASE app using Spring Initializer, JPA, embedded Tomcat, Thymeleaf template engine and package as an executable JAR file with these dependencies in the pom.xml.
I have a domain object called Company:
@Entity
@Table(name="t_company")
public class Company implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
public Company() {
}
/**
* @param companyName
*/
public Company(String companyName) {
super();
this.name = companyName;
}
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@NotEmpty
@Length(max = 100)
private String name;
@OneToMany(mappedBy = "company", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private Set<User> users = new HashSet<>();
..
}
Repository Layer:
public interface CompanyRepository extends CrudRepository<Company, Long> {
@Query("select co from Company co join co.users us where co = ?1")
Company companyUsers (Company company);
}
Service Layer:
@Service
@Transactional(readOnly = true)
public class CompanyService {
@Autowired
private CompanyRepository companyRepository;
public Company companyUsers (Company company) {
return companyRepository.companyUsers(company);
}
}
Junit file:
@Test
public void testCompanyUsers() throws Exception {
Iterable<Company> companies = companyService.findAll();
Company company = companies.iterator().next();
assertNotNull (company);
company = companyService.companyUsers(company);
assertTrue (((Collection<?>) company.getUsers()).size() > 0);
}
But when I run the test I get this error:
failed to lazily initialize a collection of role: com.cor.backend.persistence.domain.backend.Company.users, could not initialize proxy - no Session
Please read one of my articles carefully: https://arnoldgalovics.com/lazyinitializationexception-demystified/
Your main problem is that you are trying to access an entity reference outside of a transaction. You have multiple options here:
More reading about projections: https://arnoldgalovics.com/using-projections-in-your-data-access-layer/
Also, consider the performance impact of using projections: https://arnoldgalovics.com/how-much-projections-can-help/
For springboot, we need to add @Transactional
(org.springframework.transaction.annotation.Transactional)
to the class where we used the lazy loaded property:
testCompanyUsers()
i.e.
import org.springframework.transaction.annotation.Transactional;
...
@Transactional
public void testCompanyUsers() throws Exception {
...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With