I'm having a lazy initialization exception using spring. I know this is a common error and I've been through several stack questions, but none of the answers really did it for me. Here's my scenario: I have two classes that relate like such:
public class Foo implements Serializable {
@Id
@EqualsAndHashCode.Include
@Column(name = "uuid")
private UUID uuid;
@Column(name = “attribute”)
private String attribute;
@OneToMany(fetch = FetchType.LAZY, mappedBy = “foo”)
private Set<Bar> bar;
}
public class Bar implements Serializable {
@Id
@Column(name = "uuid")
private UUID uuid;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = “foo_uuid")
private Foo foo;
}
I have a rest endpoint that lists all Bar objects. In that specific endpoint, I need to return attribute
, which is a Foo attribute. Since that is not required inside the application business logic, it seemed unnecessary to add attribute
to Bar as well. So I have a BarWrapper
class, which is a custom format of Bar, to be returned by the endpoint:
@Getter
@Setter
@NoArgsConstructor
public class BarWrapper {
…
private String attribute;
public BarWrapper(final Bar bar) {
//The next line throws lazy initialization exception.
this.attribute = bar.getFoo().getAttribute()
}
I have tried @Transactional
on all classes, and didn't work. I tried to add cascade = CascadeType.ALL
, which did work, but is not a good practice. I have also tried creating a custom function just for this, but didn't help either:
@Transactional
private String extractAttribute(final Bar bar){
final Foo foo = bar.getFoo();
return foo.getAttribute();
}
How can I overcome this Lazy initialization exception?
EDIT:
This is how I'm calling the BarWrapper constructor:
@AllArgsConstructor
@Service
@Slf4j
public class BarApplicationServices {
private final FooService fooService;
private final BarService barService;
public BarWrapper createBar(final CreateBarRequestBody requestBody) {
final Foo foo = fooService.findFooToBeSettled(requestBody.getFooUuid());
final Bar createdBar = barService
.createBar(new Bar(foo));
return new BarWrapper(createdBar);
}
}