Hibernate使用ManyToOne注释保存新条目

时间:2019-07-16 13:37:36

标签: mysql hibernate spring-boot many-to-one

我对深入了解使用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找到存在项并设置为新项?

谢谢您的建议!

2 个答案:

答案 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,因此会出错。