2011-12-19 53 views
2

我有這種非標準的情況,我需要在readOnly Hibernate事務中更新對象。事情是,我加載了許多其他對象,在該事務中更改它們,但只能保存一個對象,並且保留其他對象。在我工作的數據庫PostgreSQL的8.4Spring + Hibernate + Postgresql readOnly事務,按需保存

我真的不知道我理解正確的文檔,但在撥打服務方法:

@Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW) 

應導致明確對節約打開新RW交易。

主要的是,這是行不通的:

@Transactional(readOnly = true) 
public class PersonService { 

    @Resource(name="sessionFactory") 
    private SessionFactory sessionFactory; 

    public void add(Person person){ 

     person.setFirstName("changed its name"); 
     save(person); 
    } 

    @Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW) 
    public void save(Person person) { 

     Session session = sessionFactory.getCurrentSession(); 

     session.save(person); 
     session.flush(); 
    } 
} 

之後,我得到

org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.hibernate.exception.GenericJDBCException: Could not execute JDBC batch update

從控制器,調用 '添加' 方法。 'add'處於readOnly模式,它將Person對象傳遞給'save'方法,該方法應該打開新的Transaction並保存到數據庫。在我的'add'方法項目中,我加載了很多其他的'Person'對象,這些對象不應該被保存。 我需要讀取方法的原因是我在代碼中加載了更多的對象:)將它們回滾是我想要做的最後一件事。

可以這樣做嗎?

回答

1

事務通常是通過生成一個服務接口的實現應用(你不顯示,你實現一個接口,這可能只是你的示例代碼?)

無論如何,問題是,在這種情況下,簡單地調用save(...)不會通過包裝器,它只是在目標對象上運行該方法。您需要將服務的引用注入到自身,以便它可以調用自身並獲取應用的包裝。那就是:

public class PersonServiceImpl implements PersonService { 
    PersonService personService; 
    public void readOnlyMethod() { 
    // ... 
    personService.readWriteMethod(...); 
    } 
    public void readWriteMethod(...) { 
    } 
} 

且調用棧看起來是這樣的:

PersonServiceImpl.readWriteMethod(...) 
TransactionAroundAdvice.advise(...) // starts/ends new read-write transaction 
$Proxy.readWriteMethod(...) // implementing PersonService 
PersonServiceImpl.readOnlyMethod(...) 
TransactionAroundAdvice.advise(...) // starts/ends read-only transaction 
$Proxy.readOnlyMethod(...) // implementing PersonService 
ClientCode.doSomethingNotReallyReadOnly(...) 

(什麼你所描述的一樣記錄某種類型的錯誤消息,這是我用過requiresNew聲音事務處理標記(雖然在J2EE中,但我認爲這一點在進行))

+0

+1 yup,這就是爲什麼它不起作用。在添加@Resource(name =「personService」)私人PersonService personService並調用personService.save(person)後,它工作正常並且在數據庫中保存。非常感謝! – Krystian 2011-12-20 01:58:07

+0

非常感謝! :-) – Maciej 2011-12-20 08:16:41

相關問題