У меня есть две сущности: Пользователь и Роль. Каждый из них имеет отношение @ManyToMany
друг к другу (для поиска ролей, связанных с пользователем, и наоборот).
У меня есть несколько прогнозов для каждого, и оба хранилища имеют excerptProjection
. Всякий раз, когда я звоню, чтобы получить все ресурсы /api/users
, список ресурсов возвращается, как и ожидалось. Но когда я звоню определенному ресурсу /api/users/1
, он получает список ресурсов _embedded
другого типа.
Когда я удаляю отрывок из RoleRepository, вызов /api/users/1
останавливает появление встроенных ролей, но /api/roles/1
показывает встроенных пользователей.
Код
Объекты:
public class User {
private long id;
private Instant createdAt;
private Instant updatedAt;
private String username;
private String password;
private String firstName;
private String lastName;
private String email;
@Lazy
@JsonIgnore
@Where(clause = NOT_DELETED)
@ManyToMany(cascade = CascadeType.DETACH, fetch = FetchType.LAZY)
@JoinTable(
name = "user_role_rel",
joinColumns = @JoinColumn(name = "user_id", referencedColumnName = "id"),
inverseJoinColumns = @JoinColumn(name = "role_id", referencedColumnName = "id")
)
private Set<Role> roles = new HashSet<>();
// other stuff omitted
}
public class Role {
private long id;
private Instant createdAt;
private Instant updatedAt;
private String name;
private String description;
@Lazy
@JsonIgnore
@Where(clause = NOT_DELETED)
@ManyToMany(mappedBy = "roles", cascade = CascadeType.DETACH)
private Set<User> users = new HashSet<>();
// other stuff omitted
}
Проекция:
@Projection(name = "summary", types = { User.class })
public interface Summary {
Long getId();
String getUsername();
String getFirstName();
String getLastName();
String getEmail();
}
@Projection(name = "summary", types = { Role.class })
public interface Summary {
Long getId();
String getName();
String getDescription();
}
Хранилища:
@RepositoryRestResource( excerptProjection = Summary.class )
public interface UserRepository extends SoftDeleteRepository<User, Long> {}
@RepositoryRestResource
public interface RoleRepository extends SoftDeleteRepository<Role, Long> {}
Запросы / ответы
GET /api/users/1
{
"createdAt": "2019-06-15T10:37:16.280Z",
"updatedAt": "2019-06-15T10:37:16.280Z",
"username": "ironman",
"firstName": "Tony",
"lastName": "Stark",
"email": "tony@starkindustries.com",
"_id": 1,
"_links": {
// omitted
}
}
GET /api/roles/1
{
"createdAt": "2019-06-15T10:37:15.984Z",
"updatedAt": "2019-06-15T10:37:15.984Z",
"name": "ROLE_ADMIN",
"description": "Admin role",
"_id": 1,
"_embedded": {
"users": [
{
"firstName": "Tony",
"lastName": "Stark",
"username": "ironman",
"email": "tony@starkindustries.com",
"id": 1,
"_links": {
// omitted
}
}
]
},
"_links": {
// omitted
}
}
Первый работает должным образом, отображаются только видимые поля.
Второй продолжает бросать в это _embedded
поле.
Если я добавлю отрывок в оба репозитория (что я и собираюсь сделать), то оба вызова добавят встроенные списки.
Применение прогноза к любому из этих запросов останавливает отображение встроенного списка, но, очевидно, по умолчанию никакой проекции не применяется.
Есть ли какой-нибудь способ предотвратить это?