2013-02-26 38 views
0

我有一個典型的Spring/Hibernate設置。這裏是我的Spring配置:HibernateTemplate保存執行插入但不更新

<context:annotation-config /> 

<context:component-scan base-package="com.myco.myapp.modules" /> 

<tx:annotation-driven transaction-manager="transactionManager"/> 

<bean id="sessionFactory" 
...  
</bean> 

<bean id="transactionManager" 
    class="org.springframework.orm.hibernate3.HibernateTransactionManager"> 
    <property name="sessionFactory" ref="sessionFactory" /> 
</bean> 

我有一個BaseRepository:

@Transactional(propagation = Propagation.MANDATORY) 
public final T save(final T entity) throws RepositoryException { 
    try { 
     getHibernateTemplate().save(entity); 
     return entity; 
    } catch (DataAccessException e) { 
     throw new EntityCouldNotBeSavedException(getPersistentClass(), 
      e); 
    } 
} 

這延伸的倉儲類是:

@Repository 
public class PersonRepositoryImpl extends BaseRepositoryImpl<Person, String> 

與服務:

@Service 
public class PersonServiceImpl { 
    @Autowired 
    private PersonRepository _personRespository; 

我打電話給以下方法,sav eSomeStuff(),當我插入使用BaseRepository.save()它完美的作品。但是,當我嘗試更新,它不進行更改:

@Override 
@Transactional 
public void saveSomeStuff() { 

    try { 

     Person existingPerson = _personRespository.findById("1"); 

     existingPerson.setName("John"); 

     _personRespository.save(existingPerson); 

     Person dbExistingPerson = _personRespository.findById("1"); 

     // This prints "John". 
     System.out.println(dbExistingPerson.getName()); 

     Person newPerson = new Person(); 
     newPerson.setName("Jack"); 
     _personRespository.save(newPerson); 

    } catch (RepositoryException e) { 
     e1.printStackTrace(); 

    } 
} 

我想我可能有一個transaccionality問題,但正如我所說,在離開服務方法新的人是持久化到數據庫。在日誌中我看到:

插入到人......

不過,我所做的更新並不持久,並且沒有錯誤,並在日誌中沒有「更新」的SQL語句。我認爲HibernateTemplate.save()方法可能是問題,但是從saveSomeStuff()方法中,從數據庫加載Person之後,我執行System.out,並從數據庫加載的Person具有更新的名稱。

我在這裏錯過了什麼?

回答

1

有一個單獨的方法,saveOrUpdate(entity)。如果您不想在保存時希望hibernate生成id,則可以使用它。

+0

是的,那也不管用。 :) 看來,Hibernate足夠聰明,可以區分插入和更新。我也認爲我需要使用saveOrUpdate()。因爲這就是文檔所說的使用。但似乎save()可以很好地執行更新。它只是不堅持! – 2013-02-26 16:30:19

0

保存方法將保留一個實體。如果不存在,將分配一個標識符。如果有的話,它本質上是在做一個更新。返回實體的生成ID。

+0

是的,我意識到這一點。而且它似乎正在執行更新**,在**交易中。但一旦在它之外,更新就會丟失。 沒有任何意義的是,調用相同的方法,並執行插入而不是更新,它完美地工作。 – 2013-02-27 08:35:31

0

找出問題所在。如果我包含了我的實體課程,有人可能會比我更快地看到它。

@Entity 
@Cache(usage = CacheConcurrencyStrategy.READ_ONLY) 
@Immutable 
@Table(name = "PEOPLE") 
public class Person { 
    ... 
} 

起初我正在高速緩存錯誤:

​​

的快速解決方案嗎?添加@Immutable註釋。但是,如果你閱讀文檔吧:

An immutable entity may not be updated by the application. 
Updates to an immutable entity will be ignored, but no exception is thrown. 

這就解釋了爲什麼1)更新已被忽略和2)沒有異常被拋出。

所以我擺脫了@Immutable註解並改變緩存到:

@Cache(usage = CacheConcurrencyStrategy.READ_WRITE) 

而現在一切工作正常。

總結:rtfm。

0

我偶然發現了同樣的問題。該實體被插入到數據庫中,但在更新某些未更新的列並且日誌中沒有錯誤的情況下。通過實體類去之後,我想通了,我已經標註的我的一些領域如下

@Column(name = "CREATED_DT", updatable = false) 
private Date createdOn; 

從註釋去掉更新屬性後,更新工作正常。