我有一个典型的Spring / Hibernate设置。这是我的春季配置:
<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类:
@Repository
public class PersonRepositoryImpl extends BaseRepositoryImpl<Person, String>
和服务:
@Service
public class PersonServiceImpl {
@Autowired
private PersonRepository _personRespository;
我调用以下方法saveSomeStuff(),当我使用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问题,但正如我所说,在离开Service方法后,新Person将保留在数据库中。在日志中我看到:
插入人...
但是,我所做的更新没有保留,并且没有错误,也没有更新&#39;日志中的sql语句。我认为HibernateTemplate.save()方法可能是问题,但是在saveSomeStuff()方法中,从数据库加载Person后,我执行System.out,并且从数据库加载的Person具有更新的名称。 / p>
我在这里缺少什么?
答案 0 :(得分:1)
有一个单独的方法saveOrUpdate(entity)
。如果您不希望hibernate在保存时生成id,则可以使用它。
答案 1 :(得分:0)
保存方法将保留实体。如果不存在标识符,将分配标识符。如果有的话,它实质上是在进行更新。返回生成的实体ID。
答案 2 :(得分:0)
找出问题所在。如果我已经包含了我的实体课程,那么有人可能会比我更快地看到它。
@Entity
@Cache(usage = CacheConcurrencyStrategy.READ_ONLY)
@Immutable
@Table(name = "PEOPLE")
public class Person {
...
}
最初我收到了缓存错误:
java.lang.UnsupportedOperationException: Can't write to a readonly object
快速解决方案?添加@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更改为:
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
现在一切正常。
总结:rtfm。
答案 3 :(得分:0)
我偶然发现了同样的问题。该实体已插入到数据库中,但在更新某些未更新的列时,日志中没有错误。在浏览了实体类之后,我发现我已经注释了我的一些字段,如下所示
@Column(name = "CREATED_DT", updatable = false)
private Date createdOn;
从注释中删除可更新属性后,更新工作正常。