我有两个映射到两个数据库表的实体。一个继承自另一个。子类还与父级共享复合外键。
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
,并发现它的两个具体实现(Foo
和Bar
)都抛出错误。将@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
实体。对我来说,这远远不够工作。