I have a entity call Company, and another entity call token.
1 Company will have many tokens.
So in my Company entity, I will have something like follow:
@OneToMany(mappedBy = "companyId")
public Set< Token > getTokens() {
return tokens;
}
However, I will have some logic during the return, it will change the token list before return, its something like follow:
@OneToMany(mappedBy = "companyId")
public Set< Token > getTokens() {
tokens.remove( token );
return tokens;
}
Because of I changing the value in token list, thus, every time I select the company object from db using hibernate, the company table will be updated automatically.
Base on my understanding, this is a behavior of hibernate dirty checking. So when Hibernate detect that there something changes on it, it will do the update to database.
Is there any way that can avoid this? For example maybe just call existing hibernate function, so that hibernate will know the token list is dirty, and it will no do the update.
Yes, I know the filtering logic in the getTokens() is not suitable. By right filtering logic should not apply in entity level. But because of currently there is many place using this method, if I change in this entity level, then there will impact others and if I change other place as well, it will need to retest whole application again.
Thus I am trying to find a better way on this.
What you actually want is to prevent Hibernate from auto
flushing.See hibernate docs:
A solution to this problem is to change the default configuration of
FlushModefrom auto to manual by settingFlushMode.MANUAL. In this way the dirty check mechanism will stop causing the aforementioned synchronization.Although the
Sessionis only ever flushed whenSession.flush()is explicitly called by the application as described in the hibernate documentation.Here it has to be mentioned that if you follow the suggested solution you need to pay the price of the explicitly flushing which means that you need to explicitly call the
Session.flush()method every time you want to commit something on the database.Read here some useful material regarding
FlushModeas were officially documented in hibernate documentation.UPDATE:
This solution applies on the Session, so if you want to apply this only on the specific entity you should try to create two methods. One for setting it to MANUAL and one for back to the default AUTO. In this way you will change your value after MANUAL setting to prevent flushing and subsequently you will set it back to the default in order not to affect the other entities.
Maybe the below implementation will help: