当我保存实体时,依赖集合会重复 [英] Dependent collection duplicates when I save entity

查看:113
本文介绍了当我保存实体时,依赖集合会重复的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  @Entity 
@Table(name =terminal_admin_role)
public class AdminRole {

@Id
@Column(name =role_id,nullable = false,unique = true)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator =user_id)
@SequenceGenerator(name =user_id,sequenceName =user_id)
private长管理员ID;

@Column(name =role)
私人字符串角色;

public AdminRole(String role){
this.role = role;
}

public AdminRole(){
}

//获得集合

@Override
public String toString(){
返回角色;

$ b @Override
public boolean equals(Object o){
if(this == o){
return true;
}
if(!(o instanceof AdminRole)){
return false;
}

AdminRole adminRole =(AdminRole)o;

if(!role.equals(adminRole.role)){
return false;
}

返回true;


@Override
public int hashCode(){
return role.hashCode();


code




  @Entity 
@Table(name =terminal_admin)
public class TerminalAdmin {
@ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
@JoinTable(name =admin_role,joinColumns = {
@JoinColumn(name =admin_id,nullable = false)},
inverseJoinColumns = {@JoinColumn (name =role_id,
nullable = false)})
private Set< AdminRole> adminRoles;
// ...
}

以下代码执行:< b
控制器:

  @RequestMapping(value =/ admin / addNewAdmin)
public String adminUsers(@ModelAttribute @Valid TerminalAdmin terminalAdmin,
BindingResult bindingResult,ModelMap模型,Principal主体,HttpSession会话){
...
terminalAdmin.setCreateDate(Calendar.getInstance());
terminalAdminService.saveTerminalAdmin(terminalAdmin);
...
}

服务:

  @Override 
@Transactional
public void saveTerminalAdmin(TerminalAdmin newAdmin){
String rawPassword = newAdmin.getPassword();
newAdmin.setPassword(passwordEncoder.encode(newAdmin.getPassword()));
terminalAdminDao.save(newAdmin);
emailService.sendAdminCreatedEmail(rawPassword,newAdmin.getEmail(),newAdmin.getAdminRoles());
emailService.sendAdminRegisteredForAdminEmail(newAdmin);

dao:

  @Override 
@Transactional
public void save(TerminalAdmin terminalAdmin){
sessionFactory.getCurrentSession()。save(terminalAdmin);





之后我看到管理员角色绑定到用户在AdminRole表中重复的数据库。



我错了什么?我写过equals方法。



PS



在调试前保存我看到以下值:



因为在你的新的 TerminalAdmin ,它引用的 AdminRole 不包含ID。 ID是实体的身份。它不使用 equals()来标识身份。没有ID,Hibernate简单地把它作为一个新的 AdminRole 来保存到数据库(因为你已经在 TerminalAdmin $ b


$ b

您可以选择一些选项


  1. 更改ID您的 AdminRole 添加到角色字符串,或/和

  2. 查找通过角色字符串修正 AdminRole ,并将它们设置在新的 TerminalAdmin 实体或/和

  3. 包含传入请求中的 AdminRole ID等等。


I have following domain mapping:

@Entity
@Table(name = "terminal_admin_role")
public class AdminRole {

    @Id
    @Column(name = "role_id", nullable = false, unique = true)
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "user_id")
    @SequenceGenerator(name = "user_id", sequenceName = "user_id")
    private Long adminId;

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

    public AdminRole(String role) {
        this.role = role;
    }

    public AdminRole() {
    }

    // get set

    @Override
    public String toString(){
        return role;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (!(o instanceof AdminRole)) {
            return false;
        }

        AdminRole adminRole = (AdminRole) o;

        if (!role.equals(adminRole.role)) {
            return false;
        }

        return true;
    }

    @Override
    public int hashCode() {
        return role.hashCode();
    }
}

and

@Entity
@Table(name = "terminal_admin")
public class TerminalAdmin {
    @ManyToMany(fetch=FetchType.EAGER,cascade=CascadeType.ALL)
    @JoinTable(name = "admin_role", joinColumns = { 
        @JoinColumn(name = "admin_id", nullable = false) }, 
        inverseJoinColumns = { @JoinColumn(name = "role_id", 
                nullable = false) })
    private Set<AdminRole> adminRoles;      
    //...
}

and following code to execute:
controller:

@RequestMapping(value = "/admin/addNewAdmin")
public String adminUsers(@ModelAttribute @Valid TerminalAdmin terminalAdmin,
        BindingResult bindingResult, ModelMap model, Principal principal, HttpSession session) {
    ...
    terminalAdmin.setCreateDate(Calendar.getInstance());
    terminalAdminService.saveTerminalAdmin(terminalAdmin);
    ...
 }

service:

@Override
@Transactional
public void saveTerminalAdmin(TerminalAdmin newAdmin) {
    String rawPassword = newAdmin.getPassword();
    newAdmin.setPassword(passwordEncoder.encode(newAdmin.getPassword()));
    terminalAdminDao.save(newAdmin);
    emailService.sendAdminCreatedEmail(rawPassword, newAdmin.getEmail(), newAdmin.getAdminRoles());
    emailService.sendAdminRegisteredForAdminEmail(newAdmin);
}

dao:

@Override
@Transactional
public void save(TerminalAdmin terminalAdmin) {
    sessionFactory.getCurrentSession().save(terminalAdmin);
}

After it I see that admin roles binded to user duplicated in AdminRole table in database.

What Do I wrong? I have wrote equals method.

P.S.

before saving in debug I see following values:

解决方案

Because in your new TerminalAdmin, the AdminRole it is referring does not contain ID. ID is the identity of entities. It does not use equals() to identify the identity. Without IDs, Hibernate simply treat it as a new AdminRole to be persisted to DB (as you have set corresponding cascade options in TerminalAdmin)

There are some choices you may take

  1. Change the ID of your AdminRole to the role String, or/and
  2. Lookup the correct AdminRole by role string, and set them in your new TerminalAdmin entity, or/and
  3. Contains the AdminRole ID in the incoming request, etc...

这篇关于当我保存实体时,依赖集合会重复的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