Ошибка выброса saveOrUpdate: то же значение идентификатора уже было связано с сеансом - PullRequest
0 голосов
/ 01 апреля 2019

Я работаю над грубым веб-приложением, использующим отношения «многие ко многим», но у меня действительно проблема с обновлением строки.Когда я вызываю 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);
}
}

Я попытался заменить saveOrUpdate слиянием, и оно не сработало, выдав исключение Multiple representations of the same entity.

Я также добавил session.evict() после session.saveOrUpdate(), и произошло то же исключение.

В чем проблема в моем коде?Я не вижу дубликатов моей объектной команды, вызванной в моей транзакции ... Что-то мне не хватает?

...