java - 怀疑hibernate JPA中的多对多关系

标签 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 时,如果我以相反的方式执行此操作,则通过添加对象 B 从类 A 中添加到表 A 中,而不是添加到 A_B 表中。

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

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

感谢您关注您的评论。

最佳答案

让我们以向 A_B 表添加记录的示例更具体一些。获取一个 User 对象和一个 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 的 Cascading 注释。使用正确的注释,您只能在更新时级联,例如不能在删除时级联。因此,如果在 User.skillsList 上设置 Cascade = CascadeType.UPDATE ,它应该只在更新时更改技能的属性。在此处阅读有关 CascadeType 枚举的更多信息:http://docs.jboss.org/hibernate/core/3.6/reference/en-US/html/objectstate.html#objectstate-transitive .

你的第三个问题我不太明白,但是你是否在A类中添加了自定义的toString方法?

关于java - 怀疑hibernate JPA中的多对多关系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24997851/

相关文章:

sql - SAP HANA - 更改密码 SQL

sql - 如何防止 Grails 在 dbCreate 期间生成默认的 Hibernate_sequence?

java - Android VM 是否可以在不终止整个 Android 应用程序的情况下垃圾收集静态变量?

java - 使用 Apache POI API 将 xlsx 转换为 csv

sql - 如何在 SQL 中获取上次运行的作业详细信息

sql - VBA快速将许多记录插入 Access 数据库

Java从http请求接收文件

java - 从 .dll 生成 Java 类

java - JPA/hibernate 大集合

java - hibernate 条件中的 SQL 'case when'