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

时间:2015-04-11 17:07:05

标签: java hibernate jpa orm jpql

我有一个Company实体,我用Hibernate的JPQL查询获取。该实体与Keyword实体具有多对多关联。由于连接表有一个附加列is_active,因此该表已映射到CompanyKeyword实体。这样的关联是这样的:

  

公司< - CompanyKeyword - >关键字

现在,来自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;
    }
}

对于“正常”的多对多关联,这将很有效,因为所有关联的实体都将在单个查询中获取。但是,由于我在CompanyKeyword之间有一个实体,因此Hibernate只会初始化关联的第一部分,即从Company到{{1} },而不是从CompanyKeywordCompanyKeyword。我希望这是有道理的。我正在寻找一种方法来初始化这种关联,而不必做这样的事情:

Keyword

上述代码既不干净,也不符合性能。如果可能的话,我想坚持使用当前的方法来使用JPQL查询来获取我的Company company = this.companyRepository.findOneWithSomeCustomQuery(companyId); Hibernate.initialize(company.getCompanyKeywords()); for (CompanyKeyword ck : company.getCompanyKeywords()) { Hibernate.initialize(ck.getKeyword()); } 实体,然后再初始化某些关联;在我的项目中改变它需要相当多的重构。我应该“手动”获取与第二个JPQL查询的关联,还是有更好的方法来做我没想过的?

以下是我的映射。提前谢谢!

公司

Company

CompanyKeyword

@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
}

CompanyKeywordPK

@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
}

关键字

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()
}

1 个答案:

答案 0 :(得分:0)

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

您也可以通过简单地循环和初始化每个实体,并通过启用batch fetching来避免执行太多查询。