我正在使用多对多关系开发一个粗糙的Web应用程序,但实际上我在更新行时遇到问题。当我从用户存储库中调用currentSession.saveOrUpdate(user)
时,会引发以下异常:org.hibernate.NonUniqueObjectException: A different object with the same identifier value was already associated with the session
。
这是我的代码:
控制器:
@Autowired
private UserService userService;
@Autowired
private TeamService teamService;
@GetMapping("/")
public String listProjects(Model theModel) {
/*
* To get the username using Spring Security
*/
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
String username = auth.getName();
theModel.addAttribute("username", username);
/*
* Get the current user by username
*/
User user = userService.findByUsername(username);
/*
* Get the teams of the current user
*/
List<Team> theTeams = user.getTeams();
System.out.println(user);
System.out.println(theTeams);
//Add teams to the model attribute
theModel.addAttribute("teams", theTeams);
return "home";
}
@GetMapping("renameTeamForm")
public String showNewTeamForm(@RequestParam("teamId") int teamId, Model theModel) {
Team team = teamService.findTeamById(teamId);
// team.setTeamName(team.getTeamName());
theModel.addAttribute("team",team);
return "rename-team-form";
}
@PostMapping("/saveTeam") public String
saveOrUpdateTeam(@ModelAttribute("team") Team theTeam) {
Authentication auth =
SecurityContextHolder.getContext().getAuthentication(); String username =
auth.getName();
User user = userService.findByUsername(username);
// GET TEAMS OF CURRENT USER
System.out.println("Inside showNewTeamForm method");
System.out.println(user.getTeams());
user.addTeam(theTeam);
System.out.println("The Team: " + theTeam);
userService.saveUser(user);
return "redirect:/"; }
实体:
@Entity
@Table(name = "users")
public class User {
@Id
@Column(name = "username", unique = true,
nullable = false, length = 50)
private String userName;
@Column(name = "password",
nullable = false, length = 68)
private String password;
@Column(name = "enabled", nullable = false)
private int enabled;
@ManyToMany(cascade= CascadeType.ALL , fetch = FetchType.LAZY)
@JoinTable(name="users_teams",
joinColumns=@JoinColumn(name="username"),
inverseJoinColumns=@JoinColumn(name="teams_id"))
private List<Team> teams;
public User() {
}
public User(String userName, int enabled, List<Team> teams) {
this.userName = userName;
this.enabled = enabled;
this.teams = teams;
}
public String getUserName() {
return this.userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassword() {
return this.password;
}
public void setPassword(String password) {
this.password = password;
}
public int isEnabled() {
return this.enabled;
}
public void setEnabled(int enabled) {
this.enabled = enabled;
}
public List<Team> getTeams() {
return teams;
}
public void setTeams(List<Team> teams) {
this.teams = teams;
}
public void addTeam(Team team) {
if (teams == null) {
teams = new ArrayList<>();
}
teams.add(team);
}
}
。
@Entity
@Table(name = "teams")
public class Team {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="id")
private int id;
@Column(name = "teamname")
private String teamName;
@ManyToMany(cascade= CascadeType.ALL,fetch = FetchType.LAZY)
@JoinTable(name="users_teams",
joinColumns=@JoinColumn(name="teams_id"),
inverseJoinColumns=@JoinColumn(name="username"))
private List<User> users;
// getters and setters
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public Team() {
// TODO Auto-generated constructor stub
}
public Team(String teamName) {
this.teamName = teamName;
}
public String getTeamName() {
return teamName;
}
public List<User> getUsers() {
return users;
}
public void setUsers(List<User> users) {
this.users = users;
}
public void setTeamName(String teamName) {
this.teamName = teamName;
}
}
存储库:
@Repository
public class UserDaoImpl implements UserDao {
@Autowired
SessionFactory sessionFactory;
@Override
public User findUserByUsername(String email) {
Session currentSession = sessionFactory.getCurrentSession();
String hql = "from User u where u.userName = :username";
Query<User> query = currentSession.createQuery(hql, User.class);
query.setParameter("username",email);
User user = (User) query.getSingleResult();
if (user !=null) {
Hibernate.initialize(user.getTeams());
}
return user;
}
@Override public void saveUser(User user) {
Session currentSession = sessionFactory.getCurrentSession();
currentSession.saveOrUpdate(user);
}
@Override
public List<User> findAllUsers() {
Session currentSession = sessionFactory.getCurrentSession();
String hql = "from User order by userName";
Query<User> query = currentSession.createQuery(hql, User.class);
List<User> users = query.getResultList();
return users;
}
。
@Repository
public class TeamDaoImpl implements TeamDao {
@Autowired
private SessionFactory sessionFactory;
@Override
public List<Team> findAllTeams() {
System.out.println("Finding all groups");
// get the current hibernate session
Session currentSession =
sessionFactory.getCurrentSession();
// Find all groups
Query<Team> theQuery = currentSession.createQuery("from Team order by teamName", Team.class);
// execute query and get result list
List<Team> teams = theQuery.getResultList();
// return the results
return teams;
}
@Override
public List<Team> findTeamsByUsername(String email) {
// get the current hibernate session
Session currentSession = sessionFactory.getCurrentSession();
// Find all groups
Query<Team> theQuery = currentSession.createQuery("from Team order by teamName", Team.class);
// execute query and get result list
List<Team> teams = theQuery.getResultList();
// return the results
return teams;
}
@Override
public void saveTeam(Team theTeam) {
Session currentSession = sessionFactory.getCurrentSession();
//save team
currentSession.save(theTeam);
}
@Override
public void deleteTeam(int teamId) {
Session currentSession = sessionFactory.getCurrentSession();
//delete object with primary key
Query theQuery = currentSession.createQuery("delete from Team where id=:teamId");
theQuery.setParameter("teamId", teamId);
theQuery.executeUpdate();
}
@Override
public Team findTeamById(int teamId) {
Session currentSession = sessionFactory.getCurrentSession();
String hql = "FROM Team T WHERE T.id = :teamid";
Query<Team> query = currentSession.createQuery(hql, Team.class);
query.setParameter("teamid",teamId);
Team team = (Team) query.getSingleResult();
if (team !=null) {
Hibernate.initialize(team.getUsers());
}
return team;
}
}
服务:
@Service
@Transactional
public class UserServiceImpl implements UserService {
@Autowired
private UserDao dao;
@Override
public User findByUsername(String email) {
// TODO Auto-generated method stub
return dao.findUserByUsername(email);
}
@Override public void saveUser(User user) {
dao.saveUser(user);
}
@Override
public List<User> findAllUsers() {
return dao.findAllUsers();
}
}
。
@Service
@Transactional
public class TeamServiceImpl implements TeamService {
@Autowired
private TeamDao dao;
@Override
public List<Team> findAllTeams() {
return dao.findAllTeams();
}
@Override
public void saveTeam(Team theTeam) {
dao.saveTeam(theTeam);
}
@Override
public void deleteTeam(int teamId) {
dao.deleteTeam(teamId);
}
@Override
public Team findTeamById(int teamId) {
return dao.findTeamById(teamId);
}
}
我尝试用merge替换saveOrUpdate,并且抛出异常Multiple representations of the same entity
也不起作用。
我还在session.evict()
之后添加了session.saveOrUpdate()
,并且发生了相同的异常。
我的代码有什么问题?我在交易中没有看到我的对象团队的任何重复...我缺少什么吗?