Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

On CollectionLoadContext#cleanup, localLoadingCollectionKeys contained [3] entries

I'm still new to JPA and Hibernate and I get following warnings:

WARN  [org.hibernate.engine.loading.internal.LoadContexts] (default task-4) HHH000100: Fail-safe cleanup (collections) : org.hibernate.engine.loading.internal.CollectionLoadContext@50dab521<rs=com.mysql.jdbc.JDBC42ResultSet@44f85804>
WARN  [org.hibernate.engine.loading.internal.CollectionLoadContext] (default task-4) HHH000160: On CollectionLoadContext#cleanup, localLoadingCollectionKeys contained [3] entries

The thing is: I have different users, and for some of them (with very small data), I am able log in, but for the others (with a bit more data, but still small) I am not and then the warnings come instead. My debug logs show, that when the user should be loaded, it's null. (google says, it might come from my entity relationships and the fetch types and modes). Hope someone can help me, I have no idea so far.

The following shows my two main entities and the method, which is invoked after subit login button in the view.

@XmlRootElement
@XmlAccessorType(XmlAccessType.PROPERTY)
@Entity
public class UserProfile extends StringIdEntity implements Serializable {

    private Address address;
    private String fname;
    private String lname;     

    @OneToOne(cascade = {CascadeType.ALL}, fetch= FetchType.EAGER)
    private PhysicalProfile physicalProfile;

    @OneToOne(cascade = {CascadeType.ALL}, fetch= FetchType.EAGER)
    private DietPlan dietPlan;

    @OneToMany(mappedBy = "user", fetch= FetchType.EAGER, cascade = CascadeType.ALL)
    private List<DiaryPage> diaryPages;

    @OneToMany(mappedBy = "user",fetch= FetchType.LAZY, cascade = CascadeType.ALL)
    private List<Meal> meals;

    @OneToMany(mappedBy = "user",fetch= FetchType.LAZY, cascade = CascadeType.ALL)
    private List<Invoice> invoices;

    @OneToMany(mappedBy = "user",fetch= FetchType.EAGER, orphanRemoval = true)
    @Fetch(value = FetchMode.SUBSELECT)
    private List<GroceryOrder> orders;

 @Entity @IdClass(DiaryPageID.class)
public class DiaryPage implements Comparable{ //extends StringIdEntity {

    @Id @ManyToOne
    private UserProfile user;

    @Id @Temporal(TemporalType.DATE)
    private Date date;

    private KcalRevenue kcalRevenue;

    @OneToMany(mappedBy = "diaryPage", cascade = {CascadeType.ALL}, fetch = FetchType.EAGER)
    @Fetch(value = FetchMode.SUBSELECT)
    private List<Meal> meals;

    @OneToMany(mappedBy = "page", cascade = {CascadeType.ALL}, fetch = FetchType.EAGER)
    @Fetch(value = FetchMode.SUBSELECT)
       private List<Grocery> groceries;

    @OneToMany(mappedBy = "diaryPage", cascade = {CascadeType.ALL}, fetch = FetchType.EAGER)
    @Fetch(value = FetchMode.SUBSELECT)
    private List<Workout> workouts;

    @OneToMany(mappedBy = "diaryPage", cascade = {CascadeType.ALL}, fetch = FetchType.EAGER)
    @Fetch(value = FetchMode.SUBSELECT)
    private List<Activity> activities;

public UserProfile checkUserLogin(String email, String password) {
    UserProfile user = em.find(UserProfile.class, email);
    if(user != null) {
        try {
            if(EntityUtils.hashPassword(password, user.getSalt(), UserProfile.HASH_ALGORITHM).equals(user.getPassword())) {
                return user;
            } else return null;
        } catch (EntityUtils.EntityUtilException e) {
            throw new RuntimeException("Passwort konnte nicht gehashed werden.");
        }
    } else return null;
}
like image 253
Galadriel Avatar asked Oct 29 '25 05:10

Galadriel


2 Answers

You get the same error, when you load existing data that uses an enum value you've removed in your code. E.g. if you previously had your enum defined as:

public enum SomeType {
    A,
    B,
    C
}

Then having stored entities such that there are entries with each enum.
If you then say change your enum to:

public enum SomeType {
    A,
    B,
    D
}

Now when you load your existing persisted entities, this same error is thrown because it tries to instantiate your entity with enum value C which is no longer valid.

Sadly this is not clearly communicated in the logs when this is the cause.

If you put a break point in your debugger at org.springframework.transaction.interceptor.TransactionAspectSupport#completeTransactionAfterThrowing (from spring-tx version 5.3.14 / spring boot version 2.6.2)
You'll see that the throwable param contains a message such as this: No enum constant <your enum>.OLD_VALUE

like image 123
Paul Avatar answered Oct 30 '25 22:10

Paul


I solved the problem this way: I changed all collections of entity diaryPage and the orders collection from entity userProfile to be fetched lazily. Probably in the beginning it was okay with less data, but now it's too much to be fetched eagerly in subselects. Because: UserProfile -> n diaryPages -> each page hast 4 collections

like image 39
Galadriel Avatar answered Oct 30 '25 21:10

Galadriel