Spring @Transactional合并并坚持提问

thi*_*rdy 5 java spring jpa

Spring和@stackoverflow的新手

我正在为分销商业务构建一个独立的库存和销售跟踪应用程序(Apache Pivot/Spring/JPA/Hibernate/MySQL).

到目前为止,我认为一切都是CRUD,所以我计划有一个基础类,包含@Transactional.

然后我的save泛型方法出了问题.从Spring继承和合并EntityManager的方法有区别吗?

我试着运行并调用了插入和更新的保存,它运行正常(我认为每次调用我的保存方法时,spring会自动刷新实体//看到hibernate查询被记录,这是对的吗?).

@Transactional
public abstract class GenericDAO {

    protected EntityManager em;

//  em getter+@PersistenceContext/setter

    public void save(T t) {
//        if (t.getId() == null) // create new
//        {
//            em.persist(t);
//        } else // update
//        {
            em.merge(t);
//        }
    }
}
Run Code Online (Sandbox Code Playgroud)

顺便说一句,有了这样的设置,我不会在很大程度上影响性能吗?就像调用salesDAO.findAll()来生成报告一样(不需要是事务性的,对吧?).

谢谢!!!

Kal*_*see 5

这个问题是对持久性与合并的良好讨论,并且接受的答案很好地解释了它.另一个答案也链接到一篇关于此的好博文.

根据这篇文章中的第一篇回复,听起来有可能为了保存和更新实体而调用merge,但这并不是我如何做到的.在我的Spring/JPA应用程序中,我只是让我的DAO扩展JpaDaoSupport并以下列方式使用getJpaTemplate().

/**
 * Save a new Album.
 */
public Album save(Album album) {
    getJpaTemplate().persist(album);
    return album;
}

/**
 * Update an existing Album.
 */
public Album update(Album album) {
    return getJpaTemplate().merge(album);
}
Run Code Online (Sandbox Code Playgroud)


Jas*_*man 5

Kaleb 发布的另一个 SO 问题的链接确实很好地涵盖了 persist() 与 merge() 的差异和陷阱。但是,我总是使用一个只调用 merge() 来处理插入和更新的 save() 方法来实现我的 Dao 类,而且我从未遇到过任何 persist() 与 merge() 问题。

至于性能和事务方法:使用@Transactional仅作为读取操作的方法不会真正影响性能,尽管我更喜欢在方法级别使用注释,以便我可以轻松分辨哪些方法是更新,哪些是读取。您可以通过readOnly@Transactional注释上设置属性来做到这一点。

如果您在方法中遵循命名约定(即任何读取方法总是以 开头getXXX),您还可以在 Spring 配置文件中使用 poincut 语法来自动进行这种区分:

  <tx:advice id="txAdvice" transaction-manager="txManager">
    <tx:attributes>
      <tx:method name="get*" read-only="true"/>
      <tx:method name="*"/>
    </tx:attributes>
  </tx:advice>
Run Code Online (Sandbox Code Playgroud)

有关更多信息,请参阅有关事务Spring 文档

此外,我通常将@Transactional属性放在我的 Dao 类之上一级,在服务层中。Dao 类上的方法对于每个方法调用都是不同的数据库操作,而服务方法可以为一系列更新执行单个提交/回滚。