怀疑hibernate JPA中的多对多关系

时间:2014-07-28 14:46:57

标签: java sql hibernate jpa

我从hibernate开始有几周的时间。

我有这个代码数据库

|       TABLE A               |       
-------------------------------
idA integer not null (PK)     |
name varchar(45) not null     |
lastname varchar(45) not null |


|       TABLE B               |       
-------------------------------
idB integer not null (PK)     |
name varchar(45) not null     |
lastname varchar(45) not null |


|       TABLE A_B             |       
-------------------------------
idA integer not null (PK)     |
idB integer not null (PK)     |

这些是我在java中的实体

@Entity
public class A{

@Id
private int id;

@Column
private String name;

@Column
private String lastName;

@ManyToMany(cascade={CascadeType.ALL})
@JoinTable(name="A_B", joinColumns={@JoinColumn(name="idA")}, inverseJoinColumns={@JoinColumn(name="idB")})
private List<B> ManyB;

//Getter and Setters

}


@Entity
public class B{

@Id
private int id;

@Column
private String name;

@Column
private String lastName;

@ManyToMany(mappedBy="ManyB", cascade={CascadeType.ALL})
private List<A> ManyA;

//Getter and Setters

}

我有2个具有多对多关系的对象,我在中间表中创建了数据库,使其成为一对多的关系。我有几个问题。

1 - 。要在A_B表中添加记录,只允许我在A类中声明的列表中添加对象B,如果我反过来这样做,从A类添加对象B我在表A中添加但不在A_B表中添加。

。 2 - 如何删除或修改表A_B中的记录,而无需删除或修改表A或B中的对象。

。 3 - 当你得到所有对象的列表时,例如我得到了类A,我返回一个列表并且它包含A,并且无限递归toString,这会影响内存或程序的性能吗?

感谢您的评论。

2 个答案:

答案 0 :(得分:2)

让我们举一个向A_B表添加记录的例子。获取User对象和Skill对象。每个用户都有很多技能,但Skill还有一个名为技能所有者的用户列表。因此,User是您的表A,Skill是您的表B,Skill-owner是多对多生成的表A_B。

现在,当我想向所有者添加技能时,它也会自动成为技能所有者。在JPA设置中,您必须在两侧添加属性。具体而言,您必须将技能组合添加到技能所有者的用户和用户的技能组中。因此,在您的服务类中,您应该处理这两个存储库。

技能实体:

@Entity
public class Skill {
    @Id
    @GeneratedValue
    @Column(name = "skillId")
    private long id;
    private String skill;
    @ManyToMany(fetch = FetchType.LAZY)
    @JoinTable(name = "userSkillsList",
            joinColumns = {@JoinColumn(name = "skillId")},
            inverseJoinColumns = {@JoinColumn(name = "username")})
    private Set<User> skillOwners;

}

用户实体:

@Entity
public class User {
    @Id
    private String username;
    @ManyToMany(fetch = FetchType.LAZY,
            mappedBy = "skillOwners")
    private List<Skill> skillsList = new LinkedList<Skill>();
}    

要向用户添加技能,您可以将以下内容添加到“技能”实体或您认为最合适的位置:

public void addSkillToUser(Long s) {
    Skill skill = skillRepository.findOne(s);
    selectedUser.addSkill(skill);
    skill.addSkillOwner(selectedUser);
    userRepository.save(selectedUser);
    skillRepository.save(skill);
}

并删除:

public void deleteSkill(Skill skill) {
    selectedUser.deleteSkill(skill);
    skill.removeSkillOwner(selectedUser);
    skillRepository.save(skill);
    userRepository.save(selectedUser);
}

关于删除列表中项目的问题,您应该查看JPA / Hibernate的层叠注释。使用正确的注释,您可以仅在更新时级联,而不是在删除时级联。因此,如果在User.skillsList上设置cascade = CascadeType.UPDATE,则只应在更新时更改技能的属性。在此处阅读有关CascadeType枚举的更多信息:http://docs.jboss.org/hibernate/core/3.6/reference/en-US/html/objectstate.html#objectstate-transitive

你的第三个问题我不完全明白,但你有没有为A级添加自定义toString方法?

答案 1 :(得分:0)

如果要在两个表之间建立多对多关系,请创建一对一条目的中间表。因此,您的A-B表将具有一对一的数据插入。并使用普通查询插入和删除A-B表中的记录。通过此A-B表进行所有交易。

enter image description here