我实现了org.hibernate.event.spi.PreInsertEventListener
接口(interface)来填充公共(public)字段,例如createdTime,modifiedTime等实体。我还使用 Spring Boot Data Repository 接口(interface)来处理 REST
方法。
POST
方法工作正常,并且用户详细信息将保留在表中。请求正文为:
{
"login": "nagu2",
"password": "123456",
"displayName": "Nagu 2",
"preferences": "Test",
"userProfile": {
"firstName": "Nagarajan"
},
"userStatus": "USERSTATUS_ACTIVE"
}
但是,201 响应的正文包含使用 PreInsertEventListener
填充的字段的空值。响应正文为:\
{
"createdTime": null,
"updatedTime": null,
"createdBy": null,
"updatedBy": null,
"tenant": 1,
"login": "nagu2",
"password": "123456",
"displayName": "Nagu 2",
"preferences": "Test",
"userRoles": null,
"userProfile": {
"createdTime": null,
"updatedTime": null,
"createdBy": null,
"updatedBy": null,
"tenant": 1,
"firstName": "Nagarajan",
"middleName": null,
"lastName": null,
"dateOfBirth": null,
"timeZone": null,
"primaryPhone": null,
"secondaryPhone": null,
"primaryEmail": null,
"secondaryEmail": null
},
"lastLoginTime": null,
"userStatus": "USERSTATUS_ACTIVE",
"_links": {
"self": {
"href": "http://localhost:8080/api/user/6"
},
"user": {
"href": "http://localhost:8080/api/user/6"
}
}
}
如果我 GET
201 响应的位置 URL,我确实会获取填充有非空值的所有字段。位置 URL 的 GET 响应为:
{
"createdTime": "2019-12-07T11:29:50.000+0000",
"updatedTime": "2019-12-07T11:29:50.000+0000",
"createdBy": 1,
"updatedBy": 1,
"tenant": 1,
"login": "nagu2",
"password": "123456",
"displayName": "Nagu 2",
"preferences": "Test",
"userRoles": [],
"userProfile": {
"createdTime": "2019-12-07T11:29:50.000+0000",
"updatedTime": "2019-12-07T11:29:50.000+0000",
"createdBy": 1,
"updatedBy": 1,
"tenant": 1,
"firstName": "Nagarajan",
"middleName": null,
"lastName": null,
"dateOfBirth": null,
"timeZone": null,
"primaryPhone": null,
"secondaryPhone": null,
"primaryEmail": null,
"secondaryEmail": null
},
"lastLoginTime": null,
"userStatus": "USERSTATUS_ACTIVE",
"_links": {
"self": {
"href": "http://localhost:8080/api/user/5"
},
"user": {
"href": "http://localhost:8080/api/user/5"
}
}
}
按照in this SO question的建议将RepositoryRestConfiguration.setReturnBodyOnCreate
设置为true也没有帮助。
您能帮我想办法在 POST 请求的 201 响应中为 PreInsertEventListener-modified-fields 返回非空值吗?
最佳答案
以下观点来自 This SO Question和 this blog post
If you have insert and update actions on your entity in one single transaction, then your preInsert listener actions will be overridden by the update action.
帮助我解决了问题。
这里需要注意的是:
在 onPreInsert
方法中,当我仅更新 Object[] state
中的值时,它会导致 insert
和 update
查询触发。但是,当我在 Object[] 状态和实体 (event.getEntity()) 中设置值时,hibernate 仅触发插入查询并且 201 响应 JSON 包含非空值。
以下是修改后的onPreInsert
实现:
public boolean onPreInsert(PreInsertEvent event) {
if (event.getEntity() instanceof BaseEntity) {
Object obj = event.getEntity();
BaseEntity entity = (BaseEntity) obj;
boolean isMultiTenant = event.getEntity() instanceof BaseMultiTenantEntity;
Object[] state = event.getState();
String[] propertyNames = event.getPersister().getEntityMetamodel().getPropertyNames();
Date createdTime = new Date();
entity.setCreatedTime(createdTime);
setValue(state, propertyNames, CREATED_TIME_PROPERTY, createdTime);
Integer createdBy = getUserId();
entity.setCreatedBy(createdBy);
setValue(state, propertyNames, CREATED_BY_PROPERTY, createdBy);
entity.setUpdatedTime(createdTime);
setValue(state, propertyNames, UPDATED_TIME_PROPERTY, createdTime);
entity.setUpdatedBy(createdBy);
setValue(state, propertyNames, UPDATED_BY_PROPERTY, createdBy);
if (isMultiTenant) {
BaseMultiTenantEntity multiTenantEntity = (BaseMultiTenantEntity) obj;
multiTenantEntity.setTenant(getTenant());
}
}
return false;
}
关于java - Hibernate PreInsertEventListener 修改的字段在 Spring Boot 存储库 POST 响应 JSON 中显示为 null,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59226147/