如何在hibernate中删除更改检查



Hibernate在提交事务时检查实体的状态。当获取大量数据发送到客户端时,这是无用的和性能关键的。

我找到了一个解决方案

entityManager.setFlushMode(FlushModeType.COMMIT);

我在查询后放回auto。是否有正规的更紧解

现在我正在考虑做类似的事情aspectJ这样我就不会弄乱代码,并且可以同时对服务和存储库进行注释。您对此有何看法?您将如何解决这个问题?

的例子:

@Override
public Collection<ZoomCallInfoDTO> findZoomCalls(Collection<ContactId> invitedUsers, String name, Date startTime, Date endTime, int offset, int limit, boolean asc, callId callId)
{
// Why we did it?
// Due to bad logic of finding calls in time interval (ZoomCallRepository#findAllByProfileAndcallWithinRange)
// which loaded all calls for user to compute periodical calls there are TOO many entities in hibernate.
// So during converting calls to DTOs we also have N x M queries (N - number of call to return, M - number of queries for each call conversion).
// Each query makes hibernate checks all loaded entities for autoFlush policy. And we have bad performance ((
// Possible decisions:
// 1. Switch off autoFlush policy for GET methods:
//    1.1 - Use readOnly transaction (not good for us now because stating top transaction logic is not managed)
//    1.2 - Set flushMode manually (not good as persistence decision but the cheapest now) - CURRENTLY USED
// 2. Decrease number of loaded to hibernate entities - it need to redesign logic of computing periodical calls
// 3. Merge of 1 and 2 decisions - SHOULD BE IMPLEMENTED IN FUTURE
entityManager.setFlushMode(FlushModeType.COMMIT);
if (invitedUsers != null && !invitedUsers.isEmpty())
{
throw new RuntimeException("Search by invited users is not supported.");
}
UserProfile profile = callUtil.getCurrentUserProfile();
List<ZoomCallInfoDTO> callDTOs = new ArrayList<>();
Map<callId, callCacheItem> callCache = new HashMap<>();
for (ZoomCall call : ZoomCallRepository.findAllByProfileAndcallWithinRange(profile.getId(), name, startTime, endTime, offset, limit, asc, callId))
{
callDTOs.add(create(call, profile.getId(), callCache));
}
entityManager.setFlushMode(FlushModeType.AUTO);
return callDTOs;
}

我注意到在这些操作之后有一个"autoflush"他们人太多了

一个解决方案是实现CustomEntityDirtinessStrategy

properties.setProperty("hibernate.entity_dirtiness_strategy", EntityDirtinessStrategy.class.getName());

细节:

如何自定义Hibernate脏检查机制

多:

实体污秽检查选项

CustomEntityDirtinessStrategy是Hibernate最近添加的API,允许我们提供特定于应用程序的脏检查机制。123.4567891011121314151617181920.21222324252627282930.313233343536373839公共类EntityDirtinessStrategy实现CustomEntityDirtinessStrategy {

@Override
public boolean canDirtyCheck(Object entity, EntityPersister persister, Session session) {
return entity instanceof DirtyAware;
}
@Override
public boolean isDirty(Object entity, EntityPersister persister, Session session) {
return !cast(entity).getDirtyProperties().isEmpty();
}
@Override
public void resetDirty(Object entity, EntityPersister persister, Session session) {
cast(entity).clearDirtyProperties();
}
@Override
public void findDirty(Object entity, EntityPersister persister, Session session, DirtyCheckContext dirtyCheckContext) {
final DirtyAware dirtyAware = cast(entity);
dirtyCheckContext.doDirtyChecking(
new AttributeChecker() {
@Override
public boolean isDirty(AttributeInformation attributeInformation) {
String propertyName = attributeInformation.getName();
boolean dirty = dirtyAware.getDirtyProperties().contains( propertyName );
if (dirty) {
LOGGER.info("The {} property is dirty", propertyName);
}
return dirty;
}
}
);
}
private DirtyAware cast(Object entity) {
return DirtyAware.class.cast(entity);
}

}

相关内容

  • 没有找到相关文章

最新更新