在Spring数据休息中使用自定义控制器将URI转换为实体?

时间:2017-04-25 04:28:30

标签: spring spring-data-rest

我有一个像这样的jpa实体。

@Entity
@Table(name = "location")
@Data
public class Location {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;

    @Column(name = "LOCATION_ID", unique = true)
    @NotEmpty(message = "Please Enter Location ID")

    private String name;

    @Column(name = "LOCATION_DESCRIPTION")
    @NotEmpty(message = "Please Enter Location Description")
    private String description;

    @ManyToOne
    @NotNull(message = "Please Choose a Building")


    Building building;



    @Version
    Long version;





}

和这样的存储库。

public interface LocationRepository extends PagingAndSortingRepository<Location, Long> {  
    Location findByName(@Param("name") String name);

}

我正在使用spring数据休息我可以通过提供以下有效负载来创建具有rest api的位置

{

"name":"adminxxxxx","description":"adminxxx" , "building": "http://localhost:8080/buildings/2"
}

现在我正在尝试编写将保留实体的自定义控制器。这是我的自定义控制器

@ExposesResourceFor(Location.class)
@RepositoryRestController
@BasePathAwareController
public class LocationController {

    @Autowired
    LocationRepository locationDao;

    @Autowired
    LocationResourceAssembler resourceAssembler;

    @Value("${buildings.error.messages.uniqueconstraintviolation}")
    String uniqueConstrainMessage;
    static final String TAG = LocationController.class.getSimpleName();

    @RequestMapping(value="locations",method = org.springframework.web.bind.annotation.RequestMethod.POST)
    public ResponseEntity<?> save(@RequestBody @Valid Location location) {

        try {
            location = locationDao.save(location);
            LocationResource b = resourceAssembler.toResource(location);
            return ResponseEntity.ok().body(b);
        } catch (DataIntegrityViolationException e) {

            if (locationAlreadyExists(location.getName()))
                throw new LocationAlreadyExistException(uniqueConstrainMessage, location);

            else
                throw new RuntimeException("Some Error Occured");
        }

    }

我收到此错误

exception is com.fasterxml.jackson.databind.JsonMappingException: Can not construct instance of com.alamdar.model.Building: no String-argument constructor/factory method to deserialize from String value (&#39;http://localhost:8080/buildings/2&#39;)
 at [Source: java.io.PushbackInputStream@5d468b16; line: 3, column: 60] (through reference chain: com.alamdar.model.Location[&quot;building&quot;])</div></body></html>

有人可以帮忙吗?

1 个答案:

答案 0 :(得分:0)

我不确定你为什么要编写一个自定义控制器,但问题似乎是你没有默认的没有args构造函数,所以Jackson无法实例化一个实例。

这是因为您使用的是Lombok的@Data注释:

https://projectlombok.org/features/Data.html

您还应该使用@NoArgsConstructor为您的类注释,以生成默认的no-args构造函数:

@Entity
@Table(name = "location")
@Data
@NoArgsConstructor
public class Location {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;

    @Column(name = "LOCATION_ID", unique = true)
    @NotEmpty(message = "Please Enter Location ID")

    private String name;

    @Column(name = "LOCATION_DESCRIPTION")
    @NotEmpty(message = "Please Enter Location Description")
    private String description;

    @ManyToOne
    @NotNull(message = "Please Choose a Building")
    Building building;

    @Version
    Long version;
}