Я использую Spring Boot 2.0.3, Spring Data REST, Spring HATEOAS. Моя модель предметной области достаточно структурирована, но в последнее время я обнаружил странное поведение собственных ссылок.
Я собираюсь показать часть модели, чтобы указать на проблему, удалив бесполезную часть:
Проверка зрения:
@EntityListeners(value = EyeExamListener.class)
public class EyeExam extends AbstractEntity {
@NotNull
@JoinColumn(name = "contact_id", updatable = false)
@JsonDeserialize(using = ContactUriDeserializer.class)
@ManyToOne(fetch = FetchType.LAZY, optional = false)
private Contact contact;
@NotNull
@Column(nullable = false, columnDefinition = "DATE")
private Instant date;
Контакт:
@EntityListeners({ContactListener.class})
public class Contact extends AbstractEntity {
@NotNull
@Enumerated(EnumType.STRING)
@Column(nullable = false, columnDefinition = "VARCHAR(30) DEFAULT 'CUSTOMER'")
private ContactType type = ContactType.CUSTOMER;
@NotNull
@Enumerated(EnumType.STRING)
@Column(nullable = false, columnDefinition = "VARCHAR(30) DEFAULT 'NATURAL_PERSON'")
private PersonType personType = PersonType.NATURAL_PERSON;
private String firstName;
private String lastName;
private String companyName;
Это КонтактРепозиторий:
@Transactional
@PreAuthorize("isAuthenticated()")
public interface ContactRepository extends JpaRepository<Contact, Long> {
....
....
}
Когда я получаю определенный ресурс EyeExam (https://myserver.com/api/v1/eyeExams/13), Spring возвращает:
{
"sid" : "f16d6e45-477f-11e9-898e-9d6f4f2f5990",
"createdBy" : "system",
"createdDate" : "2017-05-31T17:38:00Z",
"lastModifiedDate" : null,
"lastModifiedBy" : null,
"createdByName" : "System",
"lastModifiedByName" : null,
"date" : "2017-05-31T00:00:00Z",
"_links" : {
"self" : {
"href" : "https://myserver.com/api/v1/eyeExams/13"
},
"eyeExam" : {
"href" : "https://myserver.com/api/v1/eyeExams/13{?projection}",
"templated" : true
},
"supplyTypes" : {
"href" : "https://myserver.com/api/v1/eyeExams/13/supplyTypes"
},
"changeStatus" : {
"href" : "https://myserver.com/api/v1/eyeExams/13/changeStatus?status=%7Bstatus%7D"
},
"contact" : {
"href" : "https://myserver.com/api/v1/eyeExams/13/contact{?projection}",
"templated" : true
},
"store" : {
"href" : "https://myserver.com/api/v1/eyeExams/13/store{?projection}",
"templated" : true
}
}
}
Как видите, я получаю ссылку на связанный ресурс Контакт. Все в порядке. Теперь я получаю ресурс https://myserver.com/api/v1/eyeExams/13/контакт, и Spring отвечает:
{
"sid" : "4c2ba300-477e-11e9-898e-9d6f4f2f5990",
"createdBy" : "system",
"createdDate" : "2018-11-01T09:00:00Z",
"lastModifiedDate" : null,
"lastModifiedBy" : null,
"createdByName" : "System",
"lastModifiedByName" : null,
"type" : "CUSTOMER",
"personType" : "NATURAL_PERSON",
"firstName" : "John",
"lastName" : "Smith",
"companyName" : null,
"_links" : {
"self" : {
"href" : "https://myserver.com/api/v1/contact/22352"
},
"contact" : {
"href" : "https://myserver.com/api/v1/contact/22352{?projection}",
"templated" : true
},
"notes" : {
"href" : "https://myserver.com/api/v1/contacts/22352/notes"
},
"auditLogs" : {
"href" : "https://myserver.com/api/v1/contacts/22352/auditLogs"
},
"media" : {
"href" : "https://myserver.com/api/v1/contacts/22352/media"
},
"privacyAgreements" : {
"href" : "https://myserver.com/api/v1/contacts/22352/privacyAgreements"
},
"eyeExams" : {
"href" : "https://myserver.com/api/v1/contacts/22352/eyeExams"
},
"eyeExamsCount" : {
"href" : "https://myserver.com/api/v1/contacts/22352/eyeExams/count"
},
"documents" : {
"href" : "https://myserver.com/api/v1/contacts/22352/documents"
},
"pendingSalesOrders" : {
"href" : "https://myserver.com/api/v1/contacts/22352/pendingSalesOrders"
},
"lastPurchasedFrames" : {
"href" : "https://myserver.com/api/v1/contacts/22352/lastPurchasedFrames"
},
"store" : {
"href" : "https://myserver.com/api/v1/contact/22352/store{?projection}",
"templated" : true
}
}
}
Я хочу указать ссылку на себя. Это неправильно, на самом деле должно быть https://myserver.com/api/v1/contacts/22352 с окончанием -s.
Я использовал какой-то пользовательский ResourceProcessor, но даже без них у меня та же проблема.
Прямо сейчас я создал обходной путь в ContactResourceProcessor, переписав собственную ссылку на правильную, но я хотел бы понять, делаю ли я что-то неправильно, если это ошибка или я просто что-то пропустил.
@Selindek Я добавил репозиторий в вопрос.




Вероятно, это ошибка, но попробуйте этот обходной путь:
@RepositoryRestResource(path = "contacts")
@Transactional
@PreAuthorize("isAuthenticated()")
public interface ContactRepository extends JpaRepository<Contact, Long> {
....
....
}
Я пробовал, но у меня не работает. Мне пришлось переписать ссылку на себя в ResourceProcessor
Какие аннотации уровня класса у вас есть в интерфейсе ContactRepository?