0

我有一个典型的 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();

    }
}

我想我可能有一个跨种族问题,但正如我所说,在离开 Service 方法后,新的 Person 被持久化在数据库中。在日志中我看到:

插入人...

但是,我做的更新并没有持久化,日志中也没有错误,也没有'update' sql语句。我认为 HibernateTemplate.save() 方法可能是问题,但在 saveSomeStuff() 方法中,从数据库加载 Person 后,我执行 System.out,从数据库加载的 Person 具有更新的名称。

我在这里想念什么?

4

4 回答 4

1

有一个单独的方法,saveOrUpdate(entity)。如果你不想让hibernate在保存时生成id,你可以使用它。

于 2013-02-26T14:35:05.943 回答
0

Save 方法将持久化一个实体。如果不存在,将分配一个标识符。如果是这样,它本质上是在进行更新。返回生成的实体 ID。

于 2013-02-26T19:00:13.823 回答
0

想通了问题。如果我包含了我的 Entity 类,那么有人可能会比我更早看到它。

@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。

于 2013-02-28T12:39:35.270 回答
0

我偶然发现了同样的问题。实体被插入到数据库中,但是在更新一些未更新的列时,日志中没有错误。通过实体类后,我发现我已经注释了我的一些字段,如下所示

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

从注释中删除可更新属性后,更新工作正常。

于 2017-02-21T15:02:49.960 回答