当前位置: 首页 > 知识库问答 >
问题:

使用连接表初始化Hibernate中的多对多关联

胡光霁
2023-03-14

我用Hibernate的JPQL查询获取了一个公司实体。该实体与关键字实体有多对多关联。由于联接表有一个额外的列处于活动状态,因此该表已映射到一个公司关键字实体。所以协会是这样的:

公司

现在,来自Company实体的关联是惰性的,并且它不会被我的JPQL查询初始化,因为我想避免产生笛卡尔产品性能问题。这就是为什么我想在运行JPQL查询后初始化关联,例如:

@Service
class CompanyServiceImpl implements CompanyService {
    @Autowired
    private CompanyRepository companyRepository;

    @Transactional
    public Company findOne(int companyId) {
        Company company = this.companyRepository.findOneWithSomeCustomQuery(companyId);
        Hibernate.initialize(company.companyKeywords());
        return company;
    }
}

对于“正常的”多对多关联,这将非常有效,因为所有关联实体都将在单个查询中获取。但是,由于我有一个介于公司和关键字之间的实体,Hibernate将只初始化关联的第一部分,即从公司到公司关键字,而不是从公司关键字到关键字。我希望这有意义。我正在寻找一种方法来初始化这个关联,而不必这样做:

Company company = this.companyRepository.findOneWithSomeCustomQuery(companyId);
Hibernate.initialize(company.getCompanyKeywords());

for (CompanyKeyword ck : company.getCompanyKeywords()) {
    Hibernate.initialize(ck.getKeyword());
}

上面的代码既不干净,性能也不好。如果可能的话,我想坚持我目前的方法,使用JPQL查询获取我的Company实体,然后初始化某些关联;在我的项目中改变这一点需要相当多的重构。我应该“手动”使用第二个JPQL查询获取关联,还是有我没有想到的更好的方法?

下面是我的映射。提前感谢!

公司

@Entity
@Table(name = "company")
public class Company implements Serializable {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column
    private int id;


    @Size(max = 20)
    @OneToMany(fetch = FetchType.LAZY, mappedBy = "company")
    private Set<CompanyKeyword> companyKeywords = new HashSet<>();

    // Getters and setters
}

公司关键词

@Entity
@Table(name = "company_service")
@IdClass(CompanyServicePK.class)
public class CompanyKeyword implements Serializable {
    @Id
    @ManyToOne(fetch = FetchType.LAZY, targetEntity = Company.class)
    @JoinColumn(name = "company_id")
    private Company company;

    @Id
    @ManyToOne(fetch = FetchType.LAZY, targetEntity = Keyword.class)
    @JoinColumn(name = "keyword_id")
    private Keyword keyword;

    @Column(nullable = true)
    private boolean isActive;


    // Getters and setters
}

公司关键词PK

public class CompanyServicePK implements Serializable {
    private Company company;
    private Service service;

    public CompanyServicePK() { }

    public CompanyServicePK(Company company, Service service) {
        this.company = company;
        this.service = service;
    }

    // Getters and setters

    // hashCode()

    // equals()
}

关键字

@Entity
@Table(name = "keyword")
public class Keyword {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column
    private int id;

    // Fields and getters/setters
}

共有1个答案

公冶威
2023-03-14

您确实需要执行一个额外的JPQL查询,用其companyKeyWords和每个CompanyKeyWord的关键字获取公司。

您还可以通过简单地循环和初始化每个实体来实现这一点,并且通过启用批抓取来避免执行太多查询。

 类似资料:
  • 在我的应用程序中,用户和首选项实体之间存在多对多关联。由于连接表需要一个额外的列,因此我必须将其分解为2个一对多的关联: 用户实体: 偏好实体: 用户首选项实体: 为了更新其中一个首选项,我循环浏览用户的一组首选项,并更新值如下: 我已经确认,我试图更新的用户变量在代码运行后确实包含新值。更奇怪的是,当重定向发生时,该值会在网页上更新,但数据库不会更新!这是我用来做更新的代码,这个类用@Trans

  • 问题内容: 我想在以下(简化的)数据库中应用JPA: 因此,一个节点可以具有多个权限,并且一个权限可以被多个节点引用。 我希望我的班级看起来像这样: 但是注释“ @ManyToMany”似乎仅可用于“ @JoinTable”,在这种情况下,它不可用(据我所知)。有人知道修改数据库之外是否还有其他方法吗? 问题答案: JPA不允许这样做,因为它需要外键来引用完整的主键以用于标识目的,并且它可能不适用

  • > 我有3个实体用户、应用程序和角色。 null null Role1.getUsers().Add(user);Role1.getUsers().Add(user); role2.getUsers().add(user);role2.getUsers().add(user); user.getApplications().add(app1);user.getApplications().add(

  • 我有一个关于Hibernate ManyToMany映射的问题。我有两个类 A 和 B,它们之间的映射是由 Hibernate 解析的 ManyToMany 映射: 用户和组的外键是“A_id”和“B_id”。联接表称为A_B。 现在,我想加上C。我想A_B与C有关系,与C创建多对多关系,A_B我可以称之为A_B_C。 编辑:所以我会创建一个_B实体,A和B和A_B的关系为2 @OneToMany

  • 我的数据模型中有以下实体关系。 ERD Hibernate实体: 要求:我想用实体B的连接获取查询实体C,同时也急切地获取实体D。查询完成后,我希望如果我执行,它不应导致hibernate中的N 1查询问题。 我正在尝试以下JPQL查询: 这导致结果重复,因为与实体D交叉连接。我得到的不是一个结果,而是n个结果,其中n是实体D列表的大小。 我该如何避免这种情况?有没有办法在JPQL中不交叉连接地获

  • 我有两个多对多关联的表。 DB详细信息:用户-->列[Id,name]