【问题标题】:JPA manually create the @JoinTableJPA 手动创建 @JoinTable
【发布时间】:2012-02-14 12:30:33
【问题描述】:

您好,我遇到了 JPA 速度慢的问题。使用 jps 映射队列模型、队列快照和事件。 这是我的实体:

@Entity
@Table(name = "cmEvent")
public class Event implements Serializable {
  private static final long serialVersionUID = -3252213465022678048L;
  @Id
  @Column(name = "eventId")
  private long eventId;

  @ManyToMany(fetch = FetchType.EAGER)
  @JoinTable(
    name = "cmEventSnap",
    joinColumns = @JoinColumn(name = "eventId"),
    inverseJoinColumns = @JoinColumn(name = "snapshotId"))
  private List<Snapshot> snapshots = new ArrayList<Snapshot>();
  // setters & getters
}

@Entity
@Table(name = "cmSnapshot")
public class Snapshot implements Serializable {
  private static final long serialVersionUID = -3892306246413539227L;
  @Id
  @GeneratedValue(strategy = GenerationType.AUTO)
  @Column(name = "snapshotId")
  private long snapshotId;

  @ManyToMany(mappedBy = "snapshots", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
  private List<Event> events = new ArrayList<Event>();
  // setters & getters
}

@Entity
@Table(name = "cmQueue")
public class Queue implements Serializable {
  private static final long serialVersionUID = 2209454705341173802L;
  @Id
  @GeneratedValue(strategy = GenerationType.AUTO)
  @Column(name = "queueId")
  private long queueId;

  @OneToMany(mappedBy = "queue", cascade = CascadeType.ALL)
  private List<Snapshot> snapshots = new ArrayList<Snapshot>();
  // setters & getters
}

所以我的问题在于,从 JPA 自动创建的事件实体的 JoinTable 变得非常大,并且随着时间的推移变得越来越慢。

我想在 eventsId 列上为该表创建索引。

有没有办法通过使用注释来做到这一点? 如果没有,我该如何手动创建可连接的新实体?

谢谢。

【问题讨论】:

  • 您使用的是 Hibernate、Toplink、...?
  • @ŁukaszRżanek 我现在正在使用 jpa,但可以添加 Hibernate。
  • @Index in 在普通的 JPA 和 Hibernate 中都不起作用。您可以手动添加索引。

标签: java jpa indexing jointable


【解决方案1】:

无法从 JPA 创建索引(尽管支持 UniqueConstraints)。您应该通过 DBMS 手动添加索引。

你可以做到,例如使用 Hibernate 和 @Index,然后在修复 this bug in Hibernate 后立即重新生成模型。 (我只是在@Index 上留下注释以表明它确实存在)

【讨论】:

  • 不,在这种情况下不能使用@Index - 这是 Hibernate 中的一个已知问题!看看here
  • @ŁukaszRżanek 更新了答案,不知道!谢谢指正。
【解决方案2】:

此时,您实际上无法使用 Java 注释对此做任何事情。这是一个众所周知的使用 JPA 的多对多的陷阱,即Hibernate。

Teneo (Eclipse EMF) 是一种可以为您做到这一点的实现(创建必要的索引)。

所以,目前,您只能在 RDBMS 上手动创建索引并发出 DDL 查询...

否则here you will find an example(具有附加功能,但总体思路相同)如何手动创建连接表。

【讨论】:

  • 对了,在阅读了错误报告之后,我提出的手动创建实体来保存这两个实体的数据的解决方案会很好吗?
  • 你能指出我该怎么做吗?我想这两个实体(事件和快照)将为 EventSnapJoin @OneToMany 保存新变量,是吗?
  • 如果您需要纯 Java 解决方案(无需手动 DDL),那么可以,您可以创建一个实体并将其分别映射为 @OneToMany 和 @ManyToOne。然后@Index 就可以了。它仍然不是完美的,你必须记住这种连接的懒惰和急切的初始化。总的来说 - 底部的痛苦......
【解决方案3】:

显然,并非所有 JPA 实现都存在在连接表上创建索引的问题,尽管显然没有 JPA 标准方法。 DataNucleus JPA 肯定会处理它(因为核心代码也被 JDO 使用,并且标准确实允许在其中使用索引)。

【讨论】:

    猜你喜欢
    • 2018-08-14
    • 1970-01-01
    • 1970-01-01
    • 2021-02-10
    • 2013-01-31
    • 2012-01-24
    • 1970-01-01
    • 2014-08-22
    • 2013-02-19
    相关资源
    最近更新 更多