我的应用程序中有用户,用户中有工作细节,我使用一种方法来设置用户/工作细节数据,然后添加新用户或修改现有用户。
这是设置用户/工作数据的方法:
public WorkDetail setWorkerData(PatchWorkerRequest request, User user, WorkDetail workDetail) {
if (request.getName() != null) {
user.setName(request.getName());
}
if (request.getIdCode() != null) {
user.setIdCode(request.getIdCode());
}
if (request.getEmail() != null) {
user.setEmail(request.getEmail());
}
if (request.getPhone() != null) {
user.setPhone(request.getPhone());
}
if (request.getAddress() != null) {
user.setAddress(request.getAddress());
}
if (request.getSignatureLevel() != null) {
user.setSignatureLevel(request.getSignatureLevel());
}
if (request.getAltContactRelation() != null) {
user.setAltContactRelation(request.getAltContactRelation());
}
if (request.getAltContactPhone() != null) {
user.setAltContactPhone(request.getAltContactPhone());
}
if (request.getRoles() != null) {
user.setRoles(request.getRoles());
}
if (request.getStatus() != null) {
user.setStatus(request.getStatus());
}
// Work details
if (request.getJobRelation() != null) {
workDetail.setJobRelation(request.getJobRelation());
}
if (request.getSalary() != null) {
workDetail.setSalary(request.getSalary());
}
if (request.getDistricts() != null) {
workDetail.setDistricts(request.getDistricts());
}
if (request.getCompetences() != null) {
workDetail.setCompetences(request.getCompetences());
}
workDetail.setUser(user);
user.setWorkDetail(workDetail);
return workDetailRepository.save(workDetail);
}
现在,使用以下代码可以修改现有的工作程序:
public WorkDetail modifyWorker(Long workerId, PatchWorkerRequest request) {
WorkDetail workDetail = this.getWorkDetailById(workerId);
User user = userService.getUserById(workDetail.getUser().getId());
return setWorkerData(request, user, workDetail);
}
但是,当我尝试创建新用户/工人时,出现了"null value in column "user_id" violates not-null constraint"
错误。我认为这是因为workDetail和用户未正确连接。
这是创建新工作程序的方法:
public WorkDetail createWorker(PatchWorkerRequest request) {
WorkDetail workDetail = new WorkDetail();
User user = new User();
String generatedPassword = userService.generatePassword(8);
user.setPassword(passwordEncoder.encode(generatedPassword));
emailService.sendMail("SYDA", new String[]{request.getEmail()},
"Project SYDA",
"New password: " + generatedPassword + ".);
return setWorkerData(request, user, workDetail);
}
还有,在保存用户之后,我有什么办法可以发送电子邮件,以防万一出现错误,它不会发送电子邮件?
实体:
用户:
@Entity
@Data
@NoArgsConstructor
@TypeDefs({
@TypeDef(name = "pgsql_enum", typeClass = PostgreSQLEnumType.class)
})
@Table(name = "user_acc")
public class User implements Serializable {
@Id
@Column(unique = true, nullable = false, columnDefinition = "serial")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "name", nullable = false)
private String name;
@Column(name = "id_code")
private BigInteger idCode;
@Column(name = "email", nullable = false)
private String email;
@Column(name = "address")
private String address;
@Column(name = "phone")
private BigInteger phone;
@Column(name = "alt_contact_relation")
private String altContactRelation;
@Column(name = "alt_contact_phone")
private BigInteger altContactPhone;
@Column(name = "password", nullable = false)
@JsonIgnore
private String password;
@JsonIgnore
@Column(name = "create_time", nullable = false, updatable = false)
private Date createTime = new Date();
@JsonIgnore
@Column(name = "update_time", nullable = false)
private Date updateTime = new Date();
@Column(name = "status", nullable = false, columnDefinition = "active_status")
@Enumerated(EnumType.STRING)
@Type(type = "pgsql_enum")
private UserStatus status;
@OneToOne
@PrimaryKeyJoinColumn
@JsonIgnore
private WorkDetail workDetail;
@OneToMany(mappedBy = "user")
private List<UserFile> userFiles = new ArrayList<>();
@ManyToOne
@JoinColumn(name = "signature_level_id")
private SignatureLevel signatureLevel;
@ManyToMany(fetch = FetchType.EAGER, targetEntity = UserRole.class)
@JoinTable(name = "user_has_user_role",
joinColumns = { @JoinColumn(name = "user_id", referencedColumnName = "id")},
inverseJoinColumns = { @JoinColumn(name = "user_role_id", referencedColumnName = "id")}
)
private Set<UserRole> roles = new HashSet<>();
@ManyToMany(fetch = FetchType.EAGER, targetEntity = Mechanism.class)
@JoinTable(name = "user_has_mechanism",
joinColumns = { @JoinColumn(name = "user_id", referencedColumnName = "id")},
inverseJoinColumns = { @JoinColumn(name = "mechanism_id", referencedColumnName = "id")}
)
private Set<Mechanism> mechanisms = new HashSet<>();
@ManyToMany(fetch = FetchType.EAGER, targetEntity = Service.class)
@JoinTable(name = "user_has_service",
joinColumns = { @JoinColumn(name = "user_id", referencedColumnName = "id")},
inverseJoinColumns = { @JoinColumn(name = "service_id", referencedColumnName = "id")}
)
private Set<Service> services = new HashSet<>();
@PreUpdate
@PrePersist
public void onCreateOnUpdate() {
updateTime = new Date();
}
public enum UserStatus {
active, temporarily_inactive, inactive
}
}
WorkDetail:
@Entity
@Data
@Table(name = "work_detail")
public class WorkDetail {
@Id
@Column(unique = true, nullable = false, columnDefinition = "serial")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "salary")
private float salary;
@OneToOne(mappedBy = "workDetail",fetch = FetchType.LAZY, optional = true)
@PrimaryKeyJoinColumn
private User user;
@Column(name = "create_time", nullable = false, updatable = false)
@JsonIgnore
private Date createTime = new Date();
@Column(name = "update_time", nullable = false)
@JsonIgnore
private Date updateTime = new Date();
@OneToMany(cascade = CascadeType.ALL, mappedBy = "workDetail")
private List<UserLeave> userLeaves = new ArrayList<>();
@ManyToOne
@JoinColumn(name = "job_relation_id")
private JobRelation jobRelation;
@ManyToMany(fetch = FetchType.EAGER, targetEntity = District.class)
@JoinTable(name = "work_detail_has_district",
joinColumns = { @JoinColumn(name = "work_detail_id", referencedColumnName = "id")},
inverseJoinColumns = { @JoinColumn(name = "district_id", referencedColumnName = "id")}
)
private Set<District> districts = new HashSet<>();
@ManyToMany(fetch = FetchType.EAGER, targetEntity = Competence.class)
@JoinTable(name = "work_detail_has_competence",
joinColumns = { @JoinColumn(name = "work_detail_id", referencedColumnName = "id")},
inverseJoinColumns = { @JoinColumn(name = "competence_id", referencedColumnName = "id")}
)
private Set<Competence> competences = new HashSet<>();
@PreUpdate
@PrePersist
public void onCreateOnUpdate() {
updateTime = new Date();
}
}
Db表:
-----------------------
-- User table
-----------------------
CREATE TABLE IF NOT EXISTS user_acc (
id SERIAL NOT NULL PRIMARY KEY,
name text NOT NULL,
id_code numeric NOT NULL,
email text NOT NULL UNIQUE,
address text NULL,
alt_contact_relation text NULL,
alt_contact_phone numeric NULL,
signature_level_id integer NULL,
username text NOT NULL,
password text NOT NULL,
create_time TIMESTAMP without TIME ZONE DEFAULT now() NOT NULL,
update_time TIMESTAMP without TIME ZONE DEFAULT now() NOT NULL,
status active_status NOT NULL DEFAULT 'active',
CONSTRAINT FK_user_signature_level FOREIGN KEY (signature_level_id) REFERENCES signature_level (id)
ON DELETE NO ACTION ON UPDATE NO ACTION
);
-----------------------
-- User: work detail table
-----------------------
CREATE TABLE IF NOT EXISTS work_detail (
id SERIAL NOT NULL PRIMARY KEY,
salary decimal NULL,
job_relation_id integer NOT NULL,
user_id integer NOT NULL,
create_time TIMESTAMP without TIME ZONE DEFAULT now() NOT NULL,
update_time TIMESTAMP without TIME ZONE DEFAULT now() NOT NULL,
CONSTRAINT FK_work_detail_user FOREIGN KEY (user_id) REFERENCES user_acc (id)
ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT fk_work_details_job_relations1 FOREIGN KEY (job_relation_id)
REFERENCES job_relation (id)
ON DELETE NO ACTION
ON UPDATE NO ACTION);
答案 0 :(得分:1)
您需要先保存user
,然后再将其添加到workDetail
中。新的User
对象没有ID,这就是为什么要获取该异常的原因。
像这样:
public WorkDetail createWorker(PatchWorkerRequest request) {
WorkDetail workDetail = new WorkDetail();
User user = new User();
String generatedPassword = userService.generatePassword(8);
user.setPassword(passwordEncoder.encode(generatedPassword));
user = userRepository.save(user);
emailService.sendMail("SYDA", new String[]{request.getEmail()},
"Project SYDA",
"New password: " + generatedPassword + ".);
return setWorkerData(request, user, workDetail);
}
或者您可以在saveUser
方法内添加一个setWorkerData
调用。
...
if (request.getStatus() != null) {
user.setStatus(request.getStatus());
}
user = userRepository.save(user);
...
答案 1 :(得分:1)
在您的if let jsonData = jsonString.data(using: .utf8) {
do {
let root = try JSONDecoder().decode(RootObject.self, from: jsonData)
} catch {
print(error)
}
}
方法中,您尝试为setWorker()
对象设置user
,但是workDetail
对象没有user
,因为该用户对象是分离的模式,仍然没有user_id
与用户对象相关联。
user_id
因此,要么在设置前保存 //some code in your setWorker() Method.
workDetail.setUser(user); //you try to set a detached User Object which doesn't have it's id.
user.setWorkDetail(workDetail);
return workDetailRepository.save(workDetail);
并确保user
对象就保存在数据库中。
在上述代码之前添加此行。
user
还有另一种无需调用user = userRepository.save(user); // add this line....
workDetail.setUser(user); //now your User Object will have it's id.
user.setWorkDetail(workDetail);
return workDetailRepository.save(workDetail);
方法即可执行此操作的方法,只需使用级联的概念即可了解更多有关此Link Here
答案 2 :(得分:0)
您可以使用spring-boot-starter-mail依赖项来完成这项工作
答案 3 :(得分:0)
这表示您尝试保存workdetail对象时未保存用户对象。
因此,没有要放置的user_id,因此没有null值。
可以将您的实体寄给您吗? (特别是它们之间的映射)。
我想,如果要同时保存两个实体,应该使用@OneToOne(cascade = CascadeType.PERSIST)
之类的字眼。
答案 4 :(得分:0)
您的映射错误。
这是您应该做的事情:
在WorkDetail中:
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "user_id")
private User user;
在用户中:
@OneToOne(mappedBy = "user")
@JsonIgnore
private WorkDetail workDetail;