【问题标题】:Hibernate save new entry with ManyToOne annotationHibernate 使用 ManyToOne 注释保存新条目
【发布时间】:2019-07-16 13:37:36
【问题描述】:

我对使用 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 - 已用数据初始化。这是非常重要的。我想在为用户创建新条目时连接该信息。

所以用户有数据,f.e.

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 为空; -> 错误:无法执行语句; SQL [不适用];约束[唯一];嵌套异常是 org.hibernate.exception.ConstraintViolationException: could not execute statement

使用连接到现有条目保存新条目的正确方法是什么?我的意思是,我应该通过 id 找到存在条目并设置为新条目?

感谢您的建议!

【问题讨论】:

  • 您的服务是事务性的吗?即您是否在类或方法级别添加了@Transactional 注释?
  • 您的问题与@ManyToOne注解无关,您应该可以自己创建User没有问题。
  • 是的。具有来自org.springframework.transaction.annotation.Transactional 的注释@Service 和@Transactional。
  • id for new user is null。所以问题在于用户 ID 而不是 Fk 到用户组?什么是数据库?
  • 错误 id for new user is null 表示问题出在 ID 而不是关系上。为什么不启用 SQL 日志记录并在此处发布完整的堆栈跟踪以澄清确切的问题。

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


【解决方案1】:

两个实体的更新如下。

@Id
@Column(name = "id") //removed attributes unique = true, nullable = false
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

通过指定nullable = false,,Hibernate 在写入数据库之前检查 ID 是否为空。但是使用GenerationType.IDENTITY,ID只会在数据库写入后设置,因此会出错。

【讨论】:

  • 这就是解决方案!谢谢!
【解决方案2】:

我认为您的问题不是 ManyToOne 关系本身,而是用户的 id 生成。使用GenerationType.IDENTITY,您应该为您将保存的每个用户提供一个标识符(我在您提供的代码部分中没有看到该部分),除非数据库具有内部 id 生成(如 postgres 中的序列号)。

至于保存连接到其他现有条目的条目的方式,您正在做的应该可以正常工作。另一种方法可能是通过仅设置已知 id 而不从数据库加载它来初始化 UserGroup。当然,如果 id 无效,您将面临引用错误。

【讨论】:

  • 添加user.setId(-1L);后错误是一样的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-04
  • 2013-11-27
相关资源
最近更新 更多