java - 多对多映射 Hibernate 出现 ConstraintViolationException

标签 java hibernate many-to-many

这是相关的Java代码

角色.Java

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


private static final long serialVersionUID = 1L;

@Id
@Column(name = "id")
private int id;

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

@OneToMany(mappedBy = "pk.role", cascade=CascadeType.ALL)
private Set<UserRoles> userRoles = new HashSet<UserRoles>();
//Getters and Setters
}

User.Java

@Entity
@Table(name = "user")
public class User extends BasicModel{

@Id
@Column(name = "id")
private int id;

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

@Column(name = "email")
private String email;

@Column(name = "password")
private String password;

@OneToMany(mappedBy = "pk.user", cascade=CascadeType.ALL)
private Set<UserRoles> userRoles = new HashSet<UserRoles>();
//getters and setters
}

UserRoles.Java

@Entity
@Table(name = "user_roles")
@AssociationOverrides({
@AssociationOverride(name = "pk.user", 
    joinColumns = @JoinColumn(name = "user_id")),
@AssociationOverride(name = "pk.role", 
    joinColumns = @JoinColumn(name = "role_id")) })
public class UserRoles extends BasicModel {


private static final long serialVersionUID = 1L;

@Id
@Column(name = "id")
private int id;

@EmbeddedId
private UserRoleId pk = new UserRoleId();
//Getters and Setters
}

**UserRoleId.java**
public class UserRoleId {

@ManyToOne
private User user;

@ManyToOne
private Role role;
//Getters and Setters
}

这是我用来插入的代码

tx = session.beginTransaction();
User user = new User();

user.setName("admin");
user.setPassword("admin");
user.setEmail("admin@admin.com");

Role role = new Role();

role.setRoleName("admin");

session.save(role);

UserRoles userRole = new UserRoles();
userRole.setUser(user);
userRole.setRole(role);

user.getUserRoles().add(userRole);

session.save(user);

tx.commit();

在角色和用户类中,如果我将级联类型设置为 ALL 就像

@OneToMany(mappedBy = "pk.role", cascade=CascadeType.ALL)
private Set<UserRoles> userRoles = new HashSet<UserRoles>();

我收到以下错误

org.hibernate.exception.ConstraintViolationException: could not execute statement
at org.hibernate.exception.internal.SQLExceptionTypeDelegate.convert(SQLExceptionTypeDelegate.java:72)
at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:49)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:126)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:112)
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:190)
at org.hibernate.engine.jdbc.batch.internal.NonBatchingBatch.addToBatch(NonBatchingBatch.java:62)
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3124)
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3581)
at org.hibernate.action.internal.EntityInsertAction.execute(EntityInsertAction.java:104)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:463)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:349)
at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:350)
at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:56)
at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1222)
at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:425)
at org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.beforeTransactionCommit(JdbcTransaction.java:101)
at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.commit(AbstractTransactionImpl.java:177)
at com.testworks.test.dao.impl.UserDAOImpl.insertUser(UserDAOImpl.java:68)
at com.testworks.test.dao.impl.UserDAOImpl.main(UserDAOImpl.java:82)
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: 

Cannot add or update a child row: a foreign key constraint fails (`test`.`user_roles`, CONSTRAINT `FK_user_roles_user` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`))
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
at java.lang.reflect.Constructor.newInstance(Unknown Source)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:406)
at com.mysql.jdbc.Util.getInstance(Util.java:381)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1015)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:956)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3491)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3423)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1936)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2060)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2542)
at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:1734)
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2019)
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:1937)
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:1922)
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:187)
... 14 more

如果我将 CascadeType 设置为其他值,用户表和角色表会更新,但链接表 user_roles 不会更新。

这是mysql中的表结构

角色

DROP TABLE IF EXISTS `test`.`role`;
CREATE TABLE  `test`.`role` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`role_name` varchar(100) DEFAULT NULL,
`created_user` varchar(45) NOT NULL,
`created_date` datetime NOT NULL,
`updated_user` varchar(45) NOT NULL,
`updated_date` datetime NOT NULL,
  PRIMARY KEY (`id`)
  ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=latin1;

用户

DROP TABLE IF EXISTS `test`.`user`;
CREATE TABLE  `test`.`user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(50) DEFAULT NULL,
`email` varchar(50) DEFAULT NULL,
`password` varchar(64) DEFAULT NULL,
`created_user` varchar(45) NOT NULL,
`created_date` datetime NOT NULL,
`updated_user` varchar(45) NOT NULL,
`updated_date` datetime NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=latin1;

用户角色

DROP TABLE IF EXISTS `test`.`user_roles`;
CREATE TABLE  `test`.`user_roles` (
`id` int(10) NOT NULL,
`role_id` int(11) NOT NULL,
`user_id` int(11) NOT NULL,
`created_user` varchar(45) NOT NULL,
`created_date` datetime NOT NULL,
`updated_user` varchar(45) NOT NULL,
`updated_date` datetime NOT NULL,
 PRIMARY KEY (`id`),
 KEY `FK_user_roles_user` (`user_id`),
 KEY `FK_user_roles_roles` (`role_id`),
 CONSTRAINT `FK_user_roles_roles` FOREIGN KEY (`role_id`) REFERENCES `role` (`id`),
 CONSTRAINT `FK_user_roles_user` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`)
 ) ENGINE=InnoDB DEFAULT CHARSET=latin1;

请帮忙。

最佳答案

我浏览了此链接

http://developmentality.wordpress.com/2011/05/23/hibernate-mysql-mac-foreign-key-nightmares-a-painless-solution-to-a-painful-problem/

并执行此命令

show engine innodb status

在mysql命令行中发现,生成的查询是这样的

insert into user_roles (created_date, created_user, updated_date, updated_user, role_id, user_id, id) values ('2014-11-01 11:57:03', 'test', '2014-11-01 11:57:03', 'test', 0, 0, 0);

这是因为

user_id 和 role_id 的值没有增加。

现在我添加了这一行

@GeneratedValue(strategy = GenerationType.IDENTITY)

在用户和角色表中自动生成 ID,问题现已解决。

谢谢!

关于java - 多对多映射 Hibernate 出现 ConstraintViolationException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26686052/

相关文章:

java - 在 Tomcat 上远程编辑 SpringSource 应用程序

java - 以编程方式指定要在 Hibernate 中加载的类

hibernate - Hibernate 面试时会问哪些问题?

python - django 多对多比较

django - 当关系包含属性时,如何在django中实现多对多关系?

mysql - 一个帐户有多个具有相同用户属性的好友?如何在 DB 中实现它以及它在 ER 图中的样子

java - 提取并执行任意 Java 字节码序列

java - 在 java.util.function.Predicate 中执行 IO 操作

java - Oracle 是否会自动回滚废弃的 session ?

java - 在 QueryDSL 中使用相同的 q-object 时对象已被使用