如何解决JpaRepository缓存新创建的对象如何刷新呢?
如果您使用的是Hibernate,则这是预期的结果。当你打电话translationRepository.saveAndFlush(translation)
,并translationRepository.findOne(t.getId())
一前一后,他们打它保持的所有对象,它已经在工作的高速缓存中的同一个Hibernate
Session。因此,第二个调用只是返回传递给第一个对象的对象。这两行中没有任何内容会迫使HibernateSELECT
在数据库上为该Version
实体触发查询。
现在,JPA规范refresh
的EntityManager
接口上确实有一个方法。不幸的是,Spring Data
JPA没有使用其JpaRepository
接口公开此方法。如果可以使用此方法,则可以完成该操作t =
translationRepository.saveAndFlush(translation)
,然后versionRepository.refresh(t.getVersion())
强制JPA提供程序将版本实体与数据库同步。
实现此方法并不困难。只需SimpleJpaRepository
从Spring Data JPA
扩展类并自己实现该方法即可。有关详细信息,请参阅向所有Spring Data
JPA存储库添加自定义行为。
一种替代方法是像versionRepository.findOne(version.getId())
在转换上设置版本实体之前一样加载版本实体。由于您可以在代码中对版本ID进行硬编码,因此您的版本似乎是静态的。因此,您可以将您的Version
实体标记为@Immutable
和@Cacheable
(前者是特定于Hibernate的注释)。这样,versionRepository.findOne(version.getId())
不应在每次调用数据库时都访问数据库。
解决方法
我有一个JpaRepository在Spring MVC应用程序中持久保存新创建的实体。这个实体看起来像这样(非常简化):
@Entity
public class Translation {
.....
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
@ManyToOne(fetch = FetchType.LAZY)
private Version version;
....
}
和版本实体:
@Entity
public class Version {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "id")
private long id;
@Column(name = "name")
private String name;
@Column(name = "version_code")
private long code;
@OneToMany(fetch = FetchType.LAZY,mappedBy = "version",cascade = {CascadeType.ALL},orphanRemoval = true)
private Set<Translation> translations;
}
我创建一个这样的翻译对象
TranslationDTO t = new TranslationDTO();
t.setText(translationText);
ClientVersionDTO version = new ClientVersionDTO();
version.setId(11);
t.setVersion(version);
其中11是从一开始就已经存在于数据库中的版本。请注意,我没有为ClientVersionDTO 设置name
和code
的值。
然后,我有一个持久化新对象的服务(我使用dozer
库将DTO转换为实体)
@Service
@Transactional
public class TranslationsServiceImpl implements TranslationsService {
@Override
public Long create(TranslationDTO translationDTO) {
Translation translation = translationsConverter.unconvert(translationDTO);
Translation t = translationRepository.saveAndFlush(translation);
Translation t2 = translationRepository.findOne(t.getId());
// !!!! t2.getVersion() returns version where no values are set to 'code' and 'name'
return t2.getId();
}
}
请注意我的评论“
t2.getVersion()返回没有将任何值设置为’code’和’name’的版本”-我期望如此,这样当我从数据库中获取数据时,我将从数据库中获取一个Version
对象与code
和name
设置的值。但是,它们尚未设置。因此,基本上,我作为t2.getVersion()
对象得到的就是与输入自变量相同的对象translationDTO.getVersion()
。他们如何重新使Version
对象无效?
UPDATE 尝试将@Transactional移至JpaRepository,但结果仍然相同。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。