How to manage Lazy Loading in Mapstruct?
Asked Answered
M

2

9

I am dealing with a problem related with lazy loaded objects from the database.

Let's say that we have the below entity.

@Entity(name = "User")
@Table(name = "USERS")
public class User{
    @Id
    @GeneratedValue
    private int id

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name="NOTES_ID")
    private List<Note> notes;
}

And the Dto would be

@Mapper
public interface UserDtoMapper{

    /** the INSTACE HERE **/

    User fromDto(UserDto dto);

    UserDto toDto(User user);

}

So which could be the best approach for fetching all the users without to have a EJBException because I'm fetching them laziness?

Edit: Solution

Let's say you have the following data model

public class User{

    private String name;

    //... other fields

    @OneToMany
    private Set<Address> addresses;
}
  1. Querying without addresses, exception: When mapping from Model to DTO it will try to map addresses but because is lazy loaded (via hibernate, or any other framework) will end up in exception.

Additionally you can ignore the addresses from being mapped, as @Mehmet Bektaş . But is not needed to define the source, it's optional.

@Mapping(target = "addresses", ignore = true)
  1. Fetching relationships: This is the way. Add a join to query the addresses and Mapstruct will do the rest.
Maidenhead answered 15/3, 2016 at 15:26 Comment(3)
Fetch all the necessary data in the same transaction. That way there will be no exceptions related to lazy loading.Lysenko
Where (in which application layer) are you doing the mapping? It should happen as part of the transaction ideally, or you specify an entity graph which ensures all relationships to be mapped are eagerly loaded.Shane
#53466314Upheave
D
1

You can use Mapstruct to Lazy Load all of the entities you want when it does it's mapping (assuming session is still active). The unloaded proxies that you don't want can be ignored by using ignore annotation. More details here. Can MapStruct do a deep deproxy of Hibernate Entity Classes

Doublequick answered 10/2, 2017 at 22:3 Comment(0)
E
1

You can use ignore option.

 @Mapping(source = "user.id", target = "userId", ignore = true)

But in this way you can't map the relational fields like eager fetch type.

Exanimate answered 8/8, 2019 at 5:48 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.