@Notnull更新时不添加

时间:2019-02-01 07:09:19

标签: spring-boot lombok

我有一个模型类,用于post(create)和put(update)rest API

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.NonNull;
import lombok.Setter;

@Getter
@Setter
@NoArgsConstructor
@Entity(name= "employee")
public class employeeDetail {

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private Long employeeId;
    @NonNull
    private String employeeName;

}

因此,由于雇员ID在添加时可以为空,因此在更新操作时必须将其传递。最好实施什么?

注意:在这种情况下,雇员ID是主键,对于非主键字段也可能出现相同的情况。我使用Spring Boot,Spring数据JPA和休眠模式。数据库是mariadb。

2 个答案:

答案 0 :(得分:0)

类似这样的东西:

import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.Data;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.transaction.Transactional;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import java.util.Optional;


@Getter
@Setter
@NoArgsConstructor
@Entity(name = "employee")
class EmployeeDetail {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long employeeId; //Long is better!

    @NotNull
    private String employeeName;


    //    Needed just for conversion -> use some mapper, and remove this constructor
    public EmployeeDetail(EmployeeDetailDTO employeeDetailDTO) {
        this.employeeId = employeeDetailDTO.getEmployeeId();
        this.employeeName = employeeDetailDTO.getEmployeeName();
    }
}

interface EmployeeDetailRepo extends JpaRepository<EmployeeDetail, Long> {
}

@Data
@JsonInclude(JsonInclude.Include.NON_NULL)
class EmployeeDetailDTO {

    private Long employeeId;

    @NotNull
    private String employeeName;

//    Other fields

    //    Needed just for conversion -> use some mapper, and remove this constructor
    public EmployeeDetailDTO(EmployeeDetail employeeDetail) {
        this.employeeId = employeeDetail.getEmployeeId();
        this.employeeName = employeeDetail.getEmployeeName();
    }
}

@Service
class EmpDetailService {

    private EmployeeDetailRepo employeeDetailRepo;

    @Autowired
    public EmpDetailService(EmployeeDetailRepo employeeDetailRepo) {
        this.employeeDetailRepo = employeeDetailRepo;
    }

    public EmployeeDetailDTO add(EmployeeDetailDTO employeeDetailDTO) {
//        map EmployeeDetailDTO to EmployeeDetail
        EmployeeDetail employeeDetail = new EmployeeDetail(employeeDetailDTO);
        EmployeeDetail employeeDetail1FromDB = employeeDetailRepo.save(employeeDetail);
//        map back to dto
        return new EmployeeDetailDTO(employeeDetail1FromDB);
    }

    @Transactional
    public EmployeeDetailDTO edit(Long id, EmployeeDetailDTO employeeDetailDTO) {
//        map EmployeeDetailDTO to EmployeeDetail
        Optional<EmployeeDetail> byId = employeeDetailRepo.findById(id);
        EmployeeDetail employeeDetailFromDB = byId.orElseThrow(() -> new RuntimeException("No such user with id: " + id));
        employeeDetailFromDB.setEmployeeName(employeeDetailDTO.getEmployeeName());
        return new EmployeeDetailDTO(employeeDetailFromDB);
    }
}

@RequestMapping
class Controller {
    private EmpDetailService empDetailService;

    @Autowired
    Controller(EmpDetailService empDetailService) {
        this.empDetailService = empDetailService;
    }

    @PostMapping("/add")
    public ResponseEntity<EmployeeDetailDTO> add(@Valid @RequestBody EmployeeDetailDTO employeeDetailDTO) {
        EmployeeDetailDTO added = empDetailService.add(employeeDetailDTO);
        return new ResponseEntity<>(added, HttpStatus.OK);
    }

    @PostMapping("/edit/{id}")
    public ResponseEntity<EmployeeDetailDTO> edit(@PathVariable Long id,
                                                  @Valid @RequestBody EmployeeDetailDTO employeeDetailDTO) {
        EmployeeDetailDTO edited= empDetailService.edit(id, employeeDetailDTO);
        return new ResponseEntity<>(edited, HttpStatus.OK);
    }
}

答案 1 :(得分:-1)

由于您希望Hibernate在插入时生成您的ID,因此它应该可以为空,因此其类型为

只需将employeeId更改为Integer。


从设计的角度来看,考虑创建2种不同的业务域类,一种用于不带ID的插入,一种用于不带空值的ID的更新/选择。

public class EmployeeRegistration {
    @NonNull
    private String name;
}

public class EmployeeDetail {
    @NonNull
    private Integer employeeId;
    @NonNull
    private String name;
}

然后提出将它们转换为数据库实体的方法。