Hello, I'm running into some serious performance issues when updating an indexed entity, possibly similar issues as described in this post:
viewtopic.php?f=9&t=1043082Here is the simplified code showing how I've set up the entities and search graph:
Code:
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public class Profile {
@Id
public int id;
@Field
public String name;
@IndexedEmbedded(includePaths = "name")
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(referencedColumnName = "id")
public Profile parentProfile;
@ContainedIn
@OneToMany(mappedBy = "parentProfile")
public Set<Profile> childrenProfiles = new HashSet<Profile>();
@IndexedEmbedded(includePaths = { "id.userId" })
@OneToMany(mappedBy = "profile")
public Set<AdminMap> adminMap = new HashSet<AdminMap>();
@IndexedEmbedded(includePaths = { "id.userId" })
@OneToMany(mappedBy = "profile")
public Set<FavouritesMap> favouritesMap = new HashSet<FavouritesMap>();
}
@Indexed
@Entity
public class BusinessProfile extends Profile {...}
@Indexed
@Entity
public class UserProfile extends Profile {...}
@Entity
public class FavouritesMap {
@EmbeddedId
@IndexedEmbedded
public FavouritesMapId id;
@ContainedIn
@ManyToOne
@JoinColumn(insertable = false, updatable = false)
public Profile profile;
@ManyToOne
@JoinColumn(insertable = false, updatable = false)
public User user;
}
@Embeddable
public class FavouritesMapId {
@Field
public int userId;
public int profileId;
}
So we have a Profile entity, which can have 1 parent and many children. A Profile also has a set of users that are administrators for the profile (adminMap), and a set of users that have favourite'd that profile (favouritesMap). I've included the FavouritesMap entity class and associated id class, the AdminMap follows the same structure. The Profile entity is not directly indexed, but it's extended types are
This is the code for when a user does the action of 'favouriting' a profile:
Code:
public FavouritesMap setAsFavourite(int userId, int profileId) {
FavouritesMap fav = new FavouritesMap(new FavouritesMapId(userId, profileId));
Profile profile = (Profile)entityManager.findById(Profile.class, profileId);
fav.setProfile(profile);
entityManager.save(fav);
return fav;
}
What I would expect to happen is that when we call entityManager.save(fav), hibernate search sees the @ContainedIn field 'profile', looks up the index for that profile item, and just adds the new field (favouritesMap.id.userId) to that profile item in the index.
However what appears to be happening is that hibernate search is initialising all of the collections (adminMap, favouritesMap and childrenProfiles) in the profile entity. Which in some of my cases results in 1000's of associated entities being fetched, causing huge performance issues. This is evidenced as the method setAsFavourite is returning a FavouritesMap object with the profile field's collections all fully initialised. If I remove the hibernate search annotations, then the object is correctly returning unintialised lazy collections, suggesting it's a hibernate search issue.
So my question is, is this the correct behaviour for hibernate search to initialise all these lazy collections and reindex all fields when adding an item via a @ContainedIn reference? If so, ...why? surely it just needs to add that one new field rather than revalidate the entire index for that entity. If not, is there any obvious errors with my setup, or how may I best debug this issue?
Thanks