NullPointerException обращаясь к сущности по ID, когда используется аудит @CreatedBy - PullRequest
0 голосов
/ 08 апреля 2020

Я только что добавил отношение с @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

При получении этого приглашения с идентификатором 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, я удалил аннотацию @Data из Company и создал методы получения и установки вручную. Таким образом, получение приглашения по идентификатору работает.

Имеет ли это смысл для кого-либо?

...