带有excerptProjection的Spring RepositoryRestController

时间:2017-08-07 12:25:34

标签: spring spring-data entity spring-data-jpa hateoas

我已按照here

所述为我的Spring Data实体定义了一个@Projection

出于与此处描述的相同的原因。当我GET请求时,所有内容都按预期返回。但是,当我执行POST请求时,投影将无效。按照上面提供的示例,“地址”在链接下显示为URL,并且不会以GET请求的方式公开。

如何以同样的方式曝光?

我创建了一个@RepositoryRestController的类,我可以在其中捕获POST方法。如果我只是返回实体,它就没有链接。如果我将其作为资源返回,则链接就在那里,但“地址”也是一个链接。如果我从控制器中删除GET方法,则默认行为如上所述。

更新

我的实体与描述here ABSuperClass的实体相同,但我没有{{>>获取 1}} 我的控制器看起来像这样:

@ManyToOne

我的存储库看起来像这样:

@RepositoryRestController
public class BRepositoryRestController {

  private final BRepository bRepository;

  public BRepositoryRestController(BRepository bRepository) {
    this.bRepository = bRepository;
  }


  @RequestMapping(method = RequestMethod.POST, value = "/bs")
  public 
  ResponseEntity<?> post(@RequestBody Resource<B> bResource) {
    B b= bRepository.save(bResource.getContent());
    BProjection result = bRepository.findById(b.getId());
    return ResponseEntity.ok(new Resource<>(result));
  }
}

我的预测如下:

@RepositoryRestResource(excerptProjection = BProjection.class)
public interface BRepository extends BaseRepository<B, Long> {
  @EntityGraph(attributePaths = {"a"})
  BProjection findById(Long id);
}

SuperClassProjection看起来像这样:

@Projection(types = B.class)
public interface BProjection extends SuperClassProjection {
  A getA();
  String getSomeData();
  String getOtherData();      
}

1 个答案:

答案 0 :(得分:1)

在自定义@RepositoryRestController POST方法中,您还应该返回投影。例如:

@Projection(name = "inlineAddress", types = { Person.class }) 
public interface InlineAddress {
    String getFirstName();
    String getLastName();
    @Value("#{target.address}") 
    Address getAddress(); 
}

public interface PersonRepo extends JpaRepository<Person, Long> {
    InlineAddress findById(Long personId); 
}

@PostMapping
public ResponseEntity<?> post(...) {
    //... posting a person
    InlineAddress inlineAddress = bookRepo.findById(person.getId());
    return ResponseEntity.ok(new Resource<>(inlineAddress));
}

<强>更新

我已经更正了上面的代码和问题中的代码:

@RepositoryRestResource(excerptProjection = BProjection.class)
public interface BRepository extends CrudRepository<B, Long> {   
  BProjection findById(Long id);
}

@Projection(types = B.class)
public interface BProjection {
    @Value("#{target.a}")
    A getA();
    String getSomeData();
    String getOtherData();
}

然后一切正常。

POST请求正文:

{
    "name": "b1",
    "someData": "someData1",
    "otherData": "otherData",
    "a": {
        "name": "a1"
    }
}

回复机构:

{
    "a": {
        "name": "a1"
    },
    "someData": "someData1",
    "otherData": "otherData",
    "_links": {
        "self": {
            "href": "http://localhost:8080/api/bs/1{?projection}",
            "templated": true
        }
    }
}

见工作example