【问题标题】:JPA and a novice's issue with relationship-mappingJPA 和关系映射的新手问题
【发布时间】:2012-10-24 13:41:27
【问题描述】:

我正在尝试使以下类型的映射工作

Table event has the following columns:
id (PK)
prodgroup
errandtype

table errandtype : errandtype

table prodgroup: prodgroup

我有相应的 JPA 类

@Entity
@Table(name="event")
public class MyEvent {
    @Id
    int id;

    // what mapping should go here?
    Prodgroup prodgroup;

    // what mapping should go here?
    ErrandType errandtype;
} 

@Entity
public class Prodgroup {
    @Id
    private String prodgroup;
}

@Entity
public class ErrandType {
    @Id
    private String errandtype;
}

好的,所以问题在代码中被标记为 cmets,但无论如何我会尽量明确。

在上面的示例中,我希望将 MyEvent 类中的 Prodgroup 和 ErrandType 字段设置为相应的 Prodgroup 和 Errandtype 实例

我已经尝试过 @OneToOne 与 @joincolumns 和 mappedby 属性的关系,但我就是无法让它工作,而且我已经失去了所有逻辑方法的感觉。我对 JPA 实体映射的掌握显然很薄弱。

那么任何人都可以澄清一下吗?

【问题讨论】:

  • 您是否从 JPA 类中生成表?或者您正在尝试映射到现有表?
  • @user1697575 我正在尝试映射到现有表

标签: java jpa


【解决方案1】:

应该是:

@Entity
@Table(name="event")
public class MyEvent {
    @Id
    int id;

    // what mapping should go here?
    @ManyToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
    @JoinColumn(name = "prodgroup_id", insertable = true, updatable = true)
    Prodgroup prodgroup;

    // what mapping should go here?
    @ManyToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
    @JoinColumn(name = "errandtype_id", insertable = true, updatable = true)
    ErrandType errandtype;
} 

@Entity
public class Prodgroup {
    @Id
    private String prodgroup;
}

@Entity
public class ErrandType {
    @Id
    private String errandtype;
}

FetchType Eager 表示对象将始终被加载(如果未指定,则默认为“Lazy”)。
CascadeType.ALL 意味着 mearge/persist/remove 也将对链接表进行。

塞巴斯蒂安

【讨论】:

  • 我也会做这样的事情。但我看不出有任何理由在这种情况下使用 FetchType_EAGER。事实上,您应该避免使用它,除非由于性能问题而完全需要它。
  • @ManyToOne 注解中 fetch 的默认值是 EAGER。所以显式的 FetchType.EAGER 没有效果(当然,如果 API 不为人所知,它可能是有用的提醒)。
  • 这个答案在概念上是正确的,基本上解决了我的问题。为了让它一直工作,我不得不代理 errandtype 和 prodgroup 键。根据我收到的错误消息,PK 然后变得与整数兼容,这是必需的。如何使用单个 String 类型的 PK?对于多列 PK 有一个概念 @Embedable 但我是否也必须将这样的类用于单列但非整数 PK?
  • 是的,我认为您将需要使用@Embeddable,例如,请参阅此线程:stackoverflow.com/a/1232977/1448704
  • 但是请打开一个关于该特定主题的新主题,我想你可能会收到一个更优雅的答案。
【解决方案2】:

您的表列event.prodgroupevent.errandtype 是各自表(prodgroup、errandtype)的外键。所以你需要@ManyToOne 关联(因为许多事件可能共享一个prodgroup 或errantype)。

【讨论】:

  • 感谢您的澄清。我看到的这个关系的问题是,在 Java 的事物视图中,它实际上是一对一的映射,因为它没有父子关系(即两边都没有集合)。但是 JPA 注释显然应该与数据模型概念相关。
  • @Rythmic 如果是一对一的关联,也应该可以与@OneToOne 进行关联。我不知道你的系统,但你确定这真的是一个一对一的关联(即,一个特定的 prodgroup 或 errandtype 最多可以被 one 事件使用吗?)。
  • 不,这显然是一个多对一关联,因为某个 errandtype 和 prodgroup 都可以存在于事件表的许多行中。问题是所有显示多对一关系的示例都具有父子视图,其中父子集具有子集。在我的情况下,每个事件都只有一个差事类型和一个 prodgroup,因此在任何一个实体类中都没有集合。无论如何,它是使用上面的解决方案作为指导解决的。因此,解决方案显然是 ManyToOne,它为您赢得了支持 :) 感谢您抽出宝贵时间。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-31
相关资源
最近更新 更多