java - Hibernate PreInsertEventListener 修改的字段在 Spring Boot 存储库 POST 响应 JSON 中显示为 null

标签 java spring hibernate spring-boot

我实现了org.hibernate.event.spi.PreInsertEventListener接口(interface)来填充公共(public)字段,例如createdTimemodifiedTime等实体。我还使用 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 Questionthis 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 中的值时,它会导致 insertupdate 查询触发。但是,当我在 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/

相关文章:

java - 执行查询时出现异常

java - JPA 静态元模型生成器的正确 gradle 设置是什么?

hibernate - Java Hibernate with Persistence Question---如果没有定义FetchType,默认的方法是什么?

java - 将“转换为 %22”的正确 URLencoder 编码是什么?

java - 修改引用的对象是否会影响创建新对象的原始对象?

java - 缺少 Artifact org.springframework :spring-context:jar:${org. springframework-version}

java - 我们可以使用 Web 套接字在微服务之间进行通信吗?

java - 使用外键对 2 个表进行关联时出现 Criteria 问题

java - Java中的协作工具-在客户端之间共享数据的最佳(最简单)体系结构?

java - Spring MVC WebApp 中的推送通知