Hibernate 在尝试使用合并方法更新对象时抛出 DataIntegrityViolationException
Posted
技术标签:
【中文标题】Hibernate 在尝试使用合并方法更新对象时抛出 DataIntegrityViolationException【英文标题】:Hibernate throws DataIntegrityViolationException when trying to update object using merge method 【发布时间】:2015-04-22 10:28:32 【问题描述】:以前的update()
方法是抛出different object with the same identifier value was already associated with the session
,所以我将dao 更改为merge。现在它给了org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint [null]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement
团队DAOImpl
public void updateTeam(Team team)
Team teamToUpdate = getTeam(team.getId());
teamToUpdate.setName(team.getName());
teamToUpdate.setRating(team.getRating());
Set<TeamMember> teamMember = team.getTeamMembers();
teamToUpdate.setTeamMembers(teamMember);
getCurrentSession().merge(teamToUpdate);
团队实体
@Entity
@Table(name="teams")
public class Team
private Integer id;
private String name;
private Integer rating;
private Set<TeamMember> teamMembers;
// ...
@ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
@JoinTable(name = "team_member", joinColumns =
@JoinColumn(name = "FK_Team_id", referencedColumnName= "id"),
inverseJoinColumns = @JoinColumn(name = "FK_Member_id", referencedColumnName = "id")
)
public Set<TeamMember> getTeamMembers()
return teamMembers;
public void setTeamMembers(Set<TeamMember> teamMembers)
this.teamMembers = teamMembers;
Team
与团队成员建立多对多关系。在 SQL 级别上,它使用表完成:teams
、member
、team_member
。
违反了哪些约束?如何解决?
更新:
CREATE TABLE `member` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(45) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `teams` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(45) NOT NULL,
`rating` int(11) NOT NULL,
`FK_Organization_id` int(11) NOT NULL,
PRIMARY KEY (`id`),
KEY `FK_Organization_id` (`FK_Organization_id`),
CONSTRAINT `FK_Organization_id` FOREIGN KEY (`FK_Organization_id`) REFERENCES `organization` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `team_member` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`FK_Member_id` int(11) NOT NULL,
`FK_Team_id` int(11) NOT NULL,
PRIMARY KEY (`id`),
CONSTRAINT `FK_Member_id` FOREIGN KEY (`id`) REFERENCES `member` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT `FK_Team_id` FOREIGN KEY (`id`) REFERENCES `teams` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
错误 o.h.e.jdbc.spi.SqlExceptionHelper - 无法添加或更新子项 行:外键约束失败(
db
.team_member
, 约束FK_Member_id
外键 (id
) 引用member
(id
) 删除时没有操作更新没有操作)
数据:
UPDATE3
public Team getTeam(int id)
Team team = (Team) getCurrentSession().get(Team.class, id);
return team;
更新4 P6Spy 帮助发现错误查询:
insert into team_member (FK_Team_id, FK_Member_id) values (2, 2);
返回:
[SQL] insert into team_member (FK_Team_id, FK_Member_id) values (2, 2);
[Err] 1452 - Cannot add or update a child row: a foreign key constraint fails (`db`.`team_member`, CONSTRAINT `FK_Member_id` FOREIGN KEY (`id`) REFERENCES `member` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION)
【问题讨论】:
这可能是您的级联问题。只是为了测试,尝试不设置团队成员并尝试设置另一个字段(不使用级联)以查看会发生什么。 如果没有在TeamDAOImpl
中设置teamMembers,它可以正常工作(更新除teamMembers 之外的所有成员)
您能否发布您在执行 update() 或合并时提供的示例值..?
所以你有Team teamToUpdate = getTeam(team.getId());
,这基本上意味着team
和teamToUpdate
指向同一个团队,对吗?如果是这样,请尝试将 Set<TeamMember> teamMember = team.getTeamMembers();
更改为使用 teamToUpdate.getTeamMembers();
teamToUpdate
是另一个从传递的team
中选取更改的对象。建议更改后没有错误和更新发生
【参考方案1】:
问题出在team_member
表中的CONSTRAINT 定义中。而不是:
CONSTRAINT `FK_Member_id` FOREIGN KEY (`id`) REFERENCES `member` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT `FK_Team_id` FOREIGN KEY (`id`) REFERENCES `teams` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
必须是
CONSTRAINT `FK_Member_id` FOREIGN KEY (`FK_Member_id`) REFERENCES `member` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT `FK_Team_id` FOREIGN KEY (`FK_Team_id`) REFERENCES `teams` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
【讨论】:
以上是关于Hibernate 在尝试使用合并方法更新对象时抛出 DataIntegrityViolationException的主要内容,如果未能解决你的问题,请参考以下文章
Spring / Hibernate - 删除实体时抛出 StaleStateException