日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

hibernate自定义_如何自定义Hibernate脏检查机制

發布時間:2023/12/3 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 hibernate自定义_如何自定义Hibernate脏检查机制 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

hibernate自定義

介紹

在上一篇文章中,我描述了Hibernate自動臟檢查機制。 盡管您應該始終喜歡它,但是有時您可能想添加自己的自定義污垢檢測策略。

自定義臟檢查策略

Hibernate提供以下定制機制:

  • Hibernate攔截器#findDirty()
  • CustomEntityDirtinessStrategy

手動檢查臟物

作為練習,我將構建一個手動的臟檢查機制,以說明自定義更改檢測策略的難易程度:

自臟檢查實體

首先,我將定義一個DirtyAware接口,所有手動臟檢查實體都必須實現:

public interface DirtyAware {Set<String> getDirtyProperties();void clearDirtyProperties(); }

接下來,我將在基類中封裝當前的臟檢查邏輯:

public abstract class SelfDirtyCheckingEntity implements DirtyAware {private final Map<String, String> setterToPropertyMap = new HashMap<String, String>();@Transientprivate Set<String> dirtyProperties = new LinkedHashSet<String>();public SelfDirtyCheckingEntity() {try {BeanInfo beanInfo = Introspector.getBeanInfo(getClass());PropertyDescriptor[] descriptors = beanInfo.getPropertyDescriptors();for (PropertyDescriptor descriptor : descriptors) {Method setter = descriptor.getWriteMethod();if (setter != null) {setterToPropertyMap.put(setter.getName(), descriptor.getName());}}} catch (IntrospectionException e) {throw new IllegalStateException(e);}}@Overridepublic Set<String> getDirtyProperties() {return dirtyProperties;}@Overridepublic void clearDirtyProperties() {dirtyProperties.clear();}protected void markDirtyProperty() {String methodName = Thread.currentThread().getStackTrace()[2].getMethodName();dirtyProperties.add(setterToPropertyMap.get(methodName));} }

所有手動的臟檢查實體都必須擴展此基類,并通過調用markDirtyProperty方法顯式標記臟屬性。

實際的自我臟檢查實體如下所示:

@Entity @Table(name = "ORDER_LINE") public class OrderLine extends SelfDirtyCheckingEntity {@Id@GeneratedValue(strategy = GenerationType.AUTO)private Long id;private Long number;private String orderedBy;private Date orderedOn;public Long getId() {return id;}public Long getNumber() {return number;}public void setNumber(Long number) {this.number = number;markDirtyProperty();}public String getOrderedBy() {return orderedBy;}public void setOrderedBy(String orderedBy) {this.orderedBy = orderedBy;markDirtyProperty();}public Date getOrderedOn() {return orderedOn;}public void setOrderedOn(Date orderedOn) {this.orderedOn = orderedOn;markDirtyProperty();} }

每當調用setter時,關聯的屬性就會變臟。 為簡單起見,當我們將屬性還原為其原始值時,此簡單練習不涵蓋用例。

臟檢查測試

為了測試自臟檢查機制,我將運行以下測試用例:

@Test public void testDirtyChecking() {doInTransaction(new TransactionCallable<Void>() {@Overridepublic Void execute(Session session) {OrderLine orderLine = new OrderLine();session.persist(orderLine);session.flush();orderLine.setNumber(123L);orderLine.setOrderedBy("Vlad");orderLine.setOrderedOn(new Date());session.flush();orderLine.setOrderedBy("Alex");return null;}}); }

Hibernate攔截器解決方案

Hibernate Interceptor findDirty回調使我們可以控制臟屬性發現過程。 該方法可能返回:

  • null ,將臟檢查委托給Hibernate默認策略
  • 一個int []數組,包含修改后的屬性索引

我們的Hibernate臟檢查攔截器如下所示:

public class DirtyCheckingInterceptor extends EmptyInterceptor {@Overridepublic int[] findDirty(Object entity, Serializable id, Object[] currentState, Object[] previousState, String[] propertyNames, Type[] types) {if(entity instanceof DirtyAware) {DirtyAware dirtyAware = (DirtyAware) entity;Set<String> dirtyProperties = dirtyAware.getDirtyProperties();int[] dirtyPropertiesIndices = new int[dirtyProperties.size()];List<String> propertyNamesList = Arrays.asList(propertyNames);int i = 0;for(String dirtyProperty : dirtyProperties) {LOGGER.info("The {} property is dirty", dirtyProperty);dirtyPropertiesIndices[i++] = propertyNamesList.indexOf(dirtyProperty);}dirtyAware.clearDirtyProperties();return dirtyPropertiesIndices;}return super.findDirty(entity, id, currentState, previousState, propertyNames, types);}}

