2010-04-21 63 views
4

有沒有我可以在休眠設置的任何參數,以便臨時不允許任何東西持續存在,但只允許只讀(臨時)?我可以在applicationcontext.xml中設置嗎?春天+休眠設置不允許保存

+0

@cometta你可以展示你想要做什麼,爲什麼? – 2010-05-04 03:13:14

+0

@Arthur讓我們說我們有一個數據庫內的數據的Web應用程序。爲了演示目的,我們不希望我們的客戶端使用這些數據,因此,如果可以在xml文件中設置只讀模式,那會很好。 – cometta 2010-05-04 09:33:13

回答

3

Hibernate有一個方法Session.setReadOnly(Object persited, boolean readOnly),允許您將持久對象標記爲只讀。

Hibernate 3.5也有Session.setDefaultReadOnly(boolean),可用於將會話檢索到的所有對象設置爲只讀。

接下來的挑戰是在SessionFactory創建的Session實例上找到設置此屬性的方法。我想AOP可以用來代理LocalSessionFactoryBean來攔截創建的SessionFacotory實例,將大多數方法委託給原始實例,但攔截openSession(...)方法。但我對春季AOP並不熟悉,而且它很快就會變得很難理解。這裏有一個直接的方法:

首先,你的包在LocalSessionFactoryBean定製實現:

​​

那麼這個類添加到您的代碼庫。 (即使使用AOP,你將需要引入一些自定義代碼。)

public class ReadOnlySessionFactoryBean extends AbstractFactoryBean 
{ 
    private AbstractSessionFactoryBean sessionFactoryBean; 

    public ReadOnlySessionFactoryBean(AbstractSessionFactoryBean sessionFactoryBean) 
    { 
     this.sessionFactoryBean = sessionFactoryBean; 
    } 

    @Override 
    public Class getObjectType() 
    { 
     return sessionFactoryBean.getObjectType(); 
    } 

    @Override 
    protected Object createInstance() throws Exception 
    { 
     SessionFactory factory = sessionFactoryBean.getObject(); 
     return new WrapSessionFactory(factory); 
    } 

    static class WrapSessionFactory implements SessionFactory 
    { 
     private Sessionfactory delegate; 

     WrapSessionFactory(SessionFactory delegate) 
     { 
      this.delegate = delegate; 
     } 

     // delegate most methods to the delegate SessionFactory 

     // override all the openSession(...) methods 
     public Session openSession() 
     { 
      Session session = delegate.openSession(); 
      session.setDefaultReadOnly(true); 
      return session; 
     } 
    } 
} 

只需這一變化,你的代碼的其餘部分可以運行未經修改,每一次都會得到一個只讀的SessionFactory。如果您想確保沒有對數據庫進行寫操作,則可以覆蓋寫入數據庫的方法,例如, saveOrUpdate,update,雖然我不確定這是否真的有必要。

1

您可以標記您的交易爲只讀:

@Transactional(readOnly=true) 

一個副作用,我觀察到,當人們忘記做一個方法的事務是沒有插入或更新發生,只會選擇。您可以嘗試完全省略事務聲明。

你還可以嘗試:

<prop key="org.hibernate.FlushMode">NEVER</prop> 

(或session.setFlushMode(FlushMode.NEVER)

如果還是不行,你只能在情況下,換你DAO與spring AOP呼籲,並繼續到persist方法自定義配置屬性已設置。

+0

但我不想拋出錯誤,當我打電話hibernate.updateOrMerge。當這個被調用時,我希望它不會保存,並且不會返回錯誤 – cometta 2010-04-21 08:44:08

+0

我不確定它是否會拋出異常 – Bozho 2010-04-21 08:48:19

+0

有沒有hibernate_readonly參數可以設置? – cometta 2010-04-21 08:53:30

1

我會在數據庫級別處理這個問題,並配置應用程序在演示期間使用具有隻讀權限的用戶(對演示使用特定用戶或更改當前使用的權限)。簡單,有效,並保證以最小的努力工作。