Java Spring@Transactional合并和持久化问题

Java Spring@Transactional合并和持久化问题,java,spring,jpa,Java,Spring,Jpa,Spring和此处新增@stackoverflow 我正在为分销商业务构建一个独立的库存和销售跟踪应用程序(apachepivot/Spring/JPA/Hibernate/MySQL) 到目前为止,我认为一切都是CRUD,所以我计划用@Transactional创建一个基类 然后,我的save-generic方法出现了问题。Spring中EntityManager的持久化和合并方法有区别吗 我试着运行并调用save来进行插入和更新,它工作得很好(我认为每次调用save方法//看到hiberna

Spring和此处新增@stackoverflow

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

到目前为止,我认为一切都是CRUD,所以我计划用@Transactional创建一个基类

然后,我的save-generic方法出现了问题。Spring中EntityManager的持久化和合并方法有区别吗

我试着运行并调用save来进行插入和更新,它工作得很好(我认为每次调用save方法//看到hibernate查询被记录,spring都会自动刷新实体,对吗?)

顺便说一句,有这样的设置,我不会对性能有太大的影响,对吗?比如调用salesDAO.findAll()来生成报告(不需要是事务性的,对吧?)

谢谢

是对persist和merge的一个很好的讨论,公认的答案很好地解释了这一点。另一个答案也链接到一篇关于这一点的好博客文章

根据中的第一个回复,听起来可以调用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);
}
Kaleb提出的另一个问题确实很好地涵盖了persist()和merge()的区别和局限性。然而,我总是用一个save()方法实现我的Dao类,该方法只调用merge()来处理插入和更新,而且我从未遇到过persist()与merge()之间的任何矛盾

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

如果在方法中遵循命名约定(即任何读取方法总是以
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>

有关更多信息,请参阅


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

I guest这是最简单的方法。所以,如果我有JpaDaoSupport,并且我从中获得了一个实体,那么任何更改都将自动提交?我想我将有两种save方法的变体,一种是持久的,另一种是调用flush。对此有何评论?您的意思是自动提交而不保存或更新吗?如果是这样,我不这么认为,我总是在新实体上调用save或在现有实体上调用update来持久化。我从来都不需要调用flush方法,但是对于任何给定的请求,我的DB访问都非常简单。现在我不得不放弃尝试Spring。只是好奇,Grails是如何改进这一点的?我不必在Grails中遇到这样的问题,对吗?谢谢你的回答。我想我会坚持纯JPA(我不太需要灵活性)
  <tx:advice id="txAdvice" transaction-manager="txManager">
    <tx:attributes>
      <tx:method name="get*" read-only="true"/>
      <tx:method name="*"/>
    </tx:attributes>
  </tx:advice>