java - 在 Spring Boot 中使用 JPA 保存时,有没有办法获得“刷新”保存的实体?
问题描述
首先,我不确定这是缓存请求还是不填充字段。
我有一个名为 的实体CmsRegions
,其中包含以下内容:
public class CmsRegions extends Model implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name = "id")
private Integer id;
@Basic(optional = false)
@NotNull
@Size(min = 1, max = 100)
@Column(name = "name")
private String name;
@Lob
@Size(max = 65535)
@Column(name = "description")
private String description;
@Size(max = 2)
@Column(name = "lang")
private String lang;
@Size(max = 2)
@Column(name = "locale")
private String locale;
@Basic(optional = false)
@NotNull
@Column(name = "is_active")
private short isActive;
@Column(name = "parent_id")
private Integer parentId;
@Basic(optional = false)
@Column(name = "created", insertable = false, updatable = false)
@Temporal(TemporalType.TIMESTAMP)
private Date created;
@Basic(optional = false)
@Column(name = "modified", insertable = false, updatable = false)
@Temporal(TemporalType.TIMESTAMP)
private Date modified;
...getters and setters etc...
}
我有基本的存储库调用来检索实体:
@NoRepositoryBean
public interface BaseCmsRepository<T extends Serializable> extends JpaRepository<T, Long> {
@Query("SELECT a FROM #{#entityName} a WHERE a.id = :id")
List<T> getById(
@Param("id") Integer id
);
当我保存实体时,它会很好地保存到下表中的数据库中:
CREATE TABLE `cms_regions` (
`id` int unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(100) NOT NULL,
`description` text,
`lang` char(2) DEFAULT NULL,
`locale` char(2) DEFAULT NULL,
`is_active` tinyint unsigned NOT NULL DEFAULT '0',
`parent_id` int unsigned DEFAULT NULL,
`created` datetime DEFAULT CURRENT_TIMESTAMP,
`modified` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=32 DEFAULT CHARSET=utf8;
和字段按预期设置得很好created
,modified
但是我从保存操作中获得的结果实体具有NULL
创建日期和修改日期的值。
我运行了一个测试 - 我的最后一个插入 ID 是 31,所以我将以下代码添加到我的控制器中:
cmsService.saveRegion(region); // save entity
CmsRegions testreg1 = cmsService.getRegion(1);
CmsRegions testreg2 = cmsService.getRegion(region.getId());
CmsRegions testreg3 = cmsService.getRegion(30);
CmsRegions testreg4 = cmsService.getRegion(32); // currently saved entity new ID (32)
执行此操作时 - testreg1 如希望的那样将创建和修改的日期作为 Date 对象包含在内。testreg2 包含空值(此时 region.getId() = 32)。testreg3 包含创建和修改的日期对象。
最终值 testreg4 也是 NULL。更重要的是,下次我运行它时,testreg4 中包含了created
and的值modified
。但是下一次迭代,testreg2 中的 (33) 再次为 NULL。
我不知道这是缓存问题还是什么。似乎如果我尝试在调用完成之前提取数据库值 - 即使数据现在在数据库中(通过断点确认) - 结果字段始终为空。下一次运行,它们被填充。
为什么?我需要做什么才能获得这些值?
解决方案
在任何类似接口上使用JpaRepository#save
或此方法保存时,将返回数据库中的实体。你可以使用它。它最常用于填充生成的 id:
assertNull(entity.getId());
entity = entityRepository.save(entity);
assertNotNull(entity.getId());
当其他进程正在更改数据并且不刷新持久性上下文时,情况会更加复杂。那时将需要另一个查询。你可以通过使用EntityManager#refresh
和传递你想从数据库中“重新获取”的实体来解决这个问题。目前我不知道该机制是否存在于 spring-data-jpa 中。
推荐阅读
- python - Python unittest 无法访问 PyCharm 中的本地环境变量
- codeigniter - 使用角色autor而不是用户注册新用户(codeigniter)
- reactjs - 我是在客户端还是服务器上对 API 数据进行分页?
- php - Laravel Redis 队列忽略节流
- ios - 可扩展的 tableView 单元格字体
- go - 如何从同一地图内的另一个函数调用存储在地图中的函数
- javascript - 徽标布局问题,即使调整了窗口大小,如何使其静态?
- bash - 如何在 GCE 启动脚本中获取当前区域和项目 ID?
- c# - 移动呈现不正确 Azure App Service Blazor Webassembly(ASP.NET 托管)
- azure - Azure 数据工厂中数据流中的 DFExecutorUserError 消息