首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >@Notnull on update not on add

@Notnull on update not on add
EN

Stack Overflow用户
提问于 2019-02-01 15:09:19
回答 2查看 218关注 0票数 0

我有一个模型类,用于post(创建)和put(更新) rest API

代码语言:javascript
复制
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 data JPA和hibernate。数据库为mariadb。

EN

回答 2

Stack Overflow用户

发布于 2019-02-01 21:12:42

如下所示:

代码语言:javascript
复制
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);
    }
}
票数 0
EN

Stack Overflow用户

发布于 2019-02-01 15:44:28

由于您希望Hibernate在插入时生成yuor id,因此它的类型应该为yuor。

只需将employeeId更改为整数即可。

从设计的角度来看,考虑创建两个不同的业务域类,一个用于不带id的插入,另一个用于带有不可空id的更新/选择。

代码语言:javascript
复制
public class EmployeeRegistration {
    @NonNull
    private String name;
}

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

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

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54474567

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档