如何阻止JPA Repository投影摘录返回ManyToMany关系上的嵌入式列表

时间:2019-06-15 11:32:31

标签: java spring-data-jpa

我有两个实体User和Role。它们彼此之间具有@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字段。

如果我将摘录添加到两个存储库中(这正是我想要的),则两个调用都将添加嵌入列表。

对这两个请求中的任何一个应用投影都会阻止嵌入列表的出现,但是默认情况下显然不会应用投影。

有什么办法可以阻止这种情况的发生?

1 个答案:

答案 0 :(得分:0)

最近我遇到了同样的问题。 希望下面的代码能帮助您解决问题。

 @Configuration
public class RepositoryConfig extends RepositoryRestConfigurerAdapter {

  @Override
  public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) {
    config.getProjectionConfiguration().addProjection(Summary.class);
  }
}

请检查以下网址以获取更多详细信息:

url