一对多单向关联插入查询失败
One To Many Unidirectional association insert query getting failed
我有 User
和 Address
具有 one-to-many
单向关系的实体。
当我尝试插入带有 Address
详细信息的 User
时,它因异常 "Referential integrity constraint violation" 而失败,因为我检查了 Address
没有插入 userId
它有 0
我不明白这有什么问题。
我的用户实体:
@Entity
@Table(name = "users")
public class User{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ID")
private long id;
@OneToMany(orphanRemoval = true,cascade = CascadeType.ALL, fetch=FetchType.EAGER)
@JoinColumn(name = "USER_ID", referencedColumnName = "ID")
private List<Address> address;
// other table columns
}
我的地址实体:
@Entity
@Table(name = "address")
public class Address{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ID")
private long id;
@Column(name = "USER_ID")
private long userId;
//other table columns
}
我的控制器:
@PostMapping("/")
public ResponseEntity<UserDTO> saveUser(@RequestBody UserRequestDTO userRequestDTO){
try {
if (userRequestDTO != null) {
return new ResponseEntity<>(userService.saveUser(userRequestDTO), HttpStatus.CREATED);
}
} catch (Exception ex) {
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
}
return null;
}
我的服务层:
@Override
public UserDTO saveUser(UserRequestDTO userDto) {
User obj = modelMapper.map(userDto, User.class);
System.out.println(obj.toString());
obj = userRepository.save(obj);
return modelMapper.map(obj, UserDTO.class);
}
这是我的 UserRequestDTO 我有所有 属性
public class UserRequestDTO {
private long id;
private long clientId;
private String clientName;
private String email;
private String firstName;
private String lastName;
private String employeeNo;
private String designation;
private String status;
private String phoneNumber;
private String employeeType;
private String reportingTo;
private String department;
private String division;
private String password;
private String gender;
private String bloodGroup;
private String maritalStatus;
private String spouseName;
private String noOfChildren;
private Date dateOfBirth;
private Date hiredDate;
private LocalDate createdDate;
private String createdBy;
private LocalDate updatedDate;
private String updatedBy;
private List<Address> address;
}
查了很多在线教程,但无法找到根本原因
来自控制台的错误消息:
User(id=0, clientId=1, email=user@gmail.com, firstName=user 10, lastName=K, password=password@123, employeeNo=EH5213, phoneNumber=9999999990, status=A, designation=Developer, employeeType=FullTime, reportingTo=Roshan, department=Information Technology, division=division, locationId=null, gender=null, bloodGroup=null, maritalStatus=null, spouseName=null, noOfChildren=null, dateOfBirth=null, hiredDate=null, createdDate=2022-03-25, createdBy=admin, updatedDate=2022-03-25, updatedBy=admin, organization=null, address=[Address(id=0, clientId=1, userId=0, address1=add1Sample, address2=add2Sample, state=sample, addressType=P, country=sample, city=sample, zipCode=000002, primaryPhone=1111111111, secondaryPhone=2222222222, active=true, createdDate=2022-03-25, createdBy=admin, updatedDate=2022-03-25, updatedBy=admin), Address(id=0, clientId=1, userId=0, address1=sample2, address2=add2sample2 , state=sample2, addressType=T, country=sample2, city=sample2, zipCode=000008, primaryPhone=4444444444, secondaryPhone=666666666, active=true, createdDate=2022-03-25, createdBy=admin, updatedDate=2022-03-25, updatedBy=admin)], employeeGroups=null)
Hibernate: insert into users (id, blood_group, client_id, created_by, created_date, date_of_birth, department, designation, division, email, employee_no, employee_type, first_name, gender, hired_date, last_name, location_id, marital_status, no_of_children, organization_id, password, phone_number, reporting_to, spouse_name, status, updated_by, updated_date) values (default, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
Hibernate: insert into address (id, active, address_line_1, address_line_2, address_type, city, client_id, country, created_by, created_date, primary_phone, secondary_phone, state, updated_by, updated_date, user_id, zip_code) values (default, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
[2m2022-03-30 12:41:25.689[0;39m [33m WARN[0;39m [35m13308[0;39m [2m---[0;39m [2m[nio-8085-exec-2][0;39m [36mo.h.engine.jdbc.spi.SqlExceptionHelper [0;39m [2m:[0;39m SQL Error: 23506, SQLState: 23506
[2m2022-03-30 12:41:25.702[0;39m [31mERROR[0;39m [35m13308[0;39m [2m---[0;39m [2m[nio-8085-exec-2][0;39m [36mo.h.engine.jdbc.spi.SqlExceptionHelper [0;39m [2m:[0;39m Referential integrity constraint violation: "FK6I66IJB8TWGCQTETL8EEEED6V: PUBLIC.ADDRESS FOREIGN KEY(USER_ID) REFERENCES PUBLIC.USERS(ID) (0)"; SQL statement:
insert into address (id, active, address_line_1, address_line_2, address_type, city, client_id, country, created_by, created_date, primary_phone, secondary_phone, state, updated_by, updated_date, user_id, zip_code) values (default, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) [23506-200]
这可以通过在实体级别进行一些小的更改来解决:
变化一:
在您的用户实体中添加 nullable=false,如下所示:
@Entity
@Table(name = "users")`
public class User{`
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ID")
private long id;
@OneToMany(orphanRemoval = true,cascade = CascadeType.ALL, fetch=FetchType.EAGER)
@JoinColumn(name = "USER_ID", referencedColumnName = "ID", nullable = false)
private List<Address> address;
// other table columns
}
变2:
在您的 Address 实体中添加 insertable = false 和 updatable = false,像这样
@Entity
@Table(name = "address")
public class Address{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ID")
private long id;
@Column(name = "USER_ID", insertable = false, updatable = false)
private long userId;
//other table columns
}
使用 nullable=false : 它将非空约束应用于特定的数据库列
要了解 insertable = false, updatable = false 的用法请参考这个 :Please explain about insertable=false and updatable=false in reference to the JPA @Column annotation
您必须先插入 User
然后再插入 Address
意味着您必须在插入 Address
之前获取 User
的引用。但是在 Unidirectional Mapping
中,您不需要为插入 Address
添加代码,因为它会自动从 User
获取引用。 DTO
这里不需要。
从 Address.java
中删除此列,因为手动插入外键是不好的做法:
@Column(name = "USER_ID", insertable = false, updatable = false)
private long userId;
下面是修改后的代码:
控制器
@RequestMapping(value = "/")
@ResponseBody
public ResponseEntity<User> addUser(@RequestBody User user)
{
userRepository.save(user);
return new ResponseEntity<>(user, HttpStatus.CREATED);
}
你不想在这里创建 DTO...
我有 User
和 Address
具有 one-to-many
单向关系的实体。
当我尝试插入带有 Address
详细信息的 User
时,它因异常 "Referential integrity constraint violation" 而失败,因为我检查了 Address
没有插入 userId
它有 0
我不明白这有什么问题。
我的用户实体:
@Entity
@Table(name = "users")
public class User{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ID")
private long id;
@OneToMany(orphanRemoval = true,cascade = CascadeType.ALL, fetch=FetchType.EAGER)
@JoinColumn(name = "USER_ID", referencedColumnName = "ID")
private List<Address> address;
// other table columns
}
我的地址实体:
@Entity
@Table(name = "address")
public class Address{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ID")
private long id;
@Column(name = "USER_ID")
private long userId;
//other table columns
}
我的控制器:
@PostMapping("/")
public ResponseEntity<UserDTO> saveUser(@RequestBody UserRequestDTO userRequestDTO){
try {
if (userRequestDTO != null) {
return new ResponseEntity<>(userService.saveUser(userRequestDTO), HttpStatus.CREATED);
}
} catch (Exception ex) {
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
}
return null;
}
我的服务层:
@Override
public UserDTO saveUser(UserRequestDTO userDto) {
User obj = modelMapper.map(userDto, User.class);
System.out.println(obj.toString());
obj = userRepository.save(obj);
return modelMapper.map(obj, UserDTO.class);
}
这是我的 UserRequestDTO 我有所有 属性
public class UserRequestDTO {
private long id;
private long clientId;
private String clientName;
private String email;
private String firstName;
private String lastName;
private String employeeNo;
private String designation;
private String status;
private String phoneNumber;
private String employeeType;
private String reportingTo;
private String department;
private String division;
private String password;
private String gender;
private String bloodGroup;
private String maritalStatus;
private String spouseName;
private String noOfChildren;
private Date dateOfBirth;
private Date hiredDate;
private LocalDate createdDate;
private String createdBy;
private LocalDate updatedDate;
private String updatedBy;
private List<Address> address;
}
查了很多在线教程,但无法找到根本原因 来自控制台的错误消息:
User(id=0, clientId=1, email=user@gmail.com, firstName=user 10, lastName=K, password=password@123, employeeNo=EH5213, phoneNumber=9999999990, status=A, designation=Developer, employeeType=FullTime, reportingTo=Roshan, department=Information Technology, division=division, locationId=null, gender=null, bloodGroup=null, maritalStatus=null, spouseName=null, noOfChildren=null, dateOfBirth=null, hiredDate=null, createdDate=2022-03-25, createdBy=admin, updatedDate=2022-03-25, updatedBy=admin, organization=null, address=[Address(id=0, clientId=1, userId=0, address1=add1Sample, address2=add2Sample, state=sample, addressType=P, country=sample, city=sample, zipCode=000002, primaryPhone=1111111111, secondaryPhone=2222222222, active=true, createdDate=2022-03-25, createdBy=admin, updatedDate=2022-03-25, updatedBy=admin), Address(id=0, clientId=1, userId=0, address1=sample2, address2=add2sample2 , state=sample2, addressType=T, country=sample2, city=sample2, zipCode=000008, primaryPhone=4444444444, secondaryPhone=666666666, active=true, createdDate=2022-03-25, createdBy=admin, updatedDate=2022-03-25, updatedBy=admin)], employeeGroups=null)
Hibernate: insert into users (id, blood_group, client_id, created_by, created_date, date_of_birth, department, designation, division, email, employee_no, employee_type, first_name, gender, hired_date, last_name, location_id, marital_status, no_of_children, organization_id, password, phone_number, reporting_to, spouse_name, status, updated_by, updated_date) values (default, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
Hibernate: insert into address (id, active, address_line_1, address_line_2, address_type, city, client_id, country, created_by, created_date, primary_phone, secondary_phone, state, updated_by, updated_date, user_id, zip_code) values (default, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
[2m2022-03-30 12:41:25.689[0;39m [33m WARN[0;39m [35m13308[0;39m [2m---[0;39m [2m[nio-8085-exec-2][0;39m [36mo.h.engine.jdbc.spi.SqlExceptionHelper [0;39m [2m:[0;39m SQL Error: 23506, SQLState: 23506
[2m2022-03-30 12:41:25.702[0;39m [31mERROR[0;39m [35m13308[0;39m [2m---[0;39m [2m[nio-8085-exec-2][0;39m [36mo.h.engine.jdbc.spi.SqlExceptionHelper [0;39m [2m:[0;39m Referential integrity constraint violation: "FK6I66IJB8TWGCQTETL8EEEED6V: PUBLIC.ADDRESS FOREIGN KEY(USER_ID) REFERENCES PUBLIC.USERS(ID) (0)"; SQL statement:
insert into address (id, active, address_line_1, address_line_2, address_type, city, client_id, country, created_by, created_date, primary_phone, secondary_phone, state, updated_by, updated_date, user_id, zip_code) values (default, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) [23506-200]
这可以通过在实体级别进行一些小的更改来解决:
变化一:
在您的用户实体中添加 nullable=false,如下所示:
@Entity
@Table(name = "users")`
public class User{`
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ID")
private long id;
@OneToMany(orphanRemoval = true,cascade = CascadeType.ALL, fetch=FetchType.EAGER)
@JoinColumn(name = "USER_ID", referencedColumnName = "ID", nullable = false)
private List<Address> address;
// other table columns
}
变2: 在您的 Address 实体中添加 insertable = false 和 updatable = false,像这样
@Entity
@Table(name = "address")
public class Address{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ID")
private long id;
@Column(name = "USER_ID", insertable = false, updatable = false)
private long userId;
//other table columns
}
使用 nullable=false : 它将非空约束应用于特定的数据库列
要了解 insertable = false, updatable = false 的用法请参考这个 :Please explain about insertable=false and updatable=false in reference to the JPA @Column annotation
您必须先插入 User
然后再插入 Address
意味着您必须在插入 Address
之前获取 User
的引用。但是在 Unidirectional Mapping
中,您不需要为插入 Address
添加代码,因为它会自动从 User
获取引用。 DTO
这里不需要。
从 Address.java
中删除此列,因为手动插入外键是不好的做法:
@Column(name = "USER_ID", insertable = false, updatable = false)
private long userId;
下面是修改后的代码:
控制器
@RequestMapping(value = "/")
@ResponseBody
public ResponseEntity<User> addUser(@RequestBody User user)
{
userRepository.save(user);
return new ResponseEntity<>(user, HttpStatus.CREATED);
}
你不想在这里创建 DTO...