@ElementCollection到非收集字段

时间:2015-02-06 12:47:19

标签: jpa eclipselink jpa-2.0

我有这个@ElementCollection映射,所以我可以带来一个没有唯一ID的遗留表来工作:

@Entity @Table(...)
@Inheritance(...) @DiscriminatorColumn(...)
class Notification { 
  @Id
  @Column(name="NOTIFICATION_ID")
  private BigInteger id;
}

@Entity
@DiscriminatorValue(...)
class SomeNotification extends Notification {

  @ElementCollection
  @CollectionTable(name="LEGACY_TABLE", joinColumns=@JoinColumn(name="NOTIFICATION_ID"))
  private Set<NotificationInfo> someInformations;

}

@Embeddable
class NotificationInfo { // few columns }

我真的无法触及LEGACY_TABLE的结构,现在我正面对这个:

@Entity
@DiscriminatorValue(...)
class SpecialNotification extends Notification {

   // ? This is not a Collection, and it can't be a ManyToOne or OneToOne
   // since there is no ID declared on NotificationInfo.
   private NotificationInfo verySpecialInformation;

}

我知道默认情况下不支持此功能,但我可以实现一个Customizer来使其与EclipseLink一起使用。关键是,对于SpecialNotification实例,只有一个NotificationInfo关联,而不是很多,这就是SomeNotification的情况。

关于我可以在定制器中开始的任何想法?

谢谢!

1 个答案:

答案 0 :(得分:1)

我不确定这会有效,但值得一试。尝试@SecondaryTable@AttributeOverride

的组合
@Entity
@SecondaryTable(name="LEGACY_TABLE", 
        pkJoinColumns=@PrimaryKeyJoinColumn(name="NOTIFICATION_ID"))
@DiscriminatorValue(...)
class SpecialNotification extends Notification {
    ...
    @Embedded
    @AttributeOverrides({
        @AttributeOverride(name="someField", column=@Column(table = "LEGACY_TABLE", name="SOME_FIELD")),
        @AttributeOverride(name="someOtherField", column=@Column(table = "LEGACY_TABLE", name="SOME_OTHER_FIELD"))
    })
    private NotificationInfo verySpecialInformation;
    ...
}

<强>更新

由于@SecondaryTable默认情况下会进行内部联接(可能不需要),因此可以使用特定于供应商的API进行处理。

如果你使用Hibernate(你不是这样,从问题标签判断,但仍然如此),可以通过optional = true设置@org.hibernate.annotations.Table来完成。

使用EclipseLink,你应该使用@DescriptorCustomizerDescriptorQueryManager#setMultipleTableJoinExpression,你可以找到一个(不是现场,但足够接近)代码示例here