【问题标题】:Can JPA/JaxB populate foreign key by itself?JPA/JaxB 可以自己填充外键吗?
【发布时间】:2015-04-09 17:34:29
【问题描述】:

我正在使用带有 JPA 注释的类将 xml 数据映射到数据库中,反之则通过 JAXB。问题是 JAXB 创建的对象不包含外键字段,因此为空。 这与下面示例中的 ownerId 相关。

有没有办法解决这个问题而无需再次遍历整个树并添加外键?

@Entity    
public class Element {
    @Id
    String id;

    @OneToMany(mappedBy = "owner", fetch = FetchType.LAZY, cascade = CascadeType.ALL)    
    private List<Property> properties;     
}

@Entity    
public class Property {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int propertyId;

    @ManyToOne(optional = false, cascade = CascadeType.ALL)
    @PrimaryKeyJoinColumn(name = "ownerId", referencedColumnName = "id")
    private Element owner;
}

【问题讨论】:

  • 您在 JPA 和 JAXB 中使用相同的模型还是将 JAXB bean 映射到 JPA bean?
  • 是的,它是同一型号。我在上面的示例中省略了类以及 getter 和 setter 方法上的 jaxb 注释。

标签: java hibernate jpa jaxb eclipselink


【解决方案1】:

关系归属性所有,因此属性必须知道相关的元素对象才能将其保存到数据库。向元素内的列表添加属性是不够的。

for (Property p : element.getProperties()) p.setOwner(element);

会用钥匙解决问题。

如果您从 XML 读取数据,通常您的属性将不包含引用的元素,只有元素将具有包含属性的列表。

您可能还想从 Property 中的 ManyToONe 中删除 CascateType.ALL,因为删除 Property 会触发删除其父元素和所有相关 Properties,这可能不是您想要的)。 但是您可能希望将 orphanRemoval = true 添加到 Element 中的 OneToMany,因此如果从列表中删除某个属性,它也会在数据库中删除。

【讨论】:

  • 感谢您的帮助。不幸的是,循环遍历所有属性听起来像是一个性能杀手。我希望有另一种方式。
  • 您可以更改映射,使关系由元素而不是属性管理。至于性能,任何“自动”解决方案可能还会循环遍历列表、检查对象缓存等。一般规则是在需要之前不要过度优化,将这些对象插入数据库至少比循环慢 100 倍他们。
  • 我尝试按照您的建议在每个属性中设置元素对象。数据库中的外键仍为 NULL。我是否也必须明确设置 ownerId ?我的理解是 JPA 应该为我这样做。
【解决方案2】:

像这样将 ownerId 属性添加到您的 Property 类中怎么样?

    @Column("ownerId", insertable=false, updatable="false")
    private ownerId;

在这种情况下,您的班级中将同时拥有 ownerIdownerownerId 是只读的,owner 用于分配/更新值。

如果您想以相反的方式将 insertable=false, updatable=false 移动到 owner 属性注释。

【讨论】:

    猜你喜欢
    • 2014-08-07
    • 1970-01-01
    • 2014-01-19
    • 1970-01-01
    • 2020-06-19
    • 2018-11-04
    • 2015-12-01
    • 2012-10-21
    • 1970-01-01
    相关资源
    最近更新 更多