2014-11-01 91 views
1

這是有關Java代碼許多一對多映射的Hibernate越來越ConstraintViolationException

Role.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("[email protected]"); 

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(); 

在角色和用戶類,如果我設置CascadeType的所有像

@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設置爲其他值,用戶表和角色表g ets更新並且鏈接表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; 

user_roles

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; 

請幫忙。

回答

1

我通過此鏈接

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

去和在MySQL命令行執行該命令

show engine innodb status 

,發現,產生這樣

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和問題現已解決。

謝謝!