將此攔截器傳遞到當前的SessionFactory配置時,我們將獲得以下輸出:

INFO [main]: c.v.h.m.l.f.InterceptorDirtyCheckingTest - The number property is dirty INFO [main]: c.v.h.m.l.f.InterceptorDirtyCheckingTest - The orderedBy property is dirty INFO [main]: c.v.h.m.l.f.InterceptorDirtyCheckingTest - The orderedOn property is dirty DEBUG [main]: o.h.e.i.AbstractFlushingEventListener - Flushed: 0 insertions, 1 updates, 0 deletions to 1 objects DEBUG [main]: n.t.d.l.SLF4JQueryLoggingListener - Name: Time:1 Num:1 Query:{[update ORDER_LINE set number=?, orderedBy=?, orderedOn=? where id=?][123,Vlad,2014-08-20 07:35:05.649,1]} INFO [main]: c.v.h.m.l.f.InterceptorDirtyCheckingTest - The orderedBy property is dirty DEBUG [main]: o.h.e.i.AbstractFlushingEventListener - Flushed: 0 insertions, 1 updates, 0 deletions to 1 objects DEBUG [main]: n.t.d.l.SLF4JQueryLoggingListener - Name: Time:0 Num:1 Query:{[update ORDER_LINE set number=?, orderedBy=?, orderedOn=? where id=?][123,Alex,2014-08-20 07:35:05.649,1]}

手動臟檢查機制已檢測到傳入的更改,并將其傳播到刷新事件偵聽器。

鮮為人知的CustomEntityDirtinessStrategy

CustomEntityDirtinessStrategy是Hibernate API的新增功能,使我們能夠提供特定于應用程序的臟檢查機制。 該接口可以如下實現:

public static class EntityDirtinessStrategy implements CustomEntityDirtinessStrategy {@Overridepublic boolean canDirtyCheck(Object entity, EntityPersister persister, Session session) {return entity instanceof DirtyAware;}@Overridepublic boolean isDirty(Object entity, EntityPersister persister, Session session) {return !cast(entity).getDirtyProperties().isEmpty();}@Overridepublic void resetDirty(Object entity, EntityPersister persister, Session session) {cast(entity).clearDirtyProperties();}@Overridepublic void findDirty(Object entity, EntityPersister persister, Session session, DirtyCheckContext dirtyCheckContext) {final DirtyAware dirtyAware = cast(entity);dirtyCheckContext.doDirtyChecking(new AttributeChecker() {@Overridepublic 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);}}

要注冊CustomEntityDirtinessStrategy實現,我們必須設置以下Hibernate屬性:

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

運行我們的測試將產生以下輸出:

INFO [main]: c.v.h.m.l.f.CustomEntityDirtinessStrategyTest - The number property is dirty INFO [main]: c.v.h.m.l.f.CustomEntityDirtinessStrategyTest - The orderedBy property is dirty INFO [main]: c.v.h.m.l.f.CustomEntityDirtinessStrategyTest - The orderedOn property is dirty DEBUG [main]: o.h.e.i.AbstractFlushingEventListener - Flushed: 0 insertions, 1 updates, 0 deletions to 1 objects DEBUG [main]: n.t.d.l.SLF4JQueryLoggingListener - Name: Time:1 Num:1 Query:{[update ORDER_LINE set number=?, orderedBy=?, orderedOn=? where id=?][123,Vlad,2014-08-20 12:51:30.068,1]} INFO [main]: c.v.h.m.l.f.CustomEntityDirtinessStrategyTest - The orderedBy property is dirty DEBUG [main]: o.h.e.i.AbstractFlushingEventListener - Flushed: 0 insertions, 1 updates, 0 deletions to 1 objects DEBUG [main]: n.t.d.l.SLF4JQueryLoggingListener - Name: Time:0 Num:1 Query:{[update ORDER_LINE set number=?, orderedBy=?, orderedOn=? where id=?][123,Alex,2014-08-20 12:51:30.068,1]}

結論

盡管默認的字段級檢查或字節碼檢測替代方法足以滿足大多數應用程序的需求,但有時您還是需要對變更檢測過程進行控制。 在長期項目中,定制某些內置機制以滿足特殊的服務質量要求并不少見。 框架采用決定還應該考慮框架的可擴展性和定制支持。

  • 代碼可在GitHub上獲得 。

翻譯自: https://www.javacodegeeks.com/2014/09/how-to-customize-hibernate-dirty-checking-mechanism.html

hibernate自定義

總結

以上是生活随笔為你收集整理的hibernate自定义_如何自定义Hibernate脏检查机制的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。