Hibernate 使用 ManyToOne 注释保存新条目
Hibernate save new entry with ManyToOne annotation
我对使用 ManyToOne 注释保存新条目有深刻的理解。
我有两个table:
1) 用户组
@Entity
@Table(name="usergroup")
public class UserGroup{
@Id
@Column(name = "id", unique = true, nullable = false)
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name="name")
private String name;
@OneToMany(mappedBy="userGroup",
cascade= {CascadeType.PERSIST, CascadeType.MERGE,
CascadeType.DETACH, CascadeType.REFRESH}, fetch = FetchType.LAZY)
private List<User> users= new ArrayList<>();
//constructor, getter and setter
2) 用户
@Entity
@Table(name="user")
public class User{
@Id
@Column(name = "id", unique = true, nullable = false)
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "name")
private String name;
@ManyToOne(fetch = FetchType.LAZY, cascade= {CascadeType.PERSIST, CascadeType.MERGE,
CascadeType.DETACH, CascadeType.REFRESH}, optional = false)
@JoinColumn(name="user_group_id", referencedColumnName = "id")
private UserGroup userGroup;
第一个 table - UserGroup - 已使用数据进行初始化。这非常重要。我想在为用户创建新条目时连接该信息。
所以用户有数据,f.e。
select * from usergroup;
id name
1 name1
2 name2
3 name3
我创建了 UserRepository
public interface UserRepository extends JpaRepository<User, Long> {
}
而且是有问题的部分!
我想添加新的 User giving -> name and id 用户组。
服务:
@Override
@Transactional
public void create(String name, Long groupId) {
UserGroup userGroup = userGroupRepository.getOne(groupId);
User user = new User();
user.setName(name);
user.setUserGroup(userGroup)
userRepository.save(user);
}
问题出在哪里?
->新用户id为空;
-> 错误:无法执行语句; SQL [n/a];约束[唯一];嵌套异常是 org.hibernate.exception.ConstraintViolationException:无法执行语句
使用连接到现有条目来保存新条目是正确的方法吗?我的意思是,我应该通过 id 找到存在的条目并设置为新条目?
谢谢指教!
我认为您的问题不是 ManyToOne 关系本身,而是用户 ID 的生成。使用 GenerationType.IDENTITY
时,您应该为要保存的每个用户提供一个标识符(我在您提供的代码部分中没有看到该部分),除非数据库具有内部 ID 生成(如 postgres 中的 serial)。
至于保存与其他现有条目相关的条目的方法,您正在做的应该没问题。另一种方法是通过只设置一个已知的 id 来初始化 UserGroup,而不是从数据库中加载它。当然,如果 id 无效,您将面临引用错误。
两个实体更新如下。
@Id
@Column(name = "id") //removed attributes unique = true, nullable = false
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
通过指定 nullable = false,
Hibernate 在 写入数据库之前检查 ID 是否为空 。但是对于 GenerationType.IDENTITY
,ID 只会在数据库写入后设置,因此会出现错误。
我对使用 ManyToOne 注释保存新条目有深刻的理解。
我有两个table:
1) 用户组
@Entity
@Table(name="usergroup")
public class UserGroup{
@Id
@Column(name = "id", unique = true, nullable = false)
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name="name")
private String name;
@OneToMany(mappedBy="userGroup",
cascade= {CascadeType.PERSIST, CascadeType.MERGE,
CascadeType.DETACH, CascadeType.REFRESH}, fetch = FetchType.LAZY)
private List<User> users= new ArrayList<>();
//constructor, getter and setter
2) 用户
@Entity
@Table(name="user")
public class User{
@Id
@Column(name = "id", unique = true, nullable = false)
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "name")
private String name;
@ManyToOne(fetch = FetchType.LAZY, cascade= {CascadeType.PERSIST, CascadeType.MERGE,
CascadeType.DETACH, CascadeType.REFRESH}, optional = false)
@JoinColumn(name="user_group_id", referencedColumnName = "id")
private UserGroup userGroup;
第一个 table - UserGroup - 已使用数据进行初始化。这非常重要。我想在为用户创建新条目时连接该信息。
所以用户有数据,f.e。
select * from usergroup;
id name
1 name1
2 name2
3 name3
我创建了 UserRepository
public interface UserRepository extends JpaRepository<User, Long> {
}
而且是有问题的部分!
我想添加新的 User giving -> name and id 用户组。
服务:
@Override
@Transactional
public void create(String name, Long groupId) {
UserGroup userGroup = userGroupRepository.getOne(groupId);
User user = new User();
user.setName(name);
user.setUserGroup(userGroup)
userRepository.save(user);
}
问题出在哪里?
->新用户id为空; -> 错误:无法执行语句; SQL [n/a];约束[唯一];嵌套异常是 org.hibernate.exception.ConstraintViolationException:无法执行语句
使用连接到现有条目来保存新条目是正确的方法吗?我的意思是,我应该通过 id 找到存在的条目并设置为新条目?
谢谢指教!
我认为您的问题不是 ManyToOne 关系本身,而是用户 ID 的生成。使用 GenerationType.IDENTITY
时,您应该为要保存的每个用户提供一个标识符(我在您提供的代码部分中没有看到该部分),除非数据库具有内部 ID 生成(如 postgres 中的 serial)。
至于保存与其他现有条目相关的条目的方法,您正在做的应该没问题。另一种方法是通过只设置一个已知的 id 来初始化 UserGroup,而不是从数据库中加载它。当然,如果 id 无效,您将面临引用错误。
两个实体更新如下。
@Id
@Column(name = "id") //removed attributes unique = true, nullable = false
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
通过指定 nullable = false,
Hibernate 在 写入数据库之前检查 ID 是否为空 。但是对于 GenerationType.IDENTITY
,ID 只会在数据库写入后设置,因此会出现错误。