Colleagues summarize the cool problem of hibernate updating data unexpectedly.

Colleagues summarize the cool problem of hibernate updating data unexpectedly.

To action developers:

Since it was discovered a few days ago that after the Bean taken out from the database is modified, the modified result will be reflected in the database again, and the following analysis and solution are proposed.

 

reason:

Under normal circumstances, after the Service ends, the transaction ends. At this time, the Hibernate Session should disappear, however, because the data provides lazy loading

Therefore, it is necessary to provide a Session in the Web layer to load data. At this time, the life cycle of the Session needs to be extended. Spring

Provides the OpenSessionInViewFilter class, when a web request comes in, the request is assigned a Hibernate Session to the request thread

Up until the end of the request, at this time we retrieve a piece of information from the database to the Controller layer through the Manager, no matter how it is modified in the Controller layer,

will not be synchronized to the database, because the default session refresh method is AUTO (re-retrieving data, submitting transactions, refreshing data will activate the data synchronization function),

However, under normal circumstances, we use other Manager methods to activate the same Session after modification, so that the refresh event in the Session is activated,

The consequence of this is that Hibernate submits the modified data as legitimate dirty data. Causes the value in the database to be modified. That is, the database

The data in has been modified. This is because everyone uses the methods in the manager multiple times in the same request. Before the manager method is used for the last time, the

Data Beans were modified.

 

Solution:

Since the bean is managed in hiberante, if it is instantiated, the data will not be stored in the hiberante cache, and it will be retrieved from the database again, so that even if we

Modifying it doesn't help, so I'll propose a workaround now.

 

YHB.DISABLE_SYNC (a constant in YHB), marks an object to disable synchronization with objects in the database.

When we retrieve a piece of information from the database, the data in the object is modified for some reason, and we do not want to synchronize it to the database, please execute the object's

Bean.setVersion(YHB.DISABLE_SYNC), you can prohibit the object from modifying the database. This method is only useful for automatically submitting updates. Manually calling the update method is invalid.

After using this method in the background, it still insists on calling the update object, which will cause the version out-of-sync exception to occur. The object that works in this way is only for persistent objects in Session that do not want to be updated

It works, please confirm whether it is necessary to use it.

 

example:

UkeMember member = manager.findById(1); // Get a member

Integer version = member.getVersion(); // Temporarily store the version number of the member object,

// If there is no concept of version number in the foreground, it can be ignored

member.setVersion(YHB.DISABLE_SYNC); // Prevent the object content from synchronizing with the database object

member.setName("hello"); // Modify the content of the object

promotionRuleMng.initPromotionRules(member); // The session is activated again, and the object survives to the session.

// The data is synced to the database as it is.

member.setVersion(version); // restore the original version number

Assert.assertTrue("liutie".equals(name)); // verify or return

 

The above functions have been implemented, please pay attention to the update.

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=327065454&siteId=291194637