gpt4 book ai didi

java - hibernate Spring : @ManyToMany DataIntegrityViolationException ConstraintViolationException

转载 作者:行者123 更新时间:2023-11-30 08:29:29 27 4
gpt4 key购买 nike

我正在为 ManyToMany 之间的关系构建示例:User(1) - ()AccessLevel() - (1)Role

我已经在 J​​ava 中使用 hibernate 实现了 3 个类,如下所示:

类用户

@Entity
@Table(name="user")
public class User {
@Id
@GeneratedValue
@Column(name="USER_ID")

@ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
@JoinTable(name = "access_level", joinColumns = {
@JoinColumn(name = "user_id", nullable = false, updatable = false) },
inverseJoinColumns = { @JoinColumn(name = "role_id", nullable = false, updatable = false) })
private Set<Role> roles = new HashSet<Role>(0);

类角色

@Entity
@Table(name="role")
public class Role {

@Id
@GeneratedValue
@Column(name="role_id")
private Integer id;

@Column(name="role_name")
private String roleName;

类访问级别

@Entity
@Table(name="access_level")
public class AccessLevel {

@Id
@GeneratedValue
private Integer id;
@Column(name="role_id")
private Integer roleId;
@Column(name="user_id")
private Integer userId;

问题:

当我使用合并方法持久化 User bean 时,出现异常:

@Service
public class UserServiceImpl implements UserService {

@PersistenceContext
private EntityManager em;

@Override
@Transactional
public void save(User user) {
em.merge(user);
}

异常

org.springframework.web.util.NestedServletException: 请求过程

ing failed; nested exception is org.springframework.dao.DataIntegrityViolationException: Could not execute JDBC batch update; SQL [insert into access_level (user_id, role_id) values (?, ?)]; constraint [null]; nested exception is org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:894)
org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:789)
javax.servlet.http.HttpServlet.service(HttpServlet.java:641)
javax.servlet.http.HttpServlet.service(HttpServlet.java:722)

如您所见,hibernate 正在尝试运行此查询:

insert into access_level (user_id, role_id) values (?, ?)

从我的角度来看,即使我已将 @GeneratedValue 添加到 id 属性,hibernate 似乎也没有为 AccessLevel 生成主键。

注意:我正在使用 Postgresql 的生产环境和使用 HSQL 数据库的开发环境,这些数据库从一开始就根据实体描述创建所有模式。两种环境都会产生相同的问题。

问候,克里斯蒂安·科罗拉多

最佳答案

原因:

对于 ManyToMany 关系,您似乎不需要为“Joining Table”定义一个类。因此,如果我消除 AccessLevel 实体,逻辑将工作得很好。我进一步解释:

解释:

我在定义User类时也描述了与Role的关系:

@ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
@JoinTable(name = "access_level", joinColumns = {
@JoinColumn(name = "user_id", nullable = false, updatable = false) },
inverseJoinColumns = { @JoinColumn(name = "role_id", nullable = false, updatable = false) })
private Set<Role> roles = new HashSet<Role>(0);

这里重要的是我已经告诉 hibernate 用户实体将通过一个称为“access_level”的表与角色实体相关联,并且该表将具有 user_id 和 role_id 列以便连接以前的实体。

到目前为止,这就是 hibernate 处理多对多关系所需的全部内容,因此在合并时它会使用该信息来创建和调整此脚本:

insert into access_level (user_id, role_id) values (?, ?)

现在,当我为 AccessLevel 定义一个新实体时,问题就来了:

@Entity
@Table(name="access_level")
public class AccessLevel {

@Id
@GeneratedValue
private Integer id;
@Column(name="role_id")
private Integer roleId;
@Column(name="user_id")
private Integer userId;

现在我告诉 hibernate 有一个与 AccessLevel 实体相关的表“access_level”,它有 3 列,最重要的是 Id,它是主键。

所以我定义了两次“access_level”!

解决方案:

  • 我删除了 access_level 表的实体。
  • 我重新编写了我的生产脚本,以便获得“access_level”仅限 user_id/role_id 列。

注意:最好知道如何在不产生问题的情况下将主键添加到连接表。另一种方法是在数据库 (user_id/role_id) 中添加一个独立于 hibernate 的组合主键。

关于java - hibernate Spring : @ManyToMany DataIntegrityViolationException ConstraintViolationException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19409963/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com