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 只会在数据库写入后设置,因此会出现错误。