关于一对一关系,我有以下问题(我猜也是一对多):
假设我有以下表格:
create table user (
id bigint auto_increment primary key,
username varchar(100) not null,
constraint UK_username unique (username)
);
create table user_details(
userId bigint not null primary key,
firstName varchar(100) null,
lastName varchar(100) null,
constraint user_details_user_id_fk foreign key (userId) references user (id)
);
如您所见,两个表共享相同的主键。现在,我创建的实体如下:
import lombok.Data;
import javax.persistence.*;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;
@Data
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@NotBlank
@Column(unique = true)
@Size(min = 1, max = 100)
private String username;
@MapsId
//without this I get an exception on this table not having a column named: userDetails_userId
@JoinColumn(name = "id")
@OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
private UserDetails userDetails;
}
import lombok.Data;
import javax.persistence.*;
import javax.validation.constraints.Size;
@Data
@Entity(name = "user_details")
public class UserDetails {
@Id
private Long userId;
@Column(unique = true)
@Size(min = 1, max = 100)
private String firstName;
@Column(unique = true)
@Size(min = 1, max = 100)
private String lastName;
}
当我尝试保留新用户时,我有一个用户对象,其中生成了除user.id和userDetail.userId之外的所有值。当我尝试保留此错误时,出现以下错误:
"org.springframework.orm.jpa.JpaSystemException: ids for this class must be manually assigned before calling save(): com.app.entity.UserDetails; nested exception is org.hibernate.id.IdentifierGenerationException: ids for this class must be manually assigned before calling save(): com.app.UserDetails
请注意,要保存用户实体,我创建了以下接口:
public interface UserRepository extends JpaRepository<User, Long> { }
我使用提供的保存方法。
...
@Autowired
private UserRepository userRepository;
...
public ResponseEntity<HttpStatus> addUser(User user) {
userRepository.save(user);
return ResponseEntity.ok(HttpStatus.OK);
}
保存之前的对象如下所示:
User(id=null, username=test, userDetails=UserDetails(userId=null, firstName=test, lastName=test))
我想知道是否可以简单地保存用户对象并将生成的键级联到userDetail。
我应该使用其他方法进行保存还是我的实体有问题?
最佳答案
您做错了方向。
@Data
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@NotBlank
@Column(unique = true)
@Size(min = 1, max = 100)
private String username;
@OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "user")
private UserDetails userDetails;
}
@Data
@Entity(name = "user_details")
public class UserDetails {
@Id
private Long userId;
@Column(unique = true)
@Size(min = 1, max = 100)
private String firstName;
@Column(unique = true)
@Size(min = 1, max = 100)
private String lastName;
@MapsId
@JoinColumn(name = "USERID")
@OneToOne(fetch = FetchType.LAZY)
private User user;
}
这样,您就可以设置userDetail.user引用,并且JPA将持久保留这两个用户,为其分配ID,然后使用该ID为您填充模型和数据库中的UserDetail.id值。
您应该维护user.userDetail引用,但是它对数据库行数据的影响较小,而出于对象一致性的原因,它应该更多。