Как запретить выдержкам проекций репозитория JPA возвращать встроенные списки в отношениях ManyToMany - PullRequest
0 голосов
/ 15 июня 2019

У меня есть две сущности: Пользователь и Роль. Каждый из них имеет отношение @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 поле.

Если я добавлю отрывок в оба репозитория (что я и собираюсь сделать), то оба вызова добавят встроенные списки.

Применение прогноза к любому из этих запросов останавливает отображение встроенного списка, но, очевидно, по умолчанию никакой проекции не применяется.

Есть ли какой-нибудь способ предотвратить это?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...