首页 > 解决方案 > 使用 @CreatedBy 审计时按 ID 访问实体的 NullPointerException

问题描述

我刚刚向我的一个实体添加了与 @CreatedBy 的关系,从那时起,我收到一个 NullPointerException 通过 ID 访问它。但首先要做的事情是:

实体。我省略了一些字段,但留下了“所有者”,因为堆栈跟踪(见下文)指的是那个。“创建者”是我添加的关系。

@Entity
@Data
@NoArgsConstructor
@EntityListeners(AuditingEntityListener.class)
public class Invitation implements BaseEntity<Long>, OwnedEntity {

    @Id
    @GeneratedValue
    private Long id;

    @NotNull
    @ManyToOne
    private Company owner;

    @CreatedBy
    @OneToOne
    private Account creator;

    ...
}

“创建者”字段由我的 AuditorAware 实现设置,如下所示:

@Component
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class AuditorProvider implements AuditorAware<Account> {

    private static final Log LOG = LogFactory.getLog(AuditorProvider.class);

    private final @NonNull AccountRepo accountRepo;

    @Override
    public Optional<Account> getCurrentAuditor() {
        Optional<Account> opt = accountRepo.findMe();
        if (opt.isPresent()) {
            LOG.debug("Found auditor: " + opt.get());   
        } else {
            LOG.debug("No auditor found."); 
        }
        return opt;
    }

}

accountRepo.findMe() 方法根据安全上下文查找 Account 的当前实例。

有了这个,当我发布一个邀请实体时

curl -XPOST -H "Authorization: Bearer $TOKEN" -H "Content-type: application/hal+json" localhost:8081/invitations -d '{"email":"k@lo.de","role":"http://localhost:8081/roles/139"}'

响应体看起来不错:

{
  "email" : "k@lo.de",
  "_links" : {
    "self" : {
      "href" : "http://localhost:8081/invitations/144"
    },
    "invitation" : {
      "href" : "http://localhost:8081/invitations/144"
    },
    "creator" : {
      "href" : "http://localhost:8081/invitations/144/creator"
    },
    "role" : {
      "href" : "http://localhost:8081/invitations/144/role"
    },
    "owner" : {
      "href" : "http://localhost:8081/invitations/144/owner"
    }
  }
}

邀请的数据库表和日志显示“创建者”已成功设置。

获取所有邀请完全正常,没有任何错误:

curl -v -H "Authorization: Bearer $TOKEN" -H "Content-type: application/hal+json" http://localhost:8081/invitations

获取 ID 为 144 的邀请会给我一个 HTTP 500 错误:

curl -v -H "Authorization: Bearer $TOKEN" -H "Content-type: application/hal+json" http://localhost:8081/invitations/144

查看日志,我看到了这个堆栈跟踪:https ://pastebin.com/mVzHHddU

我在上面的代码片段中留下“所有者”关系的原因是这一行:

at training.edit.identity.model.Company.hashCode(Company.java:22) ~[classes/:na]

除此之外,我对这些行都不熟悉,我无法从错误中理解。

任何想法将不胜感激!

编辑:公司实体

@Data
@NoArgsConstructor
@Entity
public class Company implements BaseEntity<Long>, OwnedEntity {

    @Id
    @GeneratedValue
    private Long id;

    @NotNull
    private String name;

    @NotNull
    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER, orphanRemoval = true)
    private Set<Address> addresses = new HashSet<Address>();

    public boolean addAddress(Address address) {
        return this.addresses.add(address);
    }

    @JsonIgnore
    @Override
    public ScopedEntity getParent() {
        return null;
    }

    @JsonIgnore
    @Override
    public Set<Company> getTenants() {
        return Sets.newHashSet(this);
    }

    @Override
    public void configureTenant(Company tenant) {
        throw new RuntimeException("Cannot configure tenant on Company.");
    }


}

编辑:由于下面的 lombok 相关评论,我从 Company 中删除了 @Data 注释并手动创建了 getter 和 setter。像这样,通过 ID 获取邀请是有效的。

这对任何人都有意义吗?

标签: spring-data-jpaspring-data-rest

解决方案


推荐阅读