用于Inheritance.JOINED子类的Spring Data Repository,包含PrimaryKeyJoinColumn和Super Key中的Composite Key

时间:2016-04-22 21:34:33

标签: java inheritance spring-data eclipselink

我有两个映射到两个数据库表的实体。一个继承自另一个。子类还与父级共享复合外键。

Foo实体

@Entity
@Table(name = "foo")
@IdClass(FooKey.class)
@Inheritance(strategy = InheritanceType.JOINED)
@DiscriminatorColumn(name = "discriminator_flag", discriminatorType = DiscriminatorType.CHAR)
@DiscriminatorValue("F")
@Customizer(FooCustomizer.class)
public class Foo {

    @Id
    @Column(name = "id_col_1")
    private String idCol1;

    @Id
    @Column(name = "id_col_2")
    private String idCol2;
    ...
}

酒吧实体

@Entity
@Table(name = "bar")
@DiscriminatorValue("B")
@PrimaryKeyJoinColumns({ @PrimaryKeyJoinColumn(name = "foo_id_col_1", referencedColumnName = "id_col_1"), @PrimaryKeyJoinColumn(name = "foo_id_col_2", referencedColumnName = "id_col_2") })
public class Bar extends Foo {
    ...
}

Foo存储库

public interface FooRepository extends CrudRepository<Foo, FooKey> {
}

Bar Repository

public interface BarRepository extends CrudRepository<Bar, FooKey> {
}

FooRepository就像一个魅力。没问题。但是BarRepository在EclipseLink 2.5.2中导致异常(Spring-data 1.7.2.RELEASE)

No @IdClass attributes exist on the IdentifiableType [EntityTypeImpl@28997437:Bar [ javaType: class com.example.Bar descriptor: RelationalDescriptor(com.example.Bar --> [DatabaseTable(foo), DatabaseTable(bar)]), mappings: 49]].  There still may be one or more @Id or an @EmbeddedId on type.

我尝试向Bar添加@IdClass(FooKey.class)注释,但它抱怨它无法在实体上看到匹配的@Id字段(当然它们在超类上)

任何人都有任何想法如何为此成功实现BarRepository?

更新

我认为这是EclipseLink的问题及其在继承结构中处理复合键。我尝试使用MappedSuperclass执行此操作,并将Foo中的密钥和公共项移动到AbstractFoo,并发现它的两个具体实现(FooBar)都抛出错误。将@IdClass注释添加到两者作为变通方法被证明是无用的。

删除复合键并用简单的单个属性@Id替换它的工作是什么。一切正常。

因此面临着重构所有内容以使用单个密钥,然后在数据库级别对我的两个复合键列强制执行唯一约束或删除继承并应用从Bar到Foo的@OneToOne映射的选项@PrimaryKeyJoinColumns并级联所有操作,我使用了cop-out选项2.所以我的Bar实体现在看起来像

酒吧实体

@Entity
@Table(name = "bar")
@IdClass(BarKey.class)
public class Bar extends Foo {
    @Id
    @Column(name = "foo_id_col_1")
    private String fooIdCol1;

    @Id
    @Column(name = "foo_id_col_2")
    private String fooIdCol2;

    @OneToOne(cascade=CascadeType.ALL, fetch=FetchType.EAGER)
    @PrimaryKeyJoinColumns({ @PrimaryKeyJoinColumn(name = "foo_id_col_1", referencedColumnName = "id_col_1"), @PrimaryKeyJoinColumn(name = "foo_id_col_2", referencedColumnName = "id_col_2") })
    Private Foo foo;
    ...
}

现在我的BarRepository工作正常,我需要创建一个Foo实体并在我坚持之前将其附加到Bar实体。对我来说,这远远不够工作。

0 个答案:

没有答案