我对深入了解使用ManyToOne注释保存新条目有疑问。
我有两个表:
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;
第一个表UserGroup已用数据初始化。这是非常重要的。在为用户创建新条目时,我想连接该信息。
因此,用户拥有数据,例如。
select * from usergroup;
id name
1 name1
2 name2
3 name3
我创建了UserRepository
public interface UserRepository extends JpaRepository<User, Long> {
}
这是有问题的部分!
我想添加新用户->名称和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为null; ->错误:无法执行语句; SQL [n / a];约束[unique];嵌套的异常是org.hibernate.exception.ConstraintViolationException:无法执行语句
这是使用连接到现有条目保存新条目的正确方法吗?我的意思是,我应该通过id找到存在项并设置为新项?
谢谢您的建议!
答案 0 :(得分:1)
我认为您的问题不在于ManyToOne关系本身,而是用户的ID生成。使用GenerationType.IDENTITY
时,您应该为要保存的每个用户提供一个标识符(在提供的代码部分中我看不到该部分),除非数据库具有内部ID生成(如postgres中的serial)。 / p>
关于保存连接到其他现有条目的条目的方式,您应该做的很好。另一种方法是通过仅设置一个已知ID而不从数据库加载它来初始化UserGroup。当然,如果ID无效,您将遇到参考错误。
答案 1 :(得分:1)
对于两个实体,更新如下。
@Id
@Column(name = "id") //removed attributes unique = true, nullable = false
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
通过指定nullable = false,
,Hibernate正在在写入数据库之前检查ID是否为null。但是,对于GenerationType.IDENTITY
,仅在数据库写入后才设置ID,因此会出错。